最小可行性區塊鏈原理解析

加密貨幣,特別是比特幣,幾乎從各個方面都得到了大量關注:規則、管理、稅務、技術、產品創新等等,不勝枚舉。“點對點(去中心化)電子現金系統”的概念顛覆了我們以前對貨幣和金融所持有的設想。


圖1

即便如此,把數字貨幣方面擱到一邊,還有一個可以說是更有趣更深遠的創新,即底層的區塊鏈技術。無論你對比特幣或是它的山寨幣衍生品有什么看法,作為一種貨幣和價值存儲手段,它們背后的運作基礎都來自于中本聰概括的區塊鏈原理:
我們運用點對點網絡提出了重復花費問題的解決方案。網絡通過將交易散列到一個進行中的基于散列的工作量證明鏈,來對交易進行時間戳標記,并形成一個記錄,這個記錄只有在重做工作量證明的情況下才能被改變。最長的鏈不僅作為它所見證事件發生時序的證據,而且也證明它來自最大的CPU功率池……網絡本身要求架構最小化。
區塊鏈對任何“貨幣”都是不可知的。事實上,它可以適用于促成很多其他使用案例。因此,理解“最小可行區塊鏈”背后的方法和原理是有好處的:
以下將從頭開始解釋為什么需要特定的部分(數字簽名、工作量證明、交易區塊),以及它們如何集合起來形成具有卓越性能的“最小可行區塊鏈”。

<strong>用三式記賬法保障交易安全</strong>

Alice和Bob是集郵愛好者,偶爾會做做交易。如果雙方都看到喜歡的東西,可以當場協商完成交換。換言之,這是個簡單的以物易物的系統。
有一天Bob拿來一枚郵票,Alice覺得她必須要收藏,但問題是Bob對Alice所提供的交換物不是特別感興趣。Alice沮喪不已,她繼續和Bob協商,最后達成一致:他們做個單方交易,Bob先把郵票給Alice,Alice承諾以后再償還Bob。
Bob和Alice已經認識有一陣子了, 但是為了確保兩個人都信守承諾(主要是Alice),他們同意讓朋友Chuck來對交易“進行公證”。


圖2

他們把圖2這個可以表明Bob給了Alice一枚“紅色郵票”的交易收據做了三個副本(三方各持一份)。Bob和Alice可以用收據來記錄他們的交易, Chuck存儲副本作為交易證據。這個設定很簡單,但其中有一些很重要的屬性:

  1. Chuck可以鑒定Alice和Bob兩個人的真實性,以確保不會有人在他們不知情的情況下蓄意偽造交易。
  2. Chuck賬簿中的收據證明了交易發生。如果Alice聲稱交易從未發生,那么Bob可以去找Chuck,用他的收據來證明Alice說謊。
  3. 如果Chuck的賬簿中沒有收據,就證明交易未發生過。Alice和Bob都不能偽造交易。他們可以偽造交易收據,聲稱對方說謊,但同樣的,他們可以去找Chuck,查看他的賬簿。
  4. Alice和Bob都不能篡改當前的交易。如果任意一方篡改了交易,他們可以去Chuck那兒,用儲存在Chuck賬簿中的副本核實他們的副本。
    以上操作就是“三式記賬法”,操作簡便,對參與雙方都能提供很好的保障。但你也看到了它的缺點,對吧?我們對中間人寄予了很大的信任。如果Chuck決定和另一方串通,那么整個系統就土崩瓦解了。

<strong>用公鑰基礎設施(PKI)保障交易安全</strong>

Bob不滿于使用“可靠中間人”的不安全性,他決定研究一下,發現公鑰密碼可以免去使用中間人的需要!這里解釋一下:
公鑰密碼,也叫做不對稱密碼,指的是一種密碼算法,它需要兩個單獨的鑰匙,一個是秘密的(私有的),另一個是公共的。盡管這個鑰匙對應的兩部分不同,但有數學聯系。公鑰用于對純文本加密或者查驗數字簽名;私鑰用于解密密碼文本或者創建數字簽名。
運用第三方(Chuck)的原本意圖是要確認有三個屬性:

  1. 驗證真實性: 不能有惡意的一方偽裝成其他人。
  2. 不可否認性: 事實發生后,參與方不能聲稱交易沒有發生過。
  3. 完整性:事實發生后,不能再修改交易收據。
    結果是,公鑰密碼可以滿足以上所有要求。簡單地說,工作流程如圖3所示。


    圖3
  4. Alice和Bob分別生成一個固定的公鑰-私鑰對。
  5. Alice和Bob公布出他們的公鑰。
  6. Alice以純文本的形式寫一個交易收據。
  7. Alice用她的私鑰對交易信息的純文本進行加密。
  8. Alice在密碼文本上添加一個“由……簽名”的純文本備注。
  9. Alice和Bob都儲存相應的輸出結果。
    注意只有在多方參與的時候才需要第五步:如果你不知道是誰簽署了信息,就不知道該用誰的公鑰來解密,這個問題很快就會變得有關緊要。
    這看起來像是沒什么特別理由的大量工作,但我們還是來檢驗一下新收據的屬性:
  10. Bob不知道Alice的私鑰,但問題不大,因為他可以查詢她的公鑰(公鑰是全世界共享的),然后用公鑰來解密交易的密碼文本。
  11. Alice并不是真的在給交易內容“加密”,而是通過使用她的私鑰給她“簽名”的交易編碼:任何人都可以用她的公鑰對密碼文本進行解密,由于她是唯一擁有私鑰的人,這個機制保證了只有她能生成交易的秘密文本。

Bob或針對這個問題的任何其他人,如何獲得Alice的公鑰?有很多種方法來分發私鑰——例如,Alice公布在她的網站上。我們可以假定有這樣的合適的機制。
因此,使用公鑰基礎設施(PKI)可以滿足我們之前所有的要求:

  1. Bob可以用Alice的公鑰通過解密密碼文本來證明簽名交易的真實性。
  2. 只有Alice知道她的私鑰,因此Alice不能否認交易的發生——她已經簽名了。
  3. 沒有Alice的私鑰,Bob或任何其他人都不能偽造或修改交易。
  4. 注意第二條,Alice可以否認她是那個有爭議的公鑰——私鑰對的真正所有者。
  5. Alice和Bob只儲存了簽名交易的副本,消除了對中間人的需要。“神奇”的公鑰密碼和雙方以物易物系統完美匹配。

<strong>余額 = Σ(收據)</strong>

隨著公鑰基礎設施到位,Bob和Alice又完成了一些交易:Alice從Bob處得到另一張郵票,Bob從Alice那兒也挑了一張郵票。它們都按照與之前相同的步驟,生成簽名交易并將它們附加到各自的分類賬簿中。


圖4

記錄是安全的,但有一個小問題:不清楚是否任何一方有未結余額。先前只有一個交易,很清楚是誰欠誰的(Alice欠Bob)以及欠了多少(一枚紅色郵票),但是有多個交易以后,情況變得模糊起來。所有的郵票都是等值的嗎?如果是,那么Alice有一個負余額。如果不是,那就誰也說不準了!為了解決這個問題,Alice和Bob達成一致如下:

  1. 黃色郵票的價值是紅色郵票的兩倍。
  2. 藍色郵票和紅色郵票等值。
    最后為了確保他們新協議的安全性,他們用交易的相對值更新了每個交易,重新生成了分類賬簿。新的賬簿看起來像圖5那樣。


    圖5

    這樣,計算最終余額現在變成了一個簡單的事,循環訪問所有的交易,將適當的借貸記錄應用于各方。最終結果是Alice欠Bob 2個“價值單位”。什么是“價值單位”? 它是由Alice和Bob都同意的任意交換媒介,另外,由于“價值單位”并不耳熟能詳,Alice和Bob同意將1個價值單位稱為1個chroma(復數形式:chroms)。
    上面這些看起來都是小事,但每一個參與者的余額都是分類賬簿中所有收據的一個函數這一事實有重要的意義:任何人都可以計算大家的余額。不需要任何可靠的中間人,也不必對系統進行審計。任何人都可以遍歷整個分類賬簿,核實交易,計算出每一方的未結余額。

<strong>多方轉移和驗證</strong>

接下來,Bob無意中發現John有一枚郵票,他實在很喜歡。他告訴John他和Alice在使用的安全分類賬簿,并問他是否愿意做個交易,Bob把Alice欠他的余額作為支付手段轉移給John——即Bob從John那兒獲得郵票,Alice之前欠Bob的金額將變成她欠John的。John同意了,但現在他們有個問題:Bob如何能以安全和可驗證的方式把他的余額“轉移”給John?經過一番協商,他們想出一個巧妙的計劃(如圖6所示)。


圖6

Bob按照與之前相同的步驟創建了一個新交易,不過他先計算出他想要轉移的加密交易的SHA-256校驗和(一個唯一的指紋),然后將校驗和嵌入新收據中“是什么”一欄。事實上,他在將之前與Alice的交易與新的轉移收據鏈接起來,這樣就把它的價值轉移給了John。
為了保持事物的簡單性,我們假定所有的轉移都會“消費掉”被轉移交易的全部價值。要把這個系統擴展到使部分轉移成為可能并不難,但此時沒有必要考慮得那么復雜。
隨著新交易到位,John為了安全起見,做了一個加密分類賬簿的副本(現在有三個副本)并運行了一些檢查來驗證它的完整性:

  1. John提取了Alice和Bob的公鑰,驗證前三個交易的真實性。
  2. John證實了Bob轉移的是一個“有效”交易:
    2-1. 待轉移交易的地址是Bob。
    2-2. Bob此前沒有把這個交易轉移給任何其他人。
    如果所有檢查都通過了,他們就完成交易,我們可以通過遍歷分類賬簿來計算新的余額:Bob有一個凈零數余額,Alice有2個chroma的借額,John有2個chroma的貸額(由Alice提供)。這樣John現在就可以把他的新分類賬簿拿給Alice并要求她支付,即使Alice沒有出席交易,也沒有問題:
  3. Alice可以用Bob的公鑰核實新轉移交易的簽名。
  4. Alice可以核實轉移的交易是對她和Bob一個有效交易的引用。
    以上轉移和驗證過程是系統一個了不起的屬性!注意要讓它全部能工作,我們需要兩個使能技術:一個是公鑰基礎設施的運用,使數字簽名驗證成為可能;另一個是收據賬簿,使我們能夠查看完整的交易記錄以驗證余額并鏈接先前的交易來進行轉移。
    John和Bob對這個巧妙的解決辦法很滿意,然后兩人分頭回家:Bob帶著新郵票,John有了新的分類賬簿。表面上看一切完美,但是他們剛剛把自己暴露在了一個極具挑戰性的安全問題之下……你發現了嗎?

<strong>重復消費和分布式一致性</strong>

在與John完成交易后不久,Bob意識到他們剛剛在他們的系統中引入了一個嚴重的漏洞,如果他迅速行動,就可以利用這個漏洞:Bob和John都更新了他們的分類賬簿來包括新的交易,但是Alice和其他任何人都不知道交易已經發生。結果是,沒有什么能阻止Bob接近網絡中的其他人,給他們展示舊的賬簿副本,而舊的賬簿副本里沒有他和John的交易!如果Bob說服他們進行交易,就像他和John做的那樣,他就可以“重復消費”同一個交易,想進行多少次都可以!


圖7

當然,一旦多人拿著新的分類帳簿要求Alice支付,欺詐行為將被檢測到,但這已經無濟于事了——Bob已經帶著戰利品跑掉了!
只有兩個參與者的時候,不可能受到雙重消費攻擊,因為要完成交易,你要驗證并同時更新兩個分類賬簿,因此所有分類賬簿始終保持同步。然而當我們再添加另外一個參與者時,我們就引入了各參與者之間賬簿不完全和不一致的可能性,這就使雙重消費成為可能。
在計算機科學語言中,雙方分類賬簿具有“強一致性”,超過兩方的分類賬簿則需要某種形式的分布式一致性以解決雙重消費的問題。
這個問題最簡單的可能的解決方案是要求分類賬簿中列出的各方都必須在每個新交易發生時都在場,以便每個人可以同時更新他們的賬簿。這個策略對小型的群組有效,但不能擴展到有大量參與者的情況。

<strong>分布式一致性網絡的要求</strong>

我們來設想一下,我們想要將分類賬簿擴展到全世界所有集郵者,這樣任何人都可以用一種安全的方式交易他們喜歡的郵票。顯然,由于地理位置,時區和其他限制,要求每個參與者在每個交易登記的時候都在場是不可能實現的。我們能建立一個不需要每個人都在場批準的系統嗎?

  1. 地理位置算不上一個真正的問題:我們可以把交流轉移到線上。
  2. 時區問題可以通過軟件解決,我們不需要每個人手動更新分類賬簿。相反,我們可以建立一個軟件,它能在每個參與者的計算機上運行并代表他們自動接收、批準以及向分類賬簿添加交易。
    事實上,我們可以建立一個點對點(P2P)網絡,負責分發新的交易并獲得每個人的批準! 但很可惜,說起來容易做起來難。例如,雖然P2P網絡可以解決我們的地理位置和時區問題,但試想即便只有一個參與者離線,會出現什么情況? 我們是不是要阻止所有交易,直到他們再次上線?
    注意,“如何”構建P2P網絡本身就是一個龐大的課題,構建這樣一個網絡的底層機制也遠超出我們討論的范圍……我們把它作為一個練習留給讀者。


    圖8
    圖8

    原來分布式一致性的問題在計算機科學中已經被深入研究過,并且已經提出了一些有希望成功的解決方案。例如,兩階段提交(2PC)和Paxos都使這樣一種機制成為可能,即我們只需要參與者的大多數法定人數(50%以上)接受就能安全地提交新的交易:只要大多數人已經接受交易,就能保證群組中剩下的人最終匯合在同一個交易歷史。
    即便如此,單單有2PC或Paxos是不夠的。比如,在每天都有新參與者加入而其他人不預先通知就消失的情況下,2PC或Paxos如何知道我們P2P集郵者網絡中的參與者總數?如果有一個先前的參與者離線,他們是臨時還是永久離線? 相似地,還有另一個我們必須考慮的更具挑戰性的“Sybil攻擊”:沒有辦法阻止一個惡意參與者創建許多檔案,以在我們的P2P網絡中獲取不公平的投票權份額。
    如果系統中的參與者數量是固定的,并且已經驗證他們的身份真實有效(也就是說,這是一個可信網絡),那么2PC和Paxos都會工作得很好。但我們不斷變化的集郵者P2P網絡并不是這樣的情況。我們走進死胡同了嗎? 嗯,并不盡然……
    這個問題有個明顯的解決方案是從問題陳述中消除“分布的”部分。我們可以不建立一個P2P分布式系統,而是建立一個所有集郵者的全局注冊表,記錄他們的帳戶信息,對他們進行驗證并(嘗試)確保沒人能通過創建多個身份作弊,最重要的是,保證有一個共享的分類賬簿副本!具體來說,我們可以建立一個網站,這些交易在網站上進行,網站將在它的集中式數據庫里記錄所有的交易,以此確保交易的完整性和正確排序。
    以上是一個實用的解決方案,但我們得承認,它不盡如人意,因為它迫使我們失去了分類賬簿系統點對點的性質。它將所有的信任置于一個單一的集中式系統,這就帶來了一組全新的問題:什么是系統的正常運行時間,安全性和冗余;誰來維護系統,他們維護系統的動因是什么;誰有管理訪問權限等等。集中式帶來了它自己的一系列挑戰。
    讓我們回顧一下在P2P設計中遇到的一些問題:

  3. 確保每個參與者始終保持更新狀態(強一致性系統)會產生很高的協調成本,影響可用性。如果單個點不可達,整個系統都無法提交新交易。
  4. 在實踐中,我們不知道P2P網絡的全局狀態:參與者人數,個體是暫時離線還是決定離開網絡等。
  5. 假設我們可以解決上述限制,系統仍然可能受到Sybil攻擊,惡意用戶可以偽造許多身份行使不公平的投票權。
    不幸的是,解決上述所有限制是不可能的,除非我們放松一些要求: CAP定理告訴我們,我們的分布式系統不能有很強的一致性,可用性和分區容忍性。因此在實踐中,我們的P2P系統必須在(更)弱一致性的假設下操作并克服它可能帶來的影響:
  6. 我們必須接受一些分類賬簿不同步(至少是暫時不同步);
  7. 系統最終必須收斂于所有交易的整體序(線性一致性);
  8. 系統必須以可預測的方式解決分類賬簿沖突;
  9. 系統必須強制執行全局不變量——例如,沒有重復消費;
  10. 系統應該免受Sybil和類似的攻擊。

<strong>保護網絡免受Sybil攻擊</strong>

在分布式系統中實現一致性,比如通過對每個參與者的投票計數,會出現很多關于各節點“投票權”的問題:允許誰參與,某些節點是否有更多的投票權,是否每個人都平等,以及我們如何強制執行這些規則?
為了保持簡單,我們假定每個人的投票是平等的。第一步,我們可以要求每個參與者用私鑰在他們的投票上簽名,就像在他們的交易收據上簽名一樣,并將投票傳播到他們的節點上——在投票上簽名確保了別人不能代表他們投票。然后我們可以制定一個規則,只允許提交一票。如果同一個鑰匙簽名了多個投票,那么所有的投票都作廢——已經下定決心!到目前為止還好,現在難的部分來了……
最開始我們怎么知道允許哪個特定的節點參與?如果只需要一個獨特的私鑰來簽名投票,那么惡意用戶可以簡單地生成無限的新密鑰充斥網絡。根本問題是,當生成和使用偽造身份很便宜時,任何投票系統都很容易被顛覆。
為了解決這個問題,我們需要使提交投票的過程變得“昂貴”。提高生成新身份的成本,或者提交投票的過程必須產生足夠高的成本。為了讓問題更明確,我們來想幾個現實世界的例子:

  1. 你在當地政府選舉中投票時,會要求你出示身份證件(例如護照),而偽造身份證件的成本很高(希望如此)。理論上,沒什么能阻止你生成多個偽造的身份證件,但如果成本足夠高(偽造的貨幣成本,被抓的風險等),那么運行Sybil攻擊的成本將遠大于其收益。
  2. 或者,假設提交投票給你帶來了一些其他成本(例如支付費用)。如果成本足夠高,那么再次的,運行大規模Sybil攻擊的障礙也增強了。
    注意,上述例子都不能完全“解決”Sybil攻擊,但它們也不需要被完全解決。只要我們將攻擊的成本提高到大于成功破壞系統所能得到的值,那么系統就是安全的,會按照預期運行。
    注意,我們所使用的“安全”的定義是很寬松的。系統仍然會受到操縱,確切的投票計數會受到影響,但關鍵是惡意參與者不能影響最終的結果。

<strong>參與所要求的工作量證明</strong>

任何用戶都可以通過生成新的私鑰—公鑰對來輕易地(并且花很少的錢)在我們的P2P網絡中生成新的“身份”。同樣,任何用戶都可以用他們的私鑰簽名投票并將其發送到P2P網絡——這也很便宜,我們的收件箱中大量的垃圾郵件清楚地說明了這一點。 因此,提交新的投票很便宜,惡意用戶可以輕易地用盡可能多的投票淹沒網絡。
但是,如果將以上其中一個步驟變得昂貴,使你不得不消耗更多的精力、時間或金錢,情況會怎樣呢? 這就是工作量證明背后的核心思想:

  1. 工作量證明步驟對于發送者來說應該是“昂貴的”。
  2. 他人驗證工作量證明的步驟應該是“便宜的”。
    這樣一種方法有很多種可能的執行方式,但是為了達到我們的目的,我們可以再次使用之前遇到的密碼散列函數的屬性(如圖9所示)。


    圖9
  3. 很容易計算任何給定消息的散列值。
  4. 生成具有給定散列值的消息很昂貴。
    我們可以在我們的系統中施加一個新規則,要求每個簽名投票必須具有以特定子串開始的散列值,即需要部分散列沖突,比如兩個零的前綴。如果這看起來完全是任意的,那是因為它確實是任意的。跟著我的思路,我們通過幾個步驟來看看這是如何生效的:
  5. 我們假定一個有效的投票陳述是個簡單的字符串:"I vote for Bob" (“我投票給Bob”)。
  6. 我們可以用同樣的SHA-256算法來為我們的投票生成一個散列值。
    <a target="_blank" >代碼1</a>
  7. 生成的散列值無效因為它沒有以我們要求的兩個零子串開頭。
  8. 我們修改一下投票陳述,附加一個任意字符串再試一下:
    <a target="_blank" >代碼2</a>
  9. 生成的散列值也不滿足我們的條件,我們更新值,一次又一次地嘗試…… 155次嘗試之后我們最終得到了:
    <a target="_blank" >代碼3</a>
    上述工作流程的關鍵屬性是,每次我們修改完輸入,加密散列函數(在這種情況下是SHA-256)的輸出是完全不同的:當我們增加計數時,前一次嘗試的散列值并不能透露下一次嘗試所得到的散列值的任何信息。因此,生成有效投票并不僅僅是個“難的問題”,我們可以把它比喻成彩票,每次新嘗試都會給你一個隨機的輸出。同時我們也可以通過更改所需前綴的長度來調整彩票的賠率:
  10. SHA-256校驗和中的每個字符都有16個可能的值: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f.
  11. 為了生成有兩個零前綴的有效散列,發送者平均需要256 (16^2)次嘗試。
  12. 將要求變為5個零平均會需要1,000,000 (16^5) 多次嘗試……關鍵是,我們可以輕易提高成本,讓發送者找到一個有效散列需要耗費更多CPU周期。
    我們可以在一個現代CPU上計算多少個SHA256校驗和?它的成本取決于信息大小,CPU 架構和其他變量。如果你對此感到好奇,可以打開控制臺,運行一個基準測試程序: $> openssl speed sha.
    最終結果是,生成有效投票對于發送者來說是“昂貴的”,但對于接收者驗證仍然是微不足道的。接收者散列交易(一次運算)并且核實校驗和中包含所需的散列沖突前綴……太好了,那么這對我們的P2P系統有什么用呢?上述工作證明機制使我們能夠調整提交投票的成本,從而使破壞系統的總成本(即假冒足夠多的有效投票來確保特定結果)高于攻擊系統能夠獲得的價值。
    注意,“生成消息的高成本”在很多其他環境中是個有用的屬性。例如,垃圾郵件能夠運作恰恰是因為生成信息特別便宜。如果我們可以提高發送電子郵件的成本,例如要求工作量證明簽名,那么我們可以通過使成本高于利潤來打破垃圾郵件的商業模式。

<strong>建立最小可行區塊鏈</strong>

我們已經談到了很多基礎內容。在討論區塊鏈如何幫助我們構建安全的分布式賬簿之前,我們來快速地扼要概述一下我們的網絡設定,屬性和待解決的挑戰(如圖10所示):


圖10
  1. Alice和Bob完成交易并記錄在各自的分類賬簿中。 完成后,Bob有一個來自Alice的受公鑰基礎設施保障的借據。
  2. Bob和John完成一個交易,他將Alice的收據轉移給John。Bob和John都更新了賬簿,但是Alice對交易尚不知情。
    2-1. 皆大歡喜的情景:John要求Alice償還他的新借據,然后Alice得到Bob的公鑰,核實了他的交易,如果交易有效,她向John支付所需金額。
    2-2. 不太歡樂的情景:Bob用沒有記錄他和John交易的舊賬簿與Katy創建了一個重復消費交易,然后Katy和John同時出現在Alice家卻發現只有一個人能得到報償。
    由于分布式賬簿的“弱一致性”,重復消費是有可能的:Alice和Katy都不知道John和Bob之間的交易,這就使Bob利用了不一致性為自己謀利。有解決辦法嗎?如果網絡很小,所有參與者都是已知的,那么我們可以要求每個交易在被認定為有效前必須被網絡“接受”:
  3. 全體一致:每當交易發生時,雙方聯系所有其他參與者,告知他們交易的有關內容,等所有參與者“同意”后才能提交交易。因此,所有分類賬簿同時更新,不可能發生重復消費。
  4. 法定人數一致:提高網絡的處理速度和可用性(即如果有人離線,仍然可以處理交易),我們可以將上述全體一致的情況放寬到法定人數一致(整個網絡的50%)。
    對于參與者已知且已核實的小型網絡,以上任何一個策略都能立即解決問題。然而,兩種策略都不能擴展應用于更大型的動態網絡,因為在任何時間點都無法得知參與者的總數和他們的身份:
  5. 我們不知道要聯系多少人來獲得他們的同意。
  6. 我們不知道要聯系誰來獲得他們的同意。
  7. 我們不知道在與誰通話。
    注意我們可以用任意通信手段來滿足上述工作流程:當面,通過網絡,信鴿通訊等等!
    由于缺乏網絡參與者的身份和對他們的全局認識,我們必須要放寬限制。雖然我們不能保證任意特定交易都有效,那并不能阻止我們對接受交易有效的可能性做出陳述:
  8. 零確認交易:我們可以在不聯系任何其他參與者的情況下接受交易。這是對交易付款方誠信的完全信任——相信他們不會重復消費。
  9. N確認交易:我們可以聯系網絡中(已知)參與者的一部分子集,讓他們驗證我們的交易。 我們聯系的節點越多,抓住企圖欺詐我們的惡意方的可能性越大。
    “N”的值多大為好?答案取決于要轉移的金額以及你與對方的信任度和關系。如果金額很小,你可能愿意接受更高的風險級別,或者你會根據對另一方的了解程度來調整風險容忍度。或者,你會做些額外的工作,聯系其他參與者驗證你的交易。在任一情況下,處理交易速度(零確認是瞬時發生的),額外工作和交易無效的風險之間都存在一個折衷。


    圖11

    到目前為止一切順利。不過,有個額外的并發問題我們必須考慮:我們的系統依賴于來自其他節點的交易確認,但是沒有什么能阻止惡意用戶按照所需生成盡可能多的偽造身份(回想一下,我們系統中的“身份”僅僅是個公鑰—私鑰對,隨便就能生成)來滿足 Katy的驗收標準。
    Bob是否要進行攻擊是一個簡單的經濟學問題:如果收益高于成本,他就會考慮實行攻擊。相反,如果Katy可以使運行攻擊的成本高于交易的價值,那么她應該是安全的(除非Bob和她有私仇或者愿意在交易上賠錢。但這不在考慮范圍內)。為了讓問題更明確,我們做出如下假設:

  10. Bob轉移10個chroma給Katy。
  11. 生成偽造身份和交易響應的成本是0.001chroma:維持電腦運行的能源成本,支付網絡連接等。
    如果Katy要求1001次確認,對于Bob來說實行攻擊就沒有(經濟)意義了。反之,我們可以為每次確認增加一個工作量證明要求,將每次有效響應的成本從0.001chroma增加到1chroma,即找到一個有效散列會占用CPU時間,轉化為更高的能源費用。因此,Katy只要求11次確認就可以達到同樣效果的安全保障。
    注意,Katy每次請求確認也會導致一些成本:她必須耗費努力來發出請求,然后驗證響應。此外,如果生成確認和驗證的成本是一對一的,那么Katy將承擔與交易價值相等的總成本來驗證交易……當然,這沒有任何經濟意義。這就是為什么工作量證明的不對稱很關鍵。
    很好,問題解決了,對吧?在這個過程中,我們似乎……造成了另一個經濟困境。我們的網絡現在驗證每個交易產生的成本與交易本身的價值相等甚至更高。雖然這是對惡意參與者的經濟威懾,但合法參與者怎么會愿意為他人承擔成本?理性的參與者根本不會,這毫無意義。

<strong>添加“區塊”和交易費用激勵</strong>

如果網絡中的參與者必須承擔成本來驗證彼此的交易,那我們必須為他們提供經濟激勵。事實上,我們至少要抵消他們的成本,否則一個“空閑”參與者(任何沒有提交自己交易的人)將會代表網絡繼續累積成本——這樣是行不通的。還有一些我們需要解決的其他問題:

  1. 如果驗證交易的成本等于或高于交易價值本身(為了制止惡意參與者),那么總交易價值是凈零,或負數!例如,Bob把10個chroma轉移給Katy, Katy又花了10個chroma來補償其他節點來驗證交易,Katy很傷心。
  2. Katy如何為確認進行支付?如果那是它自己的交易,就會有一個遞歸問題。
    讓我們從顯而易見的問題開始:交易費用不能和交易本身的價值一樣高。當然,Katy不必原封不動地把所有價值都用于確認交易(比如,她可以分配一半的價值用于確認),但這樣又變成了一個利潤問題:如果剩余利潤(交易價值減去驗證費)足夠高,欺詐的動機仍然存在。相反,理想情況下,我們希望承擔最低的交易費用,并仍然對惡意參與者有強大的威懾,有解決方案嗎?
    我們可以通過允許網絡中的參與者一次性匯集和確認多個交易來激勵他們,也就是對一個交易“區塊”進行確認。這樣做能讓他們匯總交易費用,從而降低每個單獨交易的驗證成本。


    圖12

    一個區塊僅僅是(一個或多個)有效交易的集合——把它想象成等同于物理分類賬簿中的一個頁面。反過來,每個區塊包含對前一交易區塊(上一頁)的引用,整個分類賬簿是區塊的鏈接序列,也就是,區塊鏈。想想上面的案例:

  3. Alice和Bob生成新交易并公布到網絡上。
  4. Chris正在等著聽新交易通知,每個交易通知包含發送方愿意支付于網絡驗證和確認交易的交易費用:
    2-1. 直到有直接的經濟激勵(交易費用總額大于他的成本)來完成必要工作來驗證未決交易,Chris對未確認的交易進行匯總。
    2-2. 一旦過了這個門檻,Chris首先驗證每個未決交易,方法是核實所有的輸入都不是重復消費。
    2-3. 所有交易都被核實后,Chris在未決列表上再添加一個交易(上圖中用綠色標識),將所發布交易的費用額轉移給他自己。
    2-4. Chris生成一個包含未決交易列表的區塊,引用前一區塊(使我們可以遍歷區塊并看到整個分類賬簿),并執行工作量證明挑戰,來生成符合網絡既定規則的區塊散列值,例如N個前導零的部分散列沖突。
    2-5. 最后一旦Chris發現有效區塊,他就分發給所有的其他參與者。
  5. Alice和Bob在等著監聽新的區塊公告,尋找他們在列表中的交易:
    3-1. Alice和Bob驗證區塊的完整性,也就是驗證工作量證明和區塊所包含的交易。
    3-2. 如果區塊有效,他們的交易在列表中,那么交易就被確認了!
    我們在這里前進了一大步。以前我們的網絡中只記錄了一種類型——簽名的交易。現在我們簽名了交易和區塊。前者由參與交易的個人生成,后者由有意通過驗證和確認交易收費的各方生成。
    另外請注意,上述方案需要系統中的最小交易量來維持個人創建區塊的動機:交易越多,單個交易所需的費用越低。
    Alice宣布了一個新的交易,并收到一個Chris確認它的有效區塊。有了一個確認,那其余的呢? 而且Chris(但愿)不是唯一一個受到激勵來生成區塊的參與者。如果其他人同時生成了另外一個區塊,這兩個區塊哪個“有效”?

<strong>競爭以贏取交易費用</strong>

通過驗證交易區塊來引入匯總費用的能力,它了不起的部分在于,為網絡中的新參與者創造了一個角色,他們有直接的經濟激勵來保障網絡。你現在可以通過驗證交易賺取利潤,可以盈利的地方,競爭就隨之而來,這只會加強網絡——一個良性循環和聰明的社會工程!
即便如此,驗證交易的競爭動機又產生了另一個有趣的困境:我們如何在分布式網絡中協調區塊生成工作?簡短的回答,你可能已經猜到了,我們不會去協調。我們在系統中再額外添加一些規則,看看它們如何解決這個問題:

  1. 允許任意數量的參與者參加(“競賽”)創建有效區塊。不需要協調,感興趣的參與者反而會去找新的交易,決定是否想要以及何時想要嘗試生成有效區塊,領取交易費用。
  2. 生成有效區塊時,立即廣播到網絡中。
    2-1. 其他節點檢驗區塊的有效性(檢查每個交易和區塊本身的有效性),如果有效,就將其添加到他們的分類賬簿中,然后最終重新廣播到網絡中的其他節點。
    2-2. 添加以后,新的區塊成為分類賬簿的“最高檔”。如果同一個節點也在生成區塊,那么他們需要中止之前的工作重新開始:他們現在需要更新對最新區塊的引用,并且從最新區塊中包含的未確認列表里刪除所有交易。
    2-3. 完成以上步驟后,開始創建新區塊,希望他們第一個發現下一有效區塊,這樣他們能夠領取交易費。
  3. 重復以上步驟直到宇宙熱寂。
    生成區塊的所有參與者之間缺乏協調意味著網絡中會有重復的工作,這也OK!雖然不能保證單個參與者獲得特定區塊,只要參與網絡的預期價值(獲得區塊的概率乘以預期支出,減去成本)是正的,系統就可以自我維持。
    注意,接下來要驗證交易的節點之間沒有一致性。每個參與者匯總自己的列表,運用不同策略來使預期收益最大化。此外,由于我們工作量證明函數(為區塊SHA-256校驗和找到一個部分散列沖突)的屬性,增加獲得區塊概率的唯一方法是耗費更多的CPU周期。


    圖13

    還有一個需要應對的警告:兩個節點可能會幾乎同時發現一個有效區塊,并開始在網絡中傳播——例如上表中的Kent和Chris。因此,一部分網絡最終可能會接收Kent的區塊作為最高區塊,其余的會接受Chris的區塊。現在怎么辦?

<strong>解決鏈沖突</strong>

再次的,我們將采取一種不干涉的手段,讓區塊生成過程中的任意屬性來解決沖突,雖然還有另外一個規則:如果檢測到多個鏈,參與者應立即切換到最長的鏈,并在其頂部創建。我們來看看這在實踐中如何工作:


圖14
  1. 一些節點會開始在Kent的區塊上建立新區塊,其他人在Chris的區塊上建立。
  2. 在某一時刻,有人會發現新的區塊,開始在網絡中傳播。
    2-1. 其他節點接受新的區塊時,與一個不同的最高區塊合作的那部分網絡將檢測到現在有一個更長的鏈可替換,這意味著它們需要切換到更長的鏈上面。
    2-2. 作為被丟棄區塊的一部分但尚未被確認的任何交易都被放在未決列表中,重新開始這個過程。
    2-3. 可能的情況是,競爭狀況會持續多個區塊,但最終某個分支會超過另一個,網絡的其余部分將收斂到同一個最長的鏈上。
    很好,我們現在有了一個策略來解決網絡中不同鏈之間的沖突。具體來說,網絡通過將交易記錄在鏈接的區塊列表中來允諾交易的線性化。但至關重要的是,它沒有允諾個別區塊可以“保證”任意一個交易的狀態。想想上面的案例:
  3. Alice將她的交易發送到網絡。
  4. Chris生成一個確認她交易的有效區塊。
    但是鏈中有一個分叉,當稍后網絡收斂在Kent的分支鏈上時,Chris的區塊會被“移除”。因此,即使當Alice接收到一個有她交易的區塊,她也不能確定這個區塊將來不會被撤消!

<strong>沒有哪個區塊是“最后一個”</strong>

沒有哪個區塊是“最后一個”,永遠不會有。 如果檢測到更長的鏈,任何區塊都可以被“撤消”。實際上,檢測分叉相當快速,但總是存在出現替代鏈的可能。但是,我們唯一能說的是,特定區塊在鏈中的位置“更深”,它被撤銷的可能性就更小。因此,也沒有哪個交易可以被視為“最終一個”,我們只能陳述它被撤銷的概率。

  1. 0確認交易:不必等待任何包含交易的區塊就可以進行交換。
  2. 1確認交易:最新的有效區塊包含交易。
  3. N確認交易:有一個包含交易的有效區塊,以及N-1個區塊建立在那個有效區塊上。
    如果愿意接受風險,你可以總是選擇采用0確認交易:沒有交易費用,也不必等待確認,不過你要對對方抱有極大的信任。
    但如果你想降低風險,就要等待一個或多個區塊建立在你交易所在的區塊上。你等的時間越長,在包含你交易的區塊上建立的區塊越多,出現一個撤銷你交易的替代鏈的可能性越低。
    “撤消”指的是參與者使網絡接受一個替代交易,將資金轉移到除你以外的其他帳戶上的情形——例如,你完成交易,移交組件,獲得收據,但攻擊者接著會注入一個交易,把同樣的資金“雙重消費”到另一帳戶。
    為什么區塊鏈的長度可以很好地代表交易“安全性”?如果攻擊者想要撤消一個特定交易,那么他需要建立一個鏈,鏈開始于列出交易區塊的前一區塊,然后建立一個由其他區塊組成的、比網絡當前所用鏈更長的鏈。因此,區塊越深,通過創建新鏈來替換它所需要的計算量就越大。鏈條越長,運行攻擊的代價就越昂貴。
    在接受交易之前,你要等待多少個區塊?它沒有一個明確的數字,答案取決于網絡的特性(生成每個區塊的時間,交易和區塊的傳播延時,網絡大小等)以及交易本身:它的價值,你對另一方的了解,你的風險預測等。

<strong>(最小可行)區塊鏈的屬性 </strong>

【個體交易的安全受公鑰基礎設施保障】
驗證交易真實性:惡意方不能偽裝成他人,代表他人簽名交易。
交易真實性認證只與公鑰—私鑰對有關。不需要將密鑰對與參與者其他數據鏈接的“強認證”。事實上,單個參與者可以生成和使用多個密鑰對!從這一層面上看,網絡允許匿名交易。
不可否認性:事實發生后,參與方不能聲稱交易沒有發生過。
完整性:事實發生后,交易不能被修改。

【交易一旦被創建,就被廣播到點對點網絡中】
交易一旦被創建,就被廣播到點對點網絡中

【一個或多個交易聚集在“區塊”上】
一個區塊可以驗證一個或多個交易并領取交易費用。
這使得交易費用與每個交易的價值相比仍然是很低的。
有效區塊必須有有效的工作量證明解決方案。
有效的工作量輸出很難生成,但驗證起來很便宜。
工作量證明用于提高生成有效區塊的成本,使運行對網絡的攻擊成本更高。
任意節點都能用于生成有效區塊,一旦有效區塊生成,就被廣播到網絡中。
任意節點都能用于生成有效區塊,一旦有效區塊生成,就被廣播到網絡中。
每個區塊有一個與前一有效區塊之間的鏈接,使我們能夠遍歷網絡中所有交易記錄的完整歷史。

【節點們尋找新的交易通知,將它們并入分類賬簿中】
在區塊中包含交易,作為交易“確認”,但這一事實本身不會將交易“最終化”。相反,我們以鏈的長度代表交易的“安全性”。每個參與者可以選擇自己的風險承受水平,從0確認交易到等待任意數量的區塊。
所有上述規則和基礎設施的組合提供了一個去中心化、點對點的區塊鏈,用于實現簽名交易排序的分布式一致性。說得有點多,我知道,但它也為一個大難題提供了巧妙的解決方法。區塊鏈的單個部分(會計,密碼技術,網絡,工作量證明)并不新穎,但所有這些部分結合起來形成的新屬性很值得關注。

原文鏈接:https://www.igvita.com/2014/05/05/minimum-viable-block-chain/
感謝llya授權《程序員》翻譯本文
譯者:汪曉明,朝夕網絡創始人,前Beltal CTO。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容