天天看點

以太坊學習(7)利用RPC-JSON【post|get】與節點進行互動【2】關于調用eth_sendTransaction失敗的檢查方法

關于調用eth_sendTransaction失敗的檢查方法

本篇主要講利用JSON-RPC接口調用以太坊中已經部署好的合約函數時,如果出現調用失敗的檢查方法。

 前置知識:

  • 調用eth_sendTransaction所需的abi編碼:https://www.jianshu.com/p/e8263bdb7dcf

一、假定我們有這麼一個合約

pragma solidity ^0.4.0;

contract aPlusb{
    function aPlusb(){}
    event happen(uint input,uint output);
    function plus(address addr,uint a,uint b) returns (uint){
        uint aa;
        uint bb;
        uint cc;
        uint dd;
        aa+=bb;
        bb+=1;
        cc+=3;
        dd+=cc;
        happen(a,a+1);
        return a+1;
    }
}
           

我們的目标是通過JSON-RPC接口調用這個合約中的plus函數

二、假定我們已經封裝好這個eth_sendTransaction【這裡暫不提供,需要的請聯系】

以太坊學習(7)利用RPC-JSON【post|get】與節點進行互動【2】關于調用eth_sendTransaction失敗的檢查方法

 三、我們可以使用上述封裝好的函數進行調用

以太坊學習(7)利用RPC-JSON【post|get】與節點進行互動【2】關于調用eth_sendTransaction失敗的檢查方法

四、調用eth_sendTransaction後,會傳回一個交易哈希,我們用它來檢查調用的情況

這是傳回的交易哈希:

以太坊學習(7)利用RPC-JSON【post|get】與節點進行互動【2】關于調用eth_sendTransaction失敗的檢查方法

檢查交易情況:

  • 在geth用戶端輸入如下:
  • 注意:要與傳回的哈希對應
以太坊學習(7)利用RPC-JSON【post|get】與節點進行互動【2】關于調用eth_sendTransaction失敗的檢查方法

直接傳回null,因為還沒開始挖礦确認。

确認後,再次檢查交易情況:

以太坊學習(7)利用RPC-JSON【post|get】與節點進行互動【2】關于調用eth_sendTransaction失敗的檢查方法
  • 可以看到:logs并沒有傳回事件,表明調用失敗
  • 我們再看gas使用情況:已經達到了傳入參數限制,調用失敗
  • 這一次調用是失敗了的

五、現在開始檢查

1、先來檢查一下調用時input的data

在geth用戶端輸入:

eth.getTransaction("0x12bf6dcf88c305b03f07e135a71be36b0c013031a8b3093a7529a319cc1b1215")
           

 傳回:

以太坊學習(7)利用RPC-JSON【post|get】與節點進行互動【2】關于調用eth_sendTransaction失敗的檢查方法

2、如何确認input的data是否正确呢?

(1)快速檢查func選擇器

由前置的資料可以知道,func選擇器是input的data的前4Bytes,即前8位,按上圖來看,就是0x40761d35,我們可以通過remix裡面的detail來檢查是否正确。

以太坊學習(7)利用RPC-JSON【post|get】與節點進行互動【2】關于調用eth_sendTransaction失敗的檢查方法
以太坊學習(7)利用RPC-JSON【post|get】與節點進行互動【2】關于調用eth_sendTransaction失敗的檢查方法

 由此對比,可以看見我們的func寫錯了。現在回代碼看一下:

以太坊學習(7)利用RPC-JSON【post|get】與節點進行互動【2】關于調用eth_sendTransaction失敗的檢查方法

确實是多了一個點‘.’ 

(2)如果func檢查正确的話,如何檢查data剩下的部分?

快速法:直接在remix裡面調用一次,記錄其交易哈希,然後在geth用戶端裡面查詢,對比自己程式調用的交易input

a、在remix裡面調用

以太坊學習(7)利用RPC-JSON【post|get】與節點進行互動【2】關于調用eth_sendTransaction失敗的檢查方法

b、調用成功後,複制其交易哈希

以太坊學習(7)利用RPC-JSON【post|get】與節點進行互動【2】關于調用eth_sendTransaction失敗的檢查方法

c、在geth裡面檢查

eth.getTransaction("0x99239aeee8e25b5be68dc62fbf5ab1a03f2eb592bda31d65de6d0effeeedf12e")
           
以太坊學習(7)利用RPC-JSON【post|get】與節點進行互動【2】關于調用eth_sendTransaction失敗的檢查方法

對比自己程式調用的交易發起的input:

以太坊學習(7)利用RPC-JSON【post|get】與節點進行互動【2】關于調用eth_sendTransaction失敗的檢查方法

即可快速定位錯誤

(3)如果在前置資料中看不懂input 的data如何構造,也可以通過這種方法來幫助了解data的構造,即檢視正确的input例子

(4)這裡有個線上網站,可以直接構造abi的data,可以幫助了解:https://abi.hashex.org/

六、修改錯誤,重新調用

以太坊學習(7)利用RPC-JSON【post|get】與節點進行互動【2】關于調用eth_sendTransaction失敗的檢查方法

geth裡檢查: 

以太坊學習(7)利用RPC-JSON【post|get】與節點進行互動【2】關于調用eth_sendTransaction失敗的檢查方法
  • 可以看到:
  • 這一次調用Log有傳回,表示調用成功
  • 而且gas的消耗也正常了

七、另外,調用的時候注意gas的limit限制,如果不設定,會有預設值,可能不夠消耗。

建議:先到remix的detail裡面去看一下大概的gas 消耗,或者使用gasestimate?