更多區塊鏈知識git
區塊鏈做爲一個分佈式系統,能夠由不一樣的人或機構,將安裝了區塊鏈軟件的計算機(簡稱節點)加入到網絡裏,而後共同計算數據、共同見證交易的執行過程,並確認最終計算結果。github
如何協同這些鬆散耦合,互不信任的節點一塊兒工做,達成信任關係,並保障一致性,持續性,能夠抽象爲「共識」過程。算法
共識須要解決的幾個核心問題是:緩存
1. 誰在這個網絡裏有記帳權,也就是作爲leader發起一次記帳。 2. 作爲互相不信任的參與者,爲何要採納和相信某一我的給出的記帳。 3. 怎麼保證你們最終收到的結果都是一致的,無錯的。
公鏈上把「激勵」也做爲一個核心的考慮項,來保證鏈的可持續發展,這是合理的,可是聯盟鏈不必定會採用代幣激勵,因此本文不把激勵放到這三個核心問題裏。安全
如下介紹幾個典型共識的策略:
首先介紹 PoW(Proof Of Work)工做量證實。POW是比特幣採用的共識算法,從誕生起運行至今,表現穩健,是史上最成功的共識算法,沒有之一。 性能優化
POW的哲學簡單可靠,你們理論上均可以發起記帳,拼算力,看誰能先算出一個小几率的隨機數,也就是俗稱的挖礦,這個隨機數在數學角度有嚴謹的推演,經過動態調整的難度策略限制,不管礦工投入的硬件多強,都能控制在10分鐘左右挖到一個礦,算力強的礦工由於能夠在這段時間內計算更多的隨機數,因此更有機會比其餘人先挖到礦。 網絡
挖到礦的礦工就能夠廣播本身的記帳結果,全網的其餘節點能夠選擇接受這個結果,而後默默開始的下一輪的挖礦。挖到礦的礦工同時獲得一筆算法賦予的獎勵,也就是一些比特幣。 分佈式
若是恰好兩個礦工徹底同時的挖到礦,那麼就會出現競爭,網絡上出現了兩個記帳結果,這個時候其餘節點會隨機選擇一個,或者按順序選擇本身先接收到的一個,繼續在它基礎上進行挖礦(基於該記帳結果的基礎,再挖到的新的一次礦,稱爲新一次確認),因爲網絡有隨機延遲,隨機策略等區別,通常會有一個記帳結果會被更多人接受,有機會更快的被持續確認六次,另外一個就被拋棄了。這就是競爭和分叉處理。 性能
POW的表現有點像單純的原始年代,你們都憑力量和速度去挖礦淘金,誰先挖到一塊金子,就勝出一次,看起來很是的公平公正,簡單粗暴,無可挑剔,其簡單性也讓這個體系得以穩定運行多年。畢竟拼了老命去挖礦的礦工,只會繼續拼命挖礦來加固本身的成果,輕易不會做弊,礦工做弊會致使網絡失去公信力,其辛苦挖來的持有的資產也會貶值。其餘人想攻擊這網絡,須要投入的算力要比現有的礦工多,得比現有的已經很熟練頗有力量的礦工更努力,若是收益不是很可觀,是不值得的 -- 換句話說,反正比特幣網絡有獎勵,若是我有這超越了其餘礦工算力,爲什麼不去挖礦賺錢,破壞網絡吃力不討好乾啥(除非別有所圖)。因而,博弈論就這麼玄妙的產生了做用。 區塊鏈
同時,這種掰腕子秀肌肉的哲學,最讓人吐槽的就是不環保,能耗太多,效率較低,無腦算HASH,對科學計算也沒什麼貢獻(曾經有將算力用於計算天文問題來挖礦的方案,可是沒有造成大規模效應),參與者能經過暴力堆積硬件,採用極致優化(只能作HASH計算的)芯片,在網絡裏掌握話語權,也就是所謂的算力集中問題。
總結一下,以前的三個問題在POW裏的解決方案
1. 誰在這個網絡裏有記帳權,也就是作爲leader發起一次記帳。 雖然你們都有機會參與記帳,算力強大的人更有機會成爲記帳者,誰勁兒大誰當擂主。 2. 作爲互相不信任的參與者,爲何要接受和相信某一我的給出的記帳。 由於記帳者付出了算力的巨大代價作爲背書,他能夠爲記帳行爲負責,能夠傾向認爲他不做惡。 3. 怎麼保證你們最終收到的結果都是一致的,無錯的。
其餘人能夠從網絡裏同步到記帳者的數據,經過區塊裏的hash算法校驗數據,由於區塊數據有難以產生(須要算力),容易校驗(hash容易計算)的特性,你們對數據校驗經過後都採用記帳者給出的數據,全網一致,若有分叉,6次確認後解決。
考慮到POW的短板,行業裏提出了PoS(Proof Of Stake)權益證實的思路。PoS的基本思想是讓在網絡中擁有更多權益的人有機會在更短期裏作更多的決定,由於畢竟權益持有者人更傾向維護網絡的利益,且懼怕做惡後被懲罰,損傷本身的聲望和財產。
PoS的算法實現有不少變種,其中一個比較典型的是引入了「幣齡」的概念,好比,一我的手裏拿了一筆錢,並且持續拿了一段時間,那麼基本上能夠認爲這我的是比較忠於這個網絡的,他的權益值就比較高了。爲了鼓勵人們持有代幣,通常是有利息可圖的,因此也鼓勵了人們傾向持有資產,不斷增值,維持權益。
對權益較高的人,如何得到記帳權力,也有多個變種實現,在繼續採用挖礦算法的網絡裏,能夠加權的下降他的挖礦難度,讓他更容易挖到礦,得到記帳權。或者採用加權的輪詢算法,輪流讓權益擁有者輪流記帳。
能夠認爲,PoS引入了財富作爲公信力背書的一個考慮角度,和簡單粗暴誰有力量誰說了算的PoW對比,有利於下降純計算資源的消耗,看起來也沒有那麼肌肉感了。
總結一下PoS:
1. 誰在這個網絡裏有記帳權,也就是作爲leader發起一次記帳。 持有權益較多的一撥人競爭或輪流記帳。 2. 作爲互相不信任的參與者,爲何要接受和相信某一我的給出的記帳。 記帳者用本身的財力作爲背書,你們相信他們不會輕易做惡,若是做惡,能夠用經濟方式懲罰他。 3. 怎麼保證你們最終收到的結果都是一致的,無錯的。 經過驗證記帳權益和數據,你們相信這一輪的記帳者,一導致用他的記帳結果 。
在PoS的基礎上,又發展出了一個DPoS的共識算法。和PoS對比多了D,全稱是「Delegated Proof of Stake,股份受權證實機制」,原理是讓全部持幣人都有機會選出本身的表明,好比全網有1萬個參與人,經過必定的算法,參與人以本身的代幣爲權益證實,選出101個表明,這些表明能夠輪流或者採用PoS算法加權的得到記帳權,進行記帳。
DPoS理論上不要求選出的表明個體自己是權益全部人,看起來更民主,更開放。網絡參與者作爲選民有機會選出本身的表明,來給本身的利益代言。若是選出的表明不做爲(輪到本身記帳時不記帳),或者做惡,能夠把他們踢掉,若有必要進行懲罰(選民們也有可能被懲罰)。不然記帳者有機會得到相應的獎勵,也有可能將獎勵發放給選出本身的民衆們。
總結一下DPoS:
1. 誰在這個網絡裏有記帳權,也就是作爲leader發起一次記帳。 擁有權益的散戶,分別選出本身的表明參與記帳。 2. 作爲互相不信任的參與者,爲何要接受和相信某一我的給出的記帳。 你們相信表明,由於他們能表明至關一部分人的在網絡裏的利益。 3. 怎麼保證你們最終收到的結果都是一致的,無錯的。 相信表明,一導致用他的記帳結果 。
以上的都是在公有鏈裏採用的共識算法,都能解決可信和一致性的問題,區別在於組織方式和計算代價不一樣,有一點相同的是:都是追求「最終一致性」,而不是強一致性。
也就是說在網絡中,因爲網絡故障、通訊分區、權益和算力相近等狀況,依舊可能有多個記帳者在競爭記帳,因此每次記帳能夠理解成一次提案,你們暫時保存這一次提案的競爭結果,最終肯定下來可能要依賴屢次競爭,也就是所謂的一頓燒烤解決不了的問題,那就再來一頓,而後再一頓。直到你們看到,以前的某一次記帳,都被你們接受了,並且是接受了好幾回,才達成最終一致性,這個時間是相對比較長的,好比比特幣的6次確認,須要一個小時。公鏈裏的共識以及其餘交易行爲,能夠理解爲一種機率遊戲,隨着時間推移和投入到共識裏的工做量或權益越多,肯定性的機率就越大,大到機率上幾乎不可逆,或者必須投入匪夷所思的大量的資源才能推翻時,就達成了肯定性。
咱們的目標是實現聯盟鏈的共識,聯盟鏈和公有鏈不一樣的是,參與記帳的人,身份是可知的、可控的,可能有監管或者經濟共同利益之類的措施來約束他們。
另外,聯盟鏈的場景傾向與追求強一致性,也就是說一筆交易發生了,就不能再被分叉或回滾推翻了。因此聯盟鏈一般使用的是PBFT和Raft算法以及其變種。
因此咱們的實現是可動態配置式的記帳者列表,在具有共同利益的的聯盟鏈網絡裏,全部或大部分機構都參與記帳,你們一塊兒維護商業利益,若是某個機構在記帳過程當中犯錯、做弊、或者不工做,均可以經過少數服從多數容錯,而後進行過後追責,保護你們的利益。算法的容錯能力是能接受1/3成員的錯誤和做弊,如7個成員,只要做惡或出錯的成員在兩個和兩個如下,網絡就是安全的。但若是網絡裏有不少個做惡者,那麼這個網絡可被視爲失效。
BFT算法的過程是一次提案,幾步提交,在這個過程當中有複雜的狀態機維護的細節。起始時可按一些簡單的規則,如輪次機制,讓某一個機構的某一個節點在某個區塊高度上,成爲議長,獲得記帳權,而後進行記帳提案,其餘節點對提案進行數據驗證(驗證簽名,驗證交易數據,驗證合約計算結果等),以爲都ok以後,返回一個簽名確認,議長收集你們的簽名,達到必定的數量後,認爲達成少數服從多數的效果,則將記帳結果廣播出去,你們在將記帳結果存下來以前,還能夠再進行一次投票和計票,確認大多數人都收妥了記帳數據並沒有異議,再將記帳數據存下來,開始下一輪。
能夠形象的描述下:一個團體,好比有7我的,你們都有投票權,要對某次聚餐計劃的選擇進行投票,這個時候某一我的發起一個提議,你們看ok呀,紛紛舉手,提議的人定時數數,舉手的人超過4個,就達成決議,不然再換一我的提議。若是提議達成,決定了吃什麼何時吃,發起人給你們羣發個郵件制定日程,你們接受日程並給出反饋,當看到有很多人都接受了郵件日程不會反悔,那麼,這頓飯就成行了。
若是團隊人數較多,也是可讓一部分人成爲投票表明,好比一個上百人的班裏,由選出來的班幹部投票就能夠了。其餘人成爲「觀察者」,無條件接受這一部分人經過拜占庭容錯算法得出的結果,和DPoS的思想相似。
PBFT算法在參與人數較少的聯盟鏈裏,有至關可觀的實用價值:
1. 少數服從多數,體現了民主性。 2. 你們參與投票,都能刷存在感。 3. 不須要粗暴的算力介入,至關環保。 4. 多步提交反覆確認,一旦共識完成就達成一致性,能夠短期內就達成肯定性的交易。 5. 每次投票都有數字簽名,能夠抗抵賴,不會投了票不認。 6. 能夠不依賴代幣經濟鼓勵來保證記帳的正確性。
因此,PBFT相對公鏈的各類共識,能夠理解成特定的已知身份的團隊內的快速達成一致的一種高效算法,特定團隊的造成也是相當重要的,因此會有PBFT-Auth(通過驗證的記帳人), PBFT-PoS,PBFT-DPoS等多種變化。是否須要在投票和容錯的部分進行常場景性的優化(如帶加權係數的投票,容錯由1/3改成1/2或者改成0容錯等等),要看場景需求,目前來看,保證有一個相對簡單,運行穩定的PBFT算法是首要的。
總結一下PBFT:
PBFT的小問題在於狀態機維護複雜,投票往返步驟較多,容易受網絡波動影響,對網路延遲和丟包至關敏感,當參與者數量增多,不穩定因素會被放大,其穩定性和效率可能會顯著降低,這也是咱們在持續的踩坑和優化的部分,要作到一個企業級環境可用的,健壯的PBFT共識,是很是有挑戰性的,不但須要對區塊鏈的數據和運做哲學有很深的理解,也要對分佈式系統的通訊,協做,性能優化有大量的實踐經驗。
結合以太坊賬戶模型和智能合約引擎機制,咱們對PBFT也作了大量的優化,好比把串行的任務改爲並行,把沒必要要重複計算的數據(如區塊數據打包,簽名等)緩存下來,快速偵測記帳者存活,加快切換速度等等,都是複雜的工程,須要一次又一次迭代的長夜漫漫的腦補、實現、測試、修BUG、壓測、量化,足以從新寫一篇長文了。
聯盟鏈還能夠採用一種共識算法Raft,簡單的說能夠理解成你們選出一個記帳者,若是它穩定運行沒有掛掉,就由他記帳,你們無條件接受他的記帳結果,相信他是誠實的,若是他掛掉了,那麼你們是能夠經過超時或網絡探測感知,而後快速啓動一輪投票,來選出一個新的記帳者,而後繼續無條件的等它記帳,這樣就達成了容錯性。
這在信任度較高,機構組成簡單的的聯盟鏈或者一個機構內的私有鏈裏,是比PBFT更加高效的一種作法,由於不須要多步的反覆確認,受網絡影響的可能性也小不少。
可是Raft算法並不解決記帳者耍花樣的問題,若是選出的記帳者做惡,其餘人當時是沒有辦法識破的,最多隻能經過過後檢查來發現,在肯定性要求較高的場景,好比收了錢就要交貨的DVP場景裏,容易出現錢貨兩空的狀況。另外,Raft算法有可能在網絡波動或競爭狀況下出現短暫的網絡分叉,須要屢次確認。
Raft適合用於專一解決可用性(保持系統穩定運行),追求相對較高效率(比優化後的PBFT大體高20~50%的效率)的場景,基本忽略欺詐可能,且對交易延時要求能夠放寬(等待屢次確認)。
爲了在速度和抗欺詐之間得到平衡,也有出現PBFT-Raft混用的共識,好比讓一個記帳者固定出塊,其餘人極少輪次的投票,或者進行快速的後置檢測,若是發現Raft的記帳者在做惡,馬上回滾衝正,並踢掉並懲罰做惡的記帳者等等,這就有一些場景化的需求須要考慮了。
總結一下Raft:
1. 誰在這個網絡裏有記帳權,也就是作爲leader發起一次記帳。 選出一個記帳者,讓他作爲惟一的可信者進行記帳,除非掛掉。 2. 作爲互相不信任的參與者,爲何要接受和相信某一我的給出的記帳。 無條件相信記帳者,from the beginning till the last,至死不渝。 3. 怎麼保證你們最終收到的結果都是一致的,無錯的。 記帳者說的都是對的,你們都用他的數據,是一致的。
回顧一下:
共識算法的研究是頗有意思的課題,咱們也看到共識算法的選擇和演進,隱約和人類社會的不一樣階段是對應得上的。算法實際上是社會裏人和財產的關係在計算機世界的一種映射,研究共識算法,不只是須要研究計算機理論(圖靈機時代,其實計算機也能體現人性),也要去深入的理解社會學,經濟學,心理學,博弈論。 畢竟,在一個不徹底互信的環境裏,宛如黑暗森林,須要複雜的算法來協同、斡旋各懷心事的參與者,而且能懲罰做惡的、獎勵誠實的,目前社會制度其實也沒有完美的作到,一切努力只是儘可能的使系統運做的儘可能順暢,讓世界更好一點點。