-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add EIP-5164: Cross-Chain Execution (#5164)
* Added Cross-Chain Execution EIP * Integrated pull request review changes for EIP 5164 * Added discussion-to link * Updated EIP-5164 according to discussion - Supports public bridges - Make `relayCalls` payable - Add gas limit and caller - Added EIP feedback * Latest Pull Request changes * Changed ERC->EIP * EIP-5164: Fixed up for EIPW bot * EIP-5164: add ReceiverAware specification * EIP-5164: fix EIP-N linting * EIP-5164: improve CrossChainExecutor description * EIP-5164: improve ExecutorAware description Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com> * EIP-5164: remove executor from relayCalls * EIP-5164: reword RelayCalls requirements Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com> * EIP-5164: reword RelayedCalls requirements Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com> * EIP-5164: reword GasLimitTooHigh requirements Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com> * EIP-5164: reword Authentication requirements Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com> * EIP-5164: reword Authentication requirements Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com> * EIP-5164: reword CallFailure requirements Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com> * EIP-5164: reword ExecutedCalls requirements Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com> * EIP-5164: reword Security Considerations Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com> * EIP-5164: update rationale Co-authored-by: Pierrick Turelier <pierrick@turelier.com> Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>
- Loading branch information
1 parent
5bcd0c3
commit e14d58a
Showing
1 changed file
with
200 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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,200 @@ | ||
--- | ||
eip: 5164 | ||
title: Cross-Chain Execution | ||
description: Defines an interface that supports execution across EVM networks. | ||
author: Brendan Asselstine (@asselstine), Pierrick Turelier (@PierrickGT), Anna Carroll (@anna-carroll), Hadrien Croubois (@Amxx), Nam Chu Hoai (@nambrot), Georgios (@geogons), Theo Gonella (@mintcloud), Rafael Solari (@rsolari), Auryn Macmillan (@auryn-macmillan), Nathan Ginnever (@nginnever) | ||
discussions-to: https://ethereum-magicians.org/t/eip-5164-cross-chain-execution/9658 | ||
status: Draft | ||
type: Standards Track | ||
category: ERC | ||
created: 2022-06-14 | ||
--- | ||
|
||
## Abstract | ||
|
||
This specification defines a cross-chain execution interface for EVM-based blockchains. Developers will be able to have contracts call contracts on other chains. There are two parts to this spec: the "sending" interface and the "executing" interface. The "sending" interface specifies the interface to send a call to another chain; this interface must be implemented by bridges. The "executing" interface must be implemented by the application; it is an interface for executing cross-chain calls. This specification is agnostic of the bridge implementation; it simply standardizes the call interfaces. | ||
|
||
## Motivation | ||
|
||
Many Ethereum protocols need to coordinate state changes across multiple EVM-based blockchains. These chains often have native or third-party bridges that allow Ethereum contracts to execute code. However, bridges have different APIs so bridge integrations are custom. Each one affords different properties; with varying degrees of security, speed, and control. | ||
|
||
## Specification | ||
|
||
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119. | ||
|
||
This specification allows contracts on one chain to send messages to contracts on another chain. There are two key interfaces that needs to be implemented: | ||
|
||
- `CrossChainRelayer` | ||
- `CrossChainExecutor` | ||
|
||
The `CrossChainRelayer` lives on the origin chain. Users can share a single `CrossChainRelayer` or deploy their own. | ||
|
||
The `CrossChainExecutor` lives on the destination chain and executes relayed calls. Users can share a single `CrossChainExecutor` or deploy their own. | ||
|
||
### CrossChainRelayer | ||
|
||
The `CrossChainRelayer` lives on the chain from which messages are sent. The Relayer's job is to broadcast the messages through a transport layer. | ||
|
||
#### Methods | ||
|
||
**relayCalls** | ||
|
||
`CrossChainRelayer`s MUST emit the `RelayedCalls` event when successfully called. | ||
|
||
`CrossChainRelayer`s MUST increment a `nonce` so that each batch of calls can be uniquely identified. | ||
|
||
`CrossChainRelayer`s MAY require payment. | ||
|
||
```solidity | ||
struct Call { | ||
address target; | ||
bytes data; | ||
} | ||
interface CrossChainRelayer { | ||
function relayCalls(Call[] calldata calls, uint256 gasLimit) external payable; | ||
} | ||
``` | ||
|
||
```yaml | ||
- name: relayCalls | ||
type: function | ||
stateMutability: payable | ||
inputs: | ||
- name: calls | ||
type: Call[] | ||
- name: gasLimit | ||
type: uint256 | ||
``` | ||
#### Events | ||
**RelayedCalls** | ||
The `RelayedCalls` event MUST be emitted by the `CrossChainRelayer` when `relayCalls` is called. | ||
|
||
```solidity | ||
interface CrossChainRelayer { | ||
event RelayedCalls( | ||
uint256 indexed nonce, | ||
address indexed sender, | ||
CrossChainExecutor indexed executor, | ||
Call[] calls, | ||
uint256 gasLimit | ||
); | ||
} | ||
``` | ||
|
||
```yaml | ||
- name: RelayedCalls | ||
type: event | ||
inputs: | ||
- name: nonce | ||
indexed: true | ||
type: uint256 | ||
- name: sender | ||
indexed: true | ||
type: address | ||
- name: executor | ||
indexed: true | ||
type: address | ||
- name: calls | ||
type: Call[] | ||
- name: gasLimit | ||
type: uint256 | ||
``` | ||
|
||
#### Error handling | ||
|
||
**GasLimitTooHigh** | ||
|
||
`CrossChainRelayer`s MAY revert with `GasLimitTooHigh` if the `gasLimit` passed to `relayCalls` is higher than the maximum gas limit accepted by the bridge being used. | ||
|
||
```solidity | ||
interface CrossChainRelayer { | ||
error GasLimitTooHigh( | ||
uint256 gasLimit, | ||
uint256 maxGasLimit | ||
); | ||
} | ||
``` | ||
|
||
### CrossChainExecutor | ||
|
||
The `CrossChainExecutor` executes relayed calls. Developers must implement a `CrossChainExecutor` in order to execute messages on the receiving chain. | ||
|
||
#### Authentication | ||
|
||
`CrossChainRelayer`s SHOULD authenticate that the call has been performed by the bridge transport layer. | ||
|
||
`CrossChainRelayer`s SHOULD use [EIP-2771](./eip-2771.md) for authentication and append the address of the Transaction Signer (20 bytes of data) on the origin chain to the end of the call data being executed. | ||
|
||
#### Error handling | ||
|
||
**CallFailure** | ||
|
||
`CrossChainRelayer`s SHOULD revert with `CallFailure` if a call fails. | ||
|
||
```solidity | ||
interface CrossChainExecutor { | ||
error CallFailure( | ||
Call call, | ||
bytes errorData | ||
); | ||
} | ||
``` | ||
|
||
#### Events | ||
|
||
**ExecutedCalls** | ||
|
||
`ExecutedCalls` MUST be emitted once calls have been executed. | ||
|
||
```solidity | ||
interface CrossChainExecutor { | ||
event ExecutedCalls( | ||
CrossChainRelayer indexed relayer, | ||
uint256 indexed nonce, | ||
address indexed caller | ||
); | ||
} | ||
``` | ||
|
||
```yaml | ||
- name: ExecutedCalls | ||
type: event | ||
inputs: | ||
- name: relayer | ||
indexed: true | ||
type: CrossChainRelayer | ||
- name: nonce | ||
indexed: true | ||
type: uint256 | ||
- name: caller | ||
indexed: true | ||
type: address | ||
``` | ||
|
||
### ExecutorAware | ||
|
||
The `ExecutorAware` interface follows [EIP-2771](./eip-2771.md) and allows applications to verify where the call originated from. | ||
|
||
## Rationale | ||
|
||
The Relayer address is passed to the executor so that the execution can easily be traced by a client using the relayer address and nonce. A third party just needs to be aware of a list of Relayers and a list of Executors and can trace execution across all of them. | ||
|
||
Calls are relayed in batches because it is such a common action. Rather than have implementors take different approaches to encoding multiple calls into the `data` portion, this spec includes call batching to take away any guess work. | ||
|
||
Some bridges may require payment in the native currency, so the `relayCalls` function is payable. | ||
|
||
## Backwards Compatibility | ||
|
||
This specification is compatible with existing governance systems as it offers simple cross-chain execution. | ||
|
||
## Security Considerations | ||
|
||
Bridge trust profiles are variable, so users must understand that bridge security depends on the implementation. | ||
|
||
## Copyright | ||
|
||
Copyright and related rights waived via [CC0](../LICENSE.md). |