合约的说明书挂在名字上:ERC-205 为什么要给 ABI 压缩之后再上 ENS 图 1
合约的说明书挂在名字上:ERC-205 为什么要给 ABI 压缩之后再上 ENS · 图 1

合约的说明书挂在名字上:ERC-205 为什么要给 ABI 压缩之后再上 ENS

钱包要替你调用一个合约,前提是它手里有这份合约的接口说明书,也就是 ABI。今天最常见的方式是开发者把 ABI 打包进应用,或者从区块浏览器抓取。ERC-205 提出了另一条路:把 ABI 挂到 ENS 名字上,让查名字和查接口变成同一个动作。标准创建于 2017 年 2 月 6 日,仓库记录状态为 Stagnant,作者是 ENS 命名体系早期的设计者 Nick Johnson。它解决的问题今天依然存在:一个没有官方前端、只有合约地址的 NFT 项目,钱包怎么知道该按什么函数签名去调用。

说明书有多大,值不值得上链

标准开篇先算了一笔账。 ABI 通常很小,当时能找到的最大实例是 DAO 合约那份:未压缩 JSON 有 9450 字节,转成 CBOR 是 6920 字节,而 JSON 用 zlib 压缩后只剩 1128 字节。大多数 ABI 未压缩也只有几百字节。这个体量决定了塞进链上名字系统是划算的,也正因如此标准才敢把定义直接放进解析器,而不是像别的元数据那样只放指针。

合约的说明书挂在名字上:ERC-205 为什么要给 ABI 压缩之后再上 ENS 图 2
合约的说明书挂在名字上:ERC-205 为什么要给 ABI 压缩之后再上 ENS · 图 2

四种编码和一个查询方法

原文定义了四种编码,各用一个只有单个比特置位的常量标识:1 是明文 JSON,最通用但最臃肿,链上几乎没法直接解析;2 是 zlib 压缩 JSON,链下解起来轻松,链上基本不可行;4 是 CBOR,比 JSON 更紧凑也更适合在 EVM 这种受限环境里解析,标准还鼓励实现支持它的 stringref 扩展进一步省空间;8 是 URI,只给一个外部地址,最省但也把信任交给了那个地址背后的服务。因为常量都是单位比特,一个 uint 就能表达 256 种编码的组合。

解析器只需要提供一个方法:ABI(bytes32 node, uint256 contentType),接口标识为 0x2203ab56。调用方把自己能接受的编码做按位或塞进 contentType,解析器返回其中一种格式的内容;如果一份都没有或格式对不上,返回 (0, "")。这个 profile 对正向记录(名字指向合约)和反向记录(地址指回名字)都有效。

先查名字,再查地址

标准的查询顺序值得单独说:先用这个名字本身做一次 ABI 查询,查不到再对名字解析出的地址做反向查询。理由在 Rationale 里写得很直接——允许同一个合约挂多份接口说明(比如给某类调用方一份精简版),也允许给没有声明过接口的合约由第三方补一份;而反向兜底保证合约自己声明的规范接口优先,多个别名指向同一合约时不必重复登记。

这条路的边界

从工程角度看这份标准的口味很有意思:它把压缩格式当成接口的一部分来谈判。调用方声明支持哪些编码,解析器按对方能消化的形态交货,同一份 ABI 可以按场景给 JSON 或 CBOR——这种格式位图协商的思路,后来在不少链上协议里反复出现,比如前面提过的 ERC-165 接口探测,用的是先问支持再发请求的同一种哲学。对只想用名字找合约接口的读者,标准给出的两步查询顺序还有个小陷阱值得留意:先查名字自己、查不到再对地址做反向查询。这意味着同一个地址可以被多个名字挂出不同接口说明,钱包拿到的接口是哪一份,取决于它先撞上哪个名字——重要调用前核对接口来源,比迷信名字存在与否更可靠。

要先说清状态:Stagnant 意味着这份提案早已不再被推进,ENS 后来也没有把 ABI 记录做成主路径,今天的通行做法是从验证过的源码仓库和区块浏览器拿接口,元数据规范则走上了 tokenURI 加 JSON 的另一条线。读 ERC-205 的价值不在照抄,而在它示范的发现思路:链下大文件按 URI 挂指针、链上小数据算好体积再存。对 NFT 读者,拿它对照今天钱包连合约的现实就行:接口永远来自你信任的渠道,任何在链接里递给你的 JSON 接口定义,都要先和链上真实函数逐项核对再签名。本文为机制说明,不构成任何投资建议。