A short doc presenting the upcoming contract class/instance separation in StarkNet Alpha 0.9.0, which is planned for mid-May.

Class/Instance separation

We start by introducing some new terminology and refining an existing one:

contract class (or simply “class”): the definition of the contract, that is, its Cairo byte code, hint information, entry point names, and everything that is needed to unambiguously define its semantics.

class hash: the hash of the contract class, can be thought of as the class name.

contract instance: A triplet (class_hash, address, storage), can be thought of as an instance of the class corresponding to class_hash. When it is clear from the context, we will allow a slight abuse of notation and simply use “contract”.

This separation between classes and instances will allow us to introduce the contract factory pattern into StarkNet, and also implement delegate calls in a more natural manner.

Expected Changes

Declare transaction

A new type of declare transaction will be added to StarkNet. Similarly to deploy, declare transactions will contain the contract class. The state of StarkNet will contain a list of declared classes, that can be appended to via the new declare transaction.

Deploy syscall

After a class is declared (declare transaction was accepted), we can deploy new instances of that class. This will be done by a new deploy system call, that will take as input:

The deploy syscall will then deploy a new contract (instance of that class), whose address will be determined by the three parameters above, and the address of the contract initiating the deployment, as before (see the docs). The logic of the contract is defined by the class, which should have been declared prior to deployment.

Note that this feature introduces contract factories into StarkNet, as a contract may invoke the deploy syscall, in turn creating new contracts.

The signature of the new system call is:

func deploy{syscall_ptr : felt*}(
    class_hash : felt,
    contract_address_salt : felt,
    constructor_calldata_size : felt,
    constructor_calldata : felt*,
) -> (contract_address : felt):
    ...
end

Delegate call