
閱讀時長 3 分鐘
假 ERC-20 充值攻擊:偽造事件日誌如何騙過加密索引器
2026 年 7 月 24 日,Ethereum 上一個合約發出一筆日誌,聲稱 0.29 ETH 已抵達某個位址。實際上沒有任何 0.29 ETH 抵達任何地方。交易成功、區塊確認,而鏈上紀錄如今寫著:發生了一筆轉帳。
這段落差——鏈上所記錄的與鏈上實際發生的——就是整起攻擊。它不是對交易所的入侵,而是一張偽造的收據,被提交給一個天生就信任收據的系統。
這類攻擊由來已久。研究人員早於 2021 年的 IEEE 論文中記載了假充值漏洞,CoinDesk 也報導過 2020 年約 10 億美元的代幣暴露於此風險。值得你花時間的不是它存在這件事,而是 2026 年版本有多便宜,以及在監控儀表板上看起來有多麼平常。
這筆交易實際上包含什麼
一個外部帳戶(EOA)呼叫某個合約。該合約產生兩筆內部交易並寫入一筆事件日誌。攻擊者承擔的總風險成本:gas 費。
事件日誌就是攻擊酬載。 其內容如下:
Transfer (index_topic_1 address to, uint256 amount)
to: 0xC5518694Ef1A64eF0362eB5165A8A41e83Ff4C41
amount: 290000000000000000
看簽名,不要看名稱。
真正的轉帳會記錄是誰發送的。這一筆只記錄了誰收到
這個事件只有一個 indexed 參數、兩個 topic。沒有 from。這就是整個騙局。
真正的轉帳會記錄是誰發送的。這一筆只記錄了誰收到,因為根本沒有東西被發送。該合約自行宣告了一個事件、把它命名為 Transfer,並給了它一個任何代幣標準都不會產生的結構。它的 topic hash——0x69ca02dd4edd7bf0a4abb9ed3b7af3f14778db5d61921c...——並不是 ERC-20 的簽名 hash。它是另一個掛著同樣名字的事件。
內部交易則提供了佐證。 兩筆都標示為 Transfer、都帶著 0.29 ETH、都源自該合約。一筆指向偽造日誌中指名的位址,另一筆指回發起整起事件的帳戶。其中一筆以 callcode 執行——這是一個已棄用的 opcode,會在呼叫者自身的環境中執行借來的程式碼,在正規的現代合約中幾乎已經絕跡。
肉眼掃過 trace 的人,看到的是一個接到呼叫並移動了 ETH 的合約。用程式解析它的人,看到的是一筆充值。
為什麼交易所會入帳
充值入帳本質上是索引問題,而索引器就是模式比對器。充值管線監看區塊鏈、判斷哪些事件代表價值抵達它所控制的位址,然後記入餘額。判斷通常依賴以下條件的組合:是否存在名為 Transfer 的事件、to 欄位是否吻合充值位址、金額是否可解析、交易是否成功。
這裡每一項都成立。交易成功了。事件名為 Transfer。接收者吻合。金額乾淨地解析為 0.29 ETH。
失敗的是許多管線從未做過的那項檢查:事件的 topic hash 是否符合 ERC-20 標準簽名,以及對應的餘額變動是否真的存在於狀態中?
用事件名稱比對,你什麼都會被餵。用簽名 hash 比對並對餘額驗證,這筆交易就毫無作用。
接著下半場登場。餘額一入帳,攻擊者立即提領,兌現一筆毫無擔保的入帳。交易所送出真實資產。假充值永遠不會被對帳發現,因為多數對帳是數小時後才批次進行,而提領早已結算完成。
速度不是附帶的,它就是產品本身。
2026 年版本為何值得警惕
三件事,單獨來看沒有一件是新鮮事。
- 成本只有 gas。 無需投入任何資本,嘗試失敗也沒有損失,這意味著攻擊者可以對一百個平台同時發動,只需要其中一個索引器夠寬鬆。
- 金額很小。 0.29 ETH 不會觸發大額轉帳警報。第一次嘗試的目的不是獲利——而是確認你的管線會不會入帳。後續的金額則取決於你的提領限額允許多少。
- 它在鏈上完全可讀。 每個元素都是公開且已確認的。沒有漏洞利用、沒有失竊的金鑰、沒有被入侵的端點。你的日誌會顯示平常的一天。
最後一點在營運上最關鍵。不留痕跡的攻擊難以偵測。這起攻擊留下了完美的痕跡卻依然難以偵測,因為痕跡看起來是正確的。
三項檢查
- 比對簽名 hash,而不是事件名稱。 你的索引器應將 topic0 與標準 ERC-20 Transfer hash 比對,其餘一律丟棄——無論它掛什麼標籤。這是唯一能擋下本文所述攻擊的改動。
- 對狀態驗證,而不是對事件驗證。 事件只是一種主張。先查詢餘額、確認它真的變動了,再入帳。事件只是為了索引方便而存在,從來就不是為了作為結算證明而設計,把它當成證明才是根本的錯誤。
- 在入帳與提領之間留出時間。 無論你的確認政策為何,第一筆提領若用掉幾秒鐘前才入帳的充值,就應該走一條與例行提領不同的路徑。這起攻擊依賴兩個事件緊鄰發生。把它們分開,你的成本微乎其微,攻擊者的整個計畫卻會因此失效。
給已在正式環境運行這些控制、而非從零設計的營運者:提領授權是一個政策層,不是一項功能。它應該與核可流程、門檻與升級機制放在同一個地方——那也正是「誰核可了什麼」這份無法竄改的紀錄被寫下的地方。
真正該帶走的一件事
7 月 24 日沒有人闖進任何地方。一個合約寫了一句關於自己的話,而這句話就是設計來讓讀得很快的軟體誤讀的。你的充值管線不是帳本閱讀器,它是一個文件解析器,而且一直默默地相信文件會誠實描述自己的內容。


