﻿---
title: "EIP-712 类型化签名：域、摘要与安全验证"
description: "EIP-712 让以太坊结构化消息具备确定性并可供展示，但安全签名仍需核对确切的域、类型、值、Nonce、截止时间、执行方式和签名者策略。"
image: "https://wiki.fcontext.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://wiki.fcontext.com/llms.txt
> Use this file to discover all available pages before exploring further.

# EIP-712 类型化签名：域、摘要与安全验证

> 仅供教育参考，不构成投资建议；投资可能产生损失。

<a id="answer"></a>

## 直接答案

EIP-712 规定了以太坊应用如何描述、哈希并请求对类型化结构数据签名。请求包含 `types`、`primaryType`、`domain` 和 `message`；其摘要为 `keccak256("\x19\x01" || domainSeparator || hashStruct(message))`。这样可确保编码具有确定性，也让具备相应能力的钱包能比不透明哈希更清楚地展示字段。

它**不会**自动保证消息真实、无害、可撤销或不可重放。应用必须把权限绑定到正确的链和验证者，明确每个字段的含义，执行 Nonce 与时间限制，验证正确的签名者，并约束执行行为。有效签名只证明某个验证规则认可对特定摘要的签署；它不能证明签名者身份、知情意图，也不能证明网站或合约安全。

<a id="mechanism"></a>

## 工作原理

### 1. 确认操作和验证路径

判断请求授权的是登录、订单、投票、代币额度、转账、中继调用还是其他操作。找到重建摘要并消费签名的代码。对于外部拥有账户，验证通常从 ECDSA 签名恢复地址；对于合约账户，应用可能需要调用 ERC-1271 `isValidSignature(hash, signature)`，并检查其成功值 `0x1626ba7e`。

### 2. 锁定域

检查确切的 `EIP712Domain` 类型和值。标准字段为 `name`、`version`、`chainId`、`verifyingContract` 和 `salt`，但只有实际包含的字段才参与哈希。独立确认当前链、已部署代码和预期验证者；熟悉的名称、代币符号、代理标签或校验和地址并不足够。ERC-5267 `eip712Domain()` 可以公开合约的域，但支持该接口并非强制，代理或升级行为仍需审查。

### 3. 重建类型图

从 `primaryType` 开始，保留成员顺序，并递归收集引用的结构体。`encodeType` 会按类型名称排序后附加被引用结构体的定义。EIP-712 支持定宽整数、`address`、`bool`、`bytes1` 至 `bytes32`、动态 `bytes` 与 `string`、数组和结构体；标准未定义 `uint`、`int` 等别名、定点类型及循环值。

### 4. 解码每个值和单位

将每个消息值与其声明类型和应用含义对应起来。核对完整地址、原始整数单位、正负号、数组顺序、接收者、Spender、资产、金额、费用、限额、目标、Calldata 哈希及人类可读字符串。动态 `bytes` 和 `string` 在 `encodeData` 中以其内容的 Keccak-256 哈希表示；数组对连接后的元素编码取哈希，嵌套结构体则使用各自的 `hashStruct`。

### 5. 独立重算摘要

计算 `typeHash = keccak256(encodeType(primaryType))`，再计算 `hashStruct(message) = keccak256(typeHash || encodeData(message))`。以同样方式计算域分隔符，再与 ERC-191 版本字节 `0x19 0x01` 组合。比较前端、签名库、验证合约和独立实现得出的摘要；JSON 外观一致并不能证明类型化编码相同。

### 6. 审查重放、时间和执行控制

EIP-712 本身不包含重放保护。确认验证者会检查预期签名者、消费或作废正确的 Nonce、执行 `deadline` 或有效期限制、绑定全部安全关键执行参数，并在中继者或抢跑者先提交时仍产生相同的预期结果。域分隔只能防止实际编码域之间的冲突；缺失或错误的域字段可能留下跨合约或跨链复用路径。

### 7. 最小化签名并核对结果

拒绝隐藏字段、无法解释的类型、无限额度、遥远截止时间、未知合约、不匹配的链 ID、盲签屏幕或不完整的执行上下文。保留确切的类型化数据 JSON 和摘要，尽可能使用用途受限的账户，并检查已提交交易、收据、事件、余额、额度、Nonce、订单状态和最终性。断开网站连接不会撤销仍可用的签名或已经建立的权限。

<a id="example"></a>

## 计算示例

### 示例 1：类型与摘要构造

对于 `Order(address maker,address token,uint256 amount,uint256 nonce,uint256 deadline)`，`typeHash` 是该完整字符串的 Keccak-256 哈希，字段顺序也必须完全一致。消息哈希为 `keccak256(typeHash || maker || token || amount || nonce || deadline)`，每个编码成员占 32 字节。最终摘要加入 `0x1901`、域分隔符和该消息哈希；把 `amount` 从 `250000000` 改为 `250000001` 就会改变摘要，使旧签名失效。

### 示例 2：单位与截止时间

六位小数代币的 `250 USDC` 应编码为原始值 `250000000`，而不是 `250`。若当前时间戳为 `1727000000`，截止时间为 `1727000900`，签名窗口就是 `900 seconds = 15 minutes`。钱包的小数显示和本地时钟仅供辅助；验证者使用原始整数及其选定的链上时间规则。

### 示例 3：重放控制

一笔订单携带 Nonce `41`，最大成交量为 `5 ETH`。验证者将 Nonce 41 标记为已消费后，即使签名本身仍然有效，第二次提交也必须失败。如果合约既不消费 Nonce，也不让执行具备幂等性，同一签名便可再授权一笔 `5 ETH`；域分隔符本身无法阻止这种重放。

### 示例 4：合约钱包有效性

一个 2-of-3 合约钱包在配置签名者 A、B、C 时批准某摘要。A 和 B 的签名目前可能让 ERC-1271 返回 `0x1626ba7e`。若模块升级后用 D 替换 B，相同的签名字节可能失效，因为 ERC-1271 有效性可以取决于当前合约状态、策略、时间和外部调用；仅靠地址恢复无法判断合约账户的签名有效性。

<a id="risks"></a>

## 风险

- `chainId` 错误或缺失
- `verifyingContract` 是仿冒地址或并非预期合约
- 域的 `name` 或 `version` 具有误导性
- 代理实现或域在升级后发生变化
- `primaryType` 错误，或使用标签相似的影子类型
- 成员顺序、依赖顺序或编码器不一致
- 地址被截断、替换或错误标注
- 代币小数位或有符号与无符号整数错误
- 隐藏的数组项、嵌套结构体或任意 `bytes` 载荷
- 无限金额、过宽范围或由攻击者控制的接收者
- Nonce 缺失、过期、共享或消费方式错误
- 截止时间缺失、过远、溢出或解释含糊
- 跨链、跨合约、跨账户或跨操作重放
- 中继者扣留、审查、抢跑或重定向执行
- 签名可塑性或过于宽松的 ECDSA 恢复
- ERC-1271 签名者、模块、阈值、状态或代码变化
- 钱包渲染、盲签或不支持类型导致的失败
- 前端 JSON 与验证者使用的摘要不一致
- 撤销或取消在交易排序竞争中失败
- 将签名提示的结果误认为收据、状态变化或最终性

<a id="misconceptions"></a>

## 常见误区

### 误区 1：EIP-712 签名就是交易

它们是链下签署的消息。中继者或其他参与者可以随后把它们提交给合约，产生的交易可以消耗 Gas 并改变状态，却不必由签名者发送。

### 误区 2：结构化显示就代表请求安全

类型化字段提高了可检查性，但恶意模式、数值、合约、标签、隐藏嵌套和不完整的钱包渲染仍可能误导签名者。

### 误区 3：域分隔符能阻止所有重放

它只隔离已编码的域。同域重放仍需要 Nonce、截止时间、取消、成交量记账或幂等性；未包含的域字段不会形成任何边界。

### 误区 4：恢复出预期地址就证明获得授权

地址恢复只证明某 EOA 对摘要做了签名，不能验证应用语义；合约账户必须执行 ERC-1271 策略，而不是普通地址恢复。

### 误区 5：关闭页面或断开钱包连接会取消签名

复制出的签名会一直可用，直到验证者的 Nonce、截止时间、取消状态或策略使其失效。应确认相关链上状态，而不是依赖会话状态。

<a id="related"></a>

## 相关主题

- [链 ID](/zh-cn/crypto/chain-id/)
- [ERC-2612 Permit 的 Nonce 与截止时间](/zh-cn/crypto/erc2612-permit-nonce-deadline/)
- [Permit2 签名风险](/zh-cn/crypto/permit2-signature-risk/)
- [钱包授权](/zh-cn/crypto/wallet-approval/)
- [钱包签名](/zh-cn/crypto/wallet-signature/)

<a id="sources"></a>

## 来源

- [EIP-712: Typed structured data hashing and signing](https://eips.ethereum.org/EIPS/eip-712) - Ethereum Improvement Proposals（访问日期：2026-08-19）
- [ERC-191: Signed Data Standard](https://eips.ethereum.org/EIPS/eip-191) - Ethereum Improvement Proposals（访问日期：2026-08-19）
- [ERC-1271: Standard Signature Validation Method for Contracts](https://eips.ethereum.org/EIPS/eip-1271) - Ethereum Improvement Proposals（访问日期：2026-08-19）
- [ERC-2612: Permit Extension for EIP-20 Signed Approvals](https://eips.ethereum.org/EIPS/eip-2612) - Ethereum Improvement Proposals（访问日期：2026-08-19）
- [ERC-5267: Retrieval of EIP-712 domain](https://eips.ethereum.org/EIPS/eip-5267) - Ethereum Improvement Proposals（访问日期：2026-08-19）
- [EIP-2: Homestead Hard-fork Changes](https://eips.ethereum.org/EIPS/eip-2) - Ethereum Improvement Proposals（访问日期：2026-08-19）
- [Contract ABI Specification](https://docs.soliditylang.org/en/latest/abi-spec.html) - Solidity Documentation（访问日期：2026-08-19）
- [ERC-7730: Structured Data Clear Signing Format](https://eips.ethereum.org/EIPS/eip-7730) - Ethereum Improvement Proposals（访问日期：2026-08-19）

Source: https://wiki.fcontext.com/zh-cn/crypto/eip712-typed-signature/index.mdx
