W3
EIP-712EIP签名Final(2017-09-12)

结构化数据签名

把待签名内容定义成带类型与域的结构体,钱包能把它渲染成人能读懂的字段表。

适用链:全部 EVM 链

为什么重要:一切「可读签名」的基础:Permit、订单签名(挂单)、4337 的 userOp 签名都基于它。

函数签名与选择器

选择器是签名的 keccak256 前 4 字节;事件则是完整的 32 字节 topic0。 点一下即可复制。

签名 / 字段选择器 / topic0说明
域(domain)固定四件套:name、version、chainId、verifyingContract;可选 salt。
typesEIP-712 类型定义,字段顺序会影响最终哈希。
消息哈希keccak256("\x19\x01" || domainSeparator || hashStruct(message))。
链上校验合约用 ecrecover + 自己重算的 domainSeparator 还原签名者。
合约签名签名者是多签/智能账户时,走 EIP-1271 的 isValidSignature。

代码模板

合约侧校验(含 EIP-1271 分支)
合约侧校验(含 EIP-1271 分支)Solidity

签名里的 nonce 必须在链上标记为已使用。漏掉这一步,同一份签名可以被重复提交。

实现与使用时的常见陷阱

  • domain 里必须有 chainId 与 verifyingContract,否则签名可以跨链、跨合约重放。
  • types 里字段的顺序和类型必须与合约里的 TYPEHASH 字符串完全一致,差一个空格都会算出不同哈希。
  • 链上要用 abi.encode(补零到 32 字节)而不是 encodePacked,后者会产生哈希碰撞。
  • 签名超过 65 字节时说明是合约钱包签名,必须接入 EIP-1271 才能验签。

相关标准

同属「签名」的其他标准
想把这个标准用起来?开发者路径的第 1–2 阶段讲了怎么把它写进项目;合约 IDE里有对应的可编辑模板与静态自检;链上 API 参考则给出前端调用它的三种写法。