你的鏈上警報昨天推播了一筆 9,200 BTC 的交易所流入。四分鐘後,那筆交易還在,但它原本所在的區塊已經不在鏈上了。
鏈重組(chain reorganization,常簡稱 reorg)的定義只有一句話:節點收到一條更長或更重的分叉鏈,於是丟掉原本認定的區塊,改採新的那條。 被丟掉的區塊裡的交易,多數會回到記憶池等待重新打包,少數會永遠消失。
對只看價格的人來說,這是節點軟體的內部事務。對用鏈上數據做決策的人來說,它是資料層的一個結構性問題:你的資料庫已經寫進去的東西,可能在幾分鐘後變成假的。 更麻煩的是回測。回測讀的是已經定案的鏈,實盤讀的是還在競爭中的鏈,這兩件事在歷史資料裡長得一模一樣。
這篇文章處理四件事:鏈重組的機制與兩種來源、各條鏈的實際重組深度分佈、鏈重組污染鏈上數據的四條路徑,以及六個能寫進流程的處理做法。資料層本身怎麼建,量化交易數據層的完整框架已經寫過,這裡只處理跟共識不確定性有關的部分。
鏈重組是什麼:帳本被改寫的那幾分鐘
區塊鏈不是一條線,是一棵樹。節點在任何時刻都只選一條分支當作「正典」,選的規則各鏈不同,比特幣看累積工作量,以太坊 PoS 看分叉選擇演算法加上投票權重。
兩個礦工在相近時間出塊,網路上就同時存在兩條長度相同的鏈。下一個區塊接在誰後面,另一條就變成孤鏈。這個過程每天都在發生,而且它是正常運作的一部分,不是故障。
被丟掉的區塊在比特幣叫 stale block,在合併前的以太坊叫 uncle(或 ommer)。裡面的交易會發生三種狀況,嚴重程度遞增。
第一種:換了位置。 交易被重新打包進新的區塊,內容不變,但區塊高度、時間戳、以及它在區塊內的排序全部變了。這是最常見的情況,也最容易被忽略,因為金額對得上。
第二種:換了順序。 同一個區塊裡的交易順序被改寫。對任何依賴執行順序的邏輯來說,結論可能反過來,清算是否觸發、套利是否成交、三明治攻擊誰先誰後,都吃這個順序。
第三種:消失。 如果有一筆衝突交易先被新鏈確認,原本那筆就永遠進不了鏈。這就是雙花,也是確認數這個概念存在的唯一理由。
從資料的角度看,這三種狀況對應到三種錯誤:時間序列錯位、事件排序錯誤、記錄憑空消失。
鏈重組的兩種來源:常態競爭與異常事件
分開看這兩種來源,處理方式會完全不同。
常態競爭來自傳播延遲。出塊間隔越短、網路越分散,撞塊的機率越高。這類重組的深度幾乎都是 1,而且深度每增加一層,機率就掉一個數量級。它可以用統計方式管理。
異常事件則不吃統計。軟體版本不相容造成的共識分裂、客戶端 bug、算力租賃發動的 51% 攻擊,這三種的重組深度沒有上界,只有攻擊成本的上界。它們的頻率低到無法用歷史分佈估計,但單次影響可以清空一個部位。
比特幣 2013 年 3 月那次是最經典的案例。BIP50 的事後報告記錄了 0.7 與 0.8 版本因為資料庫層的隱性限制不同而分裂成兩條鏈,最後靠礦池協調回滾解決,深度大約 24 個區塊,持續約六小時。那不是攻擊,是兩個版本對「什麼叫合法區塊」的理解不一致。
想先補鏈上指標本身怎麼讀的,可以從鏈上籌碼分析入門那五個核心指標開始,本文假設你已經在用這類數據做決策。
各條鏈的重組深度:一張對照表
確認數要設多少,取決於你在哪條鏈上,以及你怕的是哪一種來源。
| 鏈 | 出塊間隔 | 常態重組深度 | 已知極端事件 | 最終性機制 |
|---|---|---|---|---|
| 比特幣 | 約 10 分鐘 | 1,頻率低 | 2013 年版本分裂約 24 個區塊 | 機率性,無明確最終性 |
| 以太坊 PoS | 12 秒 | 1,偶發 | 2022 年 5 月信標鏈 7 個區塊 | Casper FFG,兩個 epoch 後確定 |
| 合併前以太坊 | 約 13 秒 | 1,叔塊率個位數百分比 | 多次客戶端分歧 | 機率性 |
| 高吞吐 EVM 側鏈 | 秒級 | 數個 | 曾出現百個區塊以上的重組 | 依實作,差異大 |
| 小市值 PoW | 依鏈而定 | 1 至數個 | 2020 年 ETC 遭 51% 攻擊,深度以千計 | 機率性,安全預算低 |
「6 個確認」這個慣例不是憑感覺來的。比特幣白皮書第 11 節算過一張表:攻擊者掌握 10% 算力時,等 6 個確認之後他還能追上的機率約 0.024%。這是一個機率結論,不是保證,而且它的前提是攻擊者只有 10% 算力。
以太坊合併後換了一套邏輯。以太坊的權益證明文件說明,區塊經過兩個 epoch(64 個 slot,約 12.8 分鐘)會被標記為 finalized,要推翻它必須讓至少三分之一的質押量被罰沒。最終性在這裡不是「絕對不會變」,是「變的成本被定價成幾百億美元」。
差別很實際:比特幣上的等待是在買機率,以太坊上的等待是在買一個明確的經濟門檻。你的確認數設定應該反映的是這個差別,不是一個到處通用的數字。
鏈重組污染鏈上數據的四條路徑
路徑一:即時警報的重複計算
阿凱去年寫了一支 Telegram 警報機器人,監控大額交易所流入,收到一個確認就推播。今年五月某天凌晨,機器人推了一筆 9,200 BTC 流入某交易所,他照著自己的規則減了三成現貨。
那個區塊在四分鐘後被重組掉。交易本身沒消失,重新打包進了下一個區塊,但被拆成兩筆、時間戳往後推了 11 分鐘。機器人沒有回滾邏輯,於是它把重新出現的交易當成新事件,又推了一次。他當天的日內淨流入統計因此被灌水約 9,000 BTC。
這裡的問題不是警報發錯了,是同一筆錢被計了兩次,而資料庫沒有任何欄位記得這件事。任何用「累加事件」方式建的即時指標,只要沒有處理回滾,都會有這個偏差,而且偏差方向是單邊的,永遠往上灌。
路徑二:回測讀最終鏈,實盤讀未定鏈
這是四條裡面最貴的一條,而且它是前視偏誤的一個變種。
回測從封存節點抓歷史資料,抓到的必然是已經定案的鏈。實盤訂閱區塊頭,看到的是還在競爭中的鏈。回測裡每一筆交易的區塊高度、時間戳、排序都是正確的,因為它們早就塵埃落定;實盤裡這些欄位在幾分鐘內都可能改變。
文婷做過一支 15 分鐘級的交易所流量策略,回測年化 26%,實盤三個月 -4%。逐筆對帳之後,差異不在滑價也不在手續費:約 2.1% 的訊號在產生後的幾分鐘內改變了值,其中大部分是原本落在 bar 邊界附近的交易,重組後被分配到另一根 bar 去了。
比例聽起來很小,但那 2.1% 集中在成交量最大、也就是價格波動最劇烈的時段,因為那正是撞塊機率最高的時候。她把回測改成模擬「一個確認就決策,事後再修正」,年化剩 9%。
路徑三:供應商指標的靜默修正
用第三方 API 的人碰到的是另一個版本。資料商的指標大多建立在自己的索引器之上,索引器處理完重組之後,會把受影響的歷史區間重算並覆寫。
覆寫本身沒錯,錯的是多數 API 不會告訴你哪一段被改過。你今天拉的日線交易所餘額,跟你三個月前拉的同一段,可能不一樣,而且回應裡沒有任何欄位提示這件事。
判斷方法很土但有效:同一段區間,隔一週再拉一次,做差值。 差值不為零的欄位就是會被修正的欄位,差值的分佈就是你該給那個指標的誤差帶。做過一次之後,你對「這條序列可以拿來做多細的決策」會有完全不同的感覺。
想把這套差值檢查、回滾對帳寫成可重複執行的流程,付費實驗室裡有相關的討論串與實作範本,適合已經在跑實盤資料管線的人。
路徑四:執行層的雙花與確認數
前三條講的是資料,這一條講的是錢。
交易所入金、跨鏈橋鎖倉、借貸協議的抵押品認列,全部要決定「等幾個確認才算數」。等太少會吃雙花風險,等太多會拖慢資金週轉,套利與清算的機會窗口通常撐不了那麼久。
2020 年 ETC 遭遇 51% 攻擊時,重組深度以千個區塊計,當時多數交易所的 ETC 入金確認數遠低於那個量級,結果就是資產被雙花。攻擊成本低於可竊取金額的鏈,確認數這個參數本身就保護不了你,真正的防線是部位上限。
處理鏈重組的六個做法
| 層級 | 做法 | 具體實作 |
|---|---|---|
| 訂閱層 | 接收回滾訊號 | 以太坊看 log 物件的 removed 欄位;比特幣用 getchaintips 加上 getblock 回傳的 confirmations = -1 |
| 儲存層 | 三時間戳 | 每筆記錄同時存 block_time、ingest_time、finalized_at,查詢一律指定要哪一種 |
| 儲存層 | 可回滾寫入 | 事件表以區塊為單位可整段刪除,禁止只增不刪的累加式聚合 |
| 指標層 | 分層計算 | 決策指標只在 finalized 高度上算,未確定的部分獨立標記為預覽值 |
| 回測層 | 模擬確認延遲 | 回測強制在訊號時點加上你實盤採用的確認深度,不要用最終鏈直接算 |
| 監控層 | 快照對帳 | 每週把同一區間重拉一次做差值,差值超過門檻就停下來查 |
六個裡面最關鍵的是第二個和第五個。
三時間戳是結構性的解法。 只要寫入的時候被逼著回答「這筆資料什麼時候可得、什麼時候確定」,大部分的重組污染在寫入階段就被擋住了。單時間戳的資料表則相反,它讓污染變成預設值,而你必須靠紀律去對抗預設值。紀律會在趕時間的時候失效。
回測模擬確認延遲則是誠實稅。 以太坊 JSON-RPC 文件提供了 safe 與 finalized 兩個區塊標籤,實盤用哪一個,回測就必須用同一個口徑。文婷後來把整條管線改成只在 finalized 上算指標,訊號因此延遲了約 12.8 分鐘,年化從 9% 再掉到 7%。
代價很明顯,但拿到的東西更值錢:實盤與回測的年化偏差從 13 個百分點收斂到 2 個百分點以內。策略變差了,對策略的估計變準了,而後者才是能拿來配倉位的東西。
什麼時候可以不處理
不是每個場景都需要這一整套。過度工程也是成本。
日線以上的指標,單區塊重組的影響通常小於雜訊。 MVRV、長期持有者供給這類指標的變動量級遠大於一個區塊的差異,為它建一整套回滾管線不划算。
但日界與結算時點是例外。 落在午夜前後的大額轉帳,重組之後可能被算到隔天,月末與季末的統計對這件事特別敏感。這種時候的正確做法不是建管線,是把日界附近的資料標記為不確定,別拿來做單日結論。
深度重組是尾部風險,用倉位處理,不用資料處理。 千個區塊的重組沒有任何確認數設定擋得住。真正的防線是不要在安全預算低的鏈上放超過你願意歸零的金額。
還有一種情況是資料根本不歸你管:用第三方指標做週級以上的判斷時,路徑三的差值檢查比自建索引器實際得多。 知道誤差帶有多寬,跟自己消滅誤差,是兩件成本差幾個數量級的事。
結論:先問這條鏈定案了沒,再問指標說了什麼
把整篇收成五句話。
- 鏈重組是共識層的正常機制,不是故障,但它會讓已經寫進資料庫的鏈上數據在事後改變。
- 影響分三級:交易換位置、換順序、完全消失,分別對應時間序列錯位、事件排序錯誤與記錄消失。
- 常態重組深度幾乎都是 1,可以用機率管理;共識分裂與 51% 攻擊沒有深度上界,只能用部位上限管理。
- 污染鏈上數據的四條路徑是即時警報重複計算、回測讀最終鏈、供應商靜默修正、執行層雙花。
- 處理的核心是三時間戳資料表加上回測模擬確認延遲,一個讓污染難以寫進去,一個讓回測跟實盤講同一種話。
鏈上數據最大的優勢是無法偽造,但無法偽造不等於當下就是確定的。任何一個鏈上訊號在被拿來下決策之前,都應該先回答一個問題:這件事已經定案了,還是只是目前領先? 這兩個答案在歷史資料裡看起來一樣,在實盤裡差很多。
這類資料層的拆解,加上流動性、衍生品結構與鏈上籌碼的例行審視,我每週會整理進電子報。想在自己的研究流程上多加一層濾網的,可以訂閱追蹤。




