Immutable Keyword For Gas Optimizations
Description
Declaring variables as immutable
instead of constant
allows the Solidity compiler to generate more optimized bytecode by performing compile-time computations and reducing gas costs. When a variable is declared as constant
, the value assigned to the variable is hardcoded into the bytecode at compilation time. This can cause unnecessary bytecode bloat if the constant
value is large, leading to higher deployment costs and reduced performance.
On the other hand, declaring variables as immutable
provides the same functionality as constant
, but the variable value is computed at contract deployment time instead of compilation time. This allows the compiler to optimize the bytecode by storing the computed value in the contract initialization code, reducing the overall contract size and decreasing the gas cost for deploying and executing the contract.
Example Code
Consider the following example contract:
pragma solidity ^0.8.0;
contract ImmutableExample {
uint256 constant public CONSTANT_VALUE = 1234;
uint256 immutable public IMMUTABLE_VALUE;
constructor(uint256 _immutableValue) {
IMMUTABLE_VALUE = _immutableValue;
}
function getConstant() public pure returns (uint256) {
return CONSTANT_VALUE;
}
function getImmutable() public view returns (uint256) {
return IMMUTABLE_VALUE;
}
}
In this example, the CONSTANT_VALUE
is defined as constant
and IMMUTABLE_VALUE
is defined as immutable
. When compiled, the bytecode for the getConstant function includes a PUSH1 123
opcode to push the hardcoded value onto the stack, while the bytecode for the getImmutable
function includes no such opcode since the value is already stored in the contract initialization code.
Recommendation
It is recommended to declare variables as immutable
instead of constant
when possible to allow for gas optimization. However, it is important to note that immutable
variables can only be set during contract deployment, and any attempt to change their value will result in a runtime error.