數據儲存成本超出預期
我有一個簡單的契約,如下所示:
contract storage { bytes32 data; function f(uint256 _a, uint256 _b) public { bytes32 hash = keccak256(abi.encode(_a, _b)); data = hash; } }
我想了解為什麼呼叫函式 f 花費大約 44k gas,因為我讀到 SSTORE 最多花費 22k gas。燃氣費從哪裡來?謝謝你。
在這裡,您有一些與氣體消耗最相關的操作
假設您向函式 f 發送交易,分別將 1 和 2 傳遞為 _a 和 _b
這意味著您將獲得以下輸入:
0x13d1aa2e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
功能選擇器:0x13d1aa2e
參數_a:0000000000000000000000000000000000000000000000000000000000000001
參數_b:0000000000000000000000000000000000000000000000000000000000000002
如果您查看乙太坊黃皮書(第 27 頁),您會看到:您將為以下操作支付多少費用:
Gtxdatazero 4(gas 單位)為交易的每個零字節數據或程式碼付費。Gtxdatanonzero 16(gas 單位)為交易的每個非零字節數據或程式碼付費
0x13d1aa2e (函式選擇器) 4 個非零字節 => 4 * 16 (gas 單位) = 64
參數 _a:31 個零字節 + 1 個非零字節 => 31 * 4 + 1 * 16 = 140
參數_b:31個零字節+ 1個非零字節=> 31 * 4 + 1 * 16 = 140
Gkeccak256 30 為每次 KECCAK256 操作付費。Gkeccak256word 6 為 KECCAK256 操作的輸入數據支付每個字(四捨五入)
keccak256(abi.encode(_a, _b));
abi.encode(_a, _b) 的結果是:
0x00000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000
意思是兩個詞作為 keccak256 的輸入
每次 KECCAK256 操作支付 30 => 30
6 為 KECCAK256 操作的輸入數據支付每個字(四捨五入)=> 6 * 2 = 12
Gsset 20000儲存值從零設置為非零時為 SSTORE 操作付費 Gcoldsload 2100冷儲存訪問成本(第一次訪問事務中的狀態變數)
Gtransaction 21000為每筆交易付費
此外,您可以使用 remix 調試它並檢查執行的每個操作碼,在這裡您可以看到它花費了多少 gas