EIP-4895 withdrawal
EIP-4895 规定了一种系统级取款withdrawal
操作,可以将 validator 的 ETH 从共识层提取到执行层。
FORK_TIMESTAMP
是 1681338455
,也就是 2023-04-12T22:27:35.000Z
,此时间后各个执行客户端必须包含下列payload
校验及功能。
withdrawal
对象
定义一个称为withdrawal
的payload
级对象,它描述已在共识层验证的取款。
包含4个字段:
index
, uint64, 每次提款增加1validator_index
, uint64, validator的序号recipient
, address, 取款接收地址amount
, uint64, 取款金额, 单位是Gwei
注意:每次取款的index是一个跨越整个取款序列的全局计数器。
RLP列表:[index, validator_index, address, amount]
执行时有一个withdrawals
字段,表示取款对象列表,类似于交易列表,包含多个取款:
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]
这个新字段在执行payload
结构中的现有字段之后编码,并被视为执行payload
主体的一部分。
execution_payload_rlp = RLP([header, transactions, [], withdrawals])
execution_payload_body_rlp = RLP([transactions, [], withdrawals])
withdrawals root
通过将每次withdrawal
插入到以取款列表withdrawals
中的索引为键的 Merkle-Patricia trie 中,此承诺的构造与现有执行负载标头中的transactions root
相同。
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)
修改之后的payload
:
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,
])
执行层的校验
假设执行有效payload
格式正确,执行客户端有一个额外的有效payload
验证,以确保 withdrawals_root
与给定有效payload
列表的预期值相匹配。
assert execution_payload_header.withdrawals_root == compute_trie_root_from_indexed_data(execution_payload.withdrawals)
状态转换
取款操作在普通用户交易之后被触发。 对于每个取款,增加对应address的余额,此操作必须成功。
一些解释
-
为什么不作为一种新的交易类型?
因为取款操作不同于其他的交易。取款是由系统发起的,不是由普通用户交易。将通用 EVM 执行从此类处理中分离出来,以简化提款的测试和安全审查。
-
withdrawal为什么没有gas cost?
在给定时间内的取款操作次数是由共识层所限制的,在这种限制下所产生的取款消耗可以忽略不计。 这个界限适用于计算成本(状态中只有少数余额更新)和存储/网络成本,因为额外的有效负载占用空间很小(当前参数化将额外开销设置为当前平均有效负载大小的约 1%)。
-
为什么只是更新余额,而没有EVM的执行?
EVM的执行会使得共识层的计算更加复杂。 此EIP所建议的只更新余额消耗最小。
-
安全注意
取款交易的共识层验证对于确保将适当数量的 ETH 取回执行层至关重要。这种从共识层到执行层的 ETH 传输在 EVM 中没有当前模拟,因此值得进行非常高的安全审查。
现状
此EIP所表述的所有内容均合并至capella共识升级其中使用python进行了更具体的描述。升级完成,已合并至主网。
操作
- 提取区块奖励:只需要将
0x00
提取凭证更改为 eth10x01
地址; - 全部提款:需要在更改为“0x01”地址后,需要连接到信标节点,运行客户端相关命令退出信标链。
具体参见以下文档
https://docs.prylabs.network/docs/wallet/exiting-a-validator
https://docs.prylabs.network/docs/wallet/withdraw-validator
Reference
https://github.com/ethereum/consensus-specs/tree/dev/specs/capella