链上合同只留一个指纹:ERC-2678 包清单的字段分工与可重建源码树 图 1
链上合同只留一个指纹:ERC-2678 包清单的字段分工与可重建源码树 · 图 1

链上合同只留一个指纹:ERC-2678 包清单的字段分工与可重建源码树

验证一个链上合约的源码,拼图中总有一块缺失:编译设置、依赖版本、部署记录散落在不同地方。ERC-2678 想用一份文件把这些拼齐。摘要的定义:一个包清单数据格式,表示一个由一个或多个智能合约组成的软件包,可选包含源码以及跨多网络的全部已部署实例;清单是经过压缩的 JSON 对象,经 IPFS 这类内容寻址存储分发,发布到 ERC-1319 定义的链上登记处后即可被自由访问。文档创建于 2020 年 5 月 26 日,仓库记录状态为 Final,正文标题写明这是该格式第三版的形式化自然语言描述。在 ERC 家族里,这是一份少见的、把“软件供应链”直接标准化到链上的文本。

顶层字段的必填条件互锁

清单最外层是一组各司其职的字段。manifest 字段声明这份清单遵循的规范版本;nameversion 互相咬合——规范给的必填条件是:如果包含 version,则 name 必填,反之亦然,并规定包名必须以小写字母开头、长度不得超过 255 个字符,版本号遵循 semver;meta 放与重编译无关的包级元信息。真正承重的是三块:sources 定义源码树,规范用 should 级别要求它应当包含重编译包内合约所需的完整源码;contractTypes 承载编译输出的合约类型对象,把字节码和接口挂到对应源码文件名下;部署实例、编译器版本数组和依赖关系在正文其余部分继续展开。一条防未来的规则被单独立项:为了让向后兼容有抓手,manifest_version 被明令禁止用作字段名——它被预留给规范自己的版本演进,谁都不许占用。

链上合同只留一个指纹:ERC-2678 包清单的字段分工与可重建源码树 图 2
链上合同只留一个指纹:ERC-2678 包清单的字段分工与可重建源码树 · 图 2

验证部署:从字节码反推到源码树

摘要之外,正文给出这套格式最关键的应用场景:包清单可以用来验证链上的公开部署。验证链条被写成可执行的步骤——取目标地址的链上字节码,在清单的部署实例记录中找到匹配项,顺着实例记录引用的编译器和依赖版本,用 sources 提供的源码树重新编译,比对产物。这里每条 should 都不是客套:源码树缺一个文件、编译器版本记错一个补丁号、设置里的优化开关没写全,验证都会安静地失败。清单字段分工的意义正是把这些“静默失败源”变成机器可查的必填项,让“我验证过”第一次有标准化定义可引用。

版本三改了什么

对老用户,第三版的改动说明集中在编译相关字段:编译器定义从合约类型对象里挪到顶层 compilers 数组,规范解释理由是让编译器版本、源码和编译输出三者之间的联系更简单,也让同时使用多个编译器版本的包更好写;sources 对象的定义扩展以支持更多源文件类型,可直接充当编译器的 JSON 输入。另一条更新是对齐 solc 最新版的元数据输出格式。这些细节解释了这份 Final 标准的真实处境:它更像一份被少数工具链认真实现的规范——EthPM 生态此后长期沉寂——但格式设计本身保持完整可读。

读它现在能做什么

把它当怀旧的规范当然可以,但它提出的验证问题今天更尖锐。任何“源码已验证”的合约页面,都可以拿这份清单的字段表当检查单:页面上有没有独立声明的编译器版本数组,而不只是合约源码旁边一行小字;源码树能否覆盖全部依赖,还是只贴了主合约;部署记录是否列出地址与交易哈希,还是只给当前一个地址。一项都答不上时,所谓验证只是“有人在某个浏览器里贴过一段看起来像的代码”。ERC-2678 的答案朴素但成立:把源码树、编译器、部署实例写进同一个被内容哈希钉死的 JSON,验证从信任某个网站,变成重跑一次编译。本文为机制说明,不构成任何投资建议。