重入攻擊是什麼,跟一般理解的「駭客竊取私鑰」有什麼不同?
重入攻擊(reentrancy attack)鎖定的不是私鑰或使用者的簽署行為,而是智能合約程式碼本身在執行順序上的邏輯瑕疵。多數合約的提領邏輯理論上應該遵循「先確認餘額、扣除餘額、再把錢轉出去」的順序,但如果合約寫成「先把錢轉出去、才扣除餘額」,就會出現一個危險的空窗期:資產已經送出,帳本卻還沒更新。攻擊者利用的正是這個空窗期——透過一個惡意合約在接收到轉帳的當下,立刻回頭再呼叫一次同一個提領函式,因為此時合約帳本上顯示的餘額還沒被扣除,合約會誤判「這個帳戶還有錢可以領」,於是再送一次錢出去,而這個回呼可以在同一筆交易裡遞迴發生數十次。
這跟駭客竊取私鑰的本質差異在於:私鑰竊取靠的是騙到使用者或直接取得金鑰,重入攻擊完全不需要接觸任何使用者或私鑰,純粹是攻擊者部署一個惡意合約,利用目標合約自身程式碼裡的執行順序漏洞,對目標合約發動攻擊,受害的是合約本身管理的資產池,而不是特定使用者的錢包。
為什麼這個漏洞會存在,它在區塊鏈安全史上有什麼特殊地位?
重入攻擊之所以存在,源自於以太坊智能合約設計上一個看似無害的功能:合約可以在轉帳的同時,附帶呼叫接收方的程式碼(例如透過 fallback 或 receive 函式),這個設計原本是為了讓接收方合約能在收到資產後執行自己的邏輯,是合約之間互動的基礎機制之一,本身沒有問題。問題出在開發者如果沒有意識到「呼叫外部合約」這個動作,本質上等於暫時把程式的執行權交給了對方,對方可以在這段時間內做任何事,包括反覆呼叫回你的合約。
這個漏洞在區塊鏈安全史上有特殊地位,是因為它就是 2016 年 The DAO 事件的攻擊原理——攻擊者利用 The DAO 智能合約提領函式裡「先轉帳、後更新餘額」的順序漏洞,反覆遞迴提領,最終盜走當時價值約 6,000 萬美元的以太幣,這起事件甚至導致以太坊社群為了追回資金而執行硬分叉,分裂出以太坊(ETH)與以太坊經典(ETC)兩條鏈。這也是為什麼重入攻擊會被視為智能合約安全教育裡最基礎、也最必須理解的一課——不是因為它古老,而是因為十年後的今天,同樣的邏輯瑕疵依然在新協議裡反覆出現。
重入攻擊實際上是怎麼發生的,開發者又是怎麼防範的?
典型攻擊流程分幾步:攻擊者先部署一個惡意合約,存入少量資金到目標合約以取得合法的提領資格,接著呼叫目標合約的提領函式;目標合約如果依照「先轉帳、後更新餘額」的順序執行,會在轉出資金的當下觸發攻擊者合約的 fallback(或 receive)函式,而攻擊者早已在這個函式裡寫好「立刻再呼叫一次提領函式」的邏輯;因為此時目標合約的帳本還沒更新,攻擊者的餘額看起來還是原本的金額,提領請求會再次被核准,這個過程可以在同一筆交易裡遞迴數十次,直到合約資金池被抽乾或觸發 gas 上限。整個攻擊從發動到完成往往只需要一筆交易、幾秒鐘。
開發者防範這個漏洞的標準做法稱為「檢查-效果-互動」模式(checks-effects-interactions pattern):先執行所有條件檢查(餘額是否足夠)、接著更新合約內部狀態(先扣除餘額,把帳本改成「已經領過了」)、最後才執行外部呼叫(實際把錢轉出去)——只要把「更新帳本」這個動作排在「轉帳」之前,攻擊者回呼進來時,帳本已經顯示餘額為零,重入的提領請求會直接被拒絕。除了程式順序本身,開發者也普遍搭配使用重入鎖(reentrancy guard),在函式執行期間設下一個鎖定標記,只要偵測到同一函式在鎖定狀態下被重複呼叫,就直接中止交易,這相當於在邏輯層面加了第二道防線。
重入攻擊對一般使用者的資產意味著什麼,我該怎麼判斷風險?
重入攻擊鎖定的是協議層級的資產池,不是個別使用者的錢包,這代表使用者無法透過自己端的操作習慣(例如謹慎簽署、核對合約地址)直接防範這類攻擊——你的資產是否安全,完全取決於你存入資金的那個協議,程式碼是否正確實作了防護機制,這是一個純粹的技術實作問題,不是使用者判斷力可以介入的環節。這也是為什麼重入攻擊造成的損失,受害的往往是所有把資金存入該協議的使用者,而不是特定一兩個操作失誤的人。
對一般使用者來說,能做的具體事情包括:優先選擇經過審計、且審計報告明確提到已針對重入攻擊做過測試的協議(可在審計報告裡搜尋 reentrancy 或 checks-effects-interactions 等關鍵字)、留意協議是否採用業界廣泛使用的標準函式庫(例如 OpenZeppelin 的 ReentrancyGuard,這類函式庫已經過大量專案實戰驗證)、以及理解「審計通過」不代表這類漏洞不可能發生——2026 年初仍有協議因重入雙重鑄造漏洞被攻擊,證明這類十年前就被記錄在案的攻擊模式,至今依然會因為開發疏忽而重演。分散資金、不把大部位集中在單一協議,是使用者端唯一能實質降低這類風險曝險的做法。
2026 年 1 月,比特幣收益協議 Solv Protocol 旗下一個 Bitcoin Reserve Offering(BRO)金庫遭到重入雙重鑄造攻擊,攻擊者利用漏洞反覆執行鑄造操作 22 次,把原本合法的 135 顆 BRO 代幣,憑空鑄造成約 5.67 億顆偽造 BRO 代幣,再把這些偽造代幣兌換成約 38.05 枚 SolvBTC(當時價值約 270 萬美元)。Solv 事後承諾用協議儲備金全額補償損失,並開出贓款的 10% 作為懸賞金,希望攻擊者主動歸還資金,但截至報導當時,被盜的 SolvBTC 仍未歸還。這起事件與其他同期發生的重入相關攻擊,共同顯示重入攻擊即使在 The DAO 事件過去近十年後,依然持續造成實際損失。
合約在轉帳時附帶呼叫接收方程式碼,讓合約之間能夠靈活互動、實現更複雜的 DeFi 組合功能,這是以太坊智能合約設計的核心優勢之一;但這個彈性的代價是,一旦開發者沒有正確處理狀態更新與外部呼叫的先後順序,就會留下攻擊者可以反覆遞迴利用的破口,而這個防護責任完全落在協議開發者身上,一般使用者無從介入判斷或防範,只能透過選擇審計品質較高、採用標準防護函式庫的協議來間接降低風險。