以太坊地址永远只有二十字节吗:EIP-7676 为地址扩容留的后门缝 图 1
以太坊地址永远只有二十字节吗:EIP-7676 为地址扩容留的后门缝 · 图 1

地址为什么是四十个十六进制字符:先从一百六十位说起

以太坊地址长得像 0x 加四十个十六进制字符,也就是一百六十位、二十字节。这个数字不是随便定的:账户地址由公钥推导,取的是公钥哈希的低二十字节。但一个反直觉的事实是,EVM 内部的一切栈元素都是两百五十六位的宽数——地址作为栈值出现时,其实住在一个三十二字节的格子里,只有最低那二十字节有意义,高十二字节按规范应当为零。

问题来了:历史实现为了省事,很多操作码在执行时直接把两百五十六位值的高位『剪掉』(truncation)再用,而不是检查高位是不是零。剪掉意味着:一个高位塞了杂质的栈值,和它低二十字节的干净版本,在执行层看来是同一个地址。这给未来留下了一个尴尬——如果哪天要把地址空间扩到一百九十二位甚至更长,那些依赖截断行为部署的存量合约,语义会在一夜之间漂移。

以太坊地址永远只有二十字节吗:EIP-7676 为地址扩容留的后门缝 图 2
以太坊地址永远只有二十字节吗:EIP-7676 为地址扩容留的后门缝 · 图 2

EIP-7676 的思路:先不扩地址,先停止宽容

2024 年 4 月起草的编号 7676 提案就是处理这个尴尬的,类型是 EOF 相关,状态 Stagnant。它做了两件事。第一,在 EOF 的字节码环境中取消执行时截断:涉及目标地址的操作码若收到高九十六位非零的值,不再默默剪掉,而是触发异常停机,把当前调用帧的 Gas 全部烧完。第二,它借机引入一个新操作码 EXTBALANCE,用类似 BALANCE 的冷热定价(首次访问某地址按 EIP-2929 的标准收二千六百 Gas,已访问过收一百 Gas)读取目标余额,供带高位地址语义的新代码使用。

换句话说,7676 不是『把地址改长』的提案,而是『先把作弊通道焊死』的兼容层:新格式代码从此对高位杂质零容忍,旧的遗留代码维持截断行为不变。这样未来真要扩容地址空间时,新旧世界之间有一条明确的行为分界线,而不是靠每个客户端各自决定剪不剪。它依赖的前置提案 EOF 系列本身长期停滞,这也是 7676 停在原地的主因——皮之不存,毛将焉附。

跟状态过期、地址扩容新闻的关系

地址扩容是个周期性出现的长距离议题:状态膨胀到某个程度后,把地址从二十字节加长(比如接入状态分片或状态过期方案里的地址映射)会被重新提出。7676 这类提案的存在意义,是给那场可能几十年后才发生的搬迁提前打扫房间。对读者有用的判断法是:凡是新闻里出现『以太坊地址要变长』的字样,先问三件事——有没有正式编号、是否依赖 EOF 这样的前置设施、状态是否仍是草案。三问之后多半会发现它还在论文与研讨会阶段。

审计与开发里的一页纸

如果你是写合约或做审计的,这个提案给出的操作清单其实很短:把所有涉及目标地址的操作码调用点列出来,检查是否存在把地址截成一百六十位再重新补齐的路径——这类地址修剪在编译与序列化环节偶有发生,一旦地址表示变宽,最先出问题的就是这些工具链角落;确认对余额类操作码的依赖是否隐含高位字节必为零的假设;对先拼地址再哈希的工厂模式单独复核,因为输入字节布局的变化会直接改变派生结果,CREATE2为何能提前算出合约地址?里那条公式对输入字节序最敏感。这份检查即便与 7676 本身命运无关,也值得在审计清单里占一行。

普通用户要不要关心

不用改变任何习惯。地址格式是链的共识参数,变更需要硬分叉级别的协调,钱包、浏览器、交易所会同步换代,期间会有明确的过渡公告;你要做的仍然只是转账前先做小额测试,让新旧格式的任何缝隙由那一笔小额去踩,而不是由大额主转去踩。顺带一个冷知识可以收藏:某些跨链桥用带高位的自定义编码传递地址映射,这类系统若把带杂质地址直接交给主链执行,就会撞上与本提案同款的高位问题——7676 的停机规则等于提前告诉所有桥的作者:映射请放在链下完成。