3

I have the following contract, reduced to the minimum for testing reasons:

pragma solidity ^0.6.11;

contract PackedMultiplexer {
    function multiTransfer(address  _address1, uint _amount1, address  _address2, uint _amount2) payable public
    {
        assembly {
            pop(call(2300, _address2, _amount2, 0, 0, 0, 0))
            pop(call(2300, _address1, _amount1, 0, 0, 0, 0))
        }
    }
}

Now, I generate 2 new private keys.

I get 2 new public addresses 0x0c73c24c841ddDF2d476E7E2C1552Ea04364cc9A and 0xC16F1C0241B1204BC123650CfCb3A03046F2d91C, previously unknown to the network. Then I call the contract with those addresses and some random (constant) value for the amounts.

I get a first TX which consumes 87,191 gas.

I call a second time the contract with exactly the same parameters and get a second TX which consumes 37,191 gas.

My question: why is the gas consumption of the first execution of the contract and the second execution is different? It seems to me in both cases the same code is executed? What am I missing?

As you can see in the debugger, the first TX call opcodes consumes 37000 gas each; the second TX call opcodes consumes 12000 gas each. Why is that? How can I prevent the 37000 gas consumption?

(Note: the question holds true if you replace 2300 (first argument of call) in the code by gas() or 0.)

  • Because in the first transaction you change a state (account balance) from zero to non-zero, and in the second transaction you change it from non-zero to non-zero, which is 50% cheaper. – goodvibration Jul 20 at 4:37
  • Thanks for the comment. This does not seem to hold. I just tried. I filled 150 addresses with some ethers: ropsten.etherscan.io/tx/… Then emptied them one by one (150 txs) Then called the contract again: ropsten.etherscan.io/tx/… which consumed around 8300 gas / address, which is the lowest I can get (for new addresses it's around 25000 gas / address after the initial overhead) – coinwalletdev Jul 20 at 6:00
1

For anyone wondering the same thing, I ended up reading the yellow paper.

Turns out in p.35 they add G_{newaccount} to the gas cost, which is G_{newaccount}: Paid for a CALL or SELFDESTRUCT operation which creates an account (25000).

I couldn't find anywhere the definition of 'creating an account' which is odd (e.g. just tested: sending only an ERC-20 token to an address still force me to pay the 25k extra gas, so this is not considered as 'creating an account'...)

| improve this answer | |
  • 1
    Erc20 transfer does not do anything directly to the account, only modifies a ledger, so that would explain why that doesn't count – Lauri Peltonen Jul 20 at 6:42

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.