一个永远不能出现在开头的字节
以太坊的合约代码就是一串字节。2021 年 8 月的伦敦升级起,协议加了一条很小的规则:新部署的合约,第一个字节不能是 0xEF。通过创建交易、合约内创建指令等任何路径部署都一样——initcode 产出的一级代码若以 0xEF 开头,部署直接异常中止,当笔提供的燃料全部消耗。已经存在的合约不受影响,语义上完全不动。规则由 EIP-3541 定义,是伦敦升级里少数改共识层的小规则之一。
为什么要浪费一个字节
这个字节的用途写进提案的动机里:以太坊社区多年一直在设计一种叫可执行对象格式的打包规范(EOF 方向),思路是让合约代码像可执行文件那样有结构化的段和头部校验,部署时一次性验证,之后永远不用再猜它的结构。要让”符合格式”这个判断可信,前提是没有任何存量代码碰巧长得像这个格式的魔数。0xEF 被选中做格式头部的前导字节,理由直白:字形象”Executable Format”的缩写。
但光靠设计还不够。协议在 2021 年 5 月扫描当时状态里的一千八百多万个合约,确认没有任何一个已经部署的代码以 0xEF 开头;如果现在不立法,未来的扫描就永远不能做完。于是先用最便宜的方式把门牌号圈起来——禁止新代码使用——至于格式本身做不做、怎么做,推迟到后续提案再定。这是一种典型的”先锁名分、再定内容”的协议演进手法:规则的成本接近零,却把未来设计空间的确定性买回来了。
顺带澄清一个流传的段子
社区偶尔流传”以 0xEF 开头的合约里有隐藏彩蛋”的说法。真实情况恰好相反:0xEF 在操作码表里是未定义指令,任何代码真把它当指令执行都会异常中止。它从未被用作任何彩蛋或特殊合约的标记;协议只是禁止新的代码以它开头。把”保留字节”讲成”神秘合约入口”是对这条规则最常见的误读。
这条规则改变过什么事故吗
没有记录显示伦敦升级前后因为这条规则发生过部署事故。它约束的是部署路径而不是调用路径:一个旧合约即使历史上以 0xEF 开头(实际扫描为零),也照常执行。这条规则更像一份保险单——买了之后最好永远别用到。EOF 方向后来经历了多轮拆分与搁浅,但 0xEF 的预留一直保留着,因为收回预留意味着重新引入”魔数撞车”的不确定性,代价反而更高。
什么样的代码会被拒
规则只看”产出的一级代码首字节”这一个条件,不看发起者是谁:外部账户发创建交易不行、合约用创建指令不行、用确定性部署也不行,三条路径共用同一条拒绝逻辑。反过来说,它也不管代码其余部分长什么样——第二字节起完全自由,脚本解释器、数据段、任何合法编码都不受影响。还有一处细节常被忽略:initcode 本身可以包含 0xEF,只要它不被原样当作部署产物返回——毕竟 0xEF 作为未定义操作码一执行就中止,能活着跑完的 initcode 输出的若恰好是 0xEF 开头的字节串,才会撞上这条规则。
跟普通用户有什么关系
直接关系接近零:你转的币、签的交易、用的合约都不因它变化。间接价值是理解一类协议设计——很多看似奇怪的规则(禁用的操作码、保留的字节、上限的数值)背后不是拍脑袋,而是给未来的升级留门。下次看到”某个值是保留的、必须填零”这类约定,可以条件反射地想:这是在为哪个还没落地的功能占坑。本文只讨论协议机制,不构成任何投资建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。