Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Deploy

The deploy action creates a new entity instance from inside a route.

Basic form

Pass identity / init arguments directly:

deploy UniswapV2Pair(token0, token1)

Optional with { value: … } attaches native currency to the new instance (meaningful on EVM; ignored or unavailable on hosts without a native asset):

deploy Vault(vault_id) with { value: msg::value }

Argument arity must match the target’s constructor surface (identity members plus init-route parameters) — V32.

Deterministic addresses (EVM)

On EVM, the backend:

  1. Emits a project-wide CambrianFactory.
  2. Lowers deploy Entity(args) to a factory call that performs CREATE2 with the entity’s identity arguments as constructor args.
  3. Calls a factory-guarded initialize(...) for any non-identity init parameters.

Duplicate identical deploy trees for the same entity in one route are rejected (address occupancy collision).

The resulting address matches Entity.address(args) (and the equivalent addressOf spelling). Singletons (no identity members) use Entity.address() with no arguments.

Authors do not hand-roll a factory or salt. Details: Deterministic Addresses.

Predicting the address

let pair = UniswapV2Pair.address(token0, token1);
deploy UniswapV2Pair(token0, token1);
Notify(pair) ~> m_observer

Example

entity EscrowFactory {
    routes {
        create_escrow(buyer: address, seller: address, amount: U256)
            where msg::value >= amount : throw Underfunded()
        => [
            deploy Escrow(buyer, seller, amount) with { value: msg::value }
        ]
    }
}

entity Escrow {
    identity m_buyer: address
    identity m_seller: address

    routes {
        constructor(amount: U256) => []

        release()
            from Buyer(m_buyer) : throw Unauthorized()
        => [
            ~> m_seller with { value: m_amount }
        ]
    }

    m_amount: U256 {
        in constructor(amount) => amount
    }
}

(Exact identity / constructor split depends on your entity design; the factory always keeps CREATE2 occupancy aligned with Entity.address.)