本文档描述了一种在以太坊信标链上支持验证者提款进入EVM的系统级“操作”。它定义了提款对象结构、在执行载荷中新增字段及其根哈希,并详细说明了提款处理机制,强调其与普通交易分离以增强安全性,且不产生Gas费用。
引入一个系统级“操作”来支持从信标链“推入”到 EVM 的验证者提款。
这些操作会无条件地增加指定接收者的余额。
本 EIP 提供了一种方式,使信标链上的验证者提款能够进入 EVM。 该架构是“推”式的,而非“拉”式的,提款在从共识层出队后,必须立即在执行层进行处理。
提款在执行负载中被表示为一种新类型的对象——一个“操作”——它将提款功能与用户级交易分离。 这种方法比之前引入新交易类型的方法更为复杂,但它清晰地将这种“系统级”操作与常规交易分开。 这种分离通过减少将系统级关注点与用户数据混合所产生的交互影响,简化了测试(从而促进了安全性)。
此外,这种方法在核心协议方面比“拉”式替代方案更复杂,但确实将一项关键功能更紧密地集成到协议本身中。
| 常量 | 值 | 单位 |
|---|---|---|
FORK_TIMESTAMP |
1681338455 |
从执行时间戳 FORK_TIMESTAMP 开始,执行客户端必须引入以下对负载验证和处理的扩展:
定义一个名为 withdrawal 的新的负载级别对象,该对象描述了在共识层已验证的提款。
Withdrawal 在语法上类似于用户级交易,但与用户级交易存在于不同的领域。
Withdrawal 提供来自共识层的关键信息:
index,作为 uint64 值,每个提款递增 1,以唯一标识每个提款validator_index,作为 uint64 值,对应于共识层上的提款address,作为 20 字节值amount 以 Gwei (1e9 wei) 为单位的以太数量,作为 uint64 值。注意:每个提款的 index 是一个跨越整个提款序列的全局计数器。
Withdrawal 对象根据模式 [index, validator_index, address, amount] 序列化为 RLP 列表。
执行负载获得了一个新的 withdrawals 字段,它是一个包含 Withdrawal 数据的 RLP 列表。
例如:
withdrawal_0 = [index_0, validator_index_0, address_0, amount_0]
withdrawal_1 = [index_1, validator_index_1, address_1, amount_1]
withdrawals = [withdrawal_0, withdrawal_1]
这个新字段在执行负载结构中的现有字段之后编码,并被认为是执行负载主体的一部分。
execution_payload_rlp = RLP([header, transactions, [], withdrawals])
execution_payload_body_rlp = RLP([transactions, [], withdrawals])
注意:此模式中的空列表是由于 EIP-3675 将 ommers 值设置为固定常量。
执行负载头获得了一个新的字段,用于提交执行负载中的 withdrawals。
这种承诺的构建方式与现有执行负载头中的交易根相同,即将每个提款按其在 withdrawals 列表中的索引插入到一个 Merkle-Patricia 尝试树中。
def compute_trie_root_from_indexed_data(data):
trie = Trie.from([(i, obj) for i, obj in enumerate(data)])
return trie.root
execution_payload_header.withdrawals_root = compute_trie_root_from_indexed_data(execution_payload.withdrawals)
执行负载头通过一个新字段进行扩展,该字段包含提交给定执行负载中提供的提款列表的尝试树的 32 字节根。
示例:
execution_payload_header_rlp = RLP([
parent_hash,
0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347, # ommers hash
coinbase,
state_root,
txs_root,
receipts_root,
logs_bloom,
0, # difficulty
number,
gas_limit,
gas_used,
timestamp,
extradata,
prev_randao,
0x0000000000000000, # nonce
base_fee_per_gas,
withdrawals_root,
])
注意:本例中的字段名和常量值反映了 EIP-3675 和 EIP-4399。有关更多信息,请参阅这些 EIP。
假设执行负载格式良好,执行客户端会进行额外的负载验证,以确保 withdrawals_root 与给定负载列表中预期的值匹配。
assert execution_payload_header.withdrawals_root == compute_trie_root_from_indexed_data(execution_payload.withdrawals)
执行负载中的 withdrawals 在任何用户级交易应用之后处理。
对于 execution_payload.withdrawals 列表中的每个 withdrawal,实现会根据给定的 amount 增加指定 address 的余额。
请记住,amount 以 Gwei 为单位,因此在处理执行状态中的账户余额时,必须将其转换为 wei 单位。
这种余额变更应是无条件的,并且绝不能失败。
此操作没有相关的 gas 成本。
本 EIP 提出了一种新类型的对象——“提款操作”——因为它具有与其他现有 EVM 交易类型不同的特殊语义。
操作由整个系统发起,而不是像典型交易那样源自最终用户。
一种全新的对象类型将通用 EVM 执行与此类处理隔离开来,以简化提款的测试和安全审查。
在给定时间到达执行层的提款最大数量是有限制的(由共识层强制执行),选择此限制是为了使任何执行层操作成本在更广泛的负载执行上下文中可以忽略不计。
此限制适用于计算成本(状态中仅有少量余额更新)以及存储/网络成本,因为额外的负载占用空间保持较小(当前参数化将额外开销置于当前平均负载大小的约 1%)。
更一般的处理会引入失败的风险,这使得信标链上的记账变得复杂。
本 EIP 提出了一种提款路径,它以最低的(复杂性)成本提供了大部分好处。
没有问题。
提款交易的共识层验证对于确保将正确数量的 ETH 提款回执行层至关重要。 这种从共识层到执行层的 ETH 转移在 EVM 中目前没有类似的机制,因此值得高度安全审查。
通过 CC0 放弃版权及相关权利。
- 原文链接: github.com/nerolation/EI...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!