Gas
氣體消耗:從儲存讀取還是從靜態讀取?
我只是想知道從儲存中讀取一個變數需要多少氣體,而不是提供一個靜態數字。
例如
uint256 public someNumber = 123; function doSomething(...) ... { .... someNumber * 5 ...... }
相對
function doSomething(...) ... { .... 123 * 5 ...... }
差異有多大(我不知道/表示。它是微不足道的還是改變有影響力和代價高昂)?我想知道是否值得擁有一個可以稍後更改的動態變數,而不是一個靜態數字來優化氣體使用。
在版本 1 中,編譯器需要使用以下
SLOAD
指令從儲存中讀取:PUSH32 storage_slot // 3 gas SLOAD // 2K gas average (2100 with cold access / 1900 otherwise)
在版本 2 中,編譯器只會直接推送值:
PUSH32 123 // 3 gas
所以是的,差異很大,只有在必要時才使用儲存。
您可以使用以下程式碼輕鬆檢查它(我只使用彙編來最大限度地減少編譯器對 gas 成本計算的偏差,您可以完全可靠地完成它並獲得類似的東西):
//SPDX-License-Identifier: MIT pragma solidity ^0.8.4; contract TestGasCost { uint256 public someNumber = 123; function sload() public view returns (uint256 value, uint256 gasCost) { assembly { gasCost := gas() let _value := sload(someNumber.slot) gasCost := sub(gasCost, gas()) value := _value } // Returns value: 123 , gasCost: 2110 } function push() public view returns (uint256 value, uint256 gasCost) { assembly { gasCost := gas() let _value := 123 gasCost := sub(gasCost, gas()) value := _value } // Returns value: 123, gasCost: 10 } }
再次看到 2100 gas 成本的差異,這與第一個版本中的冷儲存訪問成本一致
SLOAD
。Opcodes gas 價格可能會發生變化,因此不要總是完全依賴這些值,但可以肯定地說,儲存總是比堆棧貴幾個數量級。