本文将介绍一种相当简单且高度集成的方法,用于实现以太坊历史数据的分布式存储,并进一步扩展至状态数据的存储。
我们将以太坊的历史数据存入 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 chunking)**并对若干常量进行调整,使上述方案更加简洁。具体而言,如果我们:
(i)实施 EIP-7976,并对零字节和非零字节采用相同的 gas 定价;
(ii)在将 Blob 升级为抗量子(quantum-resistant)时(甚至更早)增大 Blob 的大小;
那么我们就能保证每个负载分块恰好能放进一个 Blob 中!例如,若我们将 calldata 的成本设为每字节 64 gas,则根据 EIP-7825,单个交易的序列化大小将严格限制在 256 kB 以内。因此,只要我们将 Blob 大小设为 256 kB,即可满足这一保证。
我们还需要对区块级别的访问列表(access lists)做同样的处理,确保每个组成部分及其组合都遵循“每字节 64 gas”这一硬性约束。
我们增加一条规则:每个客户端必须存储其看到的每个 Blob 中一个随机选取的样本。假设我们:
将样本大小从当前的 2048 字节缩减至 512 字节,以最大化 PeerDAS 的带宽效率;
假设每个 slot 平均有 64 个 256 kB 的 Blob(总计约 16 MB),这足以支持:
相比当前水平,L2 Blob 空间提升约 20 倍;
或 gas limit 提升约 128 倍;
或两者的某种组合。
那么我们可以得出:
每个客户端存储每个 Blob 的 1/512,因此大约需要 710 个诚实节点(由于样本重叠,略高于 512)才能共同存储 ≥50% 的 Blob 数据,从而恢复全部内容。
在激进假设下(每个 slot 128 个 Blob),每个客户端每年的存储负载约为:512 * 62 * 31556926 / 12 bytes = 80 GB per year,
这对于共识节点而言属于合理范围内的额外负担。
Blob 的查询可通过复用现有的 DAS 机制,或设计一个专门优化同步过程的新协议来实现。
实际上,这一步无需额外工作。如果区块级别的访问列表已包含在 Blob 中,那么你就可以从你已知的最新状态(必要时可使用合并时期的快照)开始同步 Blob,并重放更新以计算当前状态。
如果需要,我们也可以加入一种“从左到右反复遍历状态树”的机制,但目前尚不清楚这种复杂性是否值得引入。
作者:vbuterin
原文:https://ethresear.ch/t/integrated-in-protocol-distributed-history-and-state-storage/23522/1
免责声明:本文为c2e Labs的第三方内容,仅供信息分享与传播之目的,不代表我们的立场或观点且不构成任何投资及应用建议。版权归原作者或来源方所有,如内容或素材有所争议请和我们取得联系。