把 DNS 记录放进名字服务时要放弃什么:ERC-1185 的按记录集存取
把传统域名的解析记录搬到链上,最直觉的做法是把整个区域文件塞进合约。ERC-1185 明确放弃了这条路,理由很朴素:照搬区域文件,改一条记录也要把整包数据重写一遍,在链上等于把很高的 Gas 成本摊到每次小改动上。这份提案把自己定义为名字服务的一个解析器画像,文件头记录创建于 2018 年 6 月 26 日,仓库记录状态为 Review,并声明依赖 ERC-137。
记录集是这套设计的最小单位
规范用一个三元组唯一定位一批记录:域名、记录名、资源记录类型。例如某个域名下 www 这个名字的 A 类型记录就是一组,这组里可以有零个或多个值——两条 A 记录就是这组里两个值。所有读写都围绕“组”展开,而不是围绕整个区域。
这个选择直接决定了能力边界。原文明说,工作在记录集这一层意味着这份规范无法完整支持 DNS 的某些特性,区域传送和 DNSSEC 就在其中;作者也承认可以做一套按区域的解析器画像,但那样每次更新都太贵,因此不再考虑。把这层看清楚,就能避免一个常见误判:以为“记录上了链”就等于 DNS 的全部功能都平移过来了。

四个函数的分工
设定侧有两个函数。setDNSRecords(bytes32 node, bytes data) 按 DNS 线格式一次性设定、更新或清空一批记录,函数签名在规范里写作 0x0af179d7;其中不带值的记录表示清空。查询侧提供 dnsRecords(bytes32 node, bytes32 name, uint16 resource),签名 0x2461e851,按记录名与类型返回全部匹配记录,没有记录时返回空。hasDNSRecords(bytes32 node, bytes32 name) 签名 0x4cbf6ba4,只回答“这个名字下有没有记录”,规范说明它是给处理通配资源的解析器用的,并指向 RFC 4592。
第四个是 clearDNSZone(bytes32 node),签名 0xad5780af,一次移除某个域名的全部 DNS 记录。规范特意解释了它存在的理由:逐条清空要求操作方记得自己当初写过哪些记录,而解析器并没有提供遍历某域名所有记录的方法,还可能要多笔交易;清空整区则是一次完成。
顺序要求是最容易踩的坑
setDNSRecords 的入参是一段拼接起来的线格式记录,规范强调同一组记录必须连续排列,否则后面的组会覆盖前面的组。参考实现的注释给了直观对照:先放同一名字的两条 A 记录、再放另一条 CNAME,两值会被正确存成一个组;如果把第二条 A 记录挪到 CNAME 之后,实现会先存第一条 A、再存 CNAME、再存第二条 A,结果第二条覆盖了第一条。也就是说,数据排列顺序本身是接口的一部分,工具打包时把顺序弄乱,静默丢数据不会报错。
存储结构上,参考实现用一个版本号和四层映射把记录挂起来,清空整区的做法就是把版本号加一——旧版本下的数据不再被读到,而不必逐条删除。这种“换代不清库”的思路,也解释了为什么这类合约不提供遍历接口:数据其实还躺在旧版本槽里。
记录类型编号与信任落点
类型编号本身不在这份规范里发明,规范指向 RFC 1035 及其后续文档定义的资源记录标识。链上只存编号加线格式载荷,读的一方需要自己按编号判断这是哪一类记录、载荷该怎么解。
安全考量部分写得很直接:这套方案的安全性取决于域名在名字服务里那把密钥的安全。所有记录都由能调用设定函数的地址说了算,没有额外的签名或第三方背书。参考实现另外提供了区域哈希相关的字段与事件,把整区的指纹单独挂了一份,可以订阅,但这不构成对记录内容真实性的证明。
什么人真正需要关心这份标准
对个人用户,这层机制通常隐形:只有当某个客户端把链上记录当作域名解析依据时,缓存、失败回退和空返回的处理才会浮出水面。对跑解析器或读记录做风控的团队,几个问题必须自己回答:能否枚举某域名下所有记录名(规范没给遍历方法,所以多半不能)、同组记录是否被工具正确连续打包、以及清空整区后旧值是否还留在事件日志里能被翻出来。这份提案在仓库里的状态是 Review,属于已有规范但未见全面部署记录的一类,读它时把“规定了什么”和“被谁实现了”分开,比把编号本身当安全承诺更有价值。本文为机制说明,不构成任何投资建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。