在智慧合約世界裡,一個小小的邏輯錯誤可能讓數億資金瞬間蒸發。
傳統的測試與審計雖然能發現許多問題,但仍屬於「取樣驗證」——我們只能驗證發生過的情況。
而**形式化驗證(Formal Verification, FV)**的目標則是:「數學上保證程式行為符合規格」,也就是將安全性從「實驗觀察」提升到「邏輯證明」。
🔹 什麼是形式化驗證?
定義:形式化驗證是使用數學與邏輯方法,去「證明」一段程式在所有可能輸入下都不會違反某個性質(property)。
換句話說,測試是「找 bug」,形式化驗證是「證明沒有 bug」。
🔸 一個簡單例子
假設我們有一個簡單的智能合約函式:
function withdraw(uint amount) external {
require(balance[msg.sender] >= amount, "not enough");
balance[msg.sender] -= amount;
payable(msg.sender).transfer(amount);
}
我們可以想驗證以下性質(properties):
1. 安全性 (Safety): balance 不會變成負數。
2. 一致性 (Invariant): 所有用戶餘額總和 + 合約餘額恆等於初始資金總額。
3. 活性 (Liveness): 若使用者餘額足夠,永遠能成功提領。
形式化驗證要做的,就是用邏輯公式證明這三件事「對所有輸入都成立」。
🧩 形式化驗證的核心步驟
步驟 說明
1️⃣ 定義規格(Specification)/使用邏輯語句描述合約應有行為(例如 “balance 永不為負”)。
2️⃣ 建立模型(Model)/把 Solidity 轉成可驗證的中介形式(如 EVM bytecode、或 Boogie 語言)。
3️⃣ 自動或手動證明(Proving)/使用工具(例如 SMT Solver)檢查規格是否對所有情況成立。
4️⃣ 驗證結果分析(Result Review)/若工具報錯或生成反例(counterexample),開發者需檢查並修正邏輯。
🧠 常見形式化驗證工具(Solidity生態)
工具 核心功能 特點
Certora Prover/以規格語言(Certora Rules)撰寫約束條件/商用、支援大型專案(Aave、Balancer 使用)
VerX /自動生成驗證條件並找出反例 /側重安全屬性驗證
Scribble + MythX / Slither/在程式內嵌規格(#if_scribble 標註),結合模糊測試/適合中小型專案
Echidna/雖然屬於 fuzz 工具,但能搭配 invariant 測試模擬形式驗證/開源、易入門
KEVM / Lem / Isabelle/針對 EVM bytecode 層級的形式語義驗證
/學術導向,極高精度
🔍 實例:用 Scribble 寫出可驗證性質
以 Scribble 為例,我們可以在 Solidity 原始碼中寫上「規格斷言(specification assertions)」:
/// #invariant totalSupply() <= 1000000;
/// #invariant balance[msg.sender] >= 0;
contract Token {
mapping(address => uint256) public balance;
uint256 public totalSupply;
}
然後透過:
scribble Token.sol --output-mode flat
就能生成插入檢查語句的版本,再搭配 Echidna / MythX 做動態驗證。
這種方式雖然不是真正的「完整數學證明」,但已能捕捉大部分邏輯錯誤與不變量破壞(invariant violation)。
⚖️ 優點與限制
面向 優點 限制
安全性 /可數學證明合約不會出現某類錯誤/僅限於明確定義的性質
覆蓋範圍 /涵蓋所有輸入、所有執行路徑/需明確界定狀態空間(state space)
成本 /一旦建立模型可反覆使用 /初期建模與規格撰寫成本高
適用場景 /金融協議、治理模組、bridge 合約/適合高價值系統,不適合 MVP 階段
🧠 延伸概念:Property-Based Testing
介於單元測試與形式化驗證之間的「折衷方法」是 Property-Based Testing:
• 你定義系統應保持的不變量(invariants)。
• 工具(如 Echidna)會自動產生隨機輸入測試這些條件。
例如:
function echidna_balance_never_negative() public view returns (bool) {
return balance[msg.sender] >= 0;
}
這樣的測試可以在大部分情況下找出潛在違反不變量的狀況。
形式化驗證不是要取代測試,而是補足測試的盲點。
它迫使開發者明確寫下規格(specification),讓設計意圖不再只是「想當然爾」。
對於高價值協議(DEX、Bridge、Lending),形式化驗證是未來的必備流程;
而對個人開發者,從學會定義 不變量 (Invariant) 開始,就是邁向專業安全工程師的第一步。