结构化签名:EIP-712 深度解析

本章系统介绍了结构化签名标准 EIP-712,从设计动机、安全特性到工程实现进行了全面剖析。相较于传统的 personal_sign(EIP-191)文本签名,EIP-712 支持结构化 TypedData 数据类型,具备更高的安全性、可读性与合约兼容性。我们详细解析了 EIP-712 签名格式中的

📚 作者:Henry 🧱 系列:《Web2 到 Web3:登录与身份验证机制全面进化》 · 第 3 篇 👨‍💻 受众:Web2 & Web3 开发者 / 区块链学习者 👉 系列持续更新中,建议收藏专栏或关注作者

🧩 为什么需要结构化签名?

EIP-191(即 personal_sign)的核心问题:

  • ✅ 签名的是非结构化字符串,对钱包和用户不可读
  • ❌ 安全性低:用户无法判断自己签了什么(钓鱼风险高)
  • ❌ 无法与合约交互:合约无法解析签名内容
  • ❌ 缺乏类型:签名信息语义模糊,难以校验

EIP-712 将签名对象结构化为“带类型的 JSON Schema”,解决以上问题。

📦 EIP-712 基本结构

一个结构化签名由三个部分组成:

{
  domain: DomainData,
  types: Record<string, TypeField[]>,
  message: Record<string, any>,
}

✅ 示例:

const domain = {
  name: 'MyDApp',
  version: '1',
  chainId: 1,
  verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
};

const types = {
  Login: [
    { name: 'wallet', type: 'address' },
    { name: 'nonce', type: 'string' },
    { name: 'issuedAt', type: 'string' },
  ],
};

const message = {
  wallet: '0xAbC123...',
  nonce: 'f92a1e',
  issuedAt: new Date().toISOString(),
};

🧠 核心术语解释

字段 含义
domain 用于防止跨 DApp 签名复用,绑定站点、合约等上下文
types 所有结构体定义,包括主要的 message 类型及依赖
primaryType 默认为 message 的类型,决定签名根结构
message 需要用户签名的数据实例

📊 对比:EIP-191 vs EIP-712

特性 EIP-191(personal_sign EIP-712(signTypedData
数据格式 普通字符串 结构化 JSON + 类型信息
安全性 ⚠️ 用户不可读、易钓鱼 ✅ 明确字段、上下文可读
与合约兼容 ❌ 无法在合约中还原数据 ✅ 可用于 MetaTx、Permit
校验粒度 仅地址校验 可结合合约函数参数校验
实用场景 登录签名、轻量身份认证 DeFi 授权、NFT 元交易、Login v2

EIP-712 前后端完整实现对比(ethers.js V.S wagmi/viem )

📌 签名目标:

以如下结构作为签名类型(Login 示例):


type LoginMessage = {
  wallet: string;
  nonce: string;
  issuedAt: string;
};

const domain = {
  name: 'DApp Login',
  version: '1'...

剩余70%的内容订阅专栏后可查看

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Henry Wei
Henry Wei
Web3 Frontend Dev. Exploring Social & Innovation.