diff --git a/ERCS/erc-7786.md b/ERCS/erc-7786.md index b40cfe901a4..326d56fcb32 100644 --- a/ERCS/erc-7786.md +++ b/ERCS/erc-7786.md @@ -20,7 +20,7 @@ Cross-chain messaging protocols (or bridges) allow communication between smart c Because almost every protocol implements a different workflow using a specific interface, portability between bridges is currently basically impossible. This also prevents the development of generic contracts that rely on cross chain communication. -The objective of this ERC is to provide a standard interface, and a corresponding workflow, for performing cross-chain communication between contracts. Existing cross-chain communication protocols that do not natively implement this interface should be able to adopt it using adapter gateway contracts. +The objective of this ERC is to provide a standard interface, and corresponding workflows, for performing cross-chain communication between contracts. Existing cross-chain communication protocols that do not natively implement this interface should be able to adopt it using adapter gateway contracts. Compared to previous ERCs in this area, this ERC offers compatibility with chains outside of the Ethereum/EVM ecosystem, and it is extensible to support the different feature sets of various protocols while offering a shared core of standard functionality. @@ -56,9 +56,10 @@ Each attribute key MUST have the format of a Solidity function signature, i.e., In this specification attributes are encoded as an array of `bytes` (i.e., `bytes[]`). Each element of the array MUST encode an attribute in the form of a Solidity function call, i.e., the first 4 bytes of the hash of the key followed by the ABI-encoded value. + ### Sending Procedure -An **Source Gateway** is a contract that offers a protocol to send a message to a receiver on another chain. It MUST implement `IERC7786GatewaySource`. +A **Source Gateway** is a contract that offers a protocol to send a message to a receiver on another chain. It MUST implement `IERC7786GatewaySource`. ```solidity interface IERC7786GatewaySource { @@ -69,6 +70,7 @@ interface IERC7786GatewaySource { function supportsAttribute(bytes4 selector) external view returns (bool); function sendMessage( + bytes calldata messageId, // Unique message identifier string calldata destinationChain, // [CAIP-2] chain identifier string calldata receiver, // [CAIP-10] account address bytes calldata payload, @@ -83,6 +85,7 @@ Returns a boolean indicating whether an attribute is supported by the gateway, i A gateway MAY be upgraded with support for additional attributes. Once present support for an attribute SHOULD NOT be removed to preserve backwards compatibility with users of the gateway. + #### `sendMessage` Initiates the sending of a message. @@ -103,6 +106,10 @@ This event signals that a would-be sender has requested a message to be sent. If `outboxId` is present, post-processing MAY be required to send the message through the cross-chain channel. +#### PUSH v/s PULL communication mode + +This standard supports two communication modes. The PUSH mode allows the Gateway on the destination chain to deliver the message to the application, while in the PULL mode the application fetches the message from the Gateway. In order to specify which communication mode should be used, the sender can set the attribute `pushBased=true` for the PUSH mode and `pushBased=false` for PULL mode. If the `pushBased`attribute is not set, then the Gateway will set the default value `pushBased=true`. + #### Post-processing After a sender has invoked `sendMessage`, further action MAY be required by the gateways to make the message effective. This is called _post-processing_. For example, some payment is typically required to cover the gas of executing the message at the destination. @@ -111,11 +118,21 @@ The exact interface for any such action is out of scope of this ERC. If the `pos ### Reception Procedure -A **Destination Gateway** is a contract that implements a protocol to validate messages sent on other chains. The interface of the destination gateway and how it is invoked is out of scope of this ERC. +A **Destination Gateway** is a contract that receives the sent messages. The gateway either passes the message to the app via `executeMessage` (in the push based model), or stores the message for later reading (in the pull based model). -The protocol MUST ensure delivery of a sent message to its **receiver** using the `IERC7786Receiver` interface (specified below), which the receiver MUST implement. +```solidity +interface IERC7786GatewayDestination { -Once the message can be safely delivered (see Properties), the gateway MUST invoke `executeMessage` with the message contents. + // Optional + function receiveMessage( + bytes calldata messageId, // Unique message identifier + ) external returns (Message memory); +} +``` + +Whether the interface above is implemented or not, the protocol MUST ensure delivery of a sent message to its **receiver** using the `IERC7786Receiver` interface (specified below), which the receiver MUST implement. + +Once the message can be safely delivered (see Properties), the gateway MUST invoke `executeMessage` with the message contents, unless the sender has requested otherwise via the `pushBased` attribute. The gateway MUST verify that `executeMessage` returns the correct value, and MUST revert otherwise. @@ -140,7 +157,11 @@ MUST return `IERC7786Receiver.executeMessage.selector` (`0x675b049b`). #### Interaction Diagram -![](../assets/eip-7786/send-execute.png) +In the PUSH model, the Gateway calls the application with the message. +![](../assets/erc-7786/send-execute.png) + +In the PULL model, the application fetches the message from the Gateway. +![](../assets/erc-7786/send-receive.png) ### Properties @@ -160,7 +181,9 @@ Attributes are designed so that gateways can expose any specific features the br As some cross-chain communication protocols require additional parameters beyond the destination and the payload, and because we want to send messages through those bridges without any knowledge of these additional parameters, a post-processing of the message MAY be required (after `sendMessage` is called, and before the message is delivered). The additional parameters MAY be supported through attributes, which would remove the need for a post-processing step. If these additional parameters are not provided through an attribute, an additional call to the gateway is REQUIRED for the message to be sent. If possible, the gateway SHOULD be designed so that anyone with an incentive for the message to be delivered can jump in. A malicious actor providing invalid parameters SHOULD NOT prevent the message from being successfully relayed by someone else. -Some protocols gateway support doing arbitrary direct calls on the receiver. In that case, the receiver must detect that they are being called by the gateway to properly identify cross-chain messages. Getters are available on the gateway to figure out where the cross-chain message comes from (source chain and sender address). This approach has the downside that it allows anyone to trigger any call from the gateway to any contract. This is dangerous if the gateway ever holds any assets ([ERC-20](./eip-20.md) or similar). The use of a dedicated `executeMessage` function on the receiver protects any assets or permissions held by the gateway against such attacks. If the ability to perform direct calls is desired, this can be implemented as a wrapper on top of any gateway that implements this ERC. +Cross-chain communication protocols can be classified in two categories: _PUSH_ based protocols allow for an active Gateway that can call contract functions on the destination chain. _PULL_ based protocols let the applications fetch messages from the passive Gateway. This standard supports both class of protocols via `IERC7786Receiver.executeMessage` (PUSH) and `IERC7786GatewayDestination.receiveMessage` (PULL). Currently most protocols used in practice fall in the _PUSH_ category and hence the implementation of `IERC7786GatewayDestination.receiveMessage` is optional. + +Some (PUSH based) protocols gateway support doing arbitrary direct calls on the receiver. In that case, the receiver must detect that they are being called by the gateway to properly identify cross-chain messages. Getters are available on the gateway to figure out where the cross-chain message comes from (source chain and sender address). This approach has the downside that it allows anyone to trigger any call from the gateway to any contract. This is dangerous if the gateway ever holds any assets ([ERC-20](./eip-20.md) or similar). The use of a dedicated `executeMessage` function on the receiver protects any assets or permissions held by the gateway against such attacks. If the ability to perform direct calls is desired, this can be implemented as a wrapper on top of any gateway that implements this ERC. ## Backwards Compatibility diff --git a/assets/erc-7786/send-receive.mermaid b/assets/erc-7786/send-receive.mermaid new file mode 100644 index 00000000000..8ab6eefd1a4 --- /dev/null +++ b/assets/erc-7786/send-receive.mermaid @@ -0,0 +1,15 @@ +sequenceDiagram + box Source chain + participant Sender + participant SourceGateway + end + box Destination chain + participant DestinationGateway + participant Receiver + end + Sender->>SourceGateway: sendMessage(...) + SourceGateway-->>DestinationGateway: [underlying protocol] + Receiver->>Receiver: f(...) starts execution + Receiver->>DestinationGateway: receiveMessage(...) + Receiver->>Receiver: f(...) ends execution + diff --git a/assets/erc-7786/send-receive.png b/assets/erc-7786/send-receive.png new file mode 100644 index 00000000000..84b9e9f0950 Binary files /dev/null and b/assets/erc-7786/send-receive.png differ