An initializer function is where a contract initializes its state.
Initializer functions are similar to constructors:
can only be called once
external non-initializer functions cannot be called until one of the initializers has ben called
The only exception are noinitcheck functions, which can be called even if none of the initializers has been
called.
Initialization Commitment
All contract instances have their address include a commitment to one of their initializer functions, along with
parameters and calling address. Any of the following will therefore fail:
calling the wrong initializer function
calling the initializer function with incorrect parameters
calling the initializer function from the incorrect address
It is possible however to allow for any account to call the specified initializer by setting the intended caller to
the zero address. These are called 'universal deployments'.
Multiple Initializers
A contract can have multiple initializer functions, but it is not possible to call multiple initializers on the
same instance: all initializers become disabled once any of them executes. Each individual instance can call any of
the initializers.
Initializers can be either private or public. If a contract needs to initialize both private and public state, then
it should have an external private function marked as initializer which then enqueues a call to an
external public function not marked as initializer and instead marked as only_self (so that it can
only be called in this manner).
Lack of Initializers
If a contract has no initializer function, initialization is then not required and all functions can be called at
any time. Contracts that do have initializers can also make some of their functions available prior to
initialization by marking them with the #[noinitcheck] attribute - though any contract state initialization will
of course not have taken place.
Cost
The initialization process emits a nullifier which marks the contract as initialized. All other external
functions are automatically made to check that this nullifier exists, ensuring initialization.
An initializer function is where a contract initializes its state.
Initializer functions are similar to constructors:
externalnon-initializer functions cannot be called until one of the initializers has ben calledThe only exception are
noinitcheckfunctions, which can be called even if none of the initializers has been called.Initialization Commitment
All contract instances have their address include a commitment to one of their initializer functions, along with parameters and calling address. Any of the following will therefore fail:
It is possible however to allow for any account to call the specified initializer by setting the intended caller to the zero address. These are called 'universal deployments'.
Multiple Initializers
A contract can have multiple initializer functions, but it is not possible to call multiple initializers on the same instance: all initializers become disabled once any of them executes. Each individual instance can call any of the initializers.
Initializers can be either private or public. If a contract needs to initialize both private and public state, then it should have an
externalprivate function marked asinitializerwhich then enqueues a call to anexternalpublic function not marked asinitializerand instead marked asonly_self(so that it can only be called in this manner).Lack of Initializers
If a contract has no initializer function, initialization is then not required and all functions can be called at any time. Contracts that do have initializers can also make some of their functions available prior to initialization by marking them with the
#[noinitcheck]attribute - though any contract state initialization will of course not have taken place.Cost
The initialization process emits a nullifier which marks the contract as initialized. All other
externalfunctions are automatically made to check that this nullifier exists, ensuring initialization.For private non-initializer functions, the cost of this check is equivalent to that of a call to
PrivateContext::assert_nullifier_exists. For public ones, it is equivalent to a call toPublicContext::nullifier_exists_unsafe.The
noinitcheckattribute can be used to skip the initialization nullifer checks.