區塊鏈 Blockchain – 共識機制之工作量證明 Proof-Of-Work

/ 0 評 / 15

在區塊鏈系統中,分散式網絡中各節點,需要透過共識機制去決定以哪個節點所生成區塊為系統中的新區塊,而工作量證明 Proof-Of-Work (POW) 就是其中一種。

工作量證明 Proof-Of-Work (POW)

顧名思義,工作量證明就是用來證明你做了一定量的工作,可用工作成果來證明完成相應的工作量。

簡單來說,在現實生活中,你通過了完成一系列課程得到的課程證書,其他人也可以從你這張證書中知道你是曾經完成了這一系列的課程。

歷史

工作量證明(POW),1993 年由 Cynthia Dwork Moni Naor 提出,POW 被用於阻止拒絕服務攻擊(DDOS)、反垃圾郵件等一些服務濫用的經濟對策。

第一个POW 應用是1996Adam Back 開發的 "Hashcash" 應用,它採用工作量證明共識機制來過濾垃圾郵件,微軟也將其應用在 Hotmail, Exchange, Outlook 等電郵服務上。具體做法是要求所有收到的郵件都使用強 POW 附件。此系統使得垃圾郵件發送者在大量發送郵件時在經濟成本上不可行,但卻允許個人在需要的時候互相發送信息。時至今日這種算法也被賦予新的意義,即以"挖礦"形式作為比特幣安全核心。

工作量證明(POW)共識機制算法採用了SHA-256 運算 Hash 值,特點是難以運算,卻容易驗證。

我們知道改變 Hash 值的原始數據中的任何一部份,所產生的 Hash值也會隨之變化,因此我們只需在運算 Hash 值時,加入一個不斷改變的隨機數,亦總是可以計算出以 0 開頭的 Hash 值。所以要找到符合要求的區塊 Hash 值,則需要經過進行大量運算,運算時間取決於節點的運算速度。當某個節點提供出一個符合要求的 Hash值,就說明該節點確實經過了大量的嘗試運算。當然,並不能代表說已進行了多少次運算的次數,因為尋找符合要求 Hash值是一個概率事件。

換言之,當節點擁有佔全網 N%的算力時,該節點即有 N/100的概率找到符合要求的 Hash值。

看以下的例子就會清楚:

我們首先確定一個字符串:“Samson's blog-:“ 及驗證結果的條件:在這個字符串後增加一個叫個Nonce整體值(隨機數),然後對整個字符串進行SHA-256 運算,運算出正確的Hash值結果,且符合難度值,是以"000開頭的"。如果運算出來的Hash值不符合要求,則通過遞增Nonce的值,重新運算。

開始運算:

[cce]

Samson's blog-:0 1d4256cbf78a0dd19a70187009ab37f3d90e273d184c37fa20512c0a4c0b348f

Samson's blog-:1 7443a7f641c853daa7e869e7adf45391ae061bdb78785f45455617aee370182f

Samson's blog-:2 67bf130ec93610c29d73fecfc5858fbdc27881bbbdc298b141b6fa8f5254b026

:

:

Samson's blog-:1577 000cea98062b7a38be7333fdfedcd6093624e1c3b9148ec8d52379c6015bde1e[/cce]

按照以上的條件,我們經過運算了1577次後找到符合條件(前3位為0)的Hash值。

那為什麼條件是以000開頭,那000000000開頭可以嗎?

3位為0只是這個例子的設定。其實在比特幣在生成區塊的過程中,一個符合要求的區塊 Hash 是由N個前導零構成的,而零的位數就取決於當時網絡中的難度值,也就是說,前導零的位數越多,就代表越難。

SHA-256生成的 Hash值都為256 位元,Hash值是由數字和大小寫字母構成的字符串,每一位有62種可能性(可能是 26個大寫字母、26個小寫字母,10個數字中其中一個),假設任何一個字符出現的概率是均等的,那麼第一位為0的概率是1/62,理論上需要嘗試 62次Hash運算才會出現一次第一位為0的情況,如果前兩2位為0,就得嘗試62的平方次Hash運算,以N個0開頭就需要嘗試62的N次方次運算。

所以

如果要達到以0000開頭的 Hash值,理論上要嘗試 62^4 = 14776336 次。

如果要達到以00000開頭的 Hash值,理論上要嘗試 62^5 = 916132832 次。

當然並不是純粹算有幾個前導零就解決了,否則每次難度值的調整就只能以2 的次方倍數來進行,實作上採用小於目標值的方式能更精確地調整難度值。

當前最新運算量分析(截至 2018-02-09 20:00)

根據 https://blockchain.info 上最新的區塊顯示Hash值有180開頭,理論上需要嘗試6218次方次,這個數字是非常龐大的。如此大的運算量需要投入大量的運算設備、電力。

驗證

當節點找到了滿足條件的 Hash值,就會立即廣播全網打包好的區塊,其他節點收到廣播的打包區塊,之後其他節點怎麼驗證這個 Hash值?很簡單,只需對這個字符串做一次SHA-256 運算,得到Hash值,而且符合難度值,則視為驗證通過。

如果驗證通過,則代表已經有節點成功打包區塊,其他節點就停止不再為當前區塊打包,而是轉為接納這個區塊,並加入到自己的帳本中,然後參與下一區塊的競爭(挖礦)。

如果驗證不通過,將代表節點廣播的打包區塊有問題,可能是區塊被修改或者其他違規行為,其他節點將直接扔掉這個區塊,這個區塊則無法記錄到總賬本中,而該節點所消耗的運算成本就浪費了。正正因為這樣,所有節點都自覺自律地遵守共識機制,從而保障了整個系統賬本唯一性及安全。

比特幣與工作量證明

在區塊鏈採用POW共識機制的應用中,比特幣是其中最具有代表性的。

而比特幣共識協議則主要是由 工作量證明最長鏈機制 兩部分組成。

在比特幣區塊鏈系統中,不斷有交易產生,而且每隔一個時段(10分鐘,其他區塊鏈系統並不一定相同)系統就會將就會將某個節點(伺服器)在這段時間的交易記錄打包生成一個區塊,再追加到最長的區塊鏈中並給予該節點獎勵(新區塊獎勵及交易費收益)。但是,區塊鏈中有這麼多個節點,加上吸引的獎勵,引致大家爭相記賬,從而會出現記賬記錄不同的問題,哪最後到底是以哪個節點為準呢?

比特幣系統引入工作量證明來解決這個問題,規則如下:

1. 一段時間內(10分鐘左右)只有一個節點可以記賬成功;

2. 通過工作量證明競爭獲得唯一記賬權;

3. 其他節點複製記賬結果;

不過在進行工作量證明之前,記賬節點會做進行如下準備工作:

1. 收集廣播中還沒有被記錄賬本的原始交易信息;

2. 檢查每個交易信息中付款地址有沒有足夠的餘額;

3. 驗證交易是否有正確的簽名;

4. 把驗證通過的交易信息進行打包記錄;

5. 添加一個獎勵交易:給自己的地址增加 12.5 比特幣;

6. 如果節點爭奪記賬權成功的話,就可以得到 12.5 比特幣的獎勵;

為什麼是獎勵是 12.5 比特幣?

中本聰所開發的比特幣系統只會發行2100萬個比特幣,為鼓勵外界開發儲存及處理比特幣交易的區塊,系統提供了挖掘區塊的獎勵,區塊獎勵從2009 年開始每個區塊可獲得50個比特幣的獎勵,但此一獎勵區塊回報每產出21萬個區塊減半一次,即每四年減半,2013年到20166月則是25個比特幣,20167月9日區塊獎勵再度折半到12.5個比特幣,估計到2021年時會再度折半到6.25個,在2022 年中就會挖出超過90%,因為比特幣最小單位是0.00000001(10^-8)元,所以2140 年之後區塊獎勵就會小於最小單位,也就是挖礦獎勵只有剩下手續費,同時將不再有新的比特幣產生,最終流通中的比特幣將總是略低於2100萬個。這也是比特幣系統中避免貨幣發行太多或太快、用來抑制通貨膨脹的機制。

工作量證明關鍵的三個要素分別是工作量證明函數、區塊及難度值。

1. 工作量證明函數(SHA-256)-這道題的計算方法;

2. 區塊(Block)-這道題的輸入數據;

3. 難度值(Difficulty)-這道題的所需要的計算量;

區塊的大致結構如圖所示:

比特幣的區塊由區塊頭及該區塊所包含的交易列表組成,而擁有80字節固定長度的區塊頭(當中亦包括上一個區塊的 Hash值),就是用於比特幣工作量證明的輸入數據。

因此,為了使區塊頭能體現區塊所包含的所有交易,在區塊的構造過程中,需要將該區塊要包含的交易列表,通過Merkle Tree算法生成Merkle Root Hash,並以此作為交易列表的摘要存到區塊頭中。

關於區塊的詳細介紹及Merkle Tree算法可參閱上一篇:區塊鏈 Blockchain – 創世區塊、區塊、Merkle Tree、Hash

"挖礦"有三個重要功能:

1. 發行新的比特幣(在達到發行總數之前,比特幣上限為 2100萬個);

2. 維持貨幣的的支付功能;

3. 通過算力保障系統安全;

現實例子:金礦消耗資源將黃金注入流通經濟。比特幣通過"挖礦"完成相同的事情,只不過消耗的是運算時間及能源。

難度值(Difficulty

難度值是節點(礦工)們在挖礦時候的重要的參考指標,它決定了礦工大約需要經過多少次 Hash 運算才能產生一個符合要求的區塊。比特幣區塊大約每10分鐘生成一個,如果要在不同的全網算力條件下,新區塊的產生保持都基本這個速率,難度值必需根據全網算力的變化進行相應的調整。

簡單而言,難度值被設定在無論挖礦能力如何,新區塊產生速率都保持在10分鐘一個。

難度值的調整是在每個完整節點中獨立自動發生的。

2016個區塊,所有節點都會按統一的公式自動調整難度值,這個公式是由最新 2016 個區塊的花費時長與期望時長(期望時長為20160分鐘即兩周,是按每10分鐘一個區塊的產生速率計算出的總時長)比較得出的,根據實際時長與期望時長的比值,進行相應調整(或變難或變易)。

換言之,如果區塊產生的速率比10分鐘快則增加難度,比10分鐘慢則降低難度。

這個公式可以總結為如下形式:

新難度值 = 舊難度值 * ( 過去2016個區塊花費時長 / 20160 分鐘 )

同時比特幣工作量證明需要有一個目標值,計算公式如下:

目標值 = 最大目標值 / 難度值

其中最大目標值為一個恆定值:0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

則目標值的大小與難度值成反比。

所謂挖到礦就是猜到一個 Nonce 值讓該區塊的摘要值小於一個會根據難度而線性調整的目標值,這就是工作量證明機制(Proof-of-Work

優缺點

在說優點之前,先說缺點

1. 浪費算力,耗能巨大

POW設計最初是希望大家能使用分散的運算資源,讓每個比特幣的參與者都可以使用自動的電腦進行挖礦,以公平參與來獲得比特幣獎勵。

不過,後來大家都知道,由於比特幣的吸引力,造成很多人為了增大獲得比特幣獎勵的機率,從最初

個人礦工用一般桌機(使用 CPU)就能挖到礦;

利用顯示卡的繪圖處理器(Graphic Processing Unit, GPU)可以加速數十到數百倍;

利用「場式可程式閘陣列」(Field Programmable Gate Array, FPGA 的硬體更可以加速一級;

特殊應用積體電路(Application-Specific Integrated Circuit, ASIC)的礦機、礦池甚至可以達到數百GH/s

礦池:礦工聯合起來組成礦池進行挖礦,收益將以礦工的算力按百分比來分成;

每次找到符合條件的 Hash值,繼而生成新區塊難度值就會隨增時間而增加,也造成生成新區塊的時間亦大大增加,因此大規模運算會消耗龐大的電力能源,而且在運算上的目的只是為了運算出POW,非常浪費。

2. 區塊的確認時間難以確認

由於工作量證明需要消耗大量的算力,同時比特幣大約 10分鐘 才會產生一個區塊,區塊大小只有 1MB,僅僅能夠包含 34000 筆交易,平均下來每秒只能夠處理 5~7(個位數)筆交易,所以比特幣網絡的擁堵狀況非常嚴重,區塊確認的時間難以確認。

3. 算力中心化

比特幣,應該說是區塊鏈應用中,分散式這個概念很重要,由於貪婪而誕生的具備龐大算力的礦池,令到先行的少數人擁有龐大且集中的算力,從而令後來者無法公法參與,將令到原來分散化的比特幣網絡中的"無關鍵中心化"逐漸失去特性,即使分叉,這個問題仍不能有效解決。最大礦池最高已經超過40%雜湊率,而且前兩大礦池合起來也常常超過51%。若是前兩大礦池聯手作弊就能主導區塊鏈的生成,甚至製造不實的交易資訊,造成信心破產,系統就會崩解。

4. 新的區塊鏈必須找到一種不同的散列算法,否則就會面臨比特幣的算力攻擊;

5. 容易產生分叉,需要等待多個確認;

6. 遠沒有最終性,需要檢查點機制來彌補最終性;

 

優點

1. 算法簡單,容易實現;

2. 節點間無需交換額外的信息即可達成共識;

3. 破壞系統需要投入極大的成本;

正正是因為它的缺點:工作明證明的成本太高,這也是為何我先說缺點再說優點的原因之一;

全球礦工每秒產生數十億的 Hash 值(10 ^ 18 1 Exahash)。用現有的硬件計算十億哈希,消耗0.11焦耳的能量。因此,全球每秒鐘使用約十億瓦(GW /秒)創建一種有效的工作量證明。儘管電力成本在全球範圍內變化,但是這個過程每小時消耗的能源價值也能夠佔到約$ 50,000。但是,這雖然是極大的浪費,但卻是必需的。因為是為了阻止攻擊者輕易偽裝成數以百萬計的節點,並控制網絡。在沒有其它選擇的情況下,透過這種工作量證明的"浪費"從而獲得一種"無關鍵中心化""半匿名"的而允許所有人都能夠幾乎免費即時發送現金到其它人的全球貨幣網絡來說,這個代價可能是值得的。在2009年的當時,工作量證明確實是唯一的選擇。

 

總括來說,工作量證明共識機制是目前唯一接受了實戰檢驗的公有鏈算法,雖然其缺點浪費算力,但其實這種"浪費"也是達到分散化的效果而言是必需的,至於算力中心化確實是個大問題;工作量證明背後的規則、流程等都是在實戰區塊鏈的開發及了解其他共識機制前要非常清楚了解的,這對理解區塊鏈來說是一個很重要的基礎知識。

 

參考資源:

分布式一致性與共識算法

比特幣如何挖礦(挖礦原理)-工作量證明

POW和POS共識算法簡介

共識機制

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *