Skip to main content

Canonical message service

The canonical message service passes arbitrary messages (that is, user-specified data and native currency) between a LinethLineth (Formerly the Linea Stack) The open-source ZK-rollup stack, codebase, and technical protocol that's the foundation of Linea Mainnet. Operators can deploy this stack to launch their own Ethereum-compatible L2 or L3 networks. network and its finalization layerFinalization layer The blockchain where a Lineth deployment submits proofs and state commitments for verification and hard finality. If the finalization layer is Ethereum (an L1), the deployment is an L2. If the finalization layer is Linea (an L2), the deployment is an L3.. It is general-purpose infrastructure: the canonical token bridge is built on it, and any contract or dapp can call it directly.

Message service contracts on each chain, with an operator and an offchain claiming actor

How it works

The service is a pair of message service contracts, one deployed on the network and one on the finalization layer, plus the Postman: an offchain service that watches both contracts and relays what it sees.

  1. A caller invokes sendMessage on the origin contract with a destination address, a calldata payload, any native value to transfer, and an optional delivery fee. The contract records the message and emits an event.
  2. The destination contract receives a commitment to the messages the origin chain sent.
  3. Claiming the message executes it: the destination contract checks the claim against that commitment, then calls the destination address with the payload and the value.

Claiming is permissionless: anyone can submit the claim. This gives senders two delivery modes:

  • Push: The sender pays a fee up front, and the Postman claims on their behalf, pushing the message to the recipient without them doing anything.
  • Pull: No fee is paid, so the message sits unclaimed until the recipient, or anyone else, pulls it by submitting the claim and paying the gas.

Push relies on the Postman for convenience, not for correctness. The fee goes to whoever submits the claim, so if the Postman is unavailable, the recipient or a third party can claim the message and collect the fee instead.

Message commitments

Each direction commits to its messages differently, because only one of the two chains sits behind a proof.

Network to finalization layer. Finalizing a range of blocks verifies its ZK proofZero-knowledge proof A cryptographic method that allows an individual to prove that a statement is true without conveying any additional information. This is useful for scaling blockchain networks through rollups, because it reduces the amount of information you have to provide to lower layers. and anchors the Merkle root of the messages those blocks sent. A claim carries a Merkle proof, and the contract rejects it unless the proof places the message under an anchored root. Messages are therefore only claimable once the blocks that sent them are finalized.

Finalization layer to network. The coordinator anchors incoming message hashes on the network as a rolling hash, so these messages are claimable without waiting for the next finalization. The network's rolling hash is submitted with that finalization and checked against the one the finalization-layer contract computed when the messages were sent, so a network that accepted messages nobody sent cannot finalize. In the following diagram, the check labeled "Does message exist on L1?" is the destination contract testing the message against the hashes already anchored on the network.

Message execution on the destination chain, gated on confirmation from the origin chain
Linea Mainnet example

On Linea Mainnet, the Ethereum side of the service lives in the LineaRollup contract, which serves as both the rollup and the L1 message service for messages passed across the two domains, such as token transfers, contract calls, or state synchronization. Linea-to-Ethereum (L2 to L1) messages can be claimed on Ethereum only after the L2 batch is finalized: finalization verifies the batch's zk-SNARK proof and anchors the corresponding L2 message Merkle root on L1. The message is then accepted once a Merkle proof verifies its inclusion in that finalized root. Ethereum-to-Linea (L1 to L2) messages don't wait for a finalization: the coordinator anchors their hashes on Linea as a rolling hash, and they become claimable once anchored. That rolling hash is submitted with the next finalization and must match the one LineaRollup computed when the messages were sent, so Linea can't finalize having accepted messages Ethereum never sent.

See also

Was this page helpful?