區塊鏈系列教程之 位元幣中的共識

2022-01-10 03:34:08 字數 3933 閱讀 2173

目錄總結

在位元幣的p2p網路中是怎麼達成共識的呢?達成共識需要做哪些交易的校驗呢?交易和區塊是怎麼傳播到整個區塊鏈網路的呢?看完這篇文章你就明白了。

之前我在講分布式系統的時候有講過分布式系統的幾個共識演算法,包括raft,paxos和拜占庭容錯演算法。

位元幣的共識和之前講的都不同,它使用的是工作量證明(pow)的演算法。

位元幣的去中心化共識由所有網路節點的4種獨立過程相互作用而產生:

▷ 每個全節點依據綜合標準對每個交易進行獨立驗證

▷ 通過完成工作量證明演算法的驗算,挖礦節點將交易記錄獨立打包進新區塊

▷ 每個節點獨立的對新區塊進行校驗並組裝進區塊鏈

▷ 每個節點對區塊鏈進行獨立選擇,在工作量證明機制下選擇累計工作量最大的區塊鏈

位元幣網路中,交易是由網路中的節點獨立校驗的。

在交易傳遞到臨近的節點前,每乙個收到交易的位元幣節點將會首先驗證該交易,這將確保只有有效的交易才會在網路中傳播,而無效的交易將會在第乙個節點處被廢棄。

每乙個節點在校驗每一筆交易時,都需要對照乙個長長的標準列表:

▷交易的語法和資料結構必須正確。

▷輸入與輸出列表都不能為空。

▷交易的位元組大小是小於max_block_size的。

▷每乙個輸出值,以及總量,必須在規定值的範圍內 (小於2,100萬個幣,大於0)。

▷沒有雜湊等於0,n等於-1的輸入(coinbase交易不應當被中繼)。

▷nlocktime是小於或等於int_max的。

▷交易的位元組大小是大於或等於100的。

▷交易中的簽名數量應小於簽名運算元量上限。

▷解鎖指令碼(scriptsig)只能夠將數字壓入棧中,並且鎖定指令碼(scriptpubkey)必須要符合isstandard的格式 (該格式將會拒絕非標準交易)。

▷池中或位於主分支區塊中的乙個匹配交易必須是存在的。

▷對於每乙個輸入,如果引用的輸出存在於池中任何的交易,該交易將被拒絕。

▷對於每乙個輸入,在主分支和交易池中尋找引用的輸出交易。如果輸出交易缺少任何乙個輸入,該交易將成為乙個孤立的交易。如果與其匹配的交易還沒有出現在池中,那麼將被加入到孤立交易池中。

▷對於每乙個輸入,如果引用的輸出交易是乙個coinbase輸出,該輸入必須至少獲得coinbase_maturity (100)個確認。

▷對於每乙個輸入,引用的輸出是必須存在的,並且沒有被花費。

▷使用引用的輸出交易獲得輸入值,並檢查每乙個輸入值和總值是否在規定值的範圍內 (小於2100萬個幣,大於0)。

▷如果輸入值的總和小於輸出值的總和,交易將被中止。

▷如果交易費用太低以至於無法進入乙個空的區塊,交易將被拒絕。

▷每乙個輸入的解鎖指令碼必須依據相應輸出的鎖定指令碼來驗證。

經過這麼多長長的校驗之後,交易就準備被寫入區塊了。

驗證交易後,位元幣節點會將這些交易新增到自己的記憶體池中。記憶體池也稱作交易池,用來暫存尚未被加入到區塊的交易記錄。與其他節點一樣,挖礦節點會收集、驗證並中繼新的交易。而與其他節點不同的是,挖礦節點會把這些交易整合到乙個候選區塊中。

位元幣節點需要為記憶體池中的每筆交易分配乙個優先順序,並選擇較高優先順序的交易記錄來構建候選區塊。交易的優先順序是由交易輸入所花費的 utxo的「塊齡」決定,交易輸入值高、「塊齡」大的交易比那些新的、輸入值小的交易擁有更高的優先順序。如果區塊中有足夠的空間,高優先順序的交易行為將不需要礦工費。

然後,挖礦節點會選出那些包含最小礦工費的交易,並按照「每千字節礦工費」進行排序,優先選擇礦工費高的交易來填充剩下的區塊,區塊大小上限為max_block_size。

如區塊中仍有剩餘空間,挖礦節點可以選擇那些不含礦工費的交易。有些礦工會竭盡全力將那些不含礦工費的交易整合到區塊中,而其他礦工也許會選擇忽略這些交易。

在區塊被填滿後,記憶體池中的剩餘交易會成為下乙個區塊的候選交易。因為這些交易還留在記憶體池中,所以隨著新的區塊被加到鏈上,這些交易輸入時所引用 utxo的深度(即交易「塊齡」)也會隨著變大。由於交易的優先值取決於它交易輸入的「塊齡」,所以這個交易的優先值也就隨之增長了。最後,乙個零礦工費 交易的優先值就有可能會滿足高優先順序的門檻,被免費地打包進區塊。

在區塊中打包好了交易之後,會將該區塊廣播出去,而接收到區塊的節點就會進行區塊的校驗。

當乙個節點接收到乙個新的區塊,它將對照乙個長長的標準清單對該區塊進行驗證,若沒有通過驗證,這個區塊將被拒絕。

這些標準可以在位元幣核心客戶端的checkblock函式和checkblockhead函式中獲得,它包括:

▷ 區塊的資料結構語法上有效

▷ 區塊頭的雜湊值小於目標難度(確認包含足夠的工作量證明)

▷ 區塊時間戳早於驗證時刻未來兩個小時(允許時間錯誤)

▷ 區塊大小在長度限制之內

▷ 第乙個交易(且只有第乙個)是coinbase交易

▷ 使用檢查清單驗證區塊內的交易並確保它們的有效性

因為區塊鏈是去中心化的資料結構,所以不同副本之間不能總是保持一致。區塊有可能在不同時間到達不同節點,導致節點有不同的區塊鏈視角。解決的辦法是,每乙個節點總是選擇並嘗試延長代表累計了最大工作量證明的區塊鏈,也就是最長的或最大累計難度的鏈。

在第一張圖中,網路有乙個統一的區塊鏈視角,以藍色區塊為主鏈的「頂點」

當有兩個候選區塊同時想要延長最長區塊鏈時,分叉事件就會發生。正常情況下,分叉發生在兩名礦工在較短的時間內,各自都算得了工作量證明解的時候。

兩個礦工在各自的候選區塊一發現解,便立即傳播自己的「獲勝」區塊到網路中,先是傳播給鄰近的節點而後傳播到整個網路。

每個收到有效區塊的節點都會將其併入並延長區塊鏈。如果該節點在隨後又收到了另乙個候選區塊,而這個區塊又擁有同樣父區塊,那麼節點會將這個區塊連線到候選鏈上。

其結果是,一些節點收到了乙個候選區塊,而另一些節點收到了另乙個候選區塊,這時兩個不同版本的區塊鏈就出現了。

假如工作在「綠色」區塊上的礦工找到了乙個「粉色」區塊延長了區塊鏈(藍色-綠色-粉色),他們會立刻傳播這個新區塊,整個網路會都會認為這個區塊是有效的。

所有在上一輪選擇「綠色」區塊為勝出者的節點會直接將這條鏈延長乙個區塊。

然而,那些選擇「紅色」區塊為勝出者的節點現在會看到兩個鏈:「藍色-綠色-粉色」和「藍色-紅色」。

如圖所示,這些節點會根據結果將「藍色-綠色-粉色」這條鏈設定為主鏈,將「藍色-紅色」這條鏈設定為備用鏈。這些節點接納了新的更長的鏈,被迫改變了原有對區塊鏈的觀點,這就叫做鏈的重新共識。

因為「紅」區塊做為父區塊已經不在最長鏈上,導致了他們的候選區塊已經成為了「孤塊」,所以現在任何原本想要在「藍色-紅色」鏈上延長區塊鏈的礦工都會停下來。

全網將「藍色-綠色-粉色」這條鏈識別為主鏈,「粉色」區塊為這條鏈的最後乙個區塊。全部礦工立刻將他們產生的候選區塊的父區塊切換為「粉色」,來延長「藍色-綠色-粉色」這條鏈。

通常來說區塊鏈的分叉可以分為兩種:

硬分叉,是當位元幣協議規則發生改變,舊節點拒絕接受由新節點創造的區塊的情況。違反規則的區塊將被忽視,礦工會按照他們的規則集,在他們最後見證的區塊之後建立區塊。

軟分叉,是當位元幣協議規則發生改變,舊的節點並不會意識到規則是不同的,它們將遵循改變後的規則集,繼續接受由新節點創造的區塊。礦工們可能會在他們完全沒有理解,或者驗證過的區塊上進行工作。

通過硬分叉,區塊鏈早已經不是原來的那個區塊鏈了。

從上圖可以看到,位元幣從最初的的版本已經發展了很多個分叉,他們的本質都是一樣的,問題就在於你到底認可哪條鏈。

區塊鏈之位元幣的潛在激勵

從事這種 工作量證明 的節點被稱為礦工。系統向礦工獎勵位元幣作為工作量的 證明 從而也為這樣的 算力投資 設定了 激勵機制 通過在自己電腦上執行軟體就可以獲利 位元幣 這帶來的第乙個也是最明顯的影響是 一旦位元幣具有足夠的價值,人們就開始大肆挖礦。事實上,為了增強挖礦力度,大部分挖礦工作很快都轉移到...

位元幣 位元幣中的共識協議

在位元幣系統中,hash指標有兩個用途 指向前乙個區塊和指向某筆交易。位元幣支付過程中,每筆交易都必須包含輸入和輸出。在交易時,首先會從區塊中驗證交易輸入,驗證通過後才會執行交易輸出。這一步可以防止 雙花 攻擊。區塊鏈是乙個去中心化的分布式賬本,既然是分布式,那就需要網路中的各個節點對賬本資訊達成共...

BTC 位元幣的共識協議(區塊鏈技術與應用)

怎麼驗證交易的合法性,防止雙花攻擊 由所有使用者來共同維護,這個資料結構是區塊鏈 位元幣系統中每個交易都分為輸入部分和輸出部分,輸入部分要給出這筆交易的位元幣的 以及付款方的公鑰,輸出部分要給出收款人的公鑰的雜湊值。位元幣系統中的收款位址就是收款人的公鑰取雜湊再經過一些轉換得到的。位元幣中的全結點要...