访问列表是 EIP-2930 给交易开的预知未来外挂:把即将碰的地址和存储槽提前声明出来,运行时这些访问就从冷价降到热价。省了钱,也要付挂号费——地址每个 2400 Gas、存储键每个 1900 Gas。EIP-3521 在 2021 年 4 月 15 日递交,作者 Matt Garnett 只干了一件事:论证这笔登记费里有一段是对交易目标合约的重复收费,并把它降到 calldata 的地板价。
原始账本:二十五个槽的尴尬
提案用一行算式立起问题。设交易在目标合约名下预声明 x 个存储槽:带列表的总成本是地址费 2400、x 个存储键费 1900 加上热读 100,即 2400 加 2000x;不带列表则按冷读原价计,是 2100x。令两边相等,解出 x 等于 24——换句话说,一笔交易要在目标合约名下读满二十五个不同槽,预声明才开始赚钱。每多声明一个键,真正省下的只有 2100 与 1900 加 100 之差、区区 100 Gas,而入场门票 2400 需要先被这些小额差额摊完。数字一摆,多数交易瞬间失去动机:门槛高到只有少数大循环够得着。

重复收费在哪
2930 要求存储槽必须挂在一个显式声明的地址名下,因为运行时要把这个地址加入访问集合。但按 EIP-2929 的规则,交易目标地址本来就会被默认预热——为 tx.to 自己再交一份地址费,等于同一块地皮买了两次。3521 的修法极简:访问列表里第一个出现的 tx.to 地址不再生收地址费,改按 calldata 计价;名下的存储键费用照旧;合约创建交易里,派生出的新地址享受同等待遇。为什么按 calldata?每字节单价在 EIP-2028 里经过完整的拒绝服务分析,被视为交易数据的地板价——提案的理由说,给一份零计算负担的数据收绝对最低价,已经是诚实账本的极限。
账单效果直接反映在测试向量里。一个全非零字节的地址条目折算 320 Gas(20 字节各 16),首位含一个零字节的地址折算 308 Gas——16 与 4 每字节的价差在两个向量里分毫毕现。地址项从 2400 缩到约 320 后,按作者的说法,分界线降到大约五次独特读取的水平——预声明第一次看起来像给普通合约准备的工具。它没能赶上任何一次升级的收纳清单:同年落地的硬分叉带走了访问列表本身与退款整理提案,这一步减负最终没人补,提案停进 Stagnant。原因不难从结构里读出来:这是一笔纯让利改动,而 Gas 表每加一个特例,实现与审计就多一处边角。
快速问答
问:为什么不完全免掉 tx.to 的地址项? 答:提案特意保留最低收费——访问列表要保持 2930 立下的简单可核验结构,条目按数据价计费,免得退化成免检通道。
问:那两个测试数字怎么复算? 答:按 calldata 规则,非零字节 16 Gas、零字节 4 Gas,对地址的 20 字节逐个计价即可得到 320 与 308。
问:今天买访问列表的账变了吗? 答:没变——地址 2400、键 1900 的价目沿用至今,这条减免提案从未激活。
一条判断线
读任何 gas 减免提案,先复算它的盈亏平衡方程:门票多少、每次访问省多少、多少笔能回本。三个数一摆,提案瞄准的用户群——大循环合约还是普通转账——自动显形。3521 的方程还顺手解释了另一件事:冷热的差价被历次调价压缩后,访问列表的适用范围自然收窄,这不是某个客户端的实现问题。
常见误区
一是把访问列表当成加速按钮,其实它先收预登记费,够不够本要数槽位;二是以为 tx.to 可以不出现在列表里——运行时确实默认预热,列表结构却要求显式声明;三是把这条停摆提案与后来的费用改革混为一谈,价目表至今仍是 2930 的原版数字。
风险提示:文中 gas 数字为规则常数而非费用建议,不构成投资建议;价目以 EIPs 仓库与执行层客户端文档当期版本为准。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。