1. 程式人生 > >rpc接口調用以太坊智能合約

rpc接口調用以太坊智能合約

multipl 接下來 編碼 hex login UNC ive 編譯 sage

rpc接口調用以太坊智能合約



技術分享圖片
傳送門: 柏鏈項目學院



??在以太坊摸爬滾打有些日子了,也遇到了各種各樣的問題。這幾天主要研究了一下如何通過rpc接口編譯、部署和調用合約。也遇到了一些困難和問題,下面將向大家分享。

rpc接口調用智能合約

  • 先來編寫一個簡單的智能合約
contract Multiply7 {
   event Print(uint);
   function multiply(uint input) returns (uint) {
      Print(input * 7);
      return input * 7;
   }
}
  • 這是輸入一個無符號整數做乘法的合約,接下來想要用rpc接口編譯它。編譯之前先驗證geth的solidity編譯器是否可用
curl --data ‘{"jsonrpc":"2.0","method": "eth_getCompilers", "id": 3}‘ http://localhost:8545
  • 返回結果
HTTP/1.1 200 OK
Content-Type: application/json
Vary: Origin
Date: Fri, 20 Apr 2018 02:59:24 GMT
Content-Length: 121

{"jsonrpc":"2.0","id":3,"error":{"code":-32601,"message":"The method eth_getCompilers does not exist/is not available"}}
  • 這裏竟然出現了eth_getCompilers方法不可用的錯誤,查閱資料後發現geth1.6以後的版本刪除了這個功能,刪除還包括eht.compile 等功能,至於刪除原因詳見https://github.com/ethereum/EIPs/issues/209

現在只好到remix ide上進行編譯,編譯通過後點擊"Details",復制"WEB3DEPLOY"中的"data"數據,接下來部署合約

curl -i -H ‘Content-Type:application/json‘ -d ‘{"jsonrpc":"2.0","method": "eth_sendTransaction", "params": [{"from": "0x2a5026d44ab3de2094ec79dec074d4a8612a14aa", "gas": "0xfffff", "data": "0x608060405234801561001057600080fd5b5060f58061001f6000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa1146044575b600080fd5b348015604f57600080fd5b50606c600480360381019080803590602001909291905050506082565b6040518082815260200191505060405180910390f35b60007f24abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503da600783026040518082815260200191505060405180910390a16007820290509190505600a165627a7a72305820d36dc369a6f3f653b02c492e077b9cfdb114054f44f46277eaa4826e968609010029"}], "id": 6}‘ http://localhost:8545
  • 部署合約用到eth_sendTransaction方法,其中from對應的是部署合約的賬戶地址,gas對應為gas消耗量,太少會報錯。data對應的是之前復制的data

執行命令後返回了交易hasa

HTTP/1.1 200 OK
Content-Type: application/json
Vary: Origin
Date: Fri, 20 Apr 2018 14:00:58 GMT
Content-Length: 103

{"jsonrpc":"2.0","id":6,"result":"0xa31ad7bc958290c0b401ae4e046d6e93bc67db1cb038ba2953e2cffe6bdf60fa"}
  • 通過這個交易hasa可以查詢部署合約的詳細信息,我們可以用eth_getTransactionReceipt RPC方法驗證一下
curl -i -H ‘Content-Type:application/json‘ -d ‘{"jsonrpc":"2.0","method": "eth_getTransactionReceipt", "params": ["0xa31ad7bc958290c0b401ae4e046d6e93bc67db1cb038ba2953e2cffe6bdf60fa"], "id": 7}‘ http://localhost:8545

在返回的信息中,contractAddress對應的內容就是合約的地址了

HTTP/1.1 200 OK
Content-Type: application/json
Vary: Origin
Date: Fri, 20 Apr 2018 14:05:03 GMT
Content-Length: 981

{"jsonrpc":"2.0","id":7,"result":{"blockHash":"0x5480323e9a5ac26ec585ca610cb15cffbfe26f2323e19fb8d8a967e11903d6a0","blockNumber":"0x5599","contractAddress":"0x21f981af36218aaf1a40621bfe1e57cf2f43455a","cumulativeGasUsed":"0x1ce23","from":"0x2a5026d44ab3de2094ec79dec074d4a8612a14aa","gasUsed":"0x1ce23","logs":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","status":"0x1","to":null,"transactionHash":"0xa31ad7bc958290c0b401ae4e046d6e93bc67db1cb038ba2953e2cffe6bdf60fa","transactionIndex":"0x0"}}
  • 拿到合約地址後,我們可以通過eth_sendTransaction調用合約
curl -i -H ‘Content-Type:application/json‘ -d ‘{"jsonrpc":"2.0","method": "eth_sendTransaction", "params": [{"from": "0x2a5026d44ab3de2094ec79dec074d4a8612a14aa","to":"0x21f981af36218aaf1a40621bfe1e57cf2f43455a","data":"0xc6888fa10000000000000000000000000000000000000000000000000000000000000007"}], "id": 6}‘ http://localhost:8545

from對應為調用合約的賬戶,to對應為要調用的合約地址。data對應為調用方法的簽名和傳入參數,那麽我們怎麽獲取這個值呢,首先,它的編碼方式是:sha3(“multiply(uint256)”).substring(0,10)+to_32bit_Hex_str(7)

在geth中輸入:

> web3.sha3("multiply(uint256)").substring(0, 10)
"0xc6888fa1"

而參數輸入為7,最後出結果為0000000000000000000000000000000000000000000000000000000000000007,加上前面的0xc6888fa1就得到了data的值。

通過eth_sendTransaction調用合約後返回:

HTTP/1.1 200 OK
Content-Type: application/json
Vary: Origin
Date: Fri, 20 Apr 2018 14:12:06 GMT
Content-Length: 103

{"jsonrpc":"2.0","id":6,"result":"0xbe0881901ee9e52c9e969a85a1367c4a8936c5ab77fa479aaee1c780fe5d1159"}

可以看到,返回了交易哈希,我們可以用這個交易哈希查詢詳細信息,驗證是否正確,為了返回的數據格式更方便查看,我們可以在geth私有節點中輸入獲取交易詳細信息的命令:

> eth.getTransactionReceipt("0xbe0881901ee9e52c9e969a85a1367c4a8936c5ab77fa479aaee1c780fe5d1159")

返回結果:

{
  blockHash: "0xeac4d7dd5123720ebc43fbc35778de2215738af97cf723721f0260335228eb93",
  blockNumber: 22581,
  contractAddress: null,
  cumulativeGasUsed: 22804,
  from: "0x2a5026d44ab3de2094ec79dec074d4a8612a14aa",
  gasUsed: 22804,
  logs: [{
      address: "0x21f981af36218aaf1a40621bfe1e57cf2f43455a",
      blockHash: "0xeac4d7dd5123720ebc43fbc35778de2215738af97cf723721f0260335228eb93",
      blockNumber: 22581,
      data: "0x0000000000000000000000000000000000000000000000000000000000000031",
      logIndex: 0,
      removed: false,
      topics: ["0x24abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503da"],
      transactionHash: "0xbe0881901ee9e52c9e969a85a1367c4a8936c5ab77fa479aaee1c780fe5d1159",
      transactionIndex: 0
  }],
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000004000000000000000000000000000002000000000000000000040000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000",
  status: "0x1",
  to: "0x21f981af36218aaf1a40621bfe1e57cf2f43455a",
  transactionHash: "0xbe0881901ee9e52c9e969a85a1367c4a8936c5ab77fa479aaee1c780fe5d1159",
  transactionIndex: 0
}

重點來了:我們來看一下返回數據中的logs,其中可能包含調用合約的結果。可以看到logs中也有個data,值為0x0000000000000000000000000000000000000000000000000000000000000031,把這個十六進制轉換為十進制得到數字4949正好是7*7的結果,這說明我們調用合約的multiply方法成功了並得到了正確的結果。

??以太坊的JSON RPC API的用法還有很多,在這裏就不一一介紹了。無論是web3.js還是web3j,都是對以太坊JSON RPC API開發接口的封裝。研究JSON RPC API主要出於學習目的,開發DApp還是用web3.js方便一些。



技術分享圖片

rpc接口調用以太坊智能合約