區塊鏈的帳本要如何維持一致性是相當重要的問題,所謂的分叉,是指紀錄區塊鏈帳本的節點,對帳本的共識出現分歧,簡單來說,又是全網出現兩種或多種版本的帳本,這時就必須依賴所謂的「鏈分叉選擇規則(fork choice rule)」,透過規則的設計,促使礦工們達成共識,在不同帳本中選擇一份作為該區塊鏈的權威帳本。而區塊鏈分叉又分為自然產生的「臨時性分叉」,以及區塊鏈版本升級時所導致的「硬分叉」,本文將著重探討「臨時性分叉」的原因與解決方式。
區塊鏈分叉:臨時性分叉的原因
在 PoW 的共識機制中,礦工會互相競爭,解出一道題目,誰先解出來,誰就有下一個區塊的記帳權。問題來了,有沒有有兩個礦工同時解出題目,同時產生新區塊呢?
答案是,有可能。因為這道題目是隨機的,而且網路是異步的,勢必會有礦工因為同時解出題目,因而同時產出新區塊,此時雙方便會各自廣播自己挖到的新區塊到網路上給其他節點驗證,節點驗證過後,便會認可該區塊為新區塊。
以上圖為例,甲節點(圖上可能要標記)挖出了C區塊,乙節點(圖上可能要標記)挖出D區塊,同時廣播到網路中驗證,我們說過,網路的信息在傳遞上不會同步,會有延遲的可能,因此網路中的狀態就會變成:
C隊→先接收到C區塊的節點會認可C為新區塊 (否定D區塊,並將其放在孤塊 池中)
D隊→先接收到D區塊的節點會認可D為新區塊 (否定C區塊,並將其放在孤塊池中)
區塊鏈分叉-最長鏈共識
此時礦工之間就會產生分歧,區塊鏈狀態就會長這樣:
以上圖為例,A是B的前一個區塊,又稱為「父區塊」,現在出現一個情況,C跟D區塊都同時以B作為父區塊被廣播到全網,問題來了,接下來的礦工應該要以哪一個區塊做為父區塊,繼續往下延伸呢?就是所謂的區塊鏈臨時分叉,在比特幣 PoW 算法網路中的共識規則是這樣的:
如果分叉情況出現,那麼網路上的人們繼續保持兩個分支,一但其中一個分支累積的工作量超越另一個分支,任何情況下,節點只在累計工作量多的那條鏈上工作。
簡單來說C隊以C區塊為父區塊繼續挖礦,D隊以D區塊繼續挖礦,哪一隊先挖出第二個區塊,全網便認定其為主鏈,這就是所謂的「最長鏈共識」。
以上圖為例,假設D隊率先挖出E區塊,並廣播至全網給其他節點驗證,C隊接收到E區塊後,便會將D區塊從孤塊池中取出,並以D分支作為主鏈 (因為C分支已經不是最長鏈),C區塊便成為孤塊。
你可能會好奇,為什麼C隊的礦工要乖乖遵守最長鏈共識,因為在正常狀況下,大多數礦工都會選擇按照共識規則工作,如果有礦工選擇在較短的那條分支挖礦,即便挖出新區塊,也不會被大多數礦工認可,自然也拿不到獎勵,因此在正常情況下,理性礦工都會選擇遵循「最長鏈共識」。
區塊鏈分叉對交易的影響
遇到分叉時,短鏈區塊內驗證的交易若尚未被長鏈驗證,那會發生什麼事?我們來看看中本聰本人的解釋
如果短鏈的交易不在長鏈裡,會重新被放進交易池(內存池),等待礦工打包進入後面的區塊,該筆交易的確認數也會重新計算。這就是為什麼比特幣需要等待六個區塊,才能完全確認交易,因為一般來說,用戶不會知道區塊鏈是不是處於分叉狀態,如果包含交易A的區塊在下一個區塊後,成為孤塊,交易A除了可能需要重新驗證之外,還會有面臨雙花攻擊的風險。
至於為什麼是六個區塊,這其實並不是硬性規定,有些交易所只要有兩個確認或三個確認就能夠成功入帳了,六個確認所代表的是該交易在全網共識中處於安全狀態。當然六這個數字也是經過計算得來的,詳情請見比特幣白皮書。
區塊鏈分叉:硬分叉不適用「最長鏈共識」
以上介紹的,是區塊鏈在自然情況下產生的臨時性分叉。若區塊鏈因為版本更新,抑或是社群共識分裂而產生「硬分叉」時,由於硬分叉本身不是在自然情況下發生且過程中涉及礦工的意識選擇,因此無法單純透過「最常鏈共識」解決分叉問題,詳情請見下一篇文章「硬分叉與軟分叉」。
*本文由 AMIS 首席科學家 – 陳昶吾博士協助審閱