DeFi Security 101 - 2023 - 02 - Nat Chin
三句話摘要
編寫安全的智能合約——規範、測試與自動化檢查的完整框架 安全智能合約的關鍵在於把安全融入開發流程的每個環節,從規範、單元測試、靜態分析到模糊測試形成完整的工具鏈,而不是等到上線後才考慮。 規範是安全的基礎:將代碼的目標、用戶群、函數簽名、調用堆棧、所有假設條件(入參範圍、呼叫者限制、狀態不變性)明確記錄。規範不是靜態文檔,每次代碼更新都應同步修改,否則過時文檔會成為混淆而非指引。規範能幫助識別邊界情況,指導未來擴展,並讓未來維護者清楚理解系統應如何運行。
重點整理
重點- 1
規範是安全的基礎:將代碼的目標、用戶群、函數簽名、調用堆棧、所有假設條件(入參範圍、呼叫者限制、狀態不變性)明確記錄。規範不是靜態文檔,每次代碼更新都應同步修改,否則過時文檔會成為混淆而非指引。規範能幫助識別邊界情況,指導未來擴展,並讓未來維護者清楚理解系統應如何運行。
- 2
單元測試驗證規範實現:不只測試正常路徑,也要測試異常情況、邊界值(如 uint256 的上下限)、格式錯誤的輸入。達到 100% 語句和分支覆蓋率,能在開發過程中及早發現規範與實現的差異,並在重構時防止舊 bug 重新出現——測試失敗會立即告訴你問題所在。
- 3
靜態分析工具自動掃描常見漏洞:Slither 匹配 87 個檢測器針對代碼庫快速檢查(可集成 GitHub CI),能標出重入、危險調用等問題區域。但它無法判定漏洞是否 100% 可利用或實際造成風險,需要人工確認嚴重程度,決定是否立即修復或在文檔中註記未來升級的影響。
- 4
模糊測試發現深層漏洞:Echidna 根據開發者定義的不變性自動生成隨機輸入,比單元測試更全面地探索邊界情況和組件交互問題。代價是設置和排查更複雜,但能捕捉單元測試無法覆蓋的微妙 bug,特別是涉及多個合約交互時。
實用技巧與重點
乾貨- 開源工具與資源
- Trailer Bits 工具:Slither、Echidna、Medusa
- Slither 檢測器數:87 項
- 參考資源:securecontracts.com(開發指南、事件響應計畫、程式碼示例)
- 規範應包含
- 預期功能與用戶群
- 所有公開函數的簽名與返回值
- 完整的調用堆棧與狀態變更
- 所有入參假設(值域、呼叫者限制等)
- 預期回滾時機與成功情況
- 用戶使用指南與滑點選擇範例
- 測試覆蓋目標
- 100% 語句覆蓋率
- 100% 分支覆蓋率
- 預期輸入範圍
- 邊界情況(上下限)
- 意外與格式錯誤的輸入
- 開發流程集成
- 新增函數時寫單元測試
- 代碼提交前運行 Slither(可自動化)
- 複雜模組用 Echidna 驗證不變性
結論
結論“安全智能合約的關鍵在於把安全融入開發流程的每個環節,從規範、單元測試、靜態分析到模糊測試形成完整的工具鏈,而不是等到上線後才考慮。”
完整解析
詳細Nat 用攀岩作為貫穿全場的類比——攀岩需要繩索、快掛、登山扣來保護登山者,智能合約也需要多層工具來確保代碼安全。不同的是,攀岩的保護機制是物理的,而合約安全的保護機制是流程與工具。
規範(Specification)是整個防禦體系的基礎。開發者在寫代碼時往往會做出隱含假設——函數只能由所有者調用、入參必須在某個範圍內、某些數學計算應該成立。這些假設若只存在於腦中,會造成維護困難和漏洞。將假設明確文檔化的好處在於,未來當代碼庫增長時,規範能清楚地指出各個函數如何協同、何時應該回滾、邊界在哪裡。規範不是一成不變的;每次代碼變更都應該同步更新,就像添加新函數時應該寫單元測試一樣。若文檔過時而代碼更新了,就會出現「代碼是唯一真理來源」的混亂局面,難以判定新行為是否符合預期。
有了清晰的規範,單元測試的作用就是驗證實現是否真正遵循規範。單元測試應該涵蓋三類輸入:預期的正常輸入、邊界值(如 uint256 的 0 和 2^256-1)、以及意外或格式錯誤的輸入。目標是達到 100% 的語句和分支覆蓋率——這不只是數字遊戲,而是確保代碼在各種輸入下的行為都被檢驗過。單元測試最重要的優勢是防止未來的重構意外引入舊 bug;一旦測試失敗,系統會立即告訴你。
靜態分析工具 Slither 的角色是自動化掃描常見漏洞模式。Slither 內建 87 個檢測器,可以在數秒內掃描整個代碼庫,識別重入漏洞、危險的外部呼叫等問題。它的優勢在於速度快、可集成到 CI/CD 流程,缺點是無法判定「這個漏洞是否真的可利用」——它只能說「這裡違反了最佳實踐」。安全研究人員需要人工分類,決定是立即修復還是在文檔中註記「未來如果增加新功能,這裡會有問題」。
最具挑戰性的工具是模糊測試,代表深層的安全驗證。Echidna 根據開發者預先定義的不變性(例如「代幣總供應量永遠不變」或「用戶餘額不能為負」)自動生成隨機輸入,就像讓機器人來敲鍵盤測試。模糊測試比單元測試更全面,因為它不受開發者想像力限制,能發現邊界組合、組件交互中的微妙 bug。但代價是設置更複雜,故障排查也更難。
整個流程體現了一個核心理念:安全不是上線前的檢查清單,而是開發的每一步都要做的事。在寫規範時考慮邊界,在添加函數時寫測試,在提交前跑 Slither,在構建複雜模組時跑 Echidna。多層防禦各司其職,才能有效阻止漏洞。
關鍵時刻
Pipeline v2帶時間戳的重點,會在逐字稿層級分析上線後產生。目前請先透過原始影片觀看。
事實查核
Pipeline v2說法查證是下一次管線升級的一部分。KeyFrame 只會顯示它真正能驗證的內容。

