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

From Clause

The from clause restricts who may invoke a route by checking msg::sender against an expected entity (or address) identity.

On EVM this lowers to a require(msg.sender == …) style guard.

Syntax

credit(account: address, amount: U256)
    from Shop(m_shop_id) : throw Unauthorized()
=> []

The optional : throw ErrorName(...) supplies a named custom error when the sender check fails (see Custom Errors).

Multiple senders

Join alternatives with | (OR). Each alternative carries its own : throw, and all alternatives must use the same one:

update_price(asset: String, price: U256)
    from Oracle(m_oracle_id) : throw Unauthorized()
       | Admin(m_admin_id) : throw Unauthorized()
=> []

From a stored address

from m_member compares the sender with an address held in a member (msg.sender == m_owner on EVM):

set_fee(bps: u64)
    from m_owner : throw Unauthorized()
=> []

From with where

from runs before where:

execute_trade(amount: U256)
    from Broker(m_broker_id) : throw Unauthorized()
    where amount > 0 : throw ZeroAmount()
    && m_status == Status::Active : throw Paused()
=> []

EVM arity rules (V33)

from Entity(...) takes as many arguments as the target entity has identity members (zero for singletons: from Registry()).

extern entity targets skip V33. Plain address members used as senders can be checked with from m_owner (above) or, equivalently, where msg::sender == m_owner.

On EVM, from Entity(args) compares msg.sender to the same CREATE2 expression as Entity.address(args), so authentication and addressing stay in sync. See Deterministic Addresses.

When to use from

ScenarioPrefer
Public caller actionsNo from (or where on msg::sender)
Callbacks from a known Cambrian entityfrom Entity(…)
Admin / oracle entities with predicted addressesfrom Entity(…) on EVM
Plain address stored in a memberfrom m_owner or where msg::sender == m_owner
where msg::sender == m_owner : throw Unauthorized()