標籤:

計算以太坊中 發送交易/調用合約方法 需要消耗多少gas

本文在計算調用一個合約方法需要消耗多少gas - 區塊鏈技術中文社區 同步發表

準備工作

1、三個賬戶,eth.account[0]為默認賬戶,挖礦所得的獎勵都會進入到這個賬戶

> eth.getBalance(eth.accounts[0])n736031150000000000000n> eth.getBalance(eth.accounts[1])n500050000000000000n> eth.getBalance(eth.accounts[2])n500050000000000000n

普通交易所需的gas

> eth.estimateGas({from:eth.accounts[1], to: eth.accounts[2], value:50000000000000})n21001n> eth.gasPricen20000000000n

如上,顯示這筆account[1] => account[2] 的交易需要21001 gas, 當前的gasPrice為 20000000000,下面來驗證一下

給賬戶1解鎖,發送這筆交易,並開啟挖礦打包

> eth.sendTransaction({from:eth.accounts[1], to: eth.accounts[2], value:50000000000000})nI0318 00:24:21.360815 internal/ethapi/api.go:1143] Tx(0x33b58084a35e99245b9c931204a0d161b9d00f9fae5ffb307aff29f200e5cd30) to: 0x49fbd70ca9f90972806c375a111d08950d203f96n"0x33b58084a35e99245b9c931204a0d161b9d00f9fae5ffb307aff29f200e5cd30"n

待交易被打包後

> eth.getBalance(eth.accounts[1])n499580000000000000n> eth.getBalance(eth.accounts[2])n500100000000000000n

由 cost = gas * gasPrice , ( 賬戶1減少的資產 - 賬戶2增加的資產)/ gasPrice = 消耗的gas,即以下公式應該是成立的

(500050000000000000 - 499580000000000000) - (500100000000000000 - 500050000000000000) = 21001 * 20000000000n

然而 細心的同學應該會發現,這個公式並不能成功,21001 這個數字怎麼看怎麼彆扭,如果減1 這個公式就成功了!!!繼續

查看這筆交易的明細

> eth.getTransactionReceipt("0x33b58084a35e99245b9c931204a0d161b9d00f9fae5ffb307aff29f200e5cd30")n{n blockHash: "0x8e411163367bc42a70ecc230d05dd2038afe0dccfab29c8a718a57bdbea0b2fa",n blockNumber: 134,n contractAddress: null,n cumulativeGasUsed: 21000,n from: "0x27c649b7c4f66cfaedb99d6b38527db4deda6f41",n gasUsed: 21000,n logs: [],n logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",n root: "0x2008f134f3328e48d4d05919666a5924767b00b286cf1ff27b7956654d5b6482",n to: "0x49fbd70ca9f90972806c375a111d08950d203f96",n transactionHash: "0x33b58084a35e99245b9c931204a0d161b9d00f9fae5ffb307aff29f200e5cd30",n transactionIndex: 0n}n

gasUsed: 21000 這就對上了,那麼為什麼eth.estimateGas() 計算的結果要多1 呢?這是有原因滴,如果計算出來的值和gasUsed相等,那這筆交易有可能是失敗的,但是如果 gasUsed 小於計算出來的值,那麼可以判斷這筆交易成功了

調用合約方法所需要的gas

普通的轉賬交易所需要的gas是固定的21000,但是調用合約方法所需要的gas並不一定,總結來說佔用的資源(計算量、內存等)越多,那麼所需要的gas也就越多。先準備一個最簡單的合約

pragma solidity ^0.4.8;ncontract Test {n uint public num;n function setNum(uint newNum) {n num = newNum;n }n}n

部署到私有鏈,這個過程就不再演示,最後合約實例testInstance。再看看eth.accounts[1] 和 eth.accounts[2] 的資產信息,方面後面計算

> eth.getBalance(eth.accounts[1])n499580000000000000n> eth.getBalance(eth.accounts[2])n500100000000000000n

計算調用合約方法setNum() 所需要的gas

> testInstance.setNum.estimateGas(4, {from: eth.accounts[1]})n41645n

開始調用

> testInstance.setNum.sendTransaction(4, {from: eth.accounts[1]})nI0318 07:21:31.344279 internal/ethapi/api.go:1143] Tx(0x3fad05f17f7904e08dcb9257ad28f85f29bd54c4729784fa39a9df88e3fcffab) to: 0x03a4fb357f8c38694ab536d09003076033442f9en"0x3fad05f17f7904e08dcb9257ad28f85f29bd54c4729784fa39a9df88e3fcffab"n

開啟挖礦,讓這筆交易被打包之後,再來查看下gasUsed 跟上面計算出來的數字是否吻合

> eth.getTransactionReceipt(0x3fad05f17f7904e08dcb9257ad28f85f29bd54c4729784fa39a9df88e3fcffab)n{n blockHash: "0x494f5f6fc0c156f105ffe3e4e1aa886c60f916a5998d44a03916b3f2cc733b8a",n blockNumber: 139,n contractAddress: null,n cumulativeGasUsed: 41644,n from: "0x27c649b7c4f66cfaedb99d6b38527db4deda6f41",n gasUsed: 41644,n logs: [],n logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",n root: "0x857063e074cc3195ee2f3962438f3f6c31a759cfae461448e8726a5fa069d1ae",n to: "0x03a4fb357f8c38694ab536d09003076033442f9e",n transactionHash: "0x3fad05f17f7904e08dcb9257ad28f85f29bd54c4729784fa39a9df88e3fcffab",n transactionIndex: 0n}n

可以看到gasUsed:41644 比計算出來的少1,原因上面已經講過了,這裡不再贅述!

推薦閱讀:

以太坊分叉鬧劇,以太霧 ETF or 以太修 EMO?
為什麼Q幣的價值不如後來的比特幣,以太幣?
GCS遊戲公鏈:驅動區塊鏈遊戲走向主流的基礎設施
imToken iOS 1.0.6 正式上線!
什麼是以太坊——一個從法律角度的理解

TAG:以太坊 |