本文将介绍一种相当简洁且高度集成的方法,用于实现以太坊历史数据的分布式存储,并进一步扩展至状态数据的存储。
我们将以太坊的历史数据存入 Blob(二进制大对象)。最自然的做法是定义一个函数 get_blobs(block_body) -> List[Blob],该函数将区块主体序列化并拆分为多个 Blob。随后,我们要求区块头中的 Blob 版本化哈希列表(blob versioned hash list)的前若干项,必须等于 [get_versioned_hash(blob) for blob in get_blobs(block.body)]。
为便于使用,我们可以将共识层(CL)主体的 Blob 与执行层(EL)主体(即 ExecutionPayload)的 Blob 分开处理。这样一来,ZK-EVM 证明只需将对应部分的版本化哈希作为公开见证(public witness)包含进去。这使得区块验证可以完全通过以下步骤完成:
下载区块头;
对 Blob 执行 DAS(数据可用性采样)检查;
仅下载并直接验证 CL 部分;
验证 ZK-EVM 证明。
当完整的 Lean Consensus(精简共识)特性上线后,CL 部分也将配备 ZK 证明。届时,我们将实现理想中的链上验证模式:仅需检查区块头、DAS 和证明即可完成验证——真正实现“在智能手表上也能验证整条链”(verifiability on a smartwatch)。
我们还可以通过 Payload 分块(payload chunking)并调整若干常量,使上述方案更加优雅。具体而言,如果我们:
(i) 实施 EIP-7976,并对零字节和非零字节采用相同的 gas 定价;
(ii) 在将 Blob 升级为抗量子(或更早阶段)时增大 Blob 容量;
那么我们就能保证:每个 payload 分块恰好能装入单个 Blob 中!
例如,若我们将 calldata 的成本设为每字节 64 gas,则根据 EIP-7825,任何一笔交易的序列化大小将严格小于 256 kB。此时,只要将 Blob 大小设为 256 kB,即可满足上述保证。
我们还需对区块级访问列表(block-level access lists)做同样处理,确保其每一组成部分及整体组合均遵守“每字节 64 gas”这一硬性约束。
我们引入一条新规则:每个客户端必须存储其见到的每个 Blob 的一个随机采样片段。
假设我们:
将采样大小从当前的 2048 字节缩减至 512 字节,以最大化 PeerDAS 的带宽效率;
按激进估计,平均每 slot 有 64 个 256 kB 的 Blob(总计约 16 MB)——这足以支持:
相比现状提升约 20 倍的 L2 Blob 空间,
或约 128 倍的当前 gas limit,
或两者的混合。
那么可得:
每个客户端存储每个 Blob 的 1/512,因此大约需要 710 个诚实节点(略高于 512,以应对采样重叠)才能共同存储 ≥50% 的数据,从而完整恢复所有 Blob。
每个客户端的年存储负载为(按每 slot 128 个 Blob 的激进估算):
这一负载对于共识节点而言是合理且可接受的额外开销。
Blob 的查询可通过复用现有的 DAS 机制实现,也可设计一个专门优化同步流程的新协议。
实际上,这一步无需额外工作。只要区块级访问列表已被包含在 Blob 中,用户就可以从自己已知的最新状态(必要时可使用合并时期的快照)开始同步 Blob,并重放更新以计算出当前状态。
如果需要,我们也可以加入一种“从左到右反复遍历状态树”的机制,但目前尚不明确这种复杂性是否值得引入。
综上,通过将历史与状态自然嵌入 Blob 结构,并结合 DAS 与 ZK 证明,我们有望构建一个轻量、高效、可扩展且高度去中心化的以太坊存储与验证体系。
原标题:协议内集成的分布式历史与状态存储
原文:https://ethresear.ch/t/integrated-in-protocol-distributed-history-and-state-storage/23522/1
免责声明:本文为c2e Labs的第三方内容,仅供信息分享与传播之目的,不代表我们的立场或观点且不构成任何投资及应用建议。版权归原作者或来源方所有,如内容或素材有所争议请和我们取得联系。