Gas
將狀態變數設置為相同值的 Gas 成本
根據這個規範,將狀態變數設置為相同的值會消耗 200 氣體。
但是,我在 ganache-core v2.10.2 上進行了測試,結果接近 800 gas:
Solidity 合約:
pragma solidity 0.6.12; contract MyContract { uint256 public gasUsed; uint256 public storageSlot; function func(uint256 x) public { storageSlot = x; uint256 gasLeft = gasleft(); storageSlot = x; gasUsed = gasLeft - gasleft(); } }
松露 5.x 測試:
const MyContract = artifacts.require("MyContract"); contract("MyContract", () => { it("test", async () => { const myContract = await MyContract.new(); for (let x = 0; x < 10; x++) { await myContract.func(x); const gasUsed = await myContract.gasUsed(); console.log(gasUsed.toString()); } }); });
每次迭代的列印輸出為 816,假設
gasleft()
合約函式最後一行的操作花費 16 個 gas,儲存相同的值似乎花費了 800 個 gas。我懷疑規範中的 gas 成本適用於較舊的 EVM 版本(伊斯坦布爾之前或類似的版本),其中 SLOAD 曾經花費 200 gas。
在目前的 EVM 版本中,SLOAD 已更改為 800 gas,因此我相信相同值的 SSTORE 的情況也可能已更改為 800 gas。
有人對這種差異有任何想法嗎?
根據EIP-2200和 EIP-1884 的提議(由於某種原因,我在任何地方都找不到),這種不改變的成本
SSTORE
已更改為800
gas 。我想這個值是為了向後兼容。如果你在你的規範中搜尋,你會找到和值。當一個新節點同步並驗證所有交易時,它還必須能夠理解舊的共識規則,這可能是它被包含在其中的原因。就個人而言,它也可能只是舊的未重構程式碼,我對 geth 程式碼庫不太熟悉。200``SloadGasEIP1884``SloadGasEIP1884
對於未來,我建議使用remix Web IDE來檢查和調試低級細節,例如 gas 成本。Remix 擁有我所知道的最好的調試器,允許您單獨逐步執行每個操作程式碼。