區塊鏈的 consensus

區塊鏈是個很有趣的技術。大基本概念是把原本只有一份的帳本(或者可延伸成其他紀錄),複製成每個節點都有一個副本,然後每個節點都會驗算正確性,來防止一定節點的失效或攻擊。

所以最大的問題就是要解決當不同節點資料有衝突時,該怎麼處理?這也就是所謂的拜占庭問題了。目前主流的區塊鏈有兩種做法:一種是 Bitcoin 的 POW (Proof of Work),而另一種是類似 PBFT (Pratical Byzantine Fault Tolerance),而這些就是所謂的 Consensus Algorithm。

POW 的做法原理是讓每次要產生 Block 都要付出一定成本,要能算出某種 hash (可以想成是丟某種骰子,但有超級無敵多面,然後要丟出其中一面 )才能被全網認可。所以想來亂的人也得要有付出(可能是算 hash 的電力或機器成本等)才能攻擊整個系統,要算力有辦法超過整個網路 51% 才有可能有機會攻擊。然而因為每個節點都可以當 miner 來產生 Block,所以需要處理如果網路上有人同時算出了 Block 怎麼辦?目前的做法意外的簡單,彼此會遵守一個共同規則:每個節點會認 Block 數量最多(最長)的 Chain 當成主鏈。然後當兩個衝突的 Block 出現時,看他們分別在哪條 Chain 上,哪個長,就相信哪個。若平手就繼續等,看看其他人選哪條鏈繼續接,遲早有一條會比較長,另一條就會被網路捨棄。換句話說,每個節點所相信的主鏈,可能會隨著收到的資料不同而有更改,也就是所謂的 Fork。

PBFT 概念的做法則是:全網會先挑選出一個領導者,每一次要產生 Block 時,由他發號施令,然而其他節點仍然會驗證該領導者所發號的施令合不合邏輯,若不合理就趕他下台。藉由換領導者的方式來保障不會被惡意節點攻擊,該演算法的保障是只要少於 1/3 個節點是惡意的就不會有問題。

兩個做法各自有各自的好處。

POW 最大的好處是節點的擴展很容易。每個節點都可以當 miner 來產生 Block,只要他能夠算出 hash (Proof its work)。只是它就沒有對節點數量的強保障,保障是放在算力上。除此之外,他的保障還是某種機率型的保障。如剛剛所提到,若同時網路上有兩個 Blocks 被產生,一開始大家可能會選擇接受不同的 Block,也就是每個節點當下所相信的事實是可能不同的,需要等時間來提升保障,等一段時間看看網路上的其他節點在那一剎那,選擇了哪個 Block 繼續往下接。而當一個 Block 後面被放入越來越多的 Blocks 之後(也就是所謂的 confirmation ),大概就很難有其他條 Chain 來翻轉這個 Block 了,因為大家會遵守最長 Chain 的規則。所以在 POW 的世界裡,要看一筆交易是不是穩固了,除了被放進 Block 以外,還要看那個 Block 的 confirmation 數量(後面接了多少 Block 了),只能說越多要被翻轉的機率就越低。

相對的,類 PBFT 要增加節點就相對比較麻煩,因為他們基本上是一個每個節點都必須相連的網路,每個節點都有可能成為領導節點,也都需要跟其餘的節點進行溝通。POW 的話新節點加入只需要跟整個網路有部分相接就夠,哪怕只是跟一個節點也行。然而,類 PBFT 的好處是快速,而且非機率型保障。在 PBFT 的世界裡,省掉了算 hash 的大量時間,而且每個時候只會有一個領導節點,所以不會有同時出現複數 Block 的問題,也就不需要靠 confirmation 數量來保障機率。

目前我的個人感覺是,如果是希望有條 public chain,當然是越多節點越好,可能用 POW 的方法就比較適合。然而若是企業內部,或企業聯盟想要使用 blockchain 的話,若節點數相對來說不多的話,也許使用類 PBFT 是比較適合的。

後記:其實原本想打的是關於區塊鏈實用化的問題與挑戰,結果發現好像最好先解釋一下 consensus 和一些基本問題XD。之後應該還是會繼續寫,到時會更詳細的說明兩種演算法在實用上的問題,當然,還會有其他問題也被討論。

Show your support

Clapping shows how much you appreciated Lin Po-An’s story.