EIP-712签名域名不一致:这类请求还能签吗

 / 
4

域名不一致的 EIP-712 签名,一概不签。 这不是"较真",而是 EIP-712 的安全机制——域名(Domain)里的 chainIdverifyingContract 字段就是用来防止签名被跨链、跨合约重放的。不一致说明这笔签名可能被用在别处。

欧易OKX交易所
全球领先的加密货币平台,适合新手与进阶交易者
新手福利:注册即享20% 交易手续费减免!

1. 先搞清楚 EIP-712 的"域名"是干什么的

EIP-712 是为结构化数据设计的签名标准,你钱包里看到的"请签名"弹窗,本质上是让你签一段"类型化数据"(Typed Data)。

这段数据里有个核心部分叫 域名分隔器(Domain Separator),通常包含四个关键字段:

  • name:应用的名称

  • version:版本号

  • chainId:链 ID(如以太坊主网是 1)

  • verifyingContract:验证签名的合约地址

这几个字段组合起来,唯一标识"这笔签名到底是在什么场景下用的"。域名不一致,意味着这个签名可能不是为当前这个 DApp 准备的。

2. 为什么说"域名不一致"是严重的警告信号

如果域名里的 chainIdverifyingContract 和你当前连接的网站对不上,这通常意味着签名请求来自一个恶意构造的页面。

① 缺少 chainId:签名可以在别的链上重放

OWASP 的智能合约安全标准明确指出,如果 EIP-712 域名里没有 chainIdverifyingContract,签名可能被跨合约、跨链重放,导致攻击者用你在一条链上的签名去另一条链上授权操作。

② 缺少 verifyingContract:签名可以在别的合约地址上使用

GitHub 上有真实的审计案例:由于 verifyingContract 缺失,同一个签名在多个合约地址间都能生效,攻击者可以直接用你在一处签的名去调用另一处的函数。另一个案例中,缺少 version 字段导致两个不同版本的合约域名结构相同,签名在版本间可互相复用。

chainId 写死为固定值:链分叉后签名可能失效或被重放

如果域名里的 chainId 是写死的而非动态读取 block.chainid,链升级或分叉后,原有签名可能全部失效;如果攻击者利用分叉链环境重新构建,也可能造成重放。

欧易OKX交易所
全球领先的加密货币平台,适合新手与进阶交易者
新手福利:注册即享20% 交易手续费减免!

3. 收到域名不一致的签名请求,怎么做

步骤1:拒绝签名,不要点"确认"

  • 做什么:直接关闭签名弹窗,不要尝试修改或确认。

  • 怎么做

    • 如果钱包弹窗显示"Sign typed data"且附带一串看起来像域名结构的数据,先看 verifyingContract 是不是当前 DApp 的合约地址。

    • 如果显示的是 0x000... 或一个你从未交互过的地址,拒绝。

    • 部分钱包(如 Phantom、Rabby)会直接高亮显示域名信息,重点看 chainIdverifyingContract 是否匹配当前环境。

步骤2:用工具解码 EIP-712 请求,查看完整域名

  • 做什么:在签名前,用工具解析这笔签名请求的完整内容。

  • 怎么做

    • 使用 ShieldForge 等浏览器扩展,它可以在你签名前自动解码 EIP-712 类型化数据,展示 domainmessageprimaryType,并对"无限授权"值发出警告。

    • 也可以使用 viemverifyTypedData 函数离线验证域名和消息是否匹配。

  • 做到什么程度算完成:你确认了这笔签名请求中的域名字段(nameversionchainIdverifyingContract)是否全部指向你当前交互的 DApp。

步骤3:仅当域名完全匹配当前 DApp 时,才考虑签名

  • 做什么:确认以下三个条件全部满足,再考虑签名:

    1. nameversion 是当前 DApp 的名称和版本

    2. chainId 与当前连接的链完全一致(主网不能是 1,测试网是 11155111 等)

    3. verifyingContract 是当前页面上能查到的合约地址(可以去区块浏览器上核实)

  • 做到什么程度算完成:所有字段逐一比对通过,没有"看起来差不多"的模糊空间。

前置条件:钱包已连接到一个 DApp,且 DApp 请求你签署一笔 EIP-712 签名。

常见失败原因:用户看到"Sign typed data"字样,以为只是"登录",没看域名就直接确认。近年大量资产被盗事件,根源就是盲签(Blind Signing)——即在不清楚签名内容的情况下点击确认。

风险提醒:硬件钱包或冷钱包对 EIP-712 签名没有额外保护——因为这类签名本身就是"离线"授权的设计,不需要 Gas,不需要上链确认。一旦你签了,攻击者可以立即在别的链上或别的合约上使用这笔签名,而不需要你再次确认。

做完以上检查,怎么确认自己安全了?

收到 EIP-712 签名请求时,展开钱包里的"Domain"详情,确认 chainId 是你当前连接的链号、verifyingContract 是你交互的合约地址。如果其中任何一个和预期不符,点"拒绝"。只有完全匹配,才能继续操作。如果对某个请求不确定,用 ShieldForge 等工具解码后再决定。