鏈重組與鏈上數據:回滾如何污染訊號與回測

鏈重組會把已經寫進資料庫的交易回滾,回測讀最終鏈、實盤讀未定鏈。本文拆解重組機制、各鏈深度分佈、四條資料污染路徑,以及六個可執行的處理做法。

你的鏈上警報昨天推播了一筆 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 文件提供了 safefinalized 兩個區塊標籤,實盤用哪一個,回測就必須用同一個口徑。文婷後來把整條管線改成只在 finalized 上算指標,訊號因此延遲了約 12.8 分鐘,年化從 9% 再掉到 7%。

代價很明顯,但拿到的東西更值錢:實盤與回測的年化偏差從 13 個百分點收斂到 2 個百分點以內。策略變差了,對策略的估計變準了,而後者才是能拿來配倉位的東西。

什麼時候可以不處理

不是每個場景都需要這一整套。過度工程也是成本。

日線以上的指標,單區塊重組的影響通常小於雜訊。 MVRV、長期持有者供給這類指標的變動量級遠大於一個區塊的差異,為它建一整套回滾管線不划算。

但日界與結算時點是例外。 落在午夜前後的大額轉帳,重組之後可能被算到隔天,月末與季末的統計對這件事特別敏感。這種時候的正確做法不是建管線,是把日界附近的資料標記為不確定,別拿來做單日結論。

深度重組是尾部風險,用倉位處理,不用資料處理。 千個區塊的重組沒有任何確認數設定擋得住。真正的防線是不要在安全預算低的鏈上放超過你願意歸零的金額。

還有一種情況是資料根本不歸你管:用第三方指標做週級以上的判斷時,路徑三的差值檢查比自建索引器實際得多。 知道誤差帶有多寬,跟自己消滅誤差,是兩件成本差幾個數量級的事。

結論:先問這條鏈定案了沒,再問指標說了什麼

把整篇收成五句話。

  1. 鏈重組是共識層的正常機制,不是故障,但它會讓已經寫進資料庫的鏈上數據在事後改變。
  2. 影響分三級:交易換位置、換順序、完全消失,分別對應時間序列錯位、事件排序錯誤與記錄消失。
  3. 常態重組深度幾乎都是 1,可以用機率管理;共識分裂與 51% 攻擊沒有深度上界,只能用部位上限管理。
  4. 污染鏈上數據的四條路徑是即時警報重複計算、回測讀最終鏈、供應商靜默修正、執行層雙花。
  5. 處理的核心是三時間戳資料表加上回測模擬確認延遲,一個讓污染難以寫進去,一個讓回測跟實盤講同一種話。

鏈上數據最大的優勢是無法偽造,但無法偽造不等於當下就是確定的。任何一個鏈上訊號在被拿來下決策之前,都應該先回答一個問題:這件事已經定案了,還是只是目前領先? 這兩個答案在歷史資料裡看起來一樣,在實盤裡差很多。

這類資料層的拆解,加上流動性、衍生品結構與鏈上籌碼的例行審視,我每週會整理進電子報。想在自己的研究流程上多加一層濾網的,可以訂閱追蹤。

個人頭像照片
AD.Trader Lab

AD.Trader Lab 創辦人 | 量化交易員 專注於在充滿雜訊的市場中,尋找數學上的必然性。AD.Trader Lab 實驗室主理人,帶你用數據看透漲跌背後的真相。

每日更新 · 免費

每日選幣清單

我每天在 Telegram 發一份選幣名單——標的、為什麼選它、我自己有沒有進場。

  • 每日選幣名單,附上選它的理由
  • 新文章與研究上架,第一時間通知
  • 討論區:有問題可以直接問我
免費加入 Telegram

340+ 人已經在頻道裡

已經在交易了?用我的連結註冊 OKX,手續費終身退 20% 月成交 20 萬 U,一年約退你 NT$6,000 — 交易越多退越多