Track 4 · Solidity foundations · lesson 12
Constructors and immutability
8 min
Track 4 · Solidity foundations · lesson 12
8 min
A constructor runs exactly once, during deployment, and then ceases to exist — it is not part of the deployed bytecode and can never be called again.
uint256 public constant MAX_SUPPLY = 10000; // known when you write it
address public immutable creator; // known when you deploy it
address public owner; // can change later
constant — fixed at compile time. Costs nothing to read; the value is
inlined wherever it appears.immutable — set once in the constructor, never again. Baked into the
bytecode at deployment, so reading it is far cheaper than storage.Reach for immutable for anything set once at deploy and never changed: an
owner, a token address, a start time.
It is a free optimisation — same code, cheaper reads — and it is also a security statement. A reader can see at a glance that this value can never be changed by anyone, including the deployer.
Predict
This surprises people. Deployment bytecode and runtime bytecode are different things: the deployment bytecode runs the constructor, then returns the runtime bytecode, which is what gets stored at the address.
The constructor is discarded. There is nothing to call.
During construction, the contract has an address but no runtime code yet. If the
constructor calls out to another contract, and that contract checks
addr.code.length == 0 to decide "is this an EOA or a contract?", it gets the
wrong answer.
That check is a real pattern — used to block contracts from minting an NFT, for example — and this is exactly how it gets bypassed. Do the whole thing from inside a constructor and you look like a plain account.
You will use this trick in track 7.
Check