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

Identity Members

Identity members are immutable fields fixed at deploy time. On EVM they participate in the CREATE2 address of the instance: same identity args ⇒ same address everywhere in the project.

Declaration

entity Locker {
    identity m_id: u64

    routes {
        constructor() => []
        // …
    }
}

An entity may declare several identity members; all contribute to the address, in declaration order:

entity UniswapV2Pair {
    identity m_token0: address
    identity m_token1: address
}

Rules

PropertyOrdinary memberIdentity member
Mutable after deployYes (transforms)No
Default valueAllowedForbidden
TransformsAllowedForbidden
Address arityDoes not countCounts toward Entity.address(…)

Identity values are supplied as constructor / deploy arguments (together with any non-identity init parameters). They are never rewritten by routes.

Address arity

Entity.address(args…) takes exactly as many arguments as the entity has identity members — same count and types, in declaration order:

Locker.address(locker_id)                    // one identity
UniswapV2Pair.address(token0, token1)        // two identities

from Entity(args) on EVM uses the same arity (rule V33). Mismatched arity is a compile-time error (V32 for deploy, V33 for from).

Singletons

An entity with no identity members is a singleton: one predictable address per project, and Entity.address() takes no arguments:

entity UniswapV2Factory {
    // no identity — singleton
    routes {
        constructor(fee_to_setter: address) => []
        createPair(tokenA: address, tokenB: address) => [
            deploy UniswapV2Pair(min_addr(tokenA, tokenB),
                                  max_addr(tokenA, tokenB))
        ]
    }
}

// elsewhere:
UniswapV2Factory.address()

Governor and TimelockController in examples/governor/ are singletons the same way.

When to use identity

Use identity when distinct instances must be content-addressed — token ids, pair keys (token0, token1), shard indices. If the value can change after deployment or should not affect the address, use an ordinary member instead.

See Deterministic Addresses for CREATE2 / CambrianFactory details.