Bible Network Crypto DeFi Onchain RWA AI Agent Stablecoin Chain SAFU CryptoTax DeFAI AGI Claude Me Claude Skill Claude Design Claude Cowork
獨立知識媒體
與任何項目無關聯
最深入的加密貨幣知識庫
crypto-bible.com
最新
SpaceX 上市確認持有 18,712 枚比特幣:成本均價 $35,324,擠進企業持幣榜第八,實際規模遠超事前估計  ·  BlackRock BITA 第四次修訂 S-1:管理費 0.65% 削價對手、掩護性買權讓持有 BTC 也能領月配,7 月上線在即  ·  Solana 2026:DEX 交易量超越以太坊,TVL 卻只有十分之一——這個落差說明了什麼  ·  選加密交易所不能只看手續費:安全性、合規性、出入金的完整評估框架  ·  比特幣 vs 以太坊:同為加密龍頭,它們在最根本的設計問題上選了完全不同的答案  ·  以色列加密稅自願申報只有 58 人:一個失敗的政策實驗,揭示全球課稅困境
名詞解析 · wallet-and-security

Reentrancy Attack

重入攻擊
wallet-and-security 進階

30 秒版 · 給沒耐心的人
重入攻擊(Reentrancy Attack)是一種針對智能合約的漏洞攻擊手法:攻擊者利用合約在「送出資金」之後、「更新內部狀態(帳戶餘額)」之前這個時間窗口,在收到資金的那一刻立刻重新呼叫原本的提款函數,讓合約在狀態更新前再次通過餘額檢查,進而反覆提取資金直到合約被清空。2016 年的 The DAO 攻擊(損失約 6,000 萬美元)就是利用了這個漏洞,並直接導致以太坊硬分叉(ETH/ETC 的分裂)。這個漏洞至今仍是智能合約安全審計最重要的檢查項目之一。
完整解說 +
01 · 這是什麼?

重入攻擊的技術原理是什麼,為什麼合約程式碼的「順序」那麼重要?重入攻擊的根本漏洞,在於一個智能合約在把錢打出去之後,才去更新自己的帳本——這個操作順序讓攻擊有機可乘。正確的操作應該是:先更新帳本(把用戶的餘額設為 0),再把錢打給用戶。有漏洞的寫法是:先把錢打給用戶,等打款完成後再更新帳本。問題在於:以太坊的 .call() 方法打款時,如果接收方是一個智能合約,它可以在接收到 ETH 的那一刻觸發一個「fallback 函數(回調函數)」。攻擊者在這個回調函數裡再次呼叫原合約的「withdraw」——此時原合約的帳本還沒更新,所以餘額檢查仍然通過。這個「重新進入(Re-enter)」的操作可以反覆執行,直到合約裡的 ETH 被抽完。整個漏洞的邏輯,就是「先打錢後記帳」這個錯誤順序。

02 · 為什麼存在?

The DAO 攻擊是什麼,它為什麼那麼重要?The DAO(Decentralized Autonomous Organization)是 2016 年的一個以太坊上的眾籌智能合約項目,募集了當時價值約 1.5 億美元的 ETH。在 2016 年 6 月,一名攻擊者利用重入漏洞,在 The DAO 的提款合約中反覆提款,最終轉走了約 360 萬枚 ETH(當時價值約 6,000 萬美元)。這個事件的影響遠超一般駭客攻擊:以太坊社群面臨了一個根本性的抉擇——要不要硬分叉(修改區塊鏈狀態)來把被盜的 ETH 強行歸還給 DAO 投資人?最終,以太坊社群以多數決的方式決定硬分叉,把以太坊「回滾」到攻擊發生前的狀態,歸還被盜資金。這就是今天以太坊(ETH)的由來;而拒絕承認這次硬分叉的少數人繼續維護原鏈,這就是以太坊經典(ETC)的由來。The DAO 攻擊讓整個加密行業深刻認識到智能合約安全的重要性,也奠定了「區塊鏈不可篡改性」和「治理緊急響應」之間存在根本矛盾的討論基礎。

03 · 如何影響你的決策?

如何防禦重入攻擊?有哪些已被驗證的模式?幾個標準的防禦方式。第一,Checks-Effects-Interactions(CEI)模式:這是最基本也最重要的防禦原則。合約的任何函數應按這個順序執行:Checks(先做所有的條件檢查)→ Effects(再更新合約的所有內部狀態)→ Interactions(最後才和外部合約或地址互動,例如打款)。把狀態更新放到打款之前,攻擊者即使重入,餘額也已經是 0 了,檢查不通過,攻擊失效。第二,ReentrancyGuard(重入鎖):OpenZeppelin 提供了一個標準的 ReentrancyGuard 模組,本質上是一個布林值的互斥鎖——函數執行時設為「已鎖」,完成後解鎖;若在「已鎖」狀態下有人再次呼叫,直接回滾。這是一個簡單有效的防護,適合複雜的函數調用鏈。第三,避免使用原始 call() 打款transfer()send() 方法預設只轉發 2300 Gas,不夠一個有複雜邏輯的回調函數執行,可以從結構上限制重入的可行性(但這不應作為主要防禦,因為 Gas 機制可能隨升級改變)。

04 · 你該怎麼辦?

除了重入攻擊,還有哪些常見的智能合約漏洞類型?了解重入攻擊之後,還有幾種同樣重要的智能合約漏洞類型。整數溢位/下溢(Integer Overflow/Underflow):在引入 Solidity 0.8 自動溢位保護之前,數值計算可以「繞一圈」(例如 uint8 的 255 + 1 = 0)——被利用來偽造餘額。現代 Solidity 已有保護,但舊合約仍有風險。不安全的外部呼叫(Unsafe External Call):呼叫外部合約時,若不正確處理回傳值,可能讓攻擊者控制執行流程。邏輯錯誤(Logic Error):不是技術漏洞,而是業務邏輯的設計錯誤——條件判斷顛倒、許可權控制缺失等,讓攻擊者可以不按預期的方式使用合約。閃電貸攻擊(Flash Loan Attack):利用閃電貸的瞬間巨大流動性,在一筆交易內操控市場或預言機價格,影響依賴這些價格的借貸或清算邏輯。了解這些漏洞,是評估 DeFi 協議安全性的基礎知識。

實際例子 +

用偽程式碼說明重入攻擊的完整流程。想像一個簡單的以太坊存取款合約,內部有一個 balances 映射記錄每個地址的餘額。有漏洞的 withdraw 函數:

function withdraw() external {
  require(balances[msg.sender] > 0);  // 檢查餘額
  (bool success,) = msg.sender.call{value: balances[msg.sender]}("");  // 先打款
  require(success);
  balances[msg.sender] = 0;  // 後更新餘額
}

攻擊者部署了一個惡意合約,裡面有一個 fallback 函數:

fallback() external payable {
  if (address(victim).balance > 1 ether) {
    victim.withdraw();  // 在收到 ETH 的當下立刻再次呼叫
  }
}

攻擊過程:攻擊者呼叫 victim.withdraw();合約檢查餘額 > 0(通過);合約打款給攻擊者;攻擊者的 fallback 被觸發,立刻再次呼叫 victim.withdraw();此時合約的 balances[攻擊者] 仍然是原始值(因為更新在打款之後);檢查再次通過,再次打款;……循環,直到合約沒錢。

修復版的正確順序(CEI):先 balances[msg.sender] = 0,再 .call{value: ...}。一行順序的改變,就阻斷了整個攻擊。

圖解
Reentrancy Attack: Withdraw Before Balance Updates重入攻擊 vs 安全提款雙欄對比流程圖:左側綠色欄「正常提款(安全)」——步驟順序:① 呼叫提款 → ② 檢查餘額足夠 → ③ 先更新餘額為零 → ④ 再打款。右側紅色欄「重入攻擊漏洞」——關鍵差異:步驟三和四順序反轉:② 檢查餘額通過 → ③ 先打款(回調立即觸發,攻擊者在回調中再呼叫提款)→ 餘額尚未更新,步驟②再Reentrancy Attack: Withdraw Before Balance UpdatesNormal Withdraw (Safe)1. User calls withdraw(1 ETH)2. Check: balance ≥ 1 ETH ✓3. Update balance = 04. Send 1 ETH to user ✓Reentrancy Exploit1. Attacker calls withdraw(1 ETH)2. Check: balance ≥ 1 ETH ✓3. Send 1 ETH → callback triggers↺ calls withdraw(1 ETH) AGAIN before balance updates!4. Check STILL passes (balance not yet 0)Loop repeats until contract is drained. The DAO hack (2016, $60M) used this exact pattern.Crypto Bible · crypto-bible.com
歡迎截圖分享,轉載請註明來源
常見誤解 +
✕ 誤解1
× 誤解一:重入攻擊已經是老舊漏洞,現代智能合約都已經防禦了,不需要再擔心。不對。重入攻擊雖然是 2016 年就廣為人知的漏洞,但此後仍有大量合約因為忽視 CEI 原則或引入了複雜的跨合約互動而重新暴露出重入風險。DeFi 歷史上很多八位數美元以上的攻擊都包含了重入的元素(有時和閃電貸組合)。現代的 Solidity 確實有更好的工具,但這不代表每個開發者都會使用——安全審計仍然把重入列為必查項。
✕ 誤解2
× 誤解二:只有提款(withdraw)函數才可能有重入漏洞。不對。任何在狀態更新之前進行外部呼叫的函數,都可能存在重入風險。例如,一個在分配獎勵之前呼叫外部合約的函數、一個在更新帳本之前觸發代幣轉移回調的函數,都可能被重入攻擊利用。CEI 原則適用於所有和外部合約互動的函數,不只是提款。
這件事跟你有什麼關係 +
直接影響

重入攻擊揭示的,是智能合約設計一個根本性的工程取捨:外部呼叫(把資金打給另一個地址或合約)和狀態更新之間的先後順序。「先打錢、後記帳」的直覺式寫法,讓業務邏輯更清晰(先給你錢,再說你沒錢了),但引入了重入風險;「先記帳、後打錢」(CEI)雖然在業務邏輯上稍顯彆扭,但完全消除了重入問題。這個取捨現在已有明確的共識答案——永遠用 CEI——但它提醒我們,智能合約程式碼的安全性和直覺的業務邏輯之間有時會有微妙的衝突。每一個智能合約都是公開的、不可更改的——漏洞一旦部署,修補只能靠新合約的遷移,而無法像傳統軟體那樣靜默推送修補。這讓智能合約開發在上線前的審計,比任何傳統軟體都更為關鍵。

提問
請至少輸入 10 個字