Solidity

數據儲存成本超出預期

  • October 11, 2022

我有一個簡單的契約,如下所示:

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

在此處輸入圖像描述

引用自:https://ethereum.stackexchange.com/questions/137256