Search code examples
ethereumsoliditycryptocurrency

If string in require statement is over 32 bytes is it saved in 2 storage slots? Solidity


Let's say I have require statement like this:

require(owner == msg.sender, "Only owner can call this function xxxxxxxxxx");

The string is longer than 32 bytes so my question is if it is stored in 2 storage slots.

And if we can save gas if the string is shorter than 32 bytes.

Thanks


Solution

  • Your assumption is somewhat correct. But it's not as straightforward as "one storage slot per each 32 bytes, times 2100 gas units per each slot read".

    First of all, it's a constant, so it's included in the compiled contract bytecode (that is effectively stored in multiple storage slots). Depending on how much bytecode is stored before this string in the same slot, sometimes even a string shorter than 32 bytes can be theoretically split between 2 slots.

    But because it's a part of the contract bytecode, the whole executed function is loaded into memory and the string is returned from memory, without any additional storage reads.

    So, having a longer error message is more expensive during contract deployment (need to store longer bytecode). But the execution cost only increases by 3 gas units per each memory slot access, which is insignificant in most cases.


    Example 1 - bytecode 374 bytes, execution of foo() 21510 gas.

    pragma solidity ^0.8;
    
    contract MyContract {
        function foo() external {
            require(false, "Only owner can call this function xxxxxxxxxx");
        }
    }
    

    Example 2 - bytecode 322 bytes, execution of foo() 21492 gas.

    pragma solidity ^0.8;
    
    contract MyContract {
        function foo() external {
            require(false, "no");
        }
    }