Documentation Index
Fetch the complete documentation index at: https://docs.optimism.io/llms.txt
Use this file to discover all available pages before exploring further.
OP Stack interop is in active development. Some features may be experimental.
OP Stack interoperability
It is easy for a blockchain to be certain about information it generates itself. Information that comes from other sources is harder to provide in a safe, decentralized, and uncensorable manner (this is called The Oracle Problem). The next major scalability improvement to the OP Stack is to enable a network of chains to feel like a single blockchain. This goal requires low-latency, seamless message passing and asset bridging. OP Stack interoperability is a set of protocols that lets OP Stack blockchains read each other’s state. OP Stack interoperability provides the following benefits:- ETH and ERC-20 tokens move securely between chains via native minting and burning. Asset interoperability solves the issues of liquidity fragmentation and poor user experiences caused by asset wrapping or liquidity pools.
- Apps can compose with data that exists on other chains.
- Horizontal scalability for applications that need it.
Interoperability architecture
A pre-interop OP Stack node consists of two pieces of software: a consensus client (e.g. op-node) that drives derivation, and an execution client that processes user transactions and constructs blocks (e.g. op-geth). OP Stack interop adds a cross-chain message verification layer to the rollup node. Before a node accepts a block that contains an executing message, it verifies that the matching initiating message really exists on the source chain. Nodes track every chain in their dependency set and will not advance the local chain past any block whose dependencies they cannot prove. A node participating in interop indexes the log events of every chain in its dependency set, because any of those events can serve as an initiating message. The node also reads from L1’s consensus layer to determine the safety of L2 blocks. The cross-chain verification work is built into the rollup node itself. Verifying initiating messages on other chains does mean the node operator needs a way to follow each chain in the dependency set — typically by running rollup nodes for those chains as well.How messages get from one chain to the other
A cross-chain message takes two transactions: one on the source chain and one on the destination. The first transaction creates an initiating message on the source chain. The initiating message is just a log event — any log event on any chain in the destination’s dependency set can initiate a cross-domain message. The second transaction creates an executing message on the destination chain. It calls theCrossL2Inbox predeploy to claim that a specific log event happened on a specific source chain. The call to CrossL2Inbox can come from an externally owned account or, more commonly, from a smart contract such as the L2ToL2CrossDomainMessenger.
Each executing message identifies the initiating message uniquely by its source chain ID, the source contract address (origin), the source block number, the log index within the block, and the source block timestamp. If everything checks out, CrossL2Inbox emits an ExecutingMessage event recording the cross-chain reference.
Validating messages with access lists
CrossL2Inbox itself never reads other chains’ state. It just verifies that the executing transaction has pre-declared every cross-chain message it intends to use, so that the destination chain’s node can check those declarations against its index of source-chain logs before the transaction is allowed into a block.
The declarations live in the transaction’s EIP-2930 access list, targeting the CrossL2Inbox predeploy address. For each executing message, the interop access-list spec defines up to three typed storage-key entries:
- A lookup-identity entry that packs the source chain ID, block number, log timestamp, and log index. This is the hint the node uses to find the referenced log in its index.
- An optional chain-ID extension entry, only present when the source chain ID does not fit in 64 bits.
- A checksum entry: a versioned hash that commits to the message’s full
Identifierand message hash. This is the only entry the EVM itself touches.
CrossL2Inbox, reconstructs the message it points at, and confirms that an initiating log with that identifier and hash really exists on the source chain at the required safety level. Any unrecognized entry, or any entry that points at a message the node cannot prove, fails the check and the transaction is dropped.
Inside the EVM, CrossL2Inbox.validateMessage recomputes the checksum from the Identifier and msgHash it was called with, and uses gas-cost measurement to confirm the matching storage slot is “warm” — meaning the checksum entry really was in the access list. A missing or wrong entry reverts with NotInAccessList, so a transaction that bypassed (or contradicts) the node’s pre-check can never succeed at runtime. Because deposit transactions cannot carry access lists, calls to CrossL2Inbox.validateMessage from inside a deposit always revert.
The access-list mechanism gives sequencers, builders, and verifiers a uniform, EVM-free way to drop transactions whose referenced messages do not exist — including under reorgs and equivocation — before they are ever included in a block.
Block safety levels
OP Stack interop preserves the same three safety levels app developers and node operators are already used to:- Unsafe. The block has been produced and shared over the gossip protocol, but its source data has not yet been written to L1. The sequencer that produced it could still equivocate.
- Safe. The block has been derived from data on L1 and every initiating message it references has itself reached at least the same safety level. Once a block is safe, no participant — including the sequencer — can roll it back without an L1 reorg.
- Finalized. The L1 data the block was derived from is finalized on L1 and is no longer subject to L1 reorgs.
Interop clusters
Each chain configures a dependency set — the set of chains it is willing to accept initiating messages from. Together, a group of chains whose dependency sets reach each other forms an interop cluster. Dependency sets do not have to be symmetric or fully connected. In the example above, chain B’s dependency set is{A, C}, so a message from chain E to chain B has to be relayed through chain A: send from E to A, then from A to B.
Superchain interop cluster
The OP Stack builds on top of the underlying interop protocol with a single, fully-connected mesh: every chain in the Superchain interop cluster has every other chain in its dependency set, so any chain can send a message directly to any other. Every chain in the Superchain interop cluster shares the same security model to mitigate the weakest-link risk of cross-chain messaging. As outlined in the Standard Rollup Charter, these chains share the same L1ProxyAdmin Owner, and any change to the cluster goes through the standard Protocol Upgrade vote — the established governance process for OP Stack modifications.
The Superchain interop cluster is being rolled out iteratively. To see which chains are eligible to join, visit the Superchain Index and look for chains with a Standard charter.
Next steps
- Learn how messages get from one chain to another chain.
- Learn how interop handles reorgs and avoids double-spends.
- Read the cross-chain security measures for safe interoperability.