深入解析以太坊中調用合約的三種方法

當獲取合約實例之後(比如 testInstance),在geth console中可以通過三種方法調用合約方法(比如testFunc)

  • testInstance.testFunc.sendTransaction();
  • testInstance.testFunc();
  • testInstance.testFunc.call();

本文將講解這三種調用方法的區別

  • testInstance.testFunc.sendTransaction(); 會創建一個交易,調用之後會返回一個交易hash值,它會廣播到網路,等待礦工打包, 它會消耗gas。
  • testInstance.testFunc.call(); 它完全是一個本地調用,不會向區塊鏈網路廣播任何東西,它的返回值完全取決於 testFunc 方法的代碼,不會消耗gas
  • testInstance.testFunc(); 它會比較特殊,由於有constant標識的方法不會修改狀態變數,所以它不會被編譯器執行。所以,如果testFunc() 有constant標識,它並不會被編譯器執行,web3.js會執行call()的本地操作。相反如果沒有constant標識,會執行sendTransaction()操作。

    來驗證一下

    寫個合約,代碼如下

    pragma solidity ^0.4.2;ncontract Test {n uint public testMem;nn function testFunc1() returns (string resMes){n testMem++;n resMes = "try to modify testMem,but has no constant label";n }nn function testFunc2() constant returns (string resMes){n testMem--;n resMes = "try to modify testMem and has constant label";n }n}n

    將合約部署到私有鏈,並獲取合約實例testInstance

    調用testFunc1

    > testInstance.testFunc1({from:eth.accounts[0]})nI0117 19:38:21.348763 internal/ethapi/api.go:1047] Tx(0x157d429be29953ea451ea95cf468a3a67c4a86e9b49d1b6b97cc15c579a27003) to: 0xc9bc867a613381f35b4430a6cb712eff8bb50310n"0x157d429be29953ea451ea95cf468a3a67c4a86e9b49d1b6b97cc15c579a27n

    可見,確實創建了一筆交易,開啟挖礦,等待打包…再查看下

    > testInstance.testMem()n1n> eth.getTransaction(0x157d429be29953ea451ea95cf468a3a67c4a86e9b49d1b6b97cc15c579a27003)n{nblockHash: "0x9fa0c7d071e1d2e772de3f6f326595b9d9159b0056213416018c75f2d5c04ad2",nblockNumber: 118,nfrom: "0xcb1f9cd557b5dd81955a4df89e9b4c8a33023c12",ngas: 90000,ngasPrice: 20000000000,nhash: "0x157d429be29953ea451ea95cf468a3a67c4a86e9b49d1b6b97cc15c579a27003",ninput: "0x561f5f89",nnonce: 45,nr: "0xb77558d48ab4efcaa24309b1003a7c4efabfdda26c3844c6aa18c58c6a08181a",ns: "0x57fe6dde27fa7cfd2fb422e2adc9465125750b3271127b68bb65d496d99be531",nto: "0xc9bc867a613381f35b4430a6cb712eff8bb50310",ntransactionIndex: 0,nv: "0x1c",nvalue: 0n}n

    可見,它確實是一筆交易,修改了合約的狀態變數,並且有90000的gas消耗。

    再來試下testFunc2

    > testInstance.testFunc2({from:eth.accounts[0]})n"try to modify testMem and has constant label"n

確實只是在本地執行,並沒有創建交易,所以更不會修改合約的狀態變數。


推薦閱讀:

ICO : 人傻,錢多,速來
以太坊中交易及區塊的大小限制
以太坊養貓遊戲是幹嘛的?能賺錢嗎?

TAG:以太坊 | 区块链Blockchain |