ERC-5267 与 EIP-712 域:钱包弹窗里那行合约名从哪来 图 1
ERC-5267 与 EIP-712 域:钱包弹窗里那行合约名从哪来 · 图 1

ERC-5267 与 EIP-712 域:钱包弹窗里那行合约名从哪来

签名为什么需要“域名”

EIP-712 让钱包签名结构化数据:签的不是乱码字节串,而是有类型、有字段的数据。为了防止你在这份协议上签的名被拿到另一个应用里复用,EIP-712 在计算摘要时会拼入一个域分隔符,把应用名称、版本、链号、验证合约地址等信息编进摘要本身。域不同,摘要就不同,签名不能跨域通用——同一个签名值换个域去验证,恢复出来的地址就会对不上。

问题来了:钱包和应用要生成正确的域分隔符,必须事先知道这个合约用的域结构。过去这靠各家应用手工硬编码——写错了轻则签名全部失效,重则新旧版本的域混用产生安全隐患。ERC-5267 就是补这个缺口的:它已被标记为 Final(最终)状态,规定合约应当公开一个查询函数,把自己的域声明出来。

ERC-5267 与 EIP-712 域:钱包弹窗里那行合约名从哪来 图 2
ERC-5267 与 EIP-712 域:钱包弹窗里那行合约名从哪来 · 图 2

eip712Domain 返回什么

合约实现这个函数后,任何人调用都会得到七个返回值:

  • fields:一个位图。它的第 i 位为 1,表示 EIP-712 域结构里的第 i 个可选字段(按名称、版本、链号、验证合约、盐的顺序编号)被包含在内。
  • nameversionchainIdverifyingContractsalt:对应字段的实际取值;位图没标记的字段,返回值内容不作约定但必须照样返回以便解码。
  • extensions:一个 EIP 编号列表,指向为域增加新字段的扩展标准。

规范用词很严格:所有被位图标记的值都必须返回,即使某些值看起来没用,也要照单返回以便客户端统一解码;域的设置允许在合约生命周期中变化,但不应频繁变,且链号应当跟随实际链的 EIP-155 编号,变化时合约可以发出 EIP712DomainChanged 事件提示客户端重新读取。

这跟普通用户有什么关系

关系比你想象的大。你签任何 NFT 挂单、授权认领、 Permit 类签名时,钱包计算的域分隔符必须和目标合约验证时用的完全一致,否则要么签名静默无效,要么在最糟的情形下被错误的合约复用。实践中有三类后果:

  1. 域含 verifyingContract 时,签名被锁死在单个合约上——最安全;一个 NFT 聚合器的跨市场签名若不带这个字段,就要靠其他字段组合限制范围,理解差异有助于你判断一次签名能覆盖多大范围。
  2. 合约升级或重新部署后域可能变化。如果钱包端缓存了旧域,你会看到签名反复失败或一直提示签名无效,这时清理签名授权缓存或重连应用常能解决。
  3. 高级用户和工具可以把 eip712Domain() 当作事实来源,动态核对弹窗里的应用名和合约地址是否与链上声明一致,多一道防钓鱼的交叉检查。

一个防御性习惯

把 EIP-712 弹窗当作合同而不是按钮:看应用名、看版本、看是否绑定了具体合约地址、看有效期参数。ERC-5267 的存在让“查证”成为可能,但做这个动作的始终是人。钱包默认只展示有限字段,复杂类型经常显示为哈希,遇到完全看不懂的签名请求,拒签再研究永远比硬签安全。补一个进阶线索:ERC-5267 与可读签名方向还有配套的提案谱系,例如定义了 evalEIP712Buffer 的 ERC-6384,思路是让合约自己把签名数据翻译成人话。这些方向能否普及尚待观察,但方向和 5267 一样,都指向同一个目标——让“你在签什么”从推测变成查询。

风险提示:签名授权可能被滥用造成资产损失,定期检查并撤销不用的授权是必要习惯;本文不构成任何投资建议。