Solidity
更改 2 個狀態變數和發出 1 個事件的成本如何達到 50K gas 單位?
我有這個契約:
pragma solidity ^0.4.23; contract Test { event Event(address indexed wallet); mapping (address => bool) public authorizedWallets; uint256 public authorizedWalletCount; function add(address _wallet) external { _add(_wallet); emit Event(_wallet); } function _add(address _wallet) private { require(!authorizedWallets[_wallet]); authorizedWallets[_wallet] = true; authorizedWalletCount++; } }
我正在檢查 NodeJS 上
function add
via的 gas 成本web3 v1.0.0-beta.34
:async function send(transaction) { let success = await web3.eth.personal.unlockAccount(OWNER_ADDRESS, OWNER_PASSWORD); let gas = await transaction.estimateGas({from: OWNER_ADDRESS, gasPrice: GAS_PRICE}); console.log(`gas = ${gas}`); return await transaction.send({from: OWNER_ADDRESS, gasPrice: GAS_PRICE, gas: gas}); } for (let i = 1; i < 10; i++) { let wallet = `0x5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5${i}`; let hash = await send(contract.methods.add(wallet)); }
請注意,在我列印完 gas 成本後,我會執行交易,以便它對合約產生實際影響,並隨後對下一筆交易的 gas 成本產生影響。
在第一次迭代中,gas 成本為 64827。
在以下每次迭代中,gas 成本為 49827。
我認為這種差異本身是有道理的,因為第一個事務可能比以下每個事務都將更多的 0 變為 1(我猜,在
mapping (address => bool) public authorizedWallets
資料結構中)。對我來說沒有多大意義的是,為什麼這些交易中的每一個都如此昂貴,因為只執行了幾個操作:
_add(_wallet);
require(!authorizedWallets[_wallet]);
authorizedWallets[_wallet] = true;
authorizedWalletCount++;
emit WalletAccepted(_wallet);
我正在使用 Parity 和 Ropsten 來解決所有問題(我相信這不應該重要,但也許我在這裡錯了)。
有人能解釋一下為什麼這幾個操作的成本達到 50,000 個燃氣單位嗎?
謝謝!
- 21,000 基本交易氣體成本。
authorizedWallets[_wallet] = true;
SSTORE 將零更改為非零,所以這是 20,000 氣體。authorizedWalletCount++;
做一個 SSTORE 將非零更改為非零,所以這是 5,000 氣體。emit Event(_wallet);
做一個 LOG2,花費 1,125 gas。那是 47,125,與您的總數非常接近。添加一個 SLOAD、一些散列和一些用於移動和呼叫函式的成本,我認為 49,827 是相當合理的。