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 ?

qubitz
  • 287
  • 3
  • 9

2 Answers2

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

Kof
  • 2,954
  • 6
  • 23
  • 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 05 '22 at 04: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

Nergon
  • 166
  • 5
  • 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 01 '22 at 21:15
  • none of the presented options contain constants as far as i can see – Nergon May 01 '22 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 01 '22 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 01 '22 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 01 '22 at 22:04
  • I am not able to test it atm, but i believe the constant keyword is what triggers the storing in the contract. It might be that its set as an immutable variable yes. – Nergon May 01 '22 at 22:13