談到雜湊演算法,每個程式設計師都不陌生,但是談到比特幣共識演算法PoW,如果沒有接觸過的技術人員可能覺得應該會很複雜,畢竟全球的比特幣節點數量如此龐大,達成共識的演算法應該不會很簡單。但其實如果你已掌握雜湊演算法,幾分鐘內你就能理解PoW。為了更好的說明PoW的原理,我們再把雜湊演算法及相關概念描述一下:
雜湊函式相關概念
- 雜湊函式——是一類數學函式,可以在有限合理的時間內,將任意長度的訊息壓縮為固定長度的二進位制串,其輸出值稱為雜湊值。
- 碰撞定義——是指兩個不同的訊息在同一雜湊函式作用下,具有相同的雜湊值。
- 雜湊函式的安全性——是指在現有的計算資源(包括時間、空間、資金等)下,找到一個碰撞是不可行的。
- 抗弱碰撞性——對於給定的訊息\(M_1\),要發現另一個訊息\(M_2\),滿足\(H(M_1)=H(M_2)\)在計算上是不可行的。
- 抗強碰撞性——找任意一對不同的訊息\(M_1\),\(M_2\),使\(H(M_1)=H(M_2)\)在計算上是不可行的。
- 雪崩效應——當一個輸入位發生變化時,輸出中的每一位均有50%的概率發生變化。
雜湊演算法就是以雜湊函式為基礎構造的,常用於實現資料完整性和實體認證。一個優秀的 hash 演算法,將能實現:
- 正向快速:給定明文和 hash 演算法,在有限時間和有限資源內能計算出 hash 值。
- 逆向困難:給定(若干) hash 值,在有限時間內很難(基本不可能)逆推出明文。
- 輸入敏感:原始輸入資訊修改一點資訊,產生的 hash 值看起來應該都有很大不同。
- 衝突避免:很難找到兩段內容不同的明文,使得它們的 hash 值一致(發生衝突)。
雜湊函式的性質
抗碰撞性
雜湊函式的抗碰撞性是指尋找兩個能夠產生碰撞的訊息在計算上是不可行的。但找到兩個碰撞的訊息在計算上不可行,並不意味著不存在兩個碰撞的訊息。雜湊函式是把大空間上的訊息壓縮到小空間上,碰撞肯定存在。只是計算上是不可行的。例如,如果雜湊值的長度固定為256位,顯然如果順序取\(1,2,\cdots,2^{256}+1\)這\(2^{256}+1\)個輸入值,計算它們的雜湊值,肯定能夠找到兩個輸入值,使得它們的雜湊值相同。
原像不可逆
原像不可逆,指的是知道輸入值,很容易通過雜湊函式計算出雜湊值;但知道雜湊值,沒有辦法計算出原來的輸入值。
難題友好性
難題友好性指的是沒有便捷的方法去產生一滿足特殊要求的雜湊值。
一個雜湊函式\(H\)稱為難題友好的,如果對於每個\(n\)位的輸出\(y\),若\(k\)是從一個具有較高不可預測性(高小熵)分佈中選取的,不可能以小於\(2^n\)的時間找到一個\(x\),使\(H(k||x)=y\)。
為了引申出工作量證明PoW的原理,考慮一個由雜湊函式構成的解謎問題:已知雜湊函式\(H\),一個高小熵分佈的值\(value\)以及目標範圍\(Y\),尋找\(x\),使得\(H(value||x) \in Y\)。
這個問題等價於需要找到一個輸入值,使得輸出值落在目標範圍\(Y\)內,而\(Y\)往往是所有的輸出值的一個子集。實際上,如果一個雜湊函式\(H\)的輸出位\(n\)位,那麼輸出值可以是任何一個\(0\)~\(2^n\)範圍內的值。預定義的目標範圍\(Y\)的大小決定了這個問題的求解難度。如果\(Y\)包含所有\(n\)位元的串,那麼問題就簡單了,但如果\(Y\)只包含一個元素,那麼這個求解是最難的,相當於給定一個雜湊值,找出其中一個原像,原像不可逆的性質說明了這個難度。事實上,由於\(value\)具有高小熵分佈,這確保了除了隨機嘗試\(x\)值以完成搜尋那個很大的空間外,沒有其他有效的途徑了。
雜湊函式的難題友好性構成了基於工作量證明的共識演算法的基礎。通過雜湊運算得出的符合特定要求的雜湊值,可以作為共識演算法中的工作量證明。這裡比特幣的安全保證依賴於雜湊函式的安全性,如果雜湊函式被攻破,可以想象Pow共識演算法就失效了,不用算力達到\(51\%\)就可以攻擊了。
PoW共識演算法
理解了難題友好性,就基本理解了PoW的原理。結合比特幣去理解PoW。比特幣PoW的過程,就是將不同的nonce值作為輸入,嘗試進行SHA256雜湊運算,找出滿足給定數量前導0的雜湊值的過程。要求的前導0的個數越多,代表難度越大。比特幣節點求解工作量證明問題的步驟歸納如下:
1)生成鑄幣交易,並與其他所有準備打包進區塊的交易組成交易列表,通過Merkle樹演算法生成Merkle根雜湊;
2)把Merkle根雜湊及其他相關欄位組裝成區塊頭,將區塊頭的80位元組資料作為工作量證明的輸入;
3)不停地變更區塊頭中的隨機數nonce,並對每次變更後的區塊頭做雙重SHA256運算,將結果值與當前網路的目標難度做比對,如果滿足難度條件,則解題成功,工作量證明完成。該礦工獲得記賬權,生成新區塊並廣播到全網。
最後,如果你熟悉傳統共識演算法比如Paxos、Raft等,可以對比思考一下為什麼比特幣要採用工作量證明的方式達成共識?比特幣區塊鏈實質上就是一個狀態複製機,不過相對於一般分散式系統幾個副本間達成共識,比特幣可以認為是數千數萬個“副本”達成共識,如果採用節點間協商投票等方式,在節點數量巨大且節點網路一直動態變化的情況下基本是不可行的。而Pow共識演算法,共識的過程節點只需自己計算難題就都可以了,不需要與其他節點進行協商互動,因此對節點的數量不敏感,甚至節點數量越多系統越安全,無論是一個節點還是數萬個節點,能夠達成共識。