以太坊智慧合約gas如何估計?

hahajin發表於2019-02-27

以太坊如何估計估算計算gas?Etherscan上transaction info中有個gas used by txn,結果跟remix給的結果以及geth中getTransactionReceipt的gasUsed給的結果都會是一致的,可以直接用geth或是remix模擬估算gas cost。

之前一直沒把這個問題搞清楚,所以乾脆做個試驗看一下.

remix瀏覽器下方有個可執行的log頁面,可以detail以及debug,非常方便。

以太坊智慧合約gas如何估計?

有gas cost的地方有兩個地方,transaction cost以及 execution cost,這兩個有什麼不同呢?可以參考一下他們的原始碼。

簡單說一下: transaction cost指的是將交易送至ethereum blockchain所耗費的cost,是基於data size的大小,部署合約時就是基於合約內容的大小. execution cost指的是虛擬機器(VM)執行所需的cost,而在部署合約時,會去執行建構子以及一些初始化的工作.

在這裡做一個簡單的合約試驗:

contract Test {

bytes32 public tmp;

function test(

bytes32 input,

uint num

)

constant returns (bytes32){

bytes32 result = input;

for(uint i = 0; i < num; i++) {

result = sha3(result);

}

}

function set(bytes32 input, uint num) {

tmp = test(input, num);

} }
複製程式碼

如果直接呼叫constant function的話,因為是由本身節點去計算不會更改到區塊鏈上的值,是不會消耗gas的,但是如果是由一個一般合約(非constant function call)去呼叫一個constant function的話,因為讓礦工來計算constant function,所以會消耗gas.

上面的簡單合約中,我讓test函式對第一個bytes32引數做sha3,第二個uint引數代表做幾次loop,我分別對set函式和test函式帶入10以及1000的引數,結果如下.

set(“0x63d7db5ce060b288ecf5390594d5969bc1a206ceeb24df31cffcc8876df5e44b”, 10)

transaction cost:30628execution

cost:6988 
複製程式碼
set(“0x63d7db5ce060b288ecf5390594d5969bc1a206ceeb24df31cffcc8876df5e44b”, 1000)

transaction cost:196022

execution cost:172318
複製程式碼
test(“0x63d7db5ce060b288ecf5390594d5969bc1a206ceeb24df31cffcc8876df5e44b”, 10)

transaction cost:25663 (cost only applies when called by a contract)

execution cost:2023 (cost only applies when called by a contract) 

複製程式碼
test(“0x63d7db5ce060b288ecf5390594d5969bc1a206ceeb24df31cffcc8876df5e44b”, 1000)

transaction cost:191057(cost only applies when called by a contract)

execution cost:167353(cost only applies when called by a contract)
複製程式碼

ps:用transaction cost減去execution cost的話1, 3得到23640,2, 4得到23704

大致上就是這樣一個過程.發現引數設定成1000時,也會造成transaction cost的提高.(初步猜想加上ps的計算:transaction cost中是已經包含了execution cost,一併計算在最後要支付給miner的fee,因為每個相減結果都差不多)

另外geth的estimateGas的之所以會不太準確是因為一些不確定性的operator操作會不同,比如說,在一個contract中,若是blockhash的尾數是奇數,他就去執行會消耗大量gas的合約,反之則去執行hello world合約,所以他的gas cost很大的情況下是一半一半.

所以永遠要記得設定一個合理的gas limit來防止自己遭受惡意攻擊.

另外建議可以參考traceTransaction指令,可以看每一個opcode的gas cost. 為了要確認礦工處理transaction的情況,在ropsten testnet上做個簡單的試驗.首先在ropsten faucet上拿一點兒ether來玩,然後在metamask上送出交易,因為ropsten是模擬pow的環境,所以我相信應該會是正確的數字.

重要的話再說一次結論:Etherscan上transaction info中有個gas used by txn,結果跟remix給的結果以及geth中getTransactionReceipt的gasUsed給的結果都會是一致的,以後可以直接用geth或是remix模擬估算gas cost.

參考資料:以太坊DApp開發實戰入門

可以加微信拉以太坊技術群聊。

以太坊智慧合約gas如何估計?

相關文章