ERC-1066:给智能合约的结果发一套十六进制状态码 图 1
ERC-1066:给智能合约的结果发一套十六进制状态码 · 图 1

ERC-1066:给智能合约的“结果”发一套两位十六进制的暗号

网页服务器回话会带一个状态码,200 是成功、404 是没找到。合约呢?多数函数的返回值只有真或假,出错就直接 revert,把执行现场整个回滚。ERC-1066 在 2018 年 5 月 5 日提出第三个选项:像 HTTP 那样给合约结果定义一套通用状态码,让合约能自动反应、让报错能被翻译成人话。按 ercs 仓库记录,这份提案状态为 Stagnant,但正文写得格外扎实,一张码表铺满了整个设计。

一个字节,16 乘 16 的矩阵

规范格式很简单:状态码是一个字节,可以单独返回,也可以作为多返回值的首位。码表被组织成 16 行 16 列的矩阵,高半字节是类别,低半字节是原因。通用行 0x0* 里,0x00 是失败、0x01 是成功、0x02 是等待他人、0x03 是已接受、0x04 是低于下限或不足、0x06 是触及上限、0x08 是重复或不适用。权限行 0x1* 覆盖允许与禁止、等待授权、已被撤销;查找行 0x2* 覆盖未找到、已匹配、等待撮合、重复冲突;协商行 0x3* 覆盖赞成反对、等待批准、法定人数不足;可用性行 0x4* 覆盖已暂停、已排队、已过期、已完成;金融行 0x5* 覆盖转账成败、托管、余额不足、转账量超限。还有一个重要声明:未定义的码不是自由区,而是留给未来规范化的空位。

ERC-1066:给智能合约的结果发一套十六进制状态码 图 2
ERC-1066:给智能合约的结果发一套十六进制状态码 · 图 2

与 revert 不是对手,是互补

提案反复强调状态码与“带原因的 revert”是平行互补关系:revert 适合必须中止执行、回滚一切修改的异常,状态码则适合那些不必回滚、但需要告知上下文的已知分支——等待、延迟、余额不足、需要接收方行动,都可以在不炸掉交易的前提下携带语义返回。对普通用户最直观的收益在 UX 一节:既然码是有限且已知的,报错信息就能做统一的本地化翻译层,提案甚至点名用同期的 ERC-1444 做多语言消息。今天的钱包把失败归类成“滑点超限”“授权不足”这类可行动的提示,思路正是这条线。

为什么没有普及,还值不值得读

它没有成为主流有几个现实原因:EVM 层面转账收据早有自己的状态位(EIP-658 那条线),Solidity 的 require 字符串与后来的自定义错误占据了开发者习惯,跨合约的错误传递则被 ERC-6093 用另一种方式(标准错误名)接了过去。但这份提案的码表本身仍是一份优秀的分类学笔记——它把“一笔链上操作可能处于的全部状态”系统地枚举了一遍。普通读者拿这张表对照日常报错会很有收获:等待、过期、重复、已暂停、余额不足这些状态,本就不该被统一渲染成“交易失败”。一份状态码词表的兴衰,恰好记录了行业把失败说清楚这件事上的路线选择。

一次报错排查的假想流程

把码表搬到日常,最有画面感的用法是重读自己的失败交易。交易在浏览器里失败时,若项目采用这套语义,第一行返回就应当指路:0x54 说的是钱不够,先查余额与授权;0x46 是窗口已过期,重报价而不是重试;0x42 是合约被暂停,与你的操作无关;0x16 是地址被拉黑;0x28 提示重复提交。对照这份分类学,即使项目没有直接采用该提案,同样的排查骨架也能复用:先分成功率类原因(资金、授权、限额),再分状态类原因(暂停、过期、重复),最后才怀疑网络与报价。钱包与浏览器逐步把 revert 数据渲染成可行动提示,行业最终走了自定义错误与错误名注册的组合路线,但把失败说清楚这件事的地图,这份老码表早已画了一遍。

值得一提的是码表的类别划分思路:高半字节粗分类、低半字节细原因的结构,让人和程序都能按需取用不同粒度——监控脚本只需盯类别位做路由,翻译层再读完整码值取文案。这种双层语义在协议设计里相当耐用,HTTP 的分类与子码、各类错误码体系都走同一逻辑。ERC-1066 没赢在执行层,但它的分类学在工具侧一直活得不错,钱包报错分类、区块浏览器失败归因,都是这套思想换了包装的延续。

本文为机制说明,不构成任何投资建议。