KeyFrame內部研究專用

Try to Catch This: Try-Catch in Solidity Reviewed

DeFi Security Summit - DSS·11月23日週日·3 min英文

三句話摘要

Solidity try-catch 的三個邊緣案例:哪些 revert 不會被捕獲,開發者與審計員常踩的坑。 try-catch 只捕獲「外部呼叫本體」的 revert,Solidity 在進入 try 之前插入的 EXTCODESIZE 檢查、回傳長度驗證,以及傳入參數的內部呼叫,都在保護範圍之外。 三種 catch 子句各司其職:`error` 捕獲帶原因字串的正常 revert;`panic` 捕獲算術溢位、陣列越界、除以零等程式錯誤;低層級 catch 負責其他所有情況,包括 custom error、out of gas,以及 error/panic 解碼失敗。

重點整理

重點
  • 1

    三種 catch 子句各司其職:`error` 捕獲帶原因字串的正常 revert;`panic` 捕獲算術溢位、陣列越界、除以零等程式錯誤;低層級 catch 負責其他所有情況,包括 custom error、out of gas,以及 error/panic 解碼失敗。

  • 2

    參數的內部呼叫在 try 外執行:若傳入外部函式的參數本身是一個內部呼叫,該呼叫的 revert 發生在進入 try 區塊之前,因此不受捕獲,整個交易直接失敗。

  • 3

    Solidity 自動插入的兩種前置檢查不被捕獲:呼叫合約地址前的 EXTCODESIZE 檢查(目標為 EOA 時觸發)以及回傳資料大小驗證,均在進入 try 之前執行,失敗時直接 revert。Solidity 0.8.10 起,若預期有非零回傳資料,EXTCODESIZE 檢查會被跳過。

  • 4

    try/catch 區塊內部的 revert 不再往上捕獲:在 try 或 catch 區塊裡拋出的異常,不會被同層的 catch 處理,會直接向上傳播。

實用技巧與重點

乾貨
  • 工具/語言:Solidity、Chain Security(審計公司)
  • 版本節點:Solidity 0.8.10 起,若預期非零回傳資料,EXTCODESIZE 檢查不再執行
  • 三種 catch 子句:`catch Error(string memory reason)`、`catch Panic(uint errorCode)`、`catch (bytes memory lowLevelData)`
  • 會被捕獲:外部呼叫本體內的 revert、ABI decode 失敗
  • 不會被捕獲:傳入參數的內部呼叫 revert、EXTCODESIZE 檢查失敗、回傳資料大小不符、try/catch 區塊自身內部的 revert
  • 觸發 panic 的典型情況:arithmetic overflow、invalid array access、division by zero、assert 失敗

結論

結論

try-catch 只捕獲「外部呼叫本體」的 revert,Solidity 在進入 try 之前插入的 EXTCODESIZE 檢查、回傳長度驗證,以及傳入參數的內部呼叫,都在保護範圍之外。

完整解析

詳細

智能合約開發中,try-catch 常被視為「萬用保險網」,但 Chain Security 安全工程師 Mark 在這場閃電演講中指出,這個認知存在幾個危險的盲區,即使資深審計員也偶有誤解。

try-catch 的基本結構分三層:`catch Error` 捕獲帶有 reason string 的正常 revert;`catch Panic` 處理算術溢位、陣列越界、除以零、assert 失敗等「不應出現於無錯誤程式碼」中的例外;最低層的 `catch (bytes memory)` 則接住其他所有情況,包括 custom error、out of gas,以及前兩種子句解碼失敗的情形。理論上,低層級 catch 應能兜住一切——但現實並非如此。

Mark 以一個具體例子說明:對介面 `I` 的函式 `fu` 發出外部呼叫,其參數來自另一個內部呼叫。問題在於,這個「傳入參數的內部呼叫」在控制流進入 try 區塊之前就已執行;一旦它 revert,catch 完全感知不到,交易直接失敗。這是第一個盲區。

第二個盲區是 EXTCODESIZE 檢查。Solidity 在真正發出外部呼叫前,會自動檢查目標地址是否為合約(即 code size > 0);若目標是 EOA,檢查失敗,revert 在進入 try 之前發生,同樣逃脫 catch。值得注意的是,Solidity 0.8.10 起,若預期回傳非零資料(即函式有回傳值),此 EXTCODESIZE 檢查會被跳過——這引出第三個盲區:若外部呼叫實際回傳的資料長度不符預期,Solidity 同樣會在 try 之前 revert。

整體原則因此可歸納為:外部呼叫本體內部的 revert 會被捕獲;由 Solidity 在呼叫前自動插入的各種前置檢查,以及 try/catch 區塊自身內部拋出的異常,均不會被捕獲。這條規則看似簡單,卻在真實審計中反覆造成漏洞,值得每位 Solidity 開發者內化為直覺。

關鍵時刻

Pipeline v2

帶時間戳的重點,會在逐字稿層級分析上線後產生。目前請先透過原始影片觀看。

事實查核

Pipeline v2

說法查證是下一次管線升級的一部分。KeyFrame 只會顯示它真正能驗證的內容。

更多「Web3 安全」的內容

IF YOU OWN XRP YOU NEED TO SEE THIS PRICE MANIPULATION! ⚠️
8 min
Web3 安全英文8月14日

IF YOU OWN XRP YOU NEED TO SEE THIS PRICE MANIPULATION! ⚠️

Zach Humphries

  • 機構支撐的積極意義:價格操縱常被視為負面,但Ripple掌握大量XRP供應與escrow,在熊市期間提高價格下限,實際上替零售投資者鎖定了低風險的積累區間,這不是剝削而是市場穩定機制。
  • 歷史模式驗證:2024年7月至11月XRP在50美分附近橫盤整理,低點觸及42美分(wick),高點65美分;隨後11月5日至12月5日單月上漲456%,年底到2025年初累計漲幅534%,這個歷史周期正在1美元價位重演。
  • 比特幣聯動邏輯:講者在4-5月就預測「如果比特幣跌至60k以下,XRP會跌至1美元或更低」,此預測精準應驗,反映出熊市中兩者的明確連動關係。
Minimmit, Multimmit and the New Consensus Frontier with Patrick O'Grady
72 min
Web3 安全英文PODCAST8月5日

Minimmit, Multimmit and the New Consensus Frontier with Patrick O'Grady

Zero Knowledge

  • 反向 Linux 架構:Commonware 刻意暴露棧各層級控制,讓開發者自訂執行環境、共識機制、密碼學實現,而非像 Cosmos SDK 只允許應用層以上定制。2-3 個月能組裝一條定製鏈,代價是額外深度但回報是長期維護成本降低及效能優化彈性。
  • 容錯假設的典範轉移:Alpine Glow(Solana 2025)實現單輪投票定終的關鍵是將容錯預算分離為獨立的 Byzantine 和 Crash 容限。傳統系統把 33% 當一個整體預算;新模型允許 20% 惡意加 20% 崩潰,打破了 PBFT 理論界線,釋放單輪設計空間。
  • Minimet 與 Multimet 的遞進:Minimet 是 5F+1 設定下的乾淨構造,實現更短視圖延遲;Multimet(剛發布)進一步允許並行 mini-commits 且驗證者可推翻領導者審查,使用者交易在全球分布式網路達到 200-300 毫秒端到端定終。
Private Information Retrieval (PIR) with Alex Hoover
64 min
Web3 安全英文PODCAST7月29日

Private Information Retrieval (PIR) with Alex Hoover

Zero Knowledge

  • PIR 保護的是訪問模式,不是資料本身
  • PIR 與加密不同,它關注的是隱藏「客戶端查詢了什麼」,而非「資料是否加密」。在公開資料庫(如區塊鏈)上,客戶端可以在不洩露查詢對象給伺服器的情況下檢索特定條目,解決了輕量級客戶端的隱私和防審查問題。
  • 客戶端預處理方案是突破瓶頸的關鍵