Alert Source Discuss
Standards Track: Core

EIP-2718: 类型化交易信封

定义一种新的交易类型,它是一种用于未来交易类型的信封。

Authors Micah Zoltu (@MicahZoltu)
Created 2020-06-13

摘要

TransactionType || TransactionPayload 是一个有效的交易,并且 TransactionType || ReceiptPayload 是一个有效的交易回执,其中 TransactionType 标识了交易的格式,而 *Payload 是交易/回执的内容,这些内容在未来的 EIP 中定义。

动机

过去,当我们想要添加新的交易类型时,我们必须确保它们与所有其他交易向后兼容,这意味着您只能根据编码后的 payload 来区分它们,并且不可能有一种交易同时匹配两种类型。 这在 EIP-155 中可见,其中新值被位打包到其中一个编码字段中。 目前正在讨论多个提案,这些提案定义了新的交易类型,例如允许 EOA 帐户在其上下文中直接执行代码的交易类型,允许 msg.sender 以外的其他人支付 gas 费的交易类型,以及与 layer 1 多重签名交易相关的提案。 所有这些都需要以相互兼容的方式定义,这对 EIP 作者和现在必须遵循复杂规则来区分交易类型的客户端来说,很快就变得很麻烦。

通过引入信封交易类型,我们只需要确保与现有交易的向后兼容性,然后我们只需要解决一个简单得多的问题,即确保 TransactionType 之间没有编号冲突。

规范

定义

  • || 是字节/字节数组连接运算符。

交易

FORK_BLOCK_NUMBER 开始,区块头中的交易根 必须patriciaTrie(rlp(Index) => Transaction) 的根哈希,其中:

  • Index 是此交易在区块中的索引
  • TransactionTransactionType || TransactionPayloadLegacyTransaction
  • TransactionType 是一个介于 00x7f 之间的正无符号 8 位数字,表示交易的类型
  • TransactionPayload 是一个不透明的字节数组,其解释取决于 TransactionType,并在未来的 EIP 中定义
  • LegacyTransactionrlp([nonce, gasPrice, gasLimit, to, value, data, v, r, s])

所有未来交易类型的签名 应该 包括 TransactionType 作为签名数据的第一个字节。 这使得我们不必担心一种交易类型的签名被用作另一种交易类型的签名。

回执

FORK_BLOCK_NUMBER 开始,区块头中的回执根 必须patriciaTrie(rlp(Index) => Receipt) 的根哈希,其中:

  • Index 是此回执对应的交易在区块中的索引
  • ReceiptTransactionType || ReceiptPayloadLegacyReceipt
  • TransactionType 是一个介于 00x7f 之间的正无符号 8 位数字,表示交易的类型
  • ReceiptPayload 是一个不透明的字节数组,其解释取决于 TransactionType,并在未来的 EIP 中定义
  • LegacyReceiptrlp([status, cumulativeGasUsed, logsBloom, logs])

回执的 TransactionType 必须 与具有匹配 Index 的交易的 TransactionType 匹配。

理由

TransactionType 仅上升到 0x7f

在可预见的未来,0x7f 已经足够多了,并且为扩展范围留下了许多选择,例如使用高位作为延续位。 这也防止我们与总是以大于等于 0xc0 的字节开始的旧交易类型发生冲突。

SHOULD 代替 MUST,用于 TransactionType 作为签名数据的第一个字节

虽然强烈建议所有未来的交易都对第一个字节进行签名,以确保不存在签名重用的问题,但作者承认这可能并不总是合理或可行。 一个无法实现这种情况的例子是与旧签名方案签名兼容的包装的旧交易。 另一种可能的情况是交易没有传统意义上的签名,而是有其他确定有效性的机制。

TransactionType 选择算法

关于在这个标准中定义 TransactionType 标识符分配/选择算法的讨论。 虽然有一个标准化的分配机制很好,但在编写这个标准时,并没有强烈的需求,因此被认为超出了范围。 如果认为有必要,未来的 EIP 可能会引入 TransactionType 标识符分配的标准。

不透明字节数组而不是 RLP 数组

通过使第二个字节成为不透明字节,而不是 RLP(或其他编码)列表,我们可以在未来支持交易 payload 的不同编码格式,例如 SSZ、LEB128 或固定宽度格式。

ORIGIN 和 CALLER

关于使 ORIGIN 和 CALLER 操作码依赖于交易类型,以便每种交易类型都可以定义这些操作码返回的内容的讨论。 然而,人们希望使交易类型对合约不透明,以防止合约以不同的方式对待不同类型的交易。 还有人担心与现有的对 ORIGIN 和 CALLER 操作码做出假设的合约的向后兼容性。 展望未来,我们将假定所有交易类型都有一个合理地代表第一个 EVM 帧的 CALLER 的地址,并且 ORIGIN 在所有情况下都将是相同的地址。 如果交易类型需要向合约提供额外的信息,则它们将需要一个新的操作码。

向后兼容性

客户端可以通过查看第一个字节来区分旧交易和类型化交易。 如果它以 [0, 0x7f] 范围内的值开头,那么它是一种新的交易类型,如果它以 [0xc0, 0xfe] 范围内的值开头,那么它是一种旧的交易类型。 0xff 对于 RLP 编码的交易来说是不现实的,因此保留供将来用作扩展 sentinel 值。

安全考虑

在设计新的 2718 交易类型时,强烈 建议将交易类型作为签名 payload 的第一个字节包括在内。如果您未能这样做,您的交易有可能与其他类型的交易签名兼容,这可能会给用户带来安全漏洞。

版权

根据 CC0 放弃版权和相关权利。

Citation

Please cite this document as:

Micah Zoltu (@MicahZoltu), "EIP-2718: 类型化交易信封," Ethereum Improvement Proposals, no. 2718, June 2020. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-2718.