跳到正文

EIP-712 類型化簽章:域、摘要與安全驗證

EIP-712 讓以太坊結構化訊息具備確定性並可供顯示,但安全簽章仍需核對確切的域、類型、值、Nonce、截止時間、執行方式和簽署者策略。

更新於

僅供教育參考,不構成投資建議;投資可能產生損失。

直接答案

EIP-712 規定了以太坊應用程式如何描述、雜湊並請求對類型化結構資料簽章。請求包含 typesprimaryTypedomainmessage;其摘要為 keccak256("\x19\x01" || domainSeparator || hashStruct(message))。這樣可確保編碼具有確定性,也讓具備相應能力的錢包能比不透明雜湊更清楚地顯示欄位。

不會自動保證訊息真實、無害、可撤銷或不可重放。應用程式必須把權限綁定到正確的鏈和驗證者,明確每個欄位的含義,執行 Nonce 與時間限制,驗證正確的簽署者,並約束執行行為。有效簽章只證明某個驗證規則認可對特定摘要的簽署;它不能證明簽署者身分、知情意圖,也不能證明網站或合約安全。

EIP-712 類型化簽章
0 / 5
0 項已核查; 5 項仍未解決

完成核查不代表資產、交易或系統已經安全。

工作原理

1. 確認操作和驗證路徑

判斷請求授權的是登入、訂單、投票、代幣額度、轉帳、中繼呼叫還是其他操作。找到重建摘要並消費簽章的程式碼。對於外部擁有帳戶,驗證通常從 ECDSA 簽章恢復地址;對於合約帳戶,應用可能需要呼叫 ERC-1271 isValidSignature(hash, signature),並檢查其成功值 0x1626ba7e

2. 鎖定域

檢查確切的 EIP712Domain 類型和值。標準欄位為 nameversionchainIdverifyingContractsalt,但只有實際包含的欄位才參與雜湊。獨立確認目前鏈、已部署程式碼和預期驗證者;熟悉的名稱、代幣符號、代理標籤或校驗和地址並不足夠。ERC-5267 eip712Domain() 可以公開合約的域,但支援該介面並非強制,代理或升級行為仍需審查。

3. 重建類型圖

primaryType 開始,保留成員順序,並遞歸收集引用的結構體。encodeType 會按類型名稱排序後附加被引用結構體的定義。EIP-712 支援定寬整數、addressboolbytes1bytes32、動態 bytesstring、陣列和結構體;標準未定義 uintint 等別名、定點類型及循環值。

4. 解碼每個值和單位

將每個訊息值與其聲明類型和應用含義對應起來。核對完整地址、原始整數單位、正負號、陣列順序、接收者、Spender、資產、金額、費用、限額、目標、Calldata 雜湊及人類可讀字串。動態 bytesstringencodeData 中以其內容的 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、域分隔符和該訊息雜湊;把 amount250000000 改為 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 是仿冒地址或並非預期合約
  • 域的 nameversion 具有誤導性
  • 代理實作或域在升級後發生變化
  • primaryType 錯誤,或使用標籤相似的影子類型
  • 成員順序、依賴順序或編碼器不一致
  • 地址被截斷、替換或錯誤標注
  • 代幣小數位或有符號與無符號整數錯誤
  • 隱藏的陣列項、嵌套結構體或任意 bytes 載荷
  • 無限金額、過寬範圍或由攻擊者控制的接收者
  • Nonce 缺失、過期、共享或消費方式錯誤
  • 截止時間缺失、過遠、溢出或解釋含糊
  • 跨鏈、跨合約、跨帳戶或跨操作重放
  • 中繼者扣留、審查、搶跑或重定向執行
  • 簽章可塑性或過於寬鬆的 ECDSA 恢復
  • ERC-1271 簽署者、模組、閾值、狀態或程式碼變化
  • 錢包渲染、盲簽或不支援類型導致的失敗
  • 前端 JSON 與驗證者使用的摘要不一致
  • 撤銷或取消在交易排序競爭中失敗
  • 將簽章提示的結果誤認為收據、狀態變化或最終性

常見誤區

誤區 1:EIP-712 簽章就是交易

它們是鏈下簽署的訊息。中繼者或其他參與者可以隨後把它們提交給合約,產生的交易可以消耗 Gas 並改變狀態,卻不必由簽署者發送。

誤區 2:結構化顯示就代表請求安全

類型化欄位提高了可檢查性,但惡意模式、數值、合約、標籤、隱藏嵌套和不完整的錢包渲染仍可能誤導簽署者。

誤區 3:域分隔符能阻止所有重放

它只隔離已編碼的域。同域重放仍需要 Nonce、截止時間、取消、成交量記賬或冪等性;未包含的域欄位不會形成任何邊界。

誤區 4:恢復出預期地址就證明獲得授權

地址恢復只證明某 EOA 對摘要做了簽章,不能驗證應用語義;合約帳戶必須執行 ERC-1271 策略,而不是普通地址恢復。

誤區 5:關閉頁面或斷開錢包連線會取消簽章

複製出的簽章會一直可用,直到驗證者的 Nonce、截止時間、取消狀態或策略使其失效。應確認相關鏈上狀態,而不是依賴會話狀態。

相關主題

來源

導覽

搜尋知識庫...