该EIP提出了一种新的以太坊交易类型格式,即“信封交易”(envelope transaction),通过引入TransactionType || TransactionPayload的结构,使得未来新增交易类型时,只需确保类型标识符不冲突,而无需处理复杂的与其他新交易类型的兼容性问题。这简化了EIP编写和客户端实现,同时保持了与现有传统交易的向后兼容性。
TransactionType || TransactionPayload 是一个有效的交易,而 TransactionType || ReceiptPayload 是一个有效的交易回执。其中 TransactionType 标识了交易的格式,*Payload 是交易/回执的内容,这些内容将在未来的 EIP 中定义。
过去,当我们想要添加新的交易类型时,必须确保它们与所有其他交易向后兼容。这意味着只能根据编码后的负载来区分它们,并且不可能出现同时匹配两种类型的交易。
这在 EIP-155 中有所体现,其中新值被位打包到其中一个编码字段中。
目前有多个提案正在讨论中,它们定义了新的交易类型,例如允许 EOA 账户直接在其上下文中执行代码的提案,允许 msg.sender 以外的实体支付 gas 的提案,以及与 Layer 1 多重签名交易相关的提案。
所有这些都需要以相互兼容的方式定义,这很快就给 EIP 作者和客户端带来了负担,他们现在必须遵循复杂的规则来区分交易类型。
通过引入信封交易类型,我们只需要确保与现有交易的向后兼容性,从那时起,我们只需解决一个更简单的问题:确保 TransactionType 之间没有编号冲突。
|| 是字节/字节数组的连接运算符。从 FORK_BLOCK_NUMBER 开始,区块头中的交易根 必须 是 patriciaTrie(rlp(Index) => Transaction) 的根哈希,其中:
Index 是此交易在区块中的索引。Transaction 是 TransactionType || TransactionPayload 或 LegacyTransaction。TransactionType 是一个介于 0 和 0x7f 之间的正无符号 8 位数字,表示交易的类型。TransactionPayload 是一个不透明的字节数组,其解释取决于 TransactionType 并在未来的 EIP 中定义。LegacyTransaction 是 rlp([nonce, gasPrice, gasLimit, to, value, data, v, r, s])。所有未来交易类型的签名 应该 包含 TransactionType 作为签名数据的第一字节。
这使得我们不必担心一种交易类型的签名被用作不同交易类型的签名。
从 FORK_BLOCK_NUMBER 开始,区块头中的回执根 必须 是 patriciaTrie(rlp(Index) => Receipt) 的根哈希,其中:
Index 是此回执所对应交易在区块中的索引。Receipt 是 TransactionType || ReceiptPayload 或 LegacyReceipt。TransactionType 是一个介于 0 和 0x7f 之间的正无符号 8 位数字,表示交易的类型。ReceiptPayload 是一个不透明的字节数组,其解释取决于 TransactionType 并在未来的 EIP 中定义。LegacyReceipt 是 rlp([status, cumulativeGasUsed, logsBloom, logs])。回执的 TransactionType 必须 与具有匹配 Index 的交易的 TransactionType 相匹配。
在可预见的未来,0x7f 已经足够,并且为扩展范围留下了多种选择,例如使用高位作为延续位。
这还可以防止我们与旧版交易类型发生冲突,旧版交易类型总是以 >= 0xc0 的字节开头。
虽然强烈建议所有未来交易都对第一字节进行签名,以确保不会出现签名重用问题,但作者承认这并非总是可行或有意义。 一个不可能的例子是与旧版签名方案兼容的封装旧版交易。 另一种潜在情况是交易没有传统意义上的签名,而是有其他机制来确定其有效性。
曾有讨论在此标准中定义 TransactionType 标识符的分配/选择算法。
虽然拥有一个标准化分配机制会很好,但在编写本标准时,并没有强烈的需求,因此被认为超出了范围。
如果认为有必要,未来的 EIP 可能会引入 TransactionType 标识符分配标准。
通过将第二个字节作为不透明字节,而不是 RLP(或其他编码)列表,我们可以在未来支持不同的交易负载编码格式,例如 SSZ、LEB128 或固定宽度格式。
曾有讨论将 ORIGIN 和 CALLER 操作码变得依赖于交易类型,以便每种交易类型都可以定义这些操作码的返回值。
然而,有一种愿望是使交易类型对合约不透明,以阻止合约对不同类型的交易进行区别对待。
此外,还存在对现有合约向后兼容性的担忧,这些合约对 ORIGIN 和 CALLER 操作码做出了假设。
展望未来,我们将假设所有交易类型都将有一个合理地代表第一个 EVM 帧的 CALLER 的地址,并且 ORIGIN 在所有情况下都将是相同的地址。
如果交易类型需要向合约提供额外信息,它们将需要一个新的操作码。
客户端可以通过查看第一个字节来区分旧版交易和类型化交易。
如果它以 [0, 0x7f] 范围内的值开头,则它是一种新的交易类型;如果它以 [0xc0, 0xfe] 范围内的值开头,则它是一种旧版交易类型。
0xff 对于 RLP 编码的交易来说是不现实的,因此它被保留用于未来作为扩展哨兵值。
在设计新的 2718 交易类型时,强烈建议将交易类型作为签名负载的第一个字节包含在内。如果你未能这样做,你的交易可能与另一种类型的交易签名兼容,这可能会给用户带来安全漏洞。
- 原文链接: github.com/nerolation/EI...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!