1. 程式人生 > >以太坊中的Ghost協議

以太坊中的Ghost協議

Ghost協議的引入

與比特幣中區塊鏈出塊時間相比,以太坊區塊鏈中將出塊時間從10分鐘提升到15秒,這是一個巨大的提升,然而同時帶來了一個問題,那就是區塊的共識問題。在15秒的時間內,一個新發布的區塊很很大可能還沒有擴散到整個區塊鏈網路。在這種情況下,如何達到比特幣中的共識協議,如何才能更好的遵守“鏈長為王”——最長的鏈會被認為主鏈呢? 因為以太坊極大提升了出塊時間,這引起的一個明顯的問題就是頻繁的區塊鏈分叉問題,在15秒內很大可能有多個節點同時挖出一個區塊,這些節點到底誰挖出的區塊才能成為主鏈呢? 如果繼續沿用比特幣中的區塊獎勵方法,假如幾乎在同時有多個礦工挖出了一個區塊,此時網路中佔據較大算力的礦池其算力巨大,而且通常地理位置優越,其網路與更多的節點相連,它釋出的區塊能跟更快的在網路中傳播,因此在出現區塊鏈分叉時,其所在的分叉更有可能成為主鏈。這種情況下,其他算力較低的礦池或者個體節點就不能得到出塊獎勵,在以太坊中經常發生區塊鏈分叉的情況,但最後區塊鏈的出塊獎勵大部分情況下都被大型礦池拿走,而算力小的節點通常很少拿到獎勵,這種情況叫做“Centralization Bias”。 如果以太坊沿用比特幣中的出塊獎勵方式,算力較小的礦池幾乎拿不到出塊獎勵,這個看起來不太公平,長此以往,算力小的礦工挖出區塊之後就不願意合併到算力強的礦工挖出的區塊鏈中,因為合併就意味著前面的勞動全部白費了,還不如不要合併,繼續在自己挖出的區塊上繼續挖礦,說不定運氣好能超過算力強的區塊呢。很明顯,這樣下去不利於區塊鏈出現分叉後快速合併,會影響到區塊鏈的共識,基於上述原因,以太坊的設計中引入了Ghost協議。

Ghost協議詳情

在以太坊中區塊分叉是一個司空見慣的情況,因此區塊鏈發生分叉之後儘快合併以維護區塊鏈的統一顯得尤為重要。在上圖中,假設一個大型礦池A打包了一個黑色的3號區塊,並將3號區塊flooding傳送出去,告知其他礦工3號區塊已經被A挖掘出來了。以太坊中的出快時間是15秒,在15秒內這個3號區塊並沒有完全擴散到整個區塊鏈網路中,因此其他沒有收到這個區塊的節點會繼續挖掘3號區塊。釋出了3號區塊之後A繼續挖4號區塊,在此過程中A陸續收到了其他節點挖出的3號區塊的通知,上圖中假設A收到了來自其他四個節點發布的3號區塊(上圖中灰色表示,分別是3A、3B、3C和3D),A收到這四個區塊之後菊花一緊,意識到必須儘快挖出4號區塊以證明自己所在的鏈才是主鏈,讓他們在A釋出的3號黑色區塊上繼續挖掘4號區塊。有什麼辦法讓其他節點認同併合併到A釋出的3號區塊呢?
A在正在挖掘的4號區塊中新增上了2筆鑄幣交易(為什麼是2筆,因為以太坊規定每個區塊最多包含2個對叔父區塊的獎勵),著2筆鑄幣交易分別給了釋出了3A和3B區塊的礦工,兩筆交易的價值分別是出塊獎勵的7

8\frac{7}{8},A自己本身因為招安了兩個分叉區塊,除了出塊獎勵之外,可以額外得到出塊獎勵的132\frac{1}{32}。這些資訊修改完畢之後,A繼續開始玩命挖礦,因為A是一個較大的礦池,擁有很強的算力,所以A很快的挖到了4號區塊。當A將4號區塊釋出出去後,一些節點還在挖掘4號區塊或者3號區塊的節點(尤其是3A和3B區塊所在的礦工)收到這個區塊後,立刻停下來檢查A釋出的4號區塊的合法性,驗證通過後都會停下手頭的挖礦工作,認為A釋出的4號區塊最長合法鏈,於是繼續在A釋出的4號區塊之後開始挖礦。
對於3A和3B來說,為什麼會放棄原本的區塊鏈而轉到A所在的4號區塊上繼續挖礦呢?因為他們分別獲得了出塊獎勵的7
8\frac{7}{8}
,和A繼續競爭主鏈成功的概率不大,苦苦掙扎不如坦然接受招安,於是釋出3A和3B的區塊就繼續在4號區塊之後挖礦。
而3B和3C也是幾乎和3A、3B同時釋出的區塊,3A和3B區塊得到了獎勵,3C和3D難道就要被主鏈拋棄了嗎?辛辛苦苦挖礦到頭來毛都沒有,這也不合適呀。以太坊設計的時候就想到了這種情況,一個區塊上的分叉會出現很多個,因此在4號區塊之後的5號區塊,可以繼續選擇招安主鏈上的兩個分叉區塊,但最多招安2個分叉區塊。於是5號節點的鑄幣交易中分別轉給釋出3C和3D區塊的兩個礦工出塊獎勵的68\frac{6}{8},是的,沒有看錯,3C和3D的獎勵和比3A和3B少了18\frac{1}{8},這是為什麼呢?因為3C和3D是4號區塊的uncle 區塊,但是對於5號來說,和3C、3D的距離增加了2代,因此5號區塊轉給3C和3D的區塊獎勵就會少28\frac{2}{8}。而5號區塊也樂意參加招安工作,除了出塊獎勵之外,還可以得到額外132\frac{1}{32}的出塊獎勵,不需要做很多工作就可以拿到一些獎勵,豈有不招安之理?
整個區塊中的Ghost協議是如何儘快招安分叉區塊以組成統一的區塊鏈,其過程用下圖解釋。

上圖中,礦工挖掘第N+8個區塊的時候,搜尋主鏈上還沒有被招安叔父區塊,給這些挖出分叉叔父區塊的礦工給予一定的獎勵。叔父區塊距離第N+8個區塊越近,其礦工得到的獎勵越多。最近的叔父區塊(灰色的N+7號區塊所在的礦工)可以拿到78\frac{7}{8}的出塊獎勵,每隔一代,區塊獎勵就會減少18\frac{1}{8},直到間隔8代以後的叔父區塊不再獲得獎勵。在這個過程總,每個區塊最多招安2個叔父區塊。因此,在以太坊中,每個區塊的出塊獎勵是:

$包含的叔父區塊個數(最大為2) \times \frac{1}{32} \times 出塊獎勵+ 出塊獎勵 $

而每個叔父區塊被包含之後最多得到78\frac{7}{8}的出塊獎勵,最少為0。值得注意的是,這些叔父區塊後面繼續挖掘出來的區塊不會得到任何獎勵,這是為了激勵其他區塊在發現最長的區塊鏈之後儘快進行合併。

總結

  • 以太坊區塊鏈中7代及其以內的叔父區塊都能得到獎勵,超過7代的叔父區塊將不會得到獎勵,這樣是為了避免有些礦工專門在之前的鏈上製造分叉後坐等被後面的節點招安情況。

  • 以太坊中的出塊獎勵不會隨著區塊數量的增多而減少,以太坊中無論何時出塊都會獲得出塊獎勵,而比特幣中區塊的樹目超過兩千一百萬以後就沒有出塊獎勵,此後礦工挖礦的動力來自於交易費了。