1

I have this contract:

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++;
    }
}

And I am checking the gas cost of function add via web3 v1.0.0-beta.34 on NodeJS:

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));
}

Note that after I print the gas cost, I execute the transaction so that it will take actual effect on the contract, and subsequently on the gas cost of the next transaction.

On the first iteration, the gas cost is 64827.

On each one of the following iterations, the gas cost is 49827.

This difference by itself makes sense I suppose, since the first transaction probably changes a lot more 0s into 1s than each one of the following transactions (I would guess, in the mapping (address => bool) public authorizedWallets data structure).

What doesn't make much sense to me, is how come each one of these transactions is so costly, as there are only a few operations executed:

  • _add(_wallet);
    • require(!authorizedWallets[_wallet]);
    • authorizedWallets[_wallet] = true;
    • authorizedWalletCount++;
  • emit WalletAccepted(_wallet);

I am using Parity and Ropsten for all it matters (I believe that it's not supposed to matter, but maybe I'm wrong here).

Can someone please explain why the cost of these few operations reach 50,000 gas units?

Thank you!

2
  • 21,000 base transaction gas cost.
  • authorizedWallets[_wallet] = true; does an SSTORE changing a zero to a non-zero, so that's 20,000 gas.
  • authorizedWalletCount++; does an SSTORE changing a non-zero to a non-zero, so that's 5,000 gas.
  • emit Event(_wallet); does a LOG2, which costs 1,125 gas.

That's 47,125, which is pretty close to your total. Add an SLOAD, some hashing, and some overhead for moving things around and calling functions, and I think 49,827 is pretty reasonable.

  • Changing a zero to a non-zero: doesn't the cost of that depend on the number of changed bits (in this case - a single bit)? Same question with regards to 'changing a non-zero to a non-zero'. Thank you! – goodvibration Jun 13 '18 at 20:48
  • No, it doesn't. – user19510 Jun 13 '18 at 21:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.