ERC-5164: 跨链执行
定义了一个支持跨 EVM 网络执行的接口。
Authors | Brendan Asselstine (@asselstine), Pierrick Turelier (@PierrickGT), Chris Whinfrey (@cwhinfrey) |
---|---|
Created | 2022-06-14 |
Last Call Deadline | 2023-11-15 |
Table of Contents
摘要
本规范定义了基于 EVM 的区块链的跨链执行接口。 此规范的实现将允许一条链上的合约通过发送跨链消息来调用另一条链上的合约。
该规范定义了两个组件:“消息调度器”和“消息执行器”。 消息调度器位于调用端,执行器位于接收端。 发送消息时,消息调度器会将消息通过传输层移动到消息执行器,并在那里执行它们。 此规范的实现必须实现这两个组件。
动机
许多以太坊协议需要协调多个基于 EVM 的区块链之间的状态更改。 这些链通常具有允许以太坊合约执行代码的本机或第三方桥。 但是,桥具有不同的 API,因此桥集成是自定义的。 每一个都提供不同的属性; 具有不同程度的安全性、速度和控制。 定义一个简单、通用的规范将增加代码重用,并允许我们使用通用的桥实现。
规范
本文档中使用的关键词“MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、“MAY”和“OPTIONAL”应按照 RFC 2119 中的描述进行解释。
该规范允许一条链上的合约向另一条链上的合约发送消息。 需要实现两个关键接口:
MessageDispatcher
MessageExecutor
MessageDispatcher
位于原始链上,并将消息调度到 MessageExecutor
以供执行。 MessageExecutor
位于目标链上并执行调度的消息。
MessageDispatcher
MessageDispatcher
位于发送消息的链上。 调度程序的工作是通过传输层将消息广播到一个或多个 MessageExecutor
合约。
必须为每条消息或消息批次生成唯一的 messageId
。 消息标识符在链和调度程序之间必须是唯一的。 这可以通过散列 chainId, dispatcherAddress, messageNonce
元组来实现,其中 messageNonce 是每条消息单调递增的整数。
MessageDispatcher 方法
dispatchMessage
将调度一条消息,以便由 toChainId
指定的目标链上的 MessageExecutor
执行。
当调度消息时,MessageDispatcher
必须发出 MessageDispatched
事件。
如果不支持 toChainId
,MessageDispatcher
必须恢复。
MessageDispatcher
必须将消息转发到 toChainId
上的 MessageExecutor
。
MessageDispatcher
必须为每条消息使用唯一的 messageId
。
MessageDispatcher
必须返回 messageId
,以允许消息发送者跟踪消息。
MessageDispatcher
可以要求付款。
interface MessageDispatcher {
function dispatchMessage(uint256 toChainId, address to, bytes calldata data) external payable returns (bytes32 messageId);
}
- name: dispatchMessage
type: function
stateMutability: payable
inputs:
- name: toChainId
type: uint256
- name: to
type: address
- name: data
type: bytes
outputs:
- name: messageId
type: bytes32
MessageDispatcher 事件
MessageDispatched
当调度单个消息时,MessageDispatcher
必须发出 MessageDispatched
事件。
interface MessageDispatcher {
event MessageDispatched(
bytes32 indexed messageId,
address indexed from,
uint256 indexed toChainId,
address to,
bytes data,
);
}
- name: MessageDispatched
type: event
inputs:
- name: messageId
indexed: true
type: bytes32
- name: from
indexed: true
type: address
- name: toChainId
indexed: true
type: uint256
- name: to
type: address
- name: data
type: bytes
MessageExecutor
MessageExecutor
执行调度的消息和消息批次。 开发人员必须实现 MessageExecutor
才能在接收链上执行消息。
MessageExecutor
将仅执行一次 messageId,但可以按任何顺序执行 messageId。 此规范不保证排序,因为消息和消息批次可能以非顺序方式通过传输层传输。
执行
MessageExecutor
应该使用桥传输层验证所有消息数据。
MessageExecutor
绝不能成功执行一条消息多次。
当消息执行失败时,MessageExecutor
必须恢复交易,以便稍后重试消息。
Calldata
MessageExecutor
必须将 ABI 编码的(messageId
、fromChainId
、from
)附加到要执行的每条消息的 calldata 中。 这允许消息的接收者验证跨链发送者以及消息来自的链。
to.call(abi.encodePacked(data, messageId, fromChainId, from));
- name: calldata
type: bytes
inputs:
- name: data
type: bytes
- name: messageId
type: bytes32
- name: fromChainId
type: uint256
- name: from
type: address
MessageExecutor 事件
MessageIdExecuted
一旦执行了消息或消息批次,就必须发出 MessageIdExecuted
。
interface MessageExecutor {
event MessageIdExecuted(
uint256 indexed fromChainId,
bytes32 indexed messageId
);
}
- name: MessageIdExecuted
type: event
inputs:
- name: fromChainId
indexed: true
type: uint256
- name: messageId
indexed: true
type: bytes32
MessageExecutor 错误
MessageAlreadyExecuted
如果 messageId 已经被执行,MessageExecutor
必须恢复,并且应该发出一个 MessageIdAlreadyExecuted
自定义错误。
interface MessageExecutor {
error MessageIdAlreadyExecuted(
bytes32 messageId
);
}
MessageFailure
如果单个消息失败,MessageExecutor
必须恢复,并且应该发出 MessageFailure
自定义错误。
interface MessageExecutor {
error MessageFailure(
bytes32 messageId,
bytes errorData
);
}
理由
MessageDispatcher
可以耦合到一个或多个 MessageExecutor
。 由桥决定如何耦合这两个。 用户可以通过调用 dispatchMessage
轻松桥接消息,而无需知道 MessageExecutor
地址。 客户端还可以使用 MessageIdExecuted
事件记录的数据来跟踪消息。
某些桥可能需要以本地货币支付,因此 dispatchMessage
函数是 payable 的。
向后兼容性
此规范与现有的治理系统兼容,因为它提供了简单的跨链执行。
安全注意事项
桥信任配置文件是可变的,因此用户必须了解桥安全性取决于实现。
版权
在 CC0 下放弃版权和相关权利。
Citation
Please cite this document as:
Brendan Asselstine (@asselstine), Pierrick Turelier (@PierrickGT), Chris Whinfrey (@cwhinfrey), "ERC-5164: 跨链执行 [DRAFT]," Ethereum Improvement Proposals, no. 5164, June 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-5164.