有存储却没代码的地址怎么办:EIP-8253 给零 nonce 账户统一盖一个戳 图 1
有存储却没代码的地址怎么办:EIP-8253 给零 nonce 账户统一盖一个戳 · 图 1

以太坊有一类极冷僻的地址:没有代码,nonce 是 0,存储槽里却躺着数据。多数钱包根本注意不到它们,但它们卡在一个协议细节上:合约创建落到这种地址时,规则可能放行,于是未来的合约会”继承”一段与自己无关的旧存储——状态错乱的经典配方。EIP-8253 在 2026 年 5 月提出收尾方案:在分叉区块上,把一份固定清单里这些账户的 nonce 一次性改成 1。它是草案。

幽灵地址从哪来

来历可以精确到一条规则史:在 2016 年 Spurious Dragon 升级引入 EIP-161 的账户清理规则之前,合约创建不先把目标地址的 nonce 置为一再运行构造代码。于是有这样一个窗口:构造代码往存储里写了值、最后又没返回代码(或者干脆自毁收场),产出的账户就停在”零 nonce、零代码、有存储”的三不像状态。EIP-161 之后这条路被堵上,存量却留了下来——数量不大、每一个来历可查,这正是 8253 能附上完整主网清单的原因。危险点在于创建规则(EIP-684)要求 CREATE 目标地址 nonce 为零:恰好有合约的部署地址撞进这些历史地址,合约会带着别人的存储上线。

为什么改 nonce 而不是删存储

让碰撞失败有两条路线。一条在创建时检查目标地址有没有非空存储、有就还原——这是 EIP-7610 的方向。另一条反过来,在账户身上留”已占用”记号:nonce 就是现成的记号,把 0 挪成 1,任何 CREATE 或 CREATE2 落在这些地址上都会在最早时刻自动失败,一行创建规则都不用改。8253 把自己的路线说成不规则状态转换(irregular state transition):升级块开头直接改一批账户的元数据。相比删除存储,它不制造”数据去哪了”的悬案——旧存储原样躺在那里,只是永远不会再被新合约认领;相比逐次检查,它没有运行时代价,一次付清。

一次协议补丁的分寸感

这类提案的分寸值得细看:不惩罚谁、不没收什么,甚至不解释这些地址的归属,只是用最低干预买到未来的正确性。代价同样真实:归档与索引服务要处理同一高度前后这批账户元数据不一致;测试网和分叉链得各自决定套不套用这份主网清单(提案专门讨论了非主网链的适用问题);状态指纹类工具要重新基线。清单逐地址列明,所有客户端必须在同一区块整齐划一执行——这也是它需要进协议而非脚本的原因。

一次改状态的三种剧本

让同一批地址不再危险,其实有三种剧本。剧本一是事前防线:每次合约创建多跑一步存储检查,有非空存储就还原——干净,但代价付在每一次部署上,检查本身还要进规范、进测试、进每条客户端的性能账。剧本二是事后清理:把那些幽灵地址的存储删掉,让账户回到「本来就该空」的状态——但删除状态等于改写所有人账本的历史页脚,归档与审计都得追问谁批的。剧本三是给地址盖占用戳:nonce 挪一挪,创建自然撞墙,检查不必每次做、数据一个字不碰——代价只在升级块那一次集中动作。8253 选的是第三条,并把它的非常规性写进名字(不规则状态转换)。三条剧本的排序逻辑对所有协议修补通用:能一次性付清的,别摊成运行时常税;能不动数据的,别动数据。

快速问答

问:这些账户的钱会被动吗? 答:不会。只把 nonce 从 0 改成 1,余额与存储都不碰。

问:会不会波及无辜? 答:名单逐地址核对,不在名单上的零 nonce 账户行为完全不变。

问:怎么确认我的地址在不在名单上? 答:任何状态查询都能列某地址的 nonce 与代码情况;完整清单附在提案文本里。

风险提示:本文介绍协议草案与状态模型细节,不构成任何投资建议;名单与激活方式以当期提案文本为准。