自毁合约留下的存储,谁来清:EIP-2936 与它的操作码之争 图 1
自毁合约留下的存储,谁来清:EIP-2936 与它的操作码之争 · 图 1

自毁不是删除

很多教程把 SELFDESTRUCT 写成「删除合约」。按现行规则——EIP-6780 在 2024 年 3 月的坎昆升级后生效的规定——自毁在大多数情形下只做一件事:把账户里的全部 ETH 转给指定目标,然后停止当前执行;合约的代码、存储、账户本身都不会被删。只有一种例外保留旧行为:合约在自身创建的同一笔交易里自毁。EIP-2936 讨论的就是这条规则之外的世界:合约还「活着」的时候存储归它自己管,可一旦走向生命尽头,那些存储谁来清?

自毁合约留下的存储,谁来清:EIP-2936 与它的操作码之争 图 2
自毁合约留下的存储,谁来清:EIP-2936 与它的操作码之争 · 图 2

EIP-2936 的设想:给清理者发工资

2020 年 9 月 3 日提交的 EIP-2936 提议两条改动。其一,新增指令 EXTCLEAR(提案编号为 0x5c),弹出两个参数:已自毁合约的地址和一个存储槽号;若该槽非零,就把清零动作的 Gas 账单算给调用者,同时按规则返还一部分——逻辑上等价于「谁清理僵尸数据,谁拿回退款」。其二,它计划修改 SELFDESTRUCT 本身,让自毁不再顺手清存储,并且追溯适用:历史上所有已销毁合约的存储都变成可被 EXTCLEAR 清理的对象。思路是把状态清理外包给市场:清理有利可图,僵尸数据自然有人打扫。按 EIPs 仓库原文核验时,该提案状态为 Stagnant,从未进入主网。

编号撞车的另一幕

EXTCLEAR 圈定的 0x5c 与隔年热门的瞬时存储之争撞了个正着。EIP-1153 的 TLOAD 同样使用 0x5c,并在 2024 年 3 月随坎昆升级真实上线;EIP-2330 的 EXTSLOAD 也候选过这个槽位。三个提案三个命运:TLOAD 上了主网,另外两份停在 Stagnant。今天任何资料里出现 0x5c,默认含义是 TLOAD。这个编号故事是提案世界的常态——虚拟机地址空间有限,好槽位早被人抢注,一份提案落没落地,编号去了哪儿,都是可核查的事实链。

和相邻清理提案的分工

自毁话题的提案族很容易混,一张表说清:EIP-3529(2021 年 8 月随伦敦升级生效)把清存储的退款大幅削减、上限砍到交易用量的五分之一,动机正是「不再奖励清理」,详见 清存储还能退 Gas 吗?EIP-3529 把退款上限砍到五分之一;EIP-6780 把自毁改成只转 ETH 不删数据,本文上文所述;EIP-2936 则想让清理重新有回报,方向恰好与 3529 相反。三者时间线互相咬合:先取消奖励,再冻结删除,才轮不到 2936 这种重建激励的方案出场。理解顺序,比记住编号更接近问题本质。

普通用户的现实边界

三个高频问题用现状回答。第一,「我把合约自毁了,资产会不会消失」:自毁把余额转给指定目标,不会销毁余额(目标恰好是合约自身时转账无净变化,按 6780 的规定也不再烧币),但合约没了就是没了,用户要按项目方的公告处置持仓。第二,「僵尸存储会不会让链越来越重」:会,这正是状态膨胀担忧的一部分,但截至核验时主网没有任何用户可操作的清理通道,节点必须保存全部历史数据,桌面节点越重越慢的问题因此无法靠某条指令解决。第三,「自毁权是不是地雷」:能否触发自毁由合约代码决定,代理合约、工厂合约的自毁开关往往握在少数密钥手里,这与 10442 那篇《EIP-6780后合约还能自毁吗?》的现场核查方法是同一门课。

停摆之后,方向去了哪里

自毁议题在 2936 之后并没有消亡:此后的路线转向「让自毁越来越不像删除」而非「让删除更便宜」,社区更主流的思路是用状态过期、Verkle 树等结构性方案处理旧数据。2936 的价值留下一条朴素的经验:在公共账本上,写数据容易、删数据难,任何声称「一键清理链上痕迹」的第三方服务都值得高度警惕——协议层面根本没有给它留门。

风险提示

本文涉及的指令编号、提案状态与规则描述按 EIPs 官方仓库原文核验,可能随社区推进变化,请以仓库当前内容为准。合约交互涉及资产安全,请以合约实际代码与官方文档为准,本文不构成投资建议。