進入智能合約安全的實作細節前,先把常見的設計錯誤一次列出來,能幫你在寫合約、審查或測試時有「雷區清單」。
今天我們用最精簡的一句話來說明每類錯誤,並附上簡短防護提醒,讓你在後面幾天看到範例時能快速對應。
🔹 常見錯誤類別(每項一句話說明 + 防護要點)
1. 順序錯誤(Order of operations)
• 問題:在做外部呼叫前未先更新合約狀態,導致可被重入或重複執行。
• 防護:遵循 Checks → Effects → Interactions(先檢查、先更新、再互動)。
2. 權限錯誤(Access control misconfiguration)
• 問題:沒有為敏感函式設定正確的擁有者或角色限制,任何人都能呼叫。
• 防護:採用成熟的角色/Ownable 模組(如 OpenZeppelin),並在測試中覆蓋權限邊界。
3. 數值處理錯誤(Integer overflow/underflow & precision)
• 問題:數字超出類型範圍或精度處理不當會造成餘額錯亂或錯誤分配。
• 防護:使用 Solidity ≥0.8(內建溢位檢查)或 SafeMath,並做好邊界測試。
4. 外部呼叫風險(Unchecked external calls)
• 問題:不檢查外部呼叫結果或使用不安全的呼叫方式(如 call 未處理返回值)。
• 防護:檢查返回值、限制外部地址、考慮 pull payment pattern。
5. delegatecall / 升級模式錯誤(Proxy & storage layout)
• 問題:代理(proxy)與邏輯合約 storage slot 不對齊或升級管理權限不足,導致狀態被覆寫或惡意升級。
• 防護:嚴格管理升級權限、用已驗證的代理模式(例如 OpenZeppelin Upgrades)並檢查 storage layout。
6. 隨機性與 Oracle 風險(Randomness & oracle manipulation)
• 問題:使用可被驗證者或礦工影響的 on-chain 值(如 block.timestamp)作為隨機來源或價格來源。
• 防護:使用公開且經審計的 oracle / VRF(如 Chainlink),或採用 commit–reveal 機制。
7. 錯誤處理不當(Improper error handling)
• 問題:濫用 assert、require 或忽略 revert 的情況導致資金鎖定或狀態不一致。
• 防護:依語意使用 require(輸入/驗證)、revert(回退)與 assert(不可違反的內部不變量)。
8. 事件紀錄缺失(Lack of events / logging)
• 問題:不 emit 關鍵事件會讓追蹤、審計與補償變得困難。
• 防護:在重要狀態變更與轉帳處 emit 事件,便於鏈上稽核與後續追蹤。
9. Gas 與效能問題(Gas exhaustion & unbounded loops)
• 問題:寫出需遍歷大量資料或未限制迴圈的操作,可能導致交易失敗或 DoS。
• 防護:避免 on-chain 大量迴圈,採分頁/批次處理與 gas 成本估算。
10. 經濟設計錯誤(Incentive / game-theory flaws)
• 問題:合約的獎勵或懲罰機制設計錯誤,會被使用者或機器人利用(遊戲理論 exploit)。
• 防護:用模型化與模擬測試(包含激勵對抗場景),並設計保護閥與監控機制。
常見錯誤先列出來能提供很大的心理安慰:很多漏洞不是天花亂墜的新把戲,而是可以預見、可檢測、可防範的模式。
養成「每次寫新功能就對照清單」的習慣,能把大部分初級錯誤攔在門外。
接下來幾天我們會針對這些類別逐一拆解範例與修復步驟,實作會更直觀也更好理解。