Solidity

更改 2 個狀態變數和發出 1 個事件的成本如何達到 50K gas 單位?

  • June 13, 2018

我有這個契約:

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 addvia的 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 是相當合理的。

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