-
Notifications
You must be signed in to change notification settings - Fork 829
Add ERC: Proof-based Broadcast in ERC-7786 Gateways #1072
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
eip-review-bot
merged 21 commits into
ethereum:master
from
ernestognw:feat/storage-proof-broadcasting-gateways
Jul 11, 2025
+238
−0
Merged
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
8e7bd18
Storage Proof Broadcasting for Cross-Chain Messaging Gateways
ernestognw 83a626b
up
ernestognw 936b609
up
ernestognw c012030
up
ernestognw baa4c06
Make targetBlock optional
ernestognw 5ba1441
Address feedback
ernestognw 6e8b418
up
ernestognw 126e751
Update and rename erc-xxxx.md to erc-7965.md
SamWilsn 3bfe20c
Add links
ernestognw a4fab77
nits
ernestognw 600ae4f
nits
ernestognw 2da52a0
Generalize for any cryptographic proof so it's chain agnostic
ernestognw cc1d923
update title
ernestognw fa0d43a
Mention multihoping
ernestognw ae50da0
Update erc-7965.md
ernestognw d3e4e16
Address feedback
ernestognw cd6342b
Merge branch 'master' into feat/storage-proof-broadcasting-gateways
ernestognw cebfce8
Be more explicit about the verification process
ernestognw c03261c
Merge branch 'master' into feat/storage-proof-broadcasting-gateways
ernestognw 5331578
Require ERC-7930
ernestognw ef2af17
up
ernestognw File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,238 @@ | ||
| --- | ||
| eip: 7965 | ||
| title: Proof-based Broadcast in ERC-7786 Gateways | ||
| description: Cross-chain messaging using cryptographic proofs to verify messages between blockchains. | ||
| author: Ernesto García (@ernestognw) | ||
| discussions-to: https://ethereum-magicians.org/t/erc-7965-storage-proof-broadcasting-for-cross-chain-messaging-gateways/24477 | ||
| status: Draft | ||
| type: Standards Track | ||
| category: ERC | ||
| created: 2025-06-06 | ||
| requires: 7786, 7930 | ||
| --- | ||
|
|
||
| ## Abstract | ||
|
|
||
| This document defines standardized broadcasting semantics and attributes for [ERC-7786] cross-chain messaging that enable trustless message verification through cryptographic proofs. Messages are committed on source chains in verifiable ways, then verified on destination chains using cryptographic proofs of the source chain's state or transaction history. This approach provides cross-chain communication without relying on external validators or bridge operators. | ||
|
|
||
| [ERC-7786]: ./eip-7786.md | ||
|
|
||
| ## Motivation | ||
|
|
||
| Cross-chain messaging protocols typically rely on external validators, multisigs, or optimistic mechanisms that introduce trust assumptions and potential points of failure. Cryptographic proofs offer an alternative approach where messages can be verified using the consensus mechanisms and cryptographic commitments of the chains themselves (e.g. storage proofs for EVM chains). | ||
|
|
||
| However, cryptographic proof verification requires chain-specific routing information, proof data, and verification parameters that are not addressed by the base [ERC-7786] interface. Additionally, while [ERC-7786] defines basic broadcasting through "omitted or zeroed" recipient addresses, it does not specify granular broadcasting patterns that enable targeting specific chains or chain types. Enhanced broadcasting semantics enable messages to be sent with varying levels of specificity, from all addresses on a specific chain to all supported infrastructure. | ||
|
|
||
| This document standardizes these requirements as [ERC-7786] attributes, enabling cryptographic proof-based messaging within the established cross-chain messaging framework. The specification supports multi-hop verification paths, allowing messages to traverse through multiple intermediary chains when direct verification is not possible. | ||
|
|
||
| The key benefits of this approach include: | ||
|
|
||
| - **Trustless verification**: No external validators or multisigs required. Chains trust their own consensus mechanisms. | ||
| - **Universal compatibility**: Works between chains with verifiable state relationships through shared settlement infrastructure or compatible proof systems. | ||
| - **Flexible messaging patterns**: Supports both targeted and granular broadcast messaging through standardized semantics, enabling new classes of applications like oracles and intent settlement systems. | ||
| - **Composability**: Full integration with existing [ERC-7786] infrastructure and tooling | ||
|
|
||
| ## Specification | ||
|
|
||
| The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. | ||
|
|
||
| ### Broadcasting Semantics | ||
|
|
||
| [ERC-7786] defines broadcasting as using "omitted or zeroed" recipient addresses (containing an [ERC-7930] interoperable address with all fields set to zero). This specification extends that concept to enable granular broadcasting patterns through [ERC-7930]'s flexible address structure: | ||
|
|
||
| [ERC-7930]: ./eip-7930.md | ||
|
|
||
| Broadcasting semantics in this specification extend [ERC-7786] by allowing: | ||
|
|
||
| * Interoperable addresses with `AddressLength` set to 0 and specified `ChainType` and/or `ChainReference` to broadcast messages to all addresses on a given chain | ||
| * Interoperable addresses with `ChainReferenceLength` set to 0 and a specified `ChainType` to broadcast to all chains of a given type | ||
| * Interoperable addresses with all fields set to zero to indicate universal broadcasting to all supported chains and addresses | ||
|
|
||
| Receivers of broadcast messages SHOULD validate the source and authenticity of messages according to their own security requirements. | ||
|
|
||
| ### Cryptographic Proof Attributes | ||
|
|
||
| This specification defines the following [ERC-7786] attributes for cryptographic proof messaging. Gateways MUST return true if `supportsAttribute` is called with the selector for supported attributes. | ||
|
|
||
| #### `route((bytes,bytes,uint256)[])` | ||
|
|
||
| Specifies the verification path from destination to source chain with corresponding proofs and version requirements. Each tuple contains a bytes-encoded address that SHOULD be called for verification of the next chain's state or transaction history, the cryptographic proof required for that verification step, and the expected version of the verification logic (0 means any version is acceptable). The route address MAY invoke other gateways to resend the message to the next hop. | ||
|
|
||
| When a non-zero version is specified, gateways MUST reject messages if the route address does not support the exact required version (unless `0`). Route addresses SHOULD implement version querying mechanisms to enable compatibility checking. | ||
|
|
||
| The route MUST form a valid path where each step represents a direct relationship between chains that enables state or transaction verification. For multi-hop scenarios, the route creates a chain of trust where each step verifies the next, ultimately establishing the authenticity of the source chain's state. Gateways MUST reject messages with invalid or incomplete proof data. | ||
|
|
||
| ```solidity | ||
| abi.encodeWithSignature("route((bytes,bytes,uint256)[])", hops); | ||
| ``` | ||
|
|
||
| #### `inclusionProof(bytes)` | ||
|
|
||
| The cryptographic proof demonstrating that a specific message exists in the source chain's committed state at a finalized block or transaction. For EVM chains, this would typically be an event inclusion proof or storage proof. | ||
|
|
||
| [ERC-7786] receivers MUST validate the cryptographic proof according to the source chain's proof system. | ||
|
|
||
| ```solidity | ||
| abi.encodeWithSignature("inclusionProof(bytes)", proofData); | ||
| ``` | ||
|
|
||
| #### `targetBlock(uint256)` | ||
|
|
||
| Specifies the block number or height on the source chain where the message was committed. For chains that don't use sequential block numbers, this represents the equivalent commitment identifier. | ||
|
|
||
| [ERC-7786] receivers MAY validate the target block for freshness or finality requirements according to their security policies. Receivers MAY ignore this attribute if not needed for their use case. | ||
|
|
||
| When provided, this attribute SHOULD correspond to the block or commitment whose state is proven by the cryptographic proof. | ||
|
|
||
| ```solidity | ||
| abi.encodeWithSignature("targetBlock(uint256)", blockNumber); | ||
| ``` | ||
|
|
||
| ### Relationship to Existing Proof Protocols | ||
|
|
||
| This ERC provides standard attributes that enable protocols like [ERC-7888] (for EVM storage proofs) and other proof systems to implement [ERC-7786] gateways without rebuilding their core verification logic. For example, an [ERC-7888] Broadcaster MAY expose an [ERC-7786] interface using these attributes while maintaining its existing storage proof architecture. Similarly, other proof systems can implement these same attributes using their native proof mechanisms. | ||
|
|
||
| [ERC-7888]: ./eip-7888.md | ||
|
|
||
| ### Caching | ||
|
|
||
| Gateways implementing this specification MAY implement caching mechanisms to optimize repeated proof verifications. | ||
|
|
||
| ### Mutability of Message Commitments | ||
|
|
||
| Gateways MAY choose to commit messages in ways that cannot be deleted or modified after being set, providing immutability guarantees. While not required by this standard, implementers can use [ERC-7201] to calculate namespaces for immutable storage locations on EVM chains, or equivalent immutability mechanisms on other chain architectures. | ||
|
|
||
| [ERC-7201]: ./eip-7201.md | ||
|
|
||
| ### Verification Process | ||
|
|
||
| In [ERC-7786], the `payload` contains the actual message data to be delivered, while the `attributes` contain proof metadata that establishes the payload's authenticity. The destination gateway validates the attributes through cryptographic verification, and it MAY cache results for future use. | ||
|
|
||
| For multihop scenarios, each route step verifies the next chain's state commitment, creating a chain of trust from destination to source. This enables message verification across multiple intermediate chains, similar to systems like [ERC-7888]'s BlockHashProver chains. | ||
|
|
||
| Message verification follows these steps: | ||
|
|
||
| 1. Parse the `route` and `inclusionProof` attributes from the message, and optionally `targetBlock` if provided | ||
| 2. Validate all required attributes are present and well-formed | ||
| 3. For each route step, verify block hash transition or equivalent state commitment using the paired proof and validate version requirements if specified (non-zero) | ||
| 4. Use the `inclusionProof` to verify that message data exists in the source chain's committed state at the target block obtained from the route verification. The source chain SHOULD correspond to the final validated step in the route verification process | ||
| 5. Optionally validate the `targetBlock` for freshness or finality requirements if the attribute is provided and the receiver chooses to validate it | ||
| 6. Execute the message if all verifications pass | ||
|
|
||
| ## Rationale | ||
|
|
||
| This standard extends [ERC-7786]'s attribute system to add cryptographic proof capabilities without creating new interfaces. This approach maintains compatibility with existing infrastructure while enabling trustless cross-chain verification, allowing implementations to focus on proof verification logic rather than rebuilding messaging infrastructure. | ||
|
|
||
| ### Broadcasting and Cryptographic Proofs | ||
|
|
||
| [ERC-7786] natively supports broadcasting through "omitted or zeroed" [ERC-7930] interoperable addresses. This specification extends that foundation to enable granular broadcasting patterns through [ERC-7930]'s flexible address structure. Empty address components (`AddressLength` = 0) allow broadcasting to all addresses on a specific chain, while empty chain references (`ChainReferenceLength` = 0) enable broadcasting to all chains of a specific type (e.g., all EVM chains via `eip155` namespace). Universal broadcasting uses fully zeroed addresses as defined in [ERC-7786]. | ||
|
|
||
| This multi-level broadcasting approach leverages [ERC-7930]'s inherent address structure and [ERC-7786]'s existing broadcast semantics rather than introducing new patterns, ensuring consistency with the cross-chain messaging ecosystem. The granularity enables efficient message distribution patterns: oracle feeds can target specific chains, governance messages can address entire chain families, and emergency notifications can reach all supported infrastructure. | ||
|
|
||
| Cryptographic proofs provide trustless verification relying only on chain consensus mechanisms. This approach offers universal accessibility, cryptographic guarantees, cost efficiency (gas only on source/destination chains), and enables implicit batching through shared state commitments. Multi-hop routing extends this capability to chains without direct verification relationships. | ||
|
|
||
| ### Attribute Design | ||
|
|
||
| The two required attributes provide the essential functionality for cryptographic proof verification, while the optional `targetBlock` attribute enables additional freshness and finality validation when needed. Combining route information into a single tuple maintains type safety while separating proof verification from chain state transitions allows independent optimization. The optional nature of `targetBlock` provides implementation flexibility without adding unnecessary complexity to basic use cases. | ||
|
|
||
| ### Caching | ||
|
|
||
| Caching can improve performance by storing verification results for reuse. Since proofs are deterministic, they can be safely cached. This is especially useful for broadcast messages that need multiple verifications. Implementations should cache both block hash transitions and proof verification results, while invalidating the cache when proof infrastructure changes. | ||
|
|
||
| ### Mutability of Message Commitments | ||
|
|
||
| Proving a commitment that could be deleted or modified may introduce additional security risks. For example, if a message is committed in a way that allows deletion after the message is sent, the proof will still be valid. This is why the specification does not require immutability, but allows gateways to choose to commit messages in immutable ways if they so desire. | ||
|
|
||
| ## Backwards Compatibility | ||
|
|
||
| This ERC extends [ERC-7786] through its attribute system and introduces no breaking changes to existing implementations. Gateways that do not support cryptographic proof attributes will simply reject messages containing them, which is the expected behavior for unsupported features. | ||
|
|
||
| Existing [ERC-7786] tooling and infrastructure can immediately leverage cryptographic proof messaging without modification, as the base interface remains unchanged. | ||
|
|
||
| ## Reference Implementation | ||
|
|
||
| ### Basic Gateway Usage | ||
|
|
||
| ```solidity | ||
| struct Hop { | ||
| bytes gateway; // bytes-encoded address of the gateway | ||
| bytes proof; | ||
| uint256 version; // 0 = any version | ||
| } | ||
|
|
||
| // Prepare route with proofs and version requirements | ||
| Hop[] memory hops = new Hop[](2); | ||
| hops[0] = Hop(gateway1, proof1, 1); // Require version 1 | ||
| hops[1] = Hop(gateway2, proof2, 0); // Any version acceptable | ||
|
|
||
| // Example 1: Address Broadcasting - broadcast to all addresses on Arbitrum One (42161) | ||
| bytes memory addressBroadcast = abi.encodePacked( | ||
| uint16(1), // Version | ||
| uint16(0x0000), // ChainType: eip155 | ||
| uint8(2), // ChainReferenceLength: 2 bytes for chain ID | ||
| uint16(42161), // ChainReference: Arbitrum One (42161) | ||
| uint8(0) // AddressLength: 0 (empty address = broadcast to all addresses) | ||
| ); | ||
|
|
||
| // Example 2: Chain Type Broadcasting - broadcast to all EIP-155 chains | ||
| bytes memory chainTypeBroadcast = abi.encodePacked( | ||
| uint16(1), // Version | ||
| uint16(0x0000), // ChainType: eip155 | ||
| uint8(0), // ChainReferenceLength: 0 (broadcast to all chains of this type) | ||
| uint8(0) // AddressLength: 0 (empty address) | ||
| ); | ||
|
|
||
| // Example 3: Universal Broadcasting - broadcast to all supported chains and addresses | ||
| bytes memory universalBroadcast = abi.encodePacked( | ||
| uint16(1), // Version | ||
| uint16(0x0000), // ChainType: 0 (all chain types) | ||
| uint8(0), // ChainReferenceLength: 0 (all chains) | ||
| uint8(0) // AddressLength: 0 (all addresses) | ||
| ); | ||
|
|
||
| bytes[] memory attributes = new bytes[](3); | ||
| attributes[0] = abi.encodeWithSignature("route((bytes,bytes,uint256)[])", hops); | ||
| attributes[1] = abi.encodeWithSignature("inclusionProof(bytes)", proofData); | ||
| attributes[2] = abi.encodeWithSignature("targetBlock(uint256)", blockNumber); // Optional | ||
|
|
||
| // Send message with address broadcasting | ||
| gateway.sendMessage( | ||
| addressBroadcast, // broadcast to all addresses on Arbitrum One | ||
| abi.encode("priceUpdate", asset, price), | ||
| attributes | ||
| ); | ||
|
|
||
| // Send message with chain type broadcasting | ||
| gateway.sendMessage( | ||
| chainTypeBroadcast, // broadcast to all EIP-155 chains | ||
| abi.encode("governanceProposal", proposalId, votingPeriod), | ||
| attributes | ||
| ); | ||
|
|
||
| // Send message with universal broadcasting | ||
| gateway.sendMessage( | ||
| universalBroadcast, // broadcast to all supported chains and addresses | ||
| abi.encode("pause", reason), | ||
| attributes | ||
| ); | ||
| ``` | ||
|
|
||
| ## Security Considerations | ||
|
|
||
| ### Validation Requirements | ||
|
|
||
| Gateways must rigorously validate all proof data to prevent message forgery, including proof format, completeness, and cryptographic validity. Route addresses must correspond to legitimate proof infrastructure forming a valid, connected path between chains. Only finalized blocks or equivalent commitment points should be used for proof generation to prevent reorganization attacks. | ||
|
|
||
| Consumers of cryptographic proof messages should implement appropriate freshness checks, as proofs can verify messages at any historical block or commitment, potentially including very old messages. This is not required for gateways offering immutable message commitments. | ||
|
|
||
| ### Route Security | ||
|
|
||
| The security of a multi-hop route is only as strong as the weakest proof in the verification path. When multiple route steps are used, the overall security level is determined by the step with the lowest cryptographic guarantees or the least secure consensus mechanism. Implementers should carefully evaluate each hop in their routes and consider the cumulative security implications when designing cross-chain verification paths. | ||
|
|
||
| ### Broadcast Message Security | ||
|
|
||
| Since broadcast messages can be executed by any party, receivers should implement robust validation of message sources and contents. This includes verifying the sender's authority and the message's semantic validity. | ||
|
|
||
| ## Copyright | ||
|
|
||
| Copyright and related rights waived via [CC0](../LICENSE.md). | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding is that this verification logic happens on the receiving end (destination chain). It described how to verify something actually happened on the source chain.
What I don't understand is:
what is the relationship between the "data" part of the ERC-7786 message and these attributes. It it the 7786 receiver the one that must match the data and the attributes it receives, and interpret the data in the context of these attributes which have been verified by the destination gateway ?
how are these atributes set on the sending side. If the sender expected to build them before doing the
sendcall on the source chain? If so, that means they have to correspond to data that was in place (part of the state) at least 1 block before the "send" is mined. The fact that setting the data in place, and sending the crosschain message must be done in separate block feels like a big downside.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I addressed the first point a bit better in cebfce8.
For the second point, I know each protocol has a different way of generating the proof for the same block they're proposing. For example, Taiko's SignalService uses anchor transactions at the beginning of each L2 block to establish verifiable state commitments, eliminating the need for separate block commitments. I'm not sure if this standard should determine how that's done