分布式共识四】POW共识算法
下面我來說說Bitcoin是如何通過Pow算法解決拜占庭將軍問題的。
比特幣
2008年,中本聰介紹了一個點對點的電子現(xiàn)金系統(tǒng)--比特幣。比特幣的基石是拜占庭共識協(xié)議。比特幣怎樣實現(xiàn)了拜占庭共識協(xié)議將在接下來的章節(jié)中介紹。不過首先要先介紹一下比特幣
交易
比特幣協(xié)議在數(shù)字貨幣中提供了一種交易方法,在這個方法中每個人可以對貨幣所有權,交易順序達成共識。貨幣所有權是通過公鑰來決定。整個網(wǎng)絡需要對貨幣數(shù)量與貨幣所有權之間的關系達成共識。貨幣所有權可以通過對轉(zhuǎn)賬交易(從一個賬戶轉(zhuǎn)移給另一個賬戶)簽名進行轉(zhuǎn)移。整個網(wǎng)絡需要能個解決同一筆錢不能花費兩次的難題。由于沒有一個中心化的權威機構(gòu)能夠校驗交易,因此需要在沒有受信任第三方機構(gòu)的情況下解決這個問題。就是說需要用去中心化的方法解決這個問題。
解決方案:公開向網(wǎng)絡廣播每筆交易,網(wǎng)絡中的節(jié)點對先到達的交易是有效的達成共識。每個節(jié)點檢查先到達的交易的輸出之前是否被花費。難點是:由于網(wǎng)絡通信不是及時的(異步網(wǎng)絡),所以導致所有節(jié)點收到的交易并不是完全一致的。在這個情況下找到一個確認哪一個交易是最先到達的共識是困難的。為了對交易順序達成共識,交易被打上時間戳存放在含有工作量證明的區(qū)塊中。
這個方法為交易順序共識提供了解決方案:區(qū)塊包含上一個區(qū)塊的Hash,最新交易。
Proof-of-Work?工作量證明
為了實現(xiàn)對交易打時間戳,Hash交易數(shù)據(jù)。比特幣用了工作量證明方法。網(wǎng)絡中的每個節(jié)點從事于解決一個適度困難的密碼難題。難題的解決方法是:把區(qū)塊中的所有數(shù)據(jù)做SHA256哈希運算,并且得到哈希值小于給定的目標值。區(qū)塊中還包含一個Nonce值,通過遞增Nonce來尋找正確的哈希值。這個密碼謎題被設計成,每隔10Mins會找到一個謎題答案。
一旦正確的哈希值被找到,節(jié)點就會向網(wǎng)絡中廣播這個哈希值。這個哈希值可以很容易的被網(wǎng)絡中的其他節(jié)點驗證,節(jié)點可以對收到區(qū)塊后對區(qū)塊中的數(shù)據(jù)進行SHA256運算哈希值。
花費的CPU就是工作量證明。要修改一個區(qū)塊需要重做這個區(qū)塊以及這個區(qū)塊之后所有區(qū)塊的工作量證明。這就意味比特網(wǎng)絡更傾向于最誠實的鏈,只要網(wǎng)絡中大多數(shù)節(jié)點是誠實的。
Pow的過程可以被看做是一個投票的過程。每個新增的區(qū)塊累積了以前的歷史交易(區(qū)塊是串聯(lián)成鏈的),每個節(jié)點都會繼續(xù)對以有最多投票數(shù)量的鏈繼續(xù)投票。
?
攻擊比特幣網(wǎng)絡
現(xiàn)在考慮一下網(wǎng)絡中可以存在的一種攻擊。一個惡意的節(jié)點試圖雙花之前已花費的交易。攻擊者需要重做包含這個交易的區(qū)塊,以及這個區(qū)塊之后的所有的區(qū)塊,創(chuàng)建一個比目前誠實區(qū)塊鏈更長的區(qū)塊鏈。只有網(wǎng)絡中的大多數(shù)節(jié)點都轉(zhuǎn)向攻擊者創(chuàng)建的區(qū)塊鏈,攻擊者的攻擊才算成功了。考慮交易T包含在區(qū)塊b1中。每個后續(xù)區(qū)塊b2,b3,b4,.........bn會降低交易T被修改的可能性,因為修改這些后續(xù)的區(qū)塊需要更多的算力。中本聰用概率理論證明,六個區(qū)塊后攻擊者追趕上最長鏈的可能性降低到0.0002428%。在過四個或更多區(qū)塊后這個可能行會降到0.0000012%。每新增一個區(qū)塊bn,攻擊的可能性就會以指數(shù)形式下降,很快整個攻擊的可能性就會低到可以忽略的程度。在實際中,比特幣交易會在六個區(qū)塊后被確認,因為在這種情況下,攻擊者追趕上的可能性已經(jīng)非常低了,可以認為這個交易是有效的,不再會被修改。
工作量證明Pow實現(xiàn)拜占庭共識
現(xiàn)在我們看一下比特幣的工作量證明是如何解決計算機網(wǎng)絡中的拜占庭將軍問題的。比特幣網(wǎng)絡是就交易的順序,沒有中心化機構(gòu)的情況下達成共識的,同樣拜占庭將軍也是做得同樣的事情。拜占庭將軍需要攻擊城堡,所有將軍需要對任何將軍可能提出的攻擊時間達成共識。
方案一:被所有將軍都接受到的攻擊計劃,被認為是正式的攻擊計劃。問題是:兩個或多個將軍有可能同時發(fā)出不同的攻擊計劃。
這個問題模型被工作量證明簡化了,比特幣工作量證明系統(tǒng)中,不會追蹤交易順序,取而代之是在將軍之間達成共識。每個將軍基于工作量證明,解決一個難度適當?shù)?/span>Hash難題,每個難題有足夠的難度,僅當在所有的將軍同時工作時,平均10Mins會找到一個難題的答案(solution)。當一個將軍找到問題的答案,它會把這個答案連同攻擊計劃在網(wǎng)絡中廣播。一旦收到Solution,每個將軍調(diào)整難題為在廣播中收到的攻擊時間,攻擊計劃。然后將軍繼續(xù)解決下一個工作量證明。這樣接下來每個solution會依次在第一個solution后串聯(lián)成鏈。如果有將軍還在繼續(xù)在對另一個不同的攻擊方案進行工作量證明計算,它會切換到這個最長的鏈上。這個最長鏈上積累了最多的CPU算力。
平均一個小時后,這個鏈上會有六個區(qū)塊。每個將軍可以判斷是否有足夠多的將軍工作在含有相同初始攻擊計劃的最長鏈上。鏈會在一小時累積到六個區(qū)塊,說明大多數(shù)將軍對相同的攻擊計劃進行工作量證明計算(CPU投票)。因此將軍對攻擊時間達成共識。
結(jié)論
在沒有中心化權威機構(gòu)存在的P2P網(wǎng)絡上,比特幣共識協(xié)議功能上等同于一個受信任的中心化機構(gòu)。這個協(xié)議解決了拜占庭將軍問題中缺少中心化權威機構(gòu)的難題。幫組將軍在攻擊時間上達成共識。而且,它緩解了多個攻擊計劃同時提交的可能性,同時也降低了攻擊的可能性。因此比特幣共識協(xié)議現(xiàn)代拜占庭將軍中的問題。
| ? | 拜占庭將軍問題和Bitcoin?對比 | ? |
| 拜占庭將軍問題 | ? | BitCoin |
| 攻擊時間上達成共識 | 目標 | 對合法的交易達成共識 |
| 將軍分布在城堡周圍 | 分布情況 | 節(jié)點分布在網(wǎng)絡中 |
| 忠誠的將軍和副官 | 好的 | 可信任的節(jié)點 |
| 叛徒 | 壞的 | 作惡節(jié)點 |
| 篡改消息(干擾忠誠的將軍達成共識) | 破壞 | 向區(qū)塊中加入無效非法的交易 |
| 怎么才能知道那個消息是真的 | 難點 | 怎么才能知道那個交易是合法的 |
| 暫無 | 解決方案 | Pow |
| 暫無 | 共識 | BlockChain + Pow |
Pow?是如何運行的
?
#!/bin/python
?
import sys
import time
import hashlib
from struct import unpack, pack
?
timestamp = str(time.time()) ????????????????? # Work timestamp
message = "This is a random message." ????? # Plaintext message
nonce = 0????????????????????????????
guess = 99999999999999999999
payload = timestamp + message
throttle = 100000000
target = 2**64 / throttle
?
payloadHash = hashlib.sha256(payload).digest()
?
start = time.time()
while guess > target:
???????? nonce += 1
???????? guess,=unpack('>Q',hashlib.sha256(hashlib.sha256(pack('>Q',nonce)+payloadHash).digest()).digest()[0:8])
???????? print(guess);
end = time.time()
?
print "%s:%s:%s:%s:%s:%s:%s" % (timestamp, message, nonce, guess, payload, target, end-start)
?
?
l??timestamp?開始產(chǎn)生區(qū)塊的時間戳
l??message?類似比特別中的交易,這里只做演示用字符串替代
l??payload?is a combination of the things that you will encrypt.
l??nonce?會從0到N遞增,直到找到target為止
l??guess?將會保存謎底,一開始初始化為無窮大
l??throttle?相當于比特幣中的難度
l??target?8個字節(jié)的整數(shù)最大值?(2^64)除以難度(throttle?)
?
Timestamp,message,payload是你要發(fā)送到網(wǎng)絡中的東西。它可以是區(qū)塊數(shù)據(jù)
Nonce,guess,throttle target是用來進行工作量證明運算。Pow最重要的是難于生成易于驗證。
?
while guess > target:
???????? nonce += 1
???????? guess,=unpack('>Q',hashlib.sha256(hashlib.sha256(pack('>Q',nonce)+payloadHash).digest()).digest()[0:8])
?
這三行就是Pow算法主要內(nèi)容。這是一個簡單的循環(huán)。它使用SHA256對數(shù)據(jù)進行兩輪哈希。前八個字節(jié)作為我們的謎底。
?
比特幣的除數(shù)(難度)2016個區(qū)塊后調(diào)整一次 增加或下降。上圖顯示隨著難度的增加正確謎底的可能值范圍縮小,也就是越難于發(fā)現(xiàn)Guess
nonce += 1
Nonce表示CPU的工作量,在本例子nonce?表示發(fā)現(xiàn)一個低于target的guess的累計工作量。因為每一個guess都有相同的可能性會低于target,它和nonce生成的方式是無關的。所以nonce從0開始遞增比生成隨機數(shù)成本更低。當區(qū)塊提交到網(wǎng)絡中,nonce會被用來證明區(qū)塊的正確性。
guess,=unpack('>Q',hashlib.sha256(hashlib.sha256(pack('>Q',nonce)+payloadHash).digest()).digest()[0:8])
Guess是把nonce和payload經(jīng)過兩輪SHA256哈希之后值的前8個字節(jié)。因為target的范圍是0..2^8,所以guess不可能超過target.在每次循環(huán)后,nonce是唯一會改變的值。
向網(wǎng)絡中提交nonce是安全的。因為每個曠工的payload是獨一無二的。如果曠工Alice使用了曠工Bob提交的nonce,Alice需要提供相同的payload,由于Alice不能在payload把Bob的公鑰自己的公鑰,因為這會改變兩輪SHA256哈希的輸出。改變后的輸出就一定滿足小于target這個條件。由于Alice的payload不同于Bob的payload,所以Bob的nonce對Alice就不適用。
http://www.blockchainbrother.com/article/9
總結(jié)
以上是生活随笔為你收集整理的分布式共识四】POW共识算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【分布式共识二】拜占庭将军问题----口
- 下一篇: GAUSSIAN MIXTURE VAE