24

What is the immutable keyword in Solidity and how do I use it?

2 Answers 2

28

The immutable keyword was added to Solidity in 0.6.5.

State variables can be marked immutable which causes them to be read-only, but assignable in the constructor. The value will be stored directly in the code.

From the docs:

Variables declared as immutable are a bit less restricted than those declared as constant: Immutable variables can be assigned an arbitrary value in the constructor of the contract or at the point of their declaration. They cannot be read during construction time and can only be assigned once.

An example code snippet is as follows:

pragma solidity ^0.6.5;

contract TestImmutable {
    uint256 public immutable a;

    // This is a valid constructor
    constructor (uint256 _a) public {
        a = _a;
    }
    
    // This is invalid and will not compile
    function setA (uint256 _a) public {
        a = _a;
    }
}

It is important to note that the contract creation code generated by the compiler will modify the contract’s runtime code before it is returned by replacing all references to immutables by the values assigned to them. This is important if you are comparing the runtime code generated by the compiler with the one actually stored in the blockchain.

4
  • Great post. The curious reader can take a look at Uniswap v2's Router02 contract, which makes use of the immutable keyword. Commented Jul 8, 2020 at 10:59
  • 1
    Etherscan verification: would I need to verify separately two identical contracts deployed with a different construction argument used for immutable assignment? Commented Aug 27, 2020 at 14:05
  • 1
    No, seems that it requires two different verifications. Commented Aug 27, 2020 at 14:18
  • What is the difference to a constant?
    – Qwerty
    Commented Jan 22, 2022 at 17:33
4

The answer of the Shane is pretty accurate. To answer the question of the Qwerty:

I was confusing the immutable with the constant.

Here is the brief summary directly from the official Solidity document:

  1. For constant variables, the value has to be a constant at compile time and it has to be assigned where the variable is declared. Any expression that accesses storage, blockchain data (e.g. block.timestamp, address(this).balance or block.number) or execution data (msg.value or gasleft()) or makes calls to external contracts is disallowed. Expressions that might have a side-effect on memory allocation are allowed, but those that might have a side-effect on other memory objects are not. The built-in functions keccak256, sha256, ripemd160, ecrecover, addmod and mulmod are allowed (even though, with the exception of keccak256, they do call external contracts).

  2. Variables declared as immutable are a bit less restricted than those declared as constant: Immutable variables can be assigned an arbitrary value in the constructor of the contract or at the point of their declaration. They can be assigned only once and can, from that point on, be read even during construction time.

pragma solidity >=0.7.4;

uint constant X = 32**22 + 8;

contract C {
    string constant TEXT = "abc";
    bytes32 constant MY_HASH = keccak256("abc");
    uint immutable decimals;
    uint immutable maxBalance;
    address immutable owner = msg.sender;

    constructor(uint decimals_, address ref) {
        decimals = decimals_;
        // Assignments to immutables can even access the environment.
        maxBalance = ref.balance;
    }

    function isBalanceTooHigh(address other) public view returns (bool) {
        return other.balance > maxBalance;
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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