以太坊共识层用 SSZ(Simple Serialize)描述所有要上链的结构,而 SSZ 的默克尔化规则要求列表类型预先声明一个容量上限 N。这个设计在 2020 年很自然,运行几年后暴露出三类成本。EIP-7916(2025 年 3 月创建,现处 Review 阶段)给出一个数据结构层面的解法:让列表的默克尔树像文件一样按需生长,容量不再需要预言。
定容列表的三种病
第一种病是浪费哈希。规范里比如一笔交易的结构,声明的容量常比实际内容大几个数量级——实际只有三五笔交易的区块,仍要把近乎全零的叶树一路哈希到根,白白多做几十次哈希运算。嵌套时更糟:每层都按各自上限铺开,叶数相乘。第二种病是拍脑袋的容量。MAX_TRANSACTIONS_PER_PAYLOAD 这类常量经常被设成远超当前需求的大数以防未来,但”防未来”本身没有先例可依,数值选择带着任意性。第三种病最隐蔽:跨分叉修改容量会改变默克尔树的形状,进而改变每个元素的位置编号(gindex)。历史上确有容量在分叉中被调过的字段,结果所有依赖旧 gindex 的轻客户端验证器和证明生成器要跟着返工——数据结构的地基动了,楼上的证明全部重做。

渐进树怎么长
EIP-7916 引入新类型 ProgressiveList 与 ProgressiveBitlist,配一个新的默克尔化函数 merkleize_progressive。规则是递归的:先把最早的若干叶铺成一棵小树,多出来的叶进入右侧子树,右侧子树的容量按 4 倍递推继续铺。摊开看就是一串容量 1、4、16、64……的子树肩并肩,最深的子树用零补齐(可以只在概念上存在,不必真占内存)。提案给出的容量表很直观:1 层子树容纳 32 字节,5 层约 1.1 万,10 层约 1100 万,14 层约 28.6 亿——列表短时哈希次数极少,列表长时按对数级别摊薄,彻底摆脱”先猜一个大数”的困境。容量约束从协议常量改为交给现实边界:SSZ 本身 4 GB 的可变偏移上限、网络消息尺寸、gas 上限、签名数量的物理极限。
最关键的性质是稳定性:无论列表总长怎么变,第 k 个元素永远落在同一个 gindex 上——因为它的归属只由 k 决定,与容量无关。轻客户端里”验证第 37 笔交易的某字段”这类证明因此一次写成长期有效,协议扩容列表不再构成对证明系统的破坏性变更。
与渐进容器的分工
字段有固定语义上限、想加字段不换哈希树的场景,EIP-7495 渐进容器已经覆盖——那是对容器(有名字的固定字段组)做前向兼容。EIP-7916 处理的是对偶问题:数量不定的同质元素。EIP-7688 则把两种新类型接入具体共识数据结构的改造清单一并给出。三者拼起来是同一路线图的三块拼图:字段可增、长度可涨、证明不断。
一笔对照账
用容量表做个心算:一个只有 5 个元素的列表,定容方案按 100 万容量铺树,需要哈希约 2 的 19 次方量级的内部节点路径中的上层部分(每个非空叶到根约 20 个内部节点,但整棵树根的计算在朴素实现下正比于树宽);渐进方案只为 5 个叶对应的约 5 层小树付哈希。真实实现都会做稀疏优化,但根路径的形状决定了”根承诺”的计算量下限——渐进树的下限贴着真实数据量走,定容树的下限贴着历史最疯狂的容量猜测走。这就是为什么做 ZK 证明与轻客户端的团体对它兴趣最大。
快速问答
问:渐进列表会去掉一切数量限制吗? 答:去掉的是协议层预声明容量,物理与协议的其他限制(4GB 偏移上限、消息尺寸等)仍在。
问:现有 List 会被直接替换吗? 答:提案定义新类型供迁移使用,替换节奏由后续采用型 EIP 决定(如 7688 的接入清单)。
问:gindex 稳定对谁最有用? 答:轻客户端同步协议、桥与任何长期存放验证器代码的系统——它们最怕上游树形漂移。
风险提示:证明与桥接集成涉及资产安全,请以规范原文与审计结论为准,本文不构成投资建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。