0

I have a smart contract that checks that the msg.sender is the owner. If I know that the owner address is 0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8 for example, then what is the cheapest way to hardcode this value that I use for checking msg.sender is this address

Option 1

function foo() {
require(msg.sender == 0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8)
}

option 2

function call() {
 return 0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8
}

function foo() {
require(msg.sender == call())
}

option 3

address owner = 0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8

function foo() {
require(msg.sender == owner)
}

Which way is cheaper and why ?

3

2 Answers 2

2

Let's do a concrete experiment, tested with solidity v0.8.11 -

Option 1

contract Greeter {
    uint public x = 0;

    constructor() {
    }

    function foo() public {
        require(msg.sender == address(0x7D70653a55BcAc5B96c02FADcaC7f4272C1642B9));
        x = 1;
    }
}

Deployment: 115,183 gas

Call foo(): 41,256 gas

Option 2

contract Greeter {
    uint public x = 0;

    constructor() {
    }

    function call() internal pure returns (address) {
        return address(0x7D70653a55BcAc5B96c02FADcaC7f4272C1642B9);
    }

    function foo() public {
        require(msg.sender == call());
        x = 1;
    }

}

Deployment: 117,973 gas

Call foo(): 41,291 gas

Option 3

contract Greeter {
    uint public x = 0;

    address owner = address(0x7D70653a55BcAc5B96c02FADcaC7f4272C1642B9);

    function foo() public {
        require(msg.sender == owner);
        x = 1;
    }
}

Deployment: 140,392 gas

Call foo(): 42,092 gas

Option 4

contract Greeter {
    uint public x = 0;

    address constant owner = address(0x7D70653a55BcAc5B96c02FADcaC7f4272C1642B9);

    function foo() public {
        require(msg.sender == owner);
        x = 1;
    }
}

Deployment: 115,171 gas

Call foo(): 41,256 gas


Summary

Option 4 and option 1 are about the same and the cheapest both to deploy and to call. Option 1 is slightly more expensive to deploy.

That is because a constant is about the same as a hardcoded value, both do not occupy storage space. But you need the keyword constant for it to be treated as such (was missing from option 3).

So always use constant where possible, better than s

1
  • Can you indicate the solidity version used in the tests? I'd only add that the costs applies to the examples, in a real contract depending on the usage the values obtained could be different.
    – Ismael
    May 5 at 4:45
1

The cheapest way would be the constant approach as constants do not get a storage entry assigned and are stored as values along with the contract. For more information consult the docs

6
  • Does the option 1 store it as a constant as well like option 3? Then 1 would be slightly cheaper because we are declaring it directly instead of creating a constant for it ?
    – qubitz
    May 1 at 21:15
  • none of the presented options contain constants as far as i can see
    – Nergon
    May 1 at 21:42
  • Isn't the first one a constant since obviously code itself is immutable ? if not what is the type of addres in option 1 is it?
    – qubitz
    May 1 at 21:51
  • If you read the documentation i've mentioned, it is explaining how a constant is different from an immutable variable.
    – Nergon
    May 1 at 21:59
  • yes, when you use constant owner = 0xe.... it will simply replace every instance of owner in contract by the address. if I do (msg.sender == owner) isn'T it the same or as (msg.sender == 0xe...) which might be slightly more gas efficiant? Or are you saying that in option1 the address is actually an immutable variable
    – qubitz
    May 1 at 22:04

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.