> ## Documentation Index
> Fetch the complete documentation index at: https://docs.starknet.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Factory pattern

The factory pattern is a well known pattern in object oriented programming. It provides an abstraction on how to instantiate a class.

In the case of smart contracts, we can use this pattern by defining a factory contract that has the sole responsibility of creating and managing other contracts.

## Class hash and contract instance

In Starknet, there's a separation between contract's classes and instances. A contract class serves as a blueprint, defined by the underlying Cairo bytecode, contract's entrypoints, ABI and Sierra program hash. The contract class is identified by a class hash. When you want to add a new class to the network, you first need to declare it.

When deploying a contract, you need to specify the class hash of the contract you want to deploy. Each instance of a contract has their own storage regardless of the class hash.

Using the factory pattern, we can deploy multiple instances of the same contract class and handle upgrades easily.

## Minimal example

Here's a minimal example of a factory contract that deploys the `SimpleCounter` contract:

```rust theme={null}
#[starknet::interface]
trait IFactory<TContractState> {
    fn create_counter(ref self: TContractState) -> ContractAddress;
    fn create_counter_at(ref self: TContractState, salt: felt252) -> ContractAddress;
    fn update_counter_class_hash(ref self: TContractState, new_class_hash: ClassHash);
}

#[starknet::contract]
mod Factory {
    use starknet::{
        contract_address_const,
        class_hash_const,
        get_caller_address,
        ContractAddress,
        ClassHash,
    };

    #[storage]
    struct Storage {
        counter_class_hash: ClassHash,
    }

    #[constructor]
    fn constructor(ref self: ContractState, counter_class_hash: ClassHash) {
        self.counter_class_hash.write(counter_class_hash);
    }

    #[abi(embed_v0)]
    impl Factory of super::IFactory<ContractState> {
        fn create_counter(ref self: ContractState) -> ContractAddress {
            let salt = starknet::contract_address_const::<0x123>();
            self.create_counter_at(salt)
        }

        fn create_counter_at(ref self: ContractState, salt: felt252) -> ContractAddress {
            let counter_class_hash = self.counter_class_hash.read();
            let constructor_calldata = array![];
            
            let (contract_address, _) = starknet::deploy_contract_syscall(
                counter_class_hash,
                constructor_calldata.span(),
                salt,
                false,
            ).unwrap();
            
            contract_address
        }

        fn update_counter_class_hash(ref self: ContractState, new_class_hash: ClassHash) {
            self.counter_class_hash.write(new_class_hash);
        }
    }
}
```

This factory can be used to deploy multiple instances of the `SimpleCounter` contract by calling the `create_counter` and `create_counter_at` functions.

The `SimpleCounter` class hash is stored inside the factory, and can be upgraded with the `update_counter_class_hash` function which allows to reuse the same factory contract when the `SimpleCounter` contract is upgraded.

<Note>
  This minimal example lacks several useful features such as access control, tracking of deployed contracts, events etc.
</Note>
