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

View Routes

View routes are read-only entry points. They can inspect entity state but cannot modify it, send messages, or perform side effects. Use them to expose queries to callers and other entities.

Syntax

View routes are declared with the view keyword and a return type:

view get_balance() -> U256 => [
    return(m_balance)
]

Return Type

A view route should declare a return type with -> Type (omitting it is only a warning, but such a view is useless to callers) and include a return(value) action:

view get_owner() -> address => [
    return(m_owner)
]

view get_name() -> String => [
    return(m_name)
]

view total_supply() -> U256 => [
    return(m_total_supply)
]

Read-Only Guarantee

View routes have the following restrictions:

AllowedForbidden
Read member valuesModify members (no transforms)
Call pure functionsSend messages or value (~>)
Use if/else, matchDeploy entities
Compute intermediate valuesEmit events
call a state-changing route

Cambrian rejects a view that calls a route with member transforms or state-changing actions (directly or through further calls). On EVM it also rejects a view whose body emits, sends, or deploys, since Solidity does not allow these in a view function.

Computed Views

View routes can perform computations on state before returning:

view get_balance_of(account: address) -> U256 => [
    return(m_balances[account])
]

Indexing a HashMap with a missing key yields the value type’s default (0 here), so no explicit “absent” handling is needed. Nested maps are indexed twice:

view is_approved(owner: address, spender: address) -> bool => [
    let allowance = m_allowances[owner][spender];
    return(allowance > 0)
]

Conditional Returns

Views can use if/else and match to determine the return value:

view get_status_label() -> String => [
    let label = match m_status {
        Status::Active => "active",
        Status::Paused => "paused",
        Status::Closed => "closed",
        _ => "unknown"
    };
    return(label)
]

Views with Parameters

View routes can accept parameters to query specific data:

view get_listing(id: u64) -> Listing => [
    return(m_listings[id])
]

view get_vote_count(proposal_id: u64) -> u64 => [
    return(m_votes[proposal_id])
]

No Member Transforms

View routes do not appear in member transform blocks. Since views cannot modify state, no member declares in get_balance() => .... If you find yourself writing a member transform for a view route, you need a regular route instead.

Complete Example

An entity with multiple view routes:

entity Token {
    routes {
        // ... regular routes ...

        view name() -> String => [
            return(m_name)
        ]

        view symbol() -> String => [
            return(m_symbol)
        ]

        view total_supply() -> U256 => [
            return(m_total_supply)
        ]

        view balance_of(account: address) -> U256 => [
            return(m_balances[account])
        ]

        view allowance(owner: address, spender: address) -> U256 => [
            return(m_allowances[owner][spender])
        ]
    }

    m_name: String {}
    m_symbol: String {}
    m_total_supply: U256 {}
    m_balances: HashMap<address, U256> {}
    m_allowances: HashMap<address, HashMap<address, U256>> {}
}