EIP-2972: 封装的传统交易
Authors | Micah Zoltu (@MicahZoltu) |
---|---|
Created | 2020-09-12 |
Discussion Link | https://ethereum-magicians.org/t/eip-2972-wrapped-legacy-transactions/4604 |
Requires | EIP-155, EIP-2718 |
Table of Contents
简述
两种新的交易类型,用于封装带或不带链 ID 的传统交易。
摘要
引入了两种新的 EIP-2718 交易,它们与传统交易的签名兼容,并且可以被任何客户端自动升级。
0x00 || ssz.serialize(yParity, r, s, rlp([nonce, gasPrice, gasLimit, to, value, data]))
0x01 || ssz.serialize(yParity, r, s, rlp([nonce, gasPrice, gasLimit, to, value, data, chainId, 0, 0]))
动机
我们希望最终弃用传统交易,这样我们就不必在网络和签名层中保留处理它们的代码。 但是,我们还希望确保在该弃用之前生成的交易签名仍然有效,并且资金不会因为无法签署新样式的交易而最终卡住。 此 EIP 提供了一种传输/包含交易的机制,该机制与 EIP-2718 兼容,同时仍然与传统交易的签名兼容。
规范
定义
||
是字节/字节数组连接运算符。yParity
是 secp256k1 签名过程中r
的x
值的曲线点的y
值的奇偶性(偶数为 0,奇数为 1)。
交易
从 FORK_BLOCK_NUMBER
开始,0x00 || ssz.serialize(yParity, r, s, rlp([nonce, gasPrice, gasLimit, to, value, data]))
将是一个有效的交易,其中:
- RLP 编码的交易部分以与传统交易签名/处理/处理完全相同的方式进行签名/处理/处理,但最终编码除外
- TODO: 用于区块交易根的哈希或 Merkle 树
从 FORK_BLOCK_NUMBER
开始,0x01 || ssz.serialize(yParity, r, s, rlp([nonce, gasPrice, gasLimit, to, value, data, chainId, 0, 0]))
将是一个有效的交易,其中:
- RLP 编码的交易部分以与传统交易签名/处理/处理完全相同的方式进行签名/处理/处理,但最终编码除外
- TODO: 用于区块交易根的哈希或 Merkle 树
两种交易类型的 SSZ 模式为:
Transaction[
yParity: boolean,
r: bytes32,
s: bytes32,
signedData: bytes,
]
注意:sszencode(yParity, r, s, rlp(...))
与 yParity || r || s || 0x45000000 || rlp(...)
相同
从 FORK_BLOCK_NUMBER
开始,rlp(nonce, gasPrice, gasLimit, to, value, data, v, r, s)
将不再是区块中的有效交易。
收据
从 FORK_BLOCK_NUMBER
开始,0 || ssz.serialize(status, cumulativeGasUsed, logsBloom, logs)
将是一个有效的收据,其中:
ReceiptPayload
将以与传统收据处理/处理完全相同的方式生成/处理/处理,但其编码除外- TODO: 用于区块收据根的哈希或 Merkle 树
从 FORK_BLOCK_NUMBER
开始,1 || ssz.serialize(status, cumulativeGasUsed, logsBloom, logs)
将是一个有效的收据,其中:
ReceiptPayload
将以与传统收据处理/处理完全相同的方式生成/处理/处理,但其编码除外- TODO: 用于区块收据根的哈希或 Merkle 树
两种收据类型的 SSZ 模式为:
Log[
address: bytes20,
topics: List[bytes32, 4],
data: List[uint8, 0xffffff],
]
Receipt[
status: uint8,
cumulativeGasUsed: uint64,
logsBloom: BitVector[2048],
logs: List[Log, 0xffffff],
]
从 FORK_BLOCK_NUMBER
开始,rlp(status, cumulativeGasUsed, logsBloom, logs)
将不再是区块中的有效收据。
理由
签名不包括交易类型作为第一个签名字节
这些交易类型被明确设计为与传统交易的签名兼容,这意味着我们不能更改被签名的数据。 有关更多详细信息,请参阅“安全注意事项”部分。
两种交易类型而不是一种
随着类型化交易的引入,我们不再需要进行位压缩以避免更改签名的形状。
传统交易在 EIP-155 中引入了链 ID,并且想要避免更改交易数组的长度,因此它将 chainID 位压缩到签名的 v
值中。
由于我们不再需要保证交易类型之间一致的有效负载长度,因此我们选择了两种具有清晰字段的交易类型。
签名与签名数据分开
验证签名时,必须首先将签名数据与签名分开,然后针对签名数据验证签名。
对于传统交易,这有点麻烦,因为您必须首先 RLP 解码交易,然后提取签名,然后 RLP 编码交易的子集。
EIP-155 通过要求验证者进一步解码 v
签名值以提取链 ID(如果存在)并将其包含在签名数据有效负载中,使此过程更加糟糕。
通过将签名数据完全按照签名方式进行编码,我们可以确保可以验证交易的签名,而无需事先进行任何解码。
通过预先对签名进行 SSZ 编码,我们可以轻松提取签名,甚至无需使用解码器。
SSZ 用于序列化
存在一个微弱的共识,即 RLP 对于哈希数据来说不是一个特别好的编码方案,部分原因是它无法被流式传输。
SSZ 几乎肯定会在未来的某个时候包含在以太坊中,因此客户端可能会访问 SSZ 解码器。
对于这个特定情况,在没有完整的 SSZ 解码器的情况下进行手动解码并不是太复杂,尽管它确实需要做一些“指针运算”,因为 logs
是一个可变长度项目的数组。
弃用传统交易
通过弃用传统交易,我们可以让客户端更容易,因为他们始终可以在区块中处理类型化交易。
日志和日志数据的最大长度
EIP-706 将 devp2p 消息限制为 24 位长度,这为我们提供了一个实用的上限,即目前任何单个交易的上限。 这个数字似乎远远超过了近期任何时候的合理范围,因此感觉像任何合理的上限。
向后兼容性
新交易与传统交易的签名兼容。 传统交易可以解码,然后编码为类型 0 或类型 1 交易。 此 EIP 没有为传统编码交易引入任何弃用过程,但作者鼓励客户端开发人员尽快将传统编码交易升级为类型化交易(只要合理)。
签名兼容性意味着客户端可能会看到以两种方式编码的同一交易。 在这种情况下,客户端可以选择保留哪个,但建议保留类型化交易而不是传统编码交易。 由于这两个交易将共享一个 nonce,因此一次只有一个交易在链中有效。
测试用例
待定
实现
待定
安全注意事项
虽然 EIP-2718 强烈建议将交易类型作为签名数据的第一个字节包含在内,但在这种情况下我们无法做到这一点,因为我们需要与传统交易保持签名兼容。
幸运的是,EIP-2718 还将交易类型 0xc0
到 0xfe
排除在有效的交易类型之外,并且在这种情况下签名的第一个字节在该范围内,因此我们可以确保这不会与任何未来的交易类型冲突。
这些交易类型的签名确实与传统交易冲突,但是交易的处理方式相同,因此交易最终包含为传统交易还是类型化交易都无关紧要。
版权
版权及相关权利通过 CC0 放弃。
Citation
Please cite this document as:
Micah Zoltu (@MicahZoltu), "EIP-2972: 封装的传统交易 [DRAFT]," Ethereum Improvement Proposals, no. 2972, September 2020. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-2972.