Author: Lisa A., Taiko Labs; Translation: Golden Finance xiaozou
This article will explore different L2 cross-chain messaging methods from a rollup perspective, focusing on trustless cross-chain communication. We will briefly look at direct state read methods, light client methods, and storage proofs. We will also touch on proof aggregation mechanisms, trusted third-party cross-chain message transmission, and core ZK cross-chain solutions. Finally, let's take a look at how different L2s today implement cross-chain messaging.
1. Introduction to cross-chain messaging
For cross-chain communication, all parties (L2, L3, etc.) must have direct access to the latest Ethereum state root.

All deposit layers have a “built-in” cross-chain mechanism to access the L1 state root, which is passed to L2 as a deposit message.
1.1 Two types of access to state roots
Type 1: Reading the state root directly - can be done via opcodes or precompiles. However, this has not been implemented yet, so no proof is required.
Brecht Devos described a possible method for directly reading state in a research paper: “…we can expose a precompiled contract that can directly call a smart contract on a target chain. This precompilation directly inserts and executes the smart contract code of another chain in the source chain. This ensures that the smart contract always has access to the latest available state in an efficient and easily provable manner.”
· It is also described in Optimism’s RFP “Remote Static Call Proof of Concept”.
Type 2: Proof generation — i.e. proving statements about one blockchain on another blockchain.
There are two methods for "cross-chain messaging with proof":
Trustless cross-chain communication — that is, without a trusted third party (e.g., using light clients or storage proofs). Trustless methods can be used both for third-party-generated proofs and for cross-chain communication participants to generate proofs themselves.
· Share proofs between different rollups to ensure cross-chain operations. This method is not discussed in this article. It is currently in the research and exploration stage and is not considered a solution that may be widely used.
1.2 “Cross-chain messaging with proof” approach
1.2.1 Light client cross-chain message transmission
Prove the data on chain B
Get the Merkle proof data from the full node of chain B (or archive node if storage proof of some historical states is required);
Send the block header and proof data corresponding to the chain B block containing the state we want to verify as calldata to the prover contract on chain A;
The prover contract calculates the block hash based on the block header data, queries the light client smart contract on chain A (which tracks the block hash of chain B), and checks if the hash is valid;
The proof data is verified against the bytes32 state root in the block header.

1.2.2 Proof of Storage
Storage Proof has two "workflow" options:
Generate storage proof → use on-chain
Generate storage proof → generate zk proof → use on chain
It is also possible that one entity collects multiple proofs into a single proof (including storage proof and zk proof). This is an optional optimization step and will not be discussed for now.
Let’s look at the three main stages of the storage proof “workflow”: generate storage proof, generate zk proof, and use it on-chain.
(1) Generate storage proof
Proof of storage allows us to prove that certain information exists on the blockchain and is authentic, using confidentiality commitments;
Storage proofs have been part of the crypto space since the advent of Merkle trees in 1979. However, vanilla storage proofs are usually quite large. The modern innovation is combining storage proofs with provable computation to create succinct proofs that can be verified on-chain.
To generate a storage proof, you must provide a specific block of data and its associated Merkle or Verkle path in the Merkle tree. The path consists of the sibling hashes needed to reconstruct the root hash using the same hashing algorithm.
To verify the storage proof, the recipient can recompute the root hash using the provided data and the Merkle or Verkle path. If the recomputed root hash matches the known root hash, the recipient can be confident that the data is authentic and part of the submitted dataset.
(2) Generate ZKP (Zero Knowledge Proof)
However, an Ethereum-style storage proof is about 4kb — quite large for publishing the entire storage proof to the target chain, as the proof verification would be very expensive. Therefore, it makes sense to use ZKP (e.g., ZK-SNARK) for compression to make the proof smaller and cheaper to verify.
(3)Unroll ZKP
After obtaining the ZKP, users on the target chain can unroll the proof they obtained (for example, accessing the historical state through block headers or block hashes).
Unroll can be performed in the following ways:
On-chain accumulation: The entire process of reconstructing the block header from the proof is performed directly on the blockchain. Disadvantages: high gas fees, consuming computing resources; Advantages: no additional proof time, low latency because no proof needs to be generated outside the blockchain.
On-chain compression: Remove redundant or unnecessary information from the data, or use data structures optimized for space efficiency. The compressed data is sent to the blockchain and can be decompressed when needed. Disadvantages: Compressing and decompressing data may mean additional computation, but this delay may be negligible. The compression algorithm used may have a negative impact on the security of the data; Advantages: Reduce data costs.
Off-chain storage: Store data off-chain, and put specific data blocks on-chain on demand. This is relevant for solutions that need to store a lot of data for some reason (for example, Ethereum archive nodes starting from the genesis block). Disadvantages: Same as on-chain compression; Advantages: Further reduce data costs.
1.2.3 Trusted Third Party
A complete cross-chain solution should also involve a cross-messaging solution with a trusted third party (such as oracle, centralized bridge, etc.).
1.2.4 “Universal” Proof Systems
In the case of a shared proof-of-stake aggregator mechanism, message delivery can be accelerated by receiving block hashes that are settled within the aggregator, and the settlement here will also handle message delivery (but what if there is a problem with the proof-of-stake aggregator?).
1.2.5 Some unknown issues in ZK cross-chain message transmission
Is cross-chain messaging possible without a trusted third party (which can be a single entity or multiple entities)? What is an effective mechanism for cross-chain messaging? Generally speaking, for Ethereum L2 (which has direct access to L1's block hashes) and Ethereum itself, if one chain can run a light client on another chain, etc., it can verify the block headers from that external chain, which is sufficient for trustless cross-chain messaging.
Do ZK circuits for cross-chain proof generation scale appropriately? In some cases, especially when the consensus layer (which needs to verify cross-chain operations) is very large, the circuits used for ZK cross-chain messaging can be orders of magnitude larger than rollups and on-chain storage, and computationally expensive. Presumably this problem can be overcome with a more centralized approach.
2. Example of cross-chain messaging solution
Succinct Labs uses light clients to verify the consensus from the source chain to the target chain consensus layer. The specific idea is that there is a light client protocol to ensure that the node can synchronize the block headers of the final blockchain state. ZKP is used to generate consensus proofs.
· Lagrange Labs builds non-interactive cross-chain state proofs. The Lagrange Proof Network is responsible for creating state roots. Each Lagrange node contains a portion of a shard private key that is used to prove the state of a specific chain. Each state root is a threshold-signed Verkle root that can be used to prove the state of a specific chain at a specific time. The state root is fully generic and can be used in state proofs to prove the current state of any contract or wallet in the chain.
Herodotus uses ZKP storage proofs to provide smart contracts with synchronous access to on-chain data from other Ethereum layers. For verification, it uses native L1<>L2 messaging to synchronize block hashes between Ethereum rollups.
=nil; Foundation (Mina, L1) allows smart contracts on Ethereum to verify the validity of Mina state. Generate special-purpose state proofs that are cheap to verify on Ethereum (local Mina proofs on Ethereum are expensive). It is hypothesized that (at some point in the future) applications can directly use Mina's proof generation tools to check the validity of cross-chain transactions. =nil; Foundation also has a Proof Market where users/projects can primarily buy/sell SNARK proofs, which allow trustless access to data.
Axiom: If Axiom has generated a ZKP for the ledger to date — it does not need to generate a ZKP for a specific block — it can pass this ZKP to the chain (as a relayer) and even provide access to that ZKP.
3. L2 cross-chain message passing
Disclaimer: For most L2s, cross-chain messaging is still evolving. All analysis below is based on open source information. That said, the solutions mentioned here may be in the exploration and testing phase, and rollups may eventually adopt other approaches.
(1)Taiko
Taiko stores the block hashes of each chain. For each pair of chains, it deploys two smart contracts that store each other’s hashes. In the L2←→L1 example, every time a L2 block is created on Taiko, the hash of the outlying block on L1 is stored in the TaikoL2 contract. The same works in the L1←→L2 case.
The latest known Merkle root stored on the target chain can be obtained by calling getCrossChainBlockHash(0) on the TaikoL1/TaikoL2 contract and obtaining the value/message to verify. The sibling hash of the latest known Merkle root can be obtained by using the standard RPC call eth_getProof request on the "source chain".
· Then, just send them to be verified against the latest known block hash stored in a list on the “target chain”. The validator will take a value (a leaf on the Merkle tree) and the sibling hashes to recompute the Merkle root and check if it matches the root stored in the list of block hashes on the target chain.
(2)Starknet
Starknet uses proof-of-storage for trustless cross-chain messaging.
L2→L1 messaging protocol
During Starknet transaction execution, a contract on Starknet sends an L2→L1 message.
The message parameters (containing the recipient contract and relevant data on L1) are then appended to the relevant state update (main storage tree).
L2 messages are stored on L1 in smart contracts.
Emits an event on L1 (storing the message parameters).
The recipient address on L1 can access and use the message as part of an L1 transaction by resupplying the message parameters.
· Cross-chain messages are stored in the backbone tree.
L2 → L1

L1 → L2

(3)Optimism
The communication between L1 and L2 is implemented by two special smart contracts called “messenger”.
For Optimism (L2) to Ethereum (L1) transactions, it is necessary to provide a Merkle proof of the message on L1 after the state root is written. After this proof transaction becomes part of the L1 chain, the error challenge period begins. After this waiting period, any user can "finalize" the transaction by triggering a second transaction on Ethereum to send the message to the target L1 contract.
· Cross-chain messages are stored in the backbone tree.
(4) Arbitration
· Retryable tickets are Arbitrum’s canonical method for creating L1 to L2 messaging, i.e. L1 transactions that initiate messages to be executed on L2. A Retryable can be submitted on L1 for a fixed fee (depending only on its calldata size). The main state tree is used for cross-chain communication in custom data formats in smart contracts. Submission of a retryable ticket on L1 is decoupled/asynchronous from execution on L2. Retryables provide atomicity between cross-chain operations. If the L1 transaction request submission succeeds (i.e. there is no rollback), then there is a strong guarantee that the Retryable execution on L2 will eventually succeed as well.
Arbitrum has two trees: The Nitro chain is maintained in Ethereum’s state tree format, a Merkle tree. The Assertion Tree stores the state of the Arbitrum chain confirmed on Ethereum through “assertions”. The rules for advancing the Arbitrum chain are deterministic. This means that for a given state of a chain and some new input values, there is only one valid output. Therefore, if the proof tree contains multiple leaves, then at most one leaf can represent a valid chain state.
Arbitrum’s Outbox system allows arbitrary L2-to-L1 contract calls, i.e. messages initiated from L2 are ultimately executed on L1. L2-to-L1 messages (aka “outgoing messages”) have a lot in common with Arbitrum’s L1-to-L2 messages (Retryable), though with some notable differences. Part of the Arbitrum chain’s L2 state — and what is attested in each RBlock — is the Merkle root of all L2-to-L1 messages in the chain’s history. After the attested RBlock is confirmed (usually about a week after attestation), that Merkle root is published to L1 in an Outbox contract. The Outbox contract then allows users to execute their messages.
(5)Polygon zkEVM
The zkEVM’s Bridge SC uses a special Merkle tree called an Exit Tree for each network involved in communication or asset transactions.
It uses Merkle roots (in a separate state tree), a diagram of the bridge architecture can be found on github.
The zkEVM Bridge SC implementation makes several changes to the Ethereum 2.0 deposit contract. For example, it uses a specially designed append-only Merkle tree, but employs the same logic as the Ethereum 2.0 deposit contract. Other differences are related to base hashes and leaf nodes.
The main feature of the Polygon zkEVM Bridge smart contract is the use of Exit Tree and Global Exit Tree, where the root of the Global Exit Tree is the main source of truth state. Therefore, there are two different global Exit root managers for L1 and L2, and Bridge SC has a separate logic.
(6)Scroll
· The bridge contract deployed on Ethereum and Scroll allows users to pass arbitrary messages between L1 and L2. On top of this messaging protocol, we have also built a trustless bridge protocol to allow users to bridge ERC-20 assets between L1 and L2. To send a message or funds from Ethereum to Scroll, the user calls the sendMessage transaction on the Bridge contract. The relayer will index this transaction on L1 and send it to the sequencer for inclusion in the L2 block. The process of sending messages from Scroll back to Ethereum is similar on the L2 bridge contract.
Cross-chain messages are stored in a regular message queue. The sequencer ingests cross-chain messages from this queue and adds them to the chain as regular transactions.
(7)zksync Era
Disclaimer: This section is only about zksync Era and may be different from cross-chain messaging on ZK Stack, a modular framework for building sovereign ZK superchains.
Each transaction packet has a separate L2->L1 message.
It is not possible to send transactions directly from L2 to L1. However, you can send messages of arbitrary length from zkSync Era to Ethereum, and then process the received messages on Ethereum using L1 smart contracts. zkSync Era has a request proof function that returns a boolean parameter indicating whether the message was successfully sent to L1. Retrieve the Merkle proof contained in the message by observing Ethereum or using the zks_getL2ToL1LogProof method of the zksync-web3 API.
For L1→L2, the zkSync Era smart contract allows the sender to request a transaction on Ethereum L1 and pass the data to zkSync Era L2.
Bridge contract: https://github.com/matter-labs/era-contracts/blob/main/ethereum/contracts/bridge/L1ERC20Bridge.sol
4 Conclusion
Cross-chain communication is indispensable for the "must have" applications for blockchain mass adoption (e.g., the cross-chain social recovery wallet described in Vitalik's article). Most of the cross-chain solutions currently in use are designed for L1←→L2 to cover withdrawal functionality. These solutions can be extended to more blockchains. But in the meantime, more advanced cross-chain communication solutions can be implemented, such as "direct read state" that does not require proof at all or "storage proof" that does not require trust. For most L2s, cross-chain communication still has room for development and progress.
