在區塊鏈安全史上,The DAO 攻擊(2016) 是最具代表性的事件之一。
它不僅導致超過 360 萬枚 ETH(當時約 5000 萬美元) 被盜,
也改變了整個以太坊的發展路線,最終造成 Ethereum / Ethereum Classic 的分裂。
這一天,我們就來回顧這個「改寫歷史的漏洞」。
🧩 一、DAO 是什麼?
DAO(Decentralized Autonomous Organization)是一種去中心化自治組織,
它透過智能合約管理資金與決策流程,
不需要公司、董事會或銀行,完全靠程式執行治理。
👉 The DAO 是以太坊上最早的大型 DAO 實驗,
它允許投資者:
購買 DAO Token
提案投資項目
對項目進行投票決策
簡而言之,它是當時的「去中心化創投基金」。
⚙️ 二、DAO 的合約設計(簡述)
投資者可以把 ETH 存入 DAO 合約,換取 DAO Token。
若想退出,可呼叫 splitDAO() 將自己的資金分離出來。
該函式執行邏輯如下(簡化後偽代碼):
function splitDAO() public {
uint amountToSend = balances[msg.sender];
msg.sender.call.value(amountToSend)(); // ⚠️ 發送 ETH
balances[msg.sender] = 0; // ⚠️ 狀態更新太晚!
}
問題就出在這裡 👇
在呼叫 msg.sender.call.value() 時,攻擊者可以撰寫一個惡意合約,
在接收 ETH 的同時再次呼叫 splitDAO()(即 重入攻擊),
導致「重複提款」成功
🚨 三、攻擊流程圖解
1️⃣ 攻擊者呼叫 splitDAO()
2️⃣ DAO 合約發送 ETH → 觸發攻擊者合約的 fallback 函式
3️⃣ 攻擊者合約在 fallback 中再次呼叫 splitDAO()
4️⃣ 因為 balances[msg.sender] 尚未被歸零,重複提領成功
5️⃣ 持續重入直到 DAO 資金池被掏空
💣 攻擊總損失:約 360 萬 ETH
⚔️ 四、社群回應:Hard Fork 的爭議
DAO 攻擊後,以太坊社群出現兩種聲音:
| 陣營 | 立場 | 結果 |
|---|---|---|
| 恢復派(Ethereum) | 認為應該 Hard Fork 回滾交易,把資金還給被害者 | 成為現在的 Ethereum(ETH) |
| 原則派(Ethereum Classic) | 主張「Code is Law」,不應干涉鏈上歷史 | 成為 Ethereum Classic(ETC) |
這場分裂成為區塊鏈史上最具爭議的分岔之一。
🧠 五、學到的教訓
| 教訓 | 說明 |
|---|---|
| 1️⃣ 先更新狀態再轉錢 | 避免重入攻擊的基本原則(Checks-Effects-Interactions) |
| 2️⃣ 審計要早於部署 | DAO 在未經充分安全審計的情況下就上線 |
| 3️⃣ 合約治理需要共識機制 | 發生災難時該如何補救?誰有權決定? |
| 4️⃣ 不可逆 ≠ 不可救 | Hard Fork 雖救回資金,但也動搖了「去中心化信任」的根本理念 |
The DAO 攻擊是一堂血的教訓。
它告訴我們:區塊鏈的信任不是「程式不會錯」,而是「人能預防錯」。
每一行 Solidity code 都像簽一份「不可撤銷的合約」,
寫錯的代價,可能是整條鏈的信任崩潰。
這也是為什麼今天的以太坊安全標準(如 OpenZeppelin、ReentrancyGuard、審計機制)
會被如此嚴格重視。