僅供教育參考,不構成投資建議;投資可能產生損失。
直接答案
EIP-712 規定了以太坊應用程式如何描述、雜湊並請求對類型化結構資料簽章。請求包含 types、primaryType、domain 和 message;其摘要為 keccak256("\x19\x01" || domainSeparator || hashStruct(message))。這樣可確保編碼具有確定性,也讓具備相應能力的錢包能比不透明雜湊更清楚地顯示欄位。
它不會自動保證訊息真實、無害、可撤銷或不可重放。應用程式必須把權限綁定到正確的鏈和驗證者,明確每個欄位的含義,執行 Nonce 與時間限制,驗證正確的簽署者,並約束執行行為。有效簽章只證明某個驗證規則認可對特定摘要的簽署;它不能證明簽署者身分、知情意圖,也不能證明網站或合約安全。
完成核查不代表資產、交易或系統已經安全。
工作原理
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、訂單狀態和最終性。斷開網站連線不會撤銷仍可用的簽章或已經建立的權限。
計算範例
範例 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 有效性可以取決於目前合約狀態、策略、時間和外部呼叫;僅靠地址恢復無法判斷合約帳戶的簽章有效性。
風險
chainId錯誤或缺失verifyingContract是仿冒地址或並非預期合約- 域的
name或version具有誤導性 - 代理實作或域在升級後發生變化
primaryType錯誤,或使用標籤相似的影子類型- 成員順序、依賴順序或編碼器不一致
- 地址被截斷、替換或錯誤標注
- 代幣小數位或有符號與無符號整數錯誤
- 隱藏的陣列項、嵌套結構體或任意
bytes載荷 - 無限金額、過寬範圍或由攻擊者控制的接收者
- Nonce 缺失、過期、共享或消費方式錯誤
- 截止時間缺失、過遠、溢出或解釋含糊
- 跨鏈、跨合約、跨帳戶或跨操作重放
- 中繼者扣留、審查、搶跑或重定向執行
- 簽章可塑性或過於寬鬆的 ECDSA 恢復
- ERC-1271 簽署者、模組、閾值、狀態或程式碼變化
- 錢包渲染、盲簽或不支援類型導致的失敗
- 前端 JSON 與驗證者使用的摘要不一致
- 撤銷或取消在交易排序競爭中失敗
- 將簽章提示的結果誤認為收據、狀態變化或最終性
常見誤區
誤區 1:EIP-712 簽章就是交易
它們是鏈下簽署的訊息。中繼者或其他參與者可以隨後把它們提交給合約,產生的交易可以消耗 Gas 並改變狀態,卻不必由簽署者發送。
誤區 2:結構化顯示就代表請求安全
類型化欄位提高了可檢查性,但惡意模式、數值、合約、標籤、隱藏嵌套和不完整的錢包渲染仍可能誤導簽署者。
誤區 3:域分隔符能阻止所有重放
它只隔離已編碼的域。同域重放仍需要 Nonce、截止時間、取消、成交量記賬或冪等性;未包含的域欄位不會形成任何邊界。
誤區 4:恢復出預期地址就證明獲得授權
地址恢復只證明某 EOA 對摘要做了簽章,不能驗證應用語義;合約帳戶必須執行 ERC-1271 策略,而不是普通地址恢復。
誤區 5:關閉頁面或斷開錢包連線會取消簽章
複製出的簽章會一直可用,直到驗證者的 Nonce、截止時間、取消狀態或策略使其失效。應確認相關鏈上狀態,而不是依賴會話狀態。
相關主題
來源
- EIP-712: Typed structured data hashing and signing - Ethereum Improvement Proposals(查閱日期:2026-08-19)
- ERC-191: Signed Data Standard - Ethereum Improvement Proposals(查閱日期:2026-08-19)
- ERC-1271: Standard Signature Validation Method for Contracts - Ethereum Improvement Proposals(查閱日期:2026-08-19)
- ERC-2612: Permit Extension for EIP-20 Signed Approvals - Ethereum Improvement Proposals(查閱日期:2026-08-19)
- ERC-5267: Retrieval of EIP-712 domain - Ethereum Improvement Proposals(查閱日期:2026-08-19)
- EIP-2: Homestead Hard-fork Changes - Ethereum Improvement Proposals(查閱日期:2026-08-19)
- Contract ABI Specification - Solidity Documentation(查閱日期:2026-08-19)
- ERC-7730: Structured Data Clear Signing Format - Ethereum Improvement Proposals(查閱日期:2026-08-19)