eez:on
Run a block of commands on another EEZ chain synchronously from the current one. Every call the block produces goes out through the target's cross-chain proxy and executes on the other side atomically with this transaction; helpers, conditions and loops inside evaluate on that chain. Creates each missing proxy first and estimates the gas the composed calls need.
⚗️ Experimental — available at next.evmcrispr.com.
Syntax
Section titled “Syntax”eez:on <chain> <block>Arguments
Section titled “Arguments”| Name | Type | Description |
|---|---|---|
chain | chain | EEZ chain the block runs on (eezL2, or its chain id) |
block | block | Commands whose calls execute on that chain (exec, if, loop, other modules' commands) |
Examples
Section titled “Examples”# From L1, set a value on a rollup contract in one atomic transactionswitch eezL1eez:on eezL2 ( exec 0x000000000000000000000000000000000000bEEF setValue(uint256) 42)How it works
Section titled “How it works”An EEZ rollup and its L1 share one sequencer, so a call can cross between them inside a single transaction. On the sending chain every remote contract has a deterministic cross-chain proxy; calling the proxy with ordinary calldata runs the call on the other side, and the return value (or revert) comes back in the same transaction.
eez:on interprets its block as if the script had switched to the target chain, then brings every call it produced back home as a call through that target's proxy:
- Everything inside evaluates on the target chain:
execencodes against contracts there,@token,@balanceand::reads resolve there, and so do the conditions ofifandloop. Other modules' commands work too, as long as they produce plain contract calls. @senderinside the block is the caller's own cross-chain proxy on the target chain, which is what contracts there see asmsg.sender.@mestays the connected wallet.- Each distinct target gets its proxy created with a preceding transaction if nobody has yet; the calls follow, one sending-chain transaction each. To make several of them atomic, either wrap the command in a wallet batch,
batch ( eez:on eezL2 ( … ) ), sent as one transaction by an EIP-7702 account or a Safe (several cross-chain entries), or use eez:batch, which runs the whole block as one entry from your proxy over there. Abatchinside the block is refused: it would only describe the sending wallet, which the block is not about. - Gas is estimated by simulating each remote leg on the other chain, as the other chain will see it (from your proxy there), and adding the protocol overhead (the sending chain itself cannot estimate a cross-chain call). A leg that would revert stops the script before anything is sent, with the reason — a failed assertion by its message. A leg that crosses chains again (a call to a proxy over there) cannot be simulated and gets a fixed budget. Pass
--gason the inner command if a call still runs out of gas or is evicted;--valueand--fromon the inner command pass through as well. - A far leg that reverts at execution is not mined as a failed transaction: the composer evicts the transaction, nothing is applied on either chain, and the script reports a receipt timeout. The pre-flight above catches what can be simulated; a revert deeper than one hop only shows up this way.
- Blocks nest:
eez:on eezL2 ( eez:on eezL1 ( … ) )goes L1 → L2 → L1 and comes back in the same transaction, through the proxy of a proxy. The inner block's calls are routed on the rollup first, then routed again from the sending chain; a proxy the inner block needs on the rollup is created there through the rollup registry's own proxy, atomically with the rest. Each extra hop adds the sending chain's overhead to the gas estimate. The devnet composes at least six hops. - Not allowed inside the block:
switchand contract deployments. - The EEZ chains are reached through EVMcrispr's EEZ RPC, which forwards ordinary transactions to the devnet and hands cross-chain ones to the EEZ cross-chain ingress, so any wallet works with the one network entry — no special submission step.
- A receipt on the sending chain means the cross-chain effect was applied atomically; the rollup's state reflects it a few seconds later.
- A contract on the current chain whose code calls a proxy needs no special command: a plain
execreaches across the same way.
See Also
Section titled “See Also”- eez:batch — the same block as one atomic call from your proxy
- eez:deploy-proxy — create the proxy explicitly
- @eez:proxy — resolve the proxy address without calling
- @eez:on — read the other chain from the script