一把钥匙管多个智能账户:ERC-7739 的嵌套哈希防重放
智能账户钱包很常见的布局是:一个外部账户(EOA)做主控,底下挂着好几个智能合约钱包——一个管 NFT 金库,一个管日常交互。问题出在签名上:这些智能账户验证 ERC-1271 签名时,用的可能是同一个 EOA 的私钥,而一份 EIP-712 类型化签名的内容里如果没带上“这是签给哪个账户的”,同一份签名就可能被拿到兄弟账户那里重复使用,这叫跨账户重放。ERC-7739 专门处理这个漏洞:给 ERC-1271 验证定义一套防御性重哈希方案,同时保住钱包弹窗的可读性。提案在 ercs 仓库的状态是 Draft(草稿),创建于 2024 年 5 月 28 日,依赖 ERC-191、ERC-712、ERC-1271 与 ERC-5267。
最终哈希是怎么拼的
以 TypedDataSign 流程为例,最终哈希把两层结构钉在一起:外层是应用域分隔符(APP_DOMAIN_SEPARATOR),内层是一个 TypedDataSign 结构体的 hashStruct,它的 contents 字段装着原始业务结构体的哈希,另外五个字段 name、version、chainId、verifyingContract、salt 全部取自智能账户自己的 eip712Domain()(ERC-5267 提供的域查询)。这样最终哈希同时锚定了两件事:应用那份原始内容,以及签名所属的那个账户的域。换一个兄弟智能账户,域字段就变了,验证自然失败。规范同时定义了 PersonalSign 流程的对应处理,覆盖非类型化消息的场景。

为什么要“可读”
早年的防重放思路会在签名的哈希前做拼接改写,钱包弹窗里展示的哈希失去结构,用户只能看到一串十六进制——安全性上去了,可读性下来了,反而容易让人盲签。ERC-7739 的取舍是把嵌套放在验证侧:钱包请求签名时,用户看到的仍是原始的类型化结构(应用名、链、合约、字段都正常展示),组装嵌套哈希发生在验证流程里,靠 ERC-5267 读出账户域信息后由钱包与合约各自重算。它把“防串仓”做成了用户界面几乎无感的机制。
对用户意味着什么
作为普通持有人,你接触这一层的场景主要有两个。其一是挂单签名:在 NFT 市场用智能账户签 EIP-712 订单时,若钱包与合约都支持该标准,签名天然只对该智能账户有效。其二是排障:如果某个 dApp 对你智能账户的签名验证总是失败,嵌套哈希口径不一致(一边按 ERC-7739、一边按旧式拼接)是常见原因之一,不必然是资产问题。
风险提醒
一个不防重放时会漏的洞
把机制摆成具体例子更清楚。假设某个 NFT 市场订单的 EIP-712 域里只写了市场合约地址和链 ID,没写你的账户。你有一个主钱包和一个子钱包,都由同一个 EOA 签名。你在主钱包上签了一张“以 1 ETH 卖出藏品 A”的订单。作恶者拿到签名后,把这笔订单提交给验证方,验证方调用 ERC-1271 的 isValidSignature——合约内部的逻辑如果只回落到“主控 EOA 的 secp256k1 签名有效即通过”,那么子钱包上的同一把钥匙同样“签过”这张单,订单被套用到子钱包的藏品上就成立了。ERC-7739 的重哈希让最终哈希必须包含该智能账户自己的域(通过 eip712Domain() 现场读取),验签发生在哪个账户,哈希就得按哪个账户重算,换账户即失效。它把“域属于账户”这个被 EIP-712 惯例忽略的维度补成了显式约束。
还要划清适用面:这套机制只在 ERC-1271 合约验签路径上生效,EOA 直接签名场景用不到重哈希;反过来,凡是“一个私钥背后挂着多个合约账户”的架构,都值得一问是否已经启用该标准。
要清楚 ERC-7739 防的是“同一主控下不同账户之间”的复用,它不解决假 dApp 骗签:弹窗里内容仍要逐项核对,尤其是 verifyingContract 是不是你认识的市场合约。另外域信息依赖 ERC-5267 查询,遇到未实现该接口的合约,兼容路径会不同。方案仍是草稿,多账户架构下的一切实现以合约代码为准。本文为机制说明,不构成任何投资建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。