Constructors are a special type of function that runs only once when deploying a contract, and can be used to initialize the state of the contract. Your contract must not have more than one constructor, and that constructor function must be annotated with the #[constructor] attribute. Also, a good practice consists in naming that function constructor.

Here's a simple example that demonstrates how to initialize the state of a contract on deployment by defining logic inside a constructor.

pub mod ExampleConstructor {
    use starknet::ContractAddress;

    struct Storage {
        names: LegacyMap::<ContractAddress, felt252>,

    // The constructor is decorated with a `#[constructor]` attribute.
    // It is not inside an `impl` block.
    fn constructor(ref self: ContractState, name: felt252, address: ContractAddress) {
        self.names.write(address, name);

mod tests {
    use super::{ExampleConstructor, ExampleConstructor::namesContractMemberStateTrait};
    use starknet::{ContractAddress, SyscallResultTrait, syscalls::deploy_syscall};
    use starknet::{contract_address_const, testing::{set_contract_address}};

    fn should_deploy_with_constructor_init_value() {
        let name: felt252 = 'bob';
        let address: ContractAddress = contract_address_const::<'caller'>();

        let (contract_address, _) = deploy_syscall(
            array![name, address.into()].span(),

        let state = ExampleConstructor::contract_state_for_testing();

        let name =;
        assert_eq!(name, 'bob');
Last change: 2024-06-09, commit: 3fbfb60