作者:中本聰 (Satoshi Nakamoto) 译者:金晓 摘要:一個純粹的 p2p 版本的電子現金 (cash) 貨幣允許在線支付能夠讓一方直接發送到另一方而不通過一個金融機構。數字簽名提供的這個場景的部分解決方案,但是如果在面對阻止雙重支付 (雙花) 的場景下仍然需要一個信任的第三方那麼現有的方案仍然是缺少主要利益 (不夠好) 的。這個網絡加蓋時間戳到交易上通過對這些交易做 hash 變為一個持續增長的基於隨機算列的 (hash-based) 的工作量證明 (pow) 的鏈上。最長的鏈不僅提供證明對被觀察的發生的事件順序,並且提供證明這條鏈來自最大的 CPU 計算力的池。只要主要的 CPU 算力是不被那些有攻擊網絡性質的節點所控制,他們會成長為最長的鏈並超過那些攻擊者。
這個網絡自身只需要很小的結構。信息被最有效率的方式廣播,並且節點可隨時離開或加入網絡,這些節點接受最長的 Pow 鏈作為他們 (節點) 離開網絡後發生事情的證明。摘要指出,現有的技術讓 p2p 的發送一個交易是可靠的,方法是通過數字簽名的方式,這裡暗含指出比特幣在這個方面使用的也是數字簽名的方式保證交易傳遞。但是隨後就指出,數字簽名的是無法解決雙重支付的,因為數字簽只能保證這個東西是屬於發送方的,但是沒有辦法保證這個東西發給一個人以後不會再發給其他人,因為數據是可以複製的。現有的方案就是發送方和接收方都信任一個第三方作為中介。由這個第三方記錄 A 有一個東西,並把這個東西給了 B 完成了一筆交易。也就是這個第三方具有絕對上帝的權利,而 A 和 B 都是因為 “信任著” 這個第三方交易才能成立。之後給了區塊鏈系統一個很大的介紹,其中指出區塊鏈的幾個關鍵點:時間戳,hash 作為標識,使用 hash 的工作量證明,鏈在一起。提供發生事件的順序表明區塊是 “記錄歷史的”,鏈來自最大 CPU 算力是說明其在 CPU 算力證明的規則下是唯一的,不可被顛覆的。最後說明區塊鏈的結構精簡,節點靈活,暗含這是一個多節點智能共同協作的智能系統。(就是雖然每個節點智能有限,但是所有節點都遵從一套簡單的規則,則整個系統能體現出巨大的力量)
- 介紹 現在 internet 上的貿易絕大多數都要依靠一個金融機構提供第三方信任來處理電子支付。儘管這個系統對大多數交易都工作得很好,但是它依然面對與生俱來的基於信任模型的缺陷。完全的不可逆交易不是真正可能的,因為金融機構不能避免糾紛協調處理。協調調解的成本增加了交易的成本,限制了最小的實際交易規模並且切斷了小型臨時交易的可能。並且在對不可逆服務進行不可逆付款的弱項方面存在更大的成本。因為存在撤銷的可能性,對信任的需要就被分散了。
商戶需要對他們的客戶提高警惕,所以收集他們比起需要的更多信息。一定比例的欺詐被視為是可能的。這種成本和不確定的交易是可被避免的當一個人是通過現實現金交易的方式,但是沒有一個存在的機制來確保交易是通過一個沒有可信方的通信通道進行支付的。
這段體現出區塊鏈是為了解決信任問題,因為第三方機構的存在,信任問題是一種天然存在的問題。現有的機制在維護這種信任會付出很大的成本。另一方面區塊鏈體現出不可逆和不可篡改性,並指出這兩個特性是區塊鏈天然具有的。準確的來說這裡體現出來就是區塊鏈出現的顛覆性理由。回顧目前為止的科技發展,由計算機引領了第三次信息革命,使得信息能夠在網絡中快速流動。但是互聯網雖然能夠使信息快速流動,但是卻沒法實現類似現實世界中的物質轉移。因為信息是虛擬的,但是現實中的物質是實實在在的實體。正是因為互聯網中是虛擬的,所以如果在一個虛擬的世界中模擬一個物體,就可以無限制的複製這個物體,但是同時是沒法模擬現實中的物質轉移的。舉例來說就是假設 A 要給 B 一個物品,那麼在現實世界中是實實在在的物品轉移,而在虛擬世界中就是一條消息記錄,而這條消息記錄是由 A 記錄,還是由 B 記錄,還是由一個第三方記錄呢?顯然不管是 A 記錄還是 B 記錄都不可能讓 A 和 B 都同時認同,因為他們都可以私自更改這個記錄而違約,所以就會找一個第三方來做擔保 (如公證處,中介等),A 和 B 都把自己的信任交給了這個第三方機構做擔保,所以整個體系才能共運作起來。
所以目前對這樣的模擬都是引入了第三方可信機構,人們把信任交給這個第三方,並相信由這個第三方保證模擬物品的唯一性和轉移 (不可複製)。而這個第三方是否真的可信,就是現在運行這套體系所付出的成本。這是目前這套體系的 “天然缺陷”。所以如果想要使用互聯網來模擬現實中的物質轉移,使現實中的物品和虛擬世界中的物品掛鉤,而不需要一個第三方作為這個轉移的擔保,那麼就需要引入區塊鏈機制。區塊鏈可以讓物質的轉移像信息流動一樣快速便捷,同時又由全網的人一起擔保 (全部參與的人一起擔保就相當於天然存在存在不可證偽,除非其中 51% 的人統一口徑違約),來保證在虛擬世界中的物質轉移的可靠。我認為這就是 “區塊鏈” 技術有望成為引領 “第四次技術革命” 的核心原因。
現在需要的就是一個電子支付系統基於密碼學加密證明來替代信任,允許任何兩方能夠直接交易在不需要一個可信的第三方的場景下。計算上保證的不可逆交易將會保護賣方免受欺詐,並且常規的托管機制可以很容易的被實現來保護買方。在這篇論文裡,我們提出一種方案來解決兩次支付問題使用一種 p2p 分布式的時間戳服務來生成交易的時間順序的計算證明。整個系統是安全的只要誠實節點比合作攻擊的節點控制了更多的 CPU 計算力。這裡指出,實際上信任問題是由原來的國家強制力 (銀行),企業大小 (微信,支付寶) 這種感覺或者其他的信任轉移到了 “密碼學加密” 的數學體系上,變為了是否相信數學是可靠的問題。
但是後一句的語言表達上實際上暗含了區塊鏈這個體系實際上是支付方比接收方更具備一點優勢,不是絕對平等的地位,所以接收方需要擔心支付方的攻擊 (二次支付)。最後說明,區塊鏈解決兩重支付,基礎的拓撲結構是 p2p,時間戳是確認交易順序的方式。
- 交易 (Transaction) 我們定義一枚電子幣 (electronic coin) 作為一個數字簽名鏈 (as a chain of digital signatures)。每一個擁有者 (owner) 交易貨幣 (coin) 給下一個人通過數字簽署 (私鑰簽署) 上一個交易和下一個人的公鑰的 hash 並且把這個簽署的結果附加在了這個貨幣的末尾。一個收款人可以驗證這個簽名來確保這個鏈的所有權 (chain of ownership) 這段話在原文表述的過程中直觀來說有點反直覺。因為在第一句話原文是 We define an electronic coin as a chain of digital signatures,也就是說 define coin as chain。這是一個很奇怪的東西,因為直觀來說,coin 應該是一個個的,但是 chain 是一個鏈條,很難把 coin 和 chain 聯繫在一起。
但是比特幣本質上確實就是一個鏈條,這個鏈是由一條條交易按照發生的順序組成的,而 coin 反而是不存在的,coin 是由鏈條上的交易 (transaction) 推算出來的,本身並沒有直接的 coin 出現。同時這裡看到,根據前文的描述,把一個 coin 給下一個人是通過數字簽名的方式,也就是說通過公私鑰的方式證明 coin 的來源與去處。假設現在 A 要給 B 一個 coin,那麼這個過程成為一個交易 (transaction)(比如下圖中的中間那個 Tx),這個交易記錄給 B 多少 coin,和 B 的公鑰 (指明目的地),同時提供 A 可以操作上一個交易 (如圖中的第一個 Tx。比如這個 Tx 記錄的是 X 給了 A 一筆錢,那麼相當於 A 可以操作 X 給 A 的這個交易的輸出),對這兩個共同 hash 後,付款者 A 用自己的私鑰簽署這個 hash,然後加在交易的上面。之後這個交易被廣泛地廣播到其他地方。此時作為一個旁觀者 (礦工),是在自己本地具有第一個交易之前的所有交易的,所以看到這個交易 (中間這個 Tx) 的時候,就可以用付款者 A 的公鑰 (指代的是圖中第一個交易,A 的公鑰從第一個交易中獲得) 去驗證這個交易 (中間這個交易) 的簽名以證實這個交易是不是由付款者 A 本人發出的 (因為私鑰只有 A 持有,只有用 A 的私鑰進行簽署的簽名才能和上一個交易 (第一個交易) 進行驗證通過,證明 A 可以操作第一個交易,具備這筆從 X 轉到 A 的錢)。這樣就證明了這個交易是由付款人 A 發起的。
我們來以中間那個 Tx (交易) 作為參照物。這個 Tx 是由 Owner 1 發起的,由圖中可以看出,hash 的 input 是上一個 Tx (prev Tx) 和下一個接收者的公鑰 (next owner's pub key),這 hash 的結果被 Owner 1 的私鑰進行簽署,並附加在了當前的這個交易上。目前不要和下一個 Tx 連起來看,當 Owner1 簽署完這個 Tx 後,Ta 把這個交易廣播出去,則一旦有礦工 (miner) 將這個交易打包進入區塊並鏈在誠實鏈 (最長的鏈) 上,則表示這個 Tx 是成立的。所以可以看出此時 Owner2 是不會像正常交易那樣立即知道有沒有成功的,而是需要過段時間去 "查看"(這裡是很樸素的說法,也可表示有個東西去輪詢,只要交易被打包了就通知 Owner2) 這筆交易有沒有被打包,是的話就代表交易成功了。這個過程的問題是收款人不能驗證付款人中 (one of the owners) 沒有雙重支付貨幣。
一個通常的解決方案是引入一個可信的中央認證,或鑄幣廠 (mint),來對每一筆交易檢查是否被雙重支付。在每一筆交易後,這個貨幣必須被返回到鑄幣場 (mint) 來發行一個新的貨幣 (coin),並且只有貨幣被直接的從可信的鑄幣廠發行才能保證不被雙重支付。這個解決方案的問題是全部貨幣 (money) 的命運都依靠在這個公司運作的鑄幣廠 (mint) 上,每一筆交易都必須通過他們,就像一個銀行一樣。這裡的鑄幣廠一開始很難理解是什麼意思,其實這是個很簡單的現象,只是這個過程實在是太樸素了以至於沒有人注意到現在的體系就是這樣運作了。比如現在的網上銀行 (或者支付寶),當 A 給 B 轉帳 100 塊錢,實際上是銀行開啟了一個事物 (transaction),讓 A 的賬戶上 - 100 塊,然後讓 B 的賬戶上 + 100 塊。這個 - 100 塊和 + 100 塊實際上就是銀行這個 “鑄幣廠”,銷毀了 A 的 100 塊錢,然後又生產了 100 塊錢給了 B (只不過整個流程都只是體現在信息的流動上)。
正因如此,所以才要保證這個 “貨幣” 只能從這個 “鑄幣廠”(銀行) 發行,並且這個 “鑄幣廠” 被雙方都共同信任,每一筆交易都 “必須” 通過這個 “鑄幣廠” 而沒有其他途徑。現有的體系也正是由銀行 "鑄幣廠"(唯一信任方) 來保證 A 的賬戶 - 100 的同時只有 B 的賬戶 + 100 而不會同時 C 的賬戶也 + 100 (雙重支付)。(當然要是銀行有內鬼和 A 暗地溝通,當 A 轉帳給 B 100 塊的同時給 C 也加上了 100 塊,就發生了雙重支付了。当然現在看起來是 不會發生的,這是因為銀行自身的 “監督” 體制保證的,如每天的對賬,銀行內部的監管等等。而這些監督的代價,就是維護這個體系的成本另一方面,之所以銀行能知道一筆錢是否被雙重花費了,是因為這個銀行具備了當前交易之前的所有的 “歷史交易”,它驗證一個交易是否合法的方式就是去檢查之前的所有交易的結果是否滿足當前這筆交易的要求。我們需要給收款人 (payee) 一個方法去知道之前的擁有者們 (owners) 沒有簽署過更早的交易。
對於這個目的,最早 (earliest) 的交易才是重要的,所以我們不必關心後面的交易是否嘗試去雙重支付。唯一的確保一個交易存在性的方式就是擁有查詢所有的交易。在基於鑄幣廠模型中,這個鑄幣廠擁有所有的交易並且決定哪一個交易最新到達 (which arrived first)。
為了在沒有一個可信任方的情況下完成這件事情,交易必須被公共公告,並且我們需要一個系統讓所有參與者對只對在一個單鏈順序歷史 (which they were received) 上達成共識。
收款人需要證明在每一次交易的期間,大多數節點都同意這是他們第一次收到的 (was the first received)。這裡指出首先是付款人才會發生雙重支付,而收款人是擔心付款人會不會幹這件事情 (廢話,因為利益是由付款人轉移到收款人上的)。“最早的交易才是重要的” 這句話是說,雙重支付發生的基礎是,首先要已經發生過一個交易,然後付款人想無視這筆交易,再次使用這個交易已經用過的貨幣發起另一次交易。所以這個最早的交易指代的是 “已經發生過的交易”。鑄幣廠並不關心想要發起雙重支付的人兩筆 (或以上) 的交易哪筆是這個付款方認為先發生的,他只關心此刻這個付款方發起的這個交易是否 “合法”(也就是之前這個人有沒有已經用過這筆錢了)。所以是鑄幣廠確認哪個交易在前,而不是由付款方決定哪個在前的。那麼此時的這個鑄幣廠並不歸屬任何一個第三方,那麼這個交易就必須被 “廣泛告之”,讓所有參與進來的人都知道這件事情發生了,並且所有人都知道以前發生的所有 “歷史事件” 來驗證此時被廣播的這個交易是否是合法的。但是我們知道,要讓所有參與的人都保持一致是一件相當相當困難的事情,這也就是區塊鏈所解決的問題。而最後一句就是說收款人需要大多數人 (超過 51%) 都認為那個交易是合法的了,那麼才能說明這個交易是合法的。
- 時間戳伺服器 (Timestamp Server) 我們建議的解決方案從時間戳伺服器開始。一個時間戳伺服器的工作是通過把一組數據 (items) 形成的區塊 (blocks) 的 hash 結果 (taking a hash) 加蓋上時間戳 (to be timestamped) 並廣泛的廣播 (publishing) 這個 hash,就像在報紙或者世界性新聞組網絡 (Usenet) 的發帖一樣 [2-5]。這個時間戳證明在那個時間這個數據一定是存在的,明顯的,要得到這個 hash (就只能在這個時間)(in order to get into the hash)。每一個時間戳包含了上一個時間戳在它的 hash 中 (includes the previous timestamp in its hash),形成了一個鏈條,隨著每個新增的時間戳都加強 (reinforcing) 了這個新增之前的所有時間戳。從這部分開始說明的就是礦工 (miner) 所幹的工作。這裡的一組數據就是指很多筆交易,然後把這一組數據打包成了一個區塊 (block),並把這個區塊加蓋上時間戳並做 hash,以此來保證時間的先後順序,也就是要完成第 2 部分所介紹的 “確保歷史順序”。而因為要得到這個 hash 是和當時的時間戳聯系在一起的,所以這個 hash 就標識著時間了。
因為這些區塊是形成一個鏈條的,而區塊的增長是 CPU 算力的證明 (後文會描述),所以因為 hash-> 體現了時間戳 ->hash 被鏈在一起 -> 鏈上一個新的區塊需要耗費 CPU-> 所以之前的 hash 就一定是正確的 (不斷被加強可信度)。
這個圖就是為了說明時間和區塊掛鉤,區塊和 hash 掛鉤,和這些 hash 因為區塊鏈的性質連在一起,所以之前掛鉤的時間戳是不可被篡改的。
4. 工作量證明 (Proof of Work)#
一個基於 p2p 的分布式時間戳伺服器,我們將會需要使用一個類似於 Adam Back's Hashcash [6] 的工作量證明系統,而不是使用報紙或者世界新聞網絡組。工作量證明機制引入對一個值的掃描 (scan) 在 hash 的時候,例如在 SHA-256 下,這個 hash 從一串 0bits 開始。需要的平均工作是所需 0bit 數的指數,並且可以通過執行單個 hash 來被驗證。該部分就是 bitcoin 區塊鏈的另一個核心部分,就是廣泛被人所知的 PoW。在前面章節提到過首先 A 與 B 發生了一筆交易,然後這筆交易被廣播,由於沒有第三方,所以參與的人就是全網的所有節點。這些節點在收到這個交易和其他好多交易後,打包成為一個區塊並加蓋上了 hash。那么現在的問題就來了,如果這些旁觀的礦工都分別收到了很多交易消息並打包出了自己的區塊,那麼怎麼保證全網達成共識呢?
也就是假設 C,D,E 三個礦工都收到交易消息了,然後因為他們收到的交易消息不完全一致,收到的時間也不完全一致,那麼產生的區塊的 hash 肯定天差萬別,有 p2p 經驗的人都知道此時就需要保證 C,D,E 三個人最後需要達成共識,這樣才能保證整個網絡都認同同一個區塊鏈所發生的 “歷史事件的順序”,否則整個體系將會毫無用處。而中本聰在這裡的方式就是引入了 POW 來讓 C,D,E 三個人用付出”CPU 算力 “的途徑去以概率性成功的方式去搶奪記錄區塊的權利 (也就是俗稱的” 記帳權 “)。原文中的 scan 就是指暴力枚舉。因為對於 SHA-256 來說,以目前的密碼學來說,要達到某個符合的條件,只有進行暴力枚舉的方式去獲得,顯然,” 暴力 “的快慢,是由 CPU 的計算能力決定的,而要暴力的規模,就是這個 POW 機制的” 難度 “。
因為要枚舉出這個值是以” 概率性 “的事件 (想象一下去猜測一個不知道密碼的壓縮文件會怎麼暴力破解),但是因為要經過相當多次枚舉,最後平均下來,得到的結果確實可衡量的 (也就是概率的期望值,在有些礦池把這個近似的叫幸運值?不太確定)。對於我們的時間戳網絡,我們實現這個工作量證明通過在區塊中增加一個 nonce,直到一個給出塊的 hash 所需要的 0-bits 值 (位數) 被找到。
一旦 CPU 效率被花費來作為工作量證明,這個區塊不能再被改變去重做相應的工作。之後區塊被鏈在它之後,要改變這個區塊說需要的工作將會包含這個塊之後所有塊所需要的工作量。對於這個區塊” 猜測 “得到的那個滿足要求的值的方式就是改變這裡的 nonce。(因為對於散列函數來說,只要做一點小的改動,結果就會完全不同。獲得滿足要求值得方式就是不斷變換 nonce 使得整個區塊的 hash 滿足難度要求) 所以這個 nonce 就代表了當前這礦工,為了奪取到這一輪區塊的” 記帳權 “,所付出的勞動 (CPU 算力,電費) 的” 證明 “。所以可以直接把 nonce 看作是” 勞動 (工作量) 的證明 “。而後半部分是說明,假如區塊中有更改,那麼這個 hash 就被更改了,那麼就需要重新計算這個區塊的 nonce,也就是要改變前面的區塊,那麼你要把要改的這個區塊一直到目前這輪所需要的區塊全部都計算過來 (付出需要的全部勞動) 才可做到。
這個圖實際上和上一個圖一樣,只是這裡著重體現出每個區塊的內容,指明一個區塊是包含上一個 hash 的 (Prev Hash),並且 Nonce 是區塊中的一個部分。一旦更改 Nonce,Prev Hash, Tx 其中任何一個,那麼這個區塊的 Hash 也會改變,之後的區塊也全部都要改。 工作量證明同時解決了多數決策中決定代表的問題。如果大多數人只根據一個人一 ip 進行投票 (one-IP one_vote),這樣會被任何能夠分配很多 ip 的人破壞。工作量證明本質上是一 CPU 一票 (one-CPU-one-vote)。主要的 (大多數) 的決定是由最長的鏈所代表,最長鏈擁有最大的工作量花費在其中。如果一個大多數 CPU 算力都被誠實節點所控制,那麼最誠實的鏈就會增長得最快且超過其他任何計算鏈。
想要改變一個過去的區塊,攻擊者需要重做這個區塊和所有在這個塊後的區塊的工作量證明,之後還要追趕上並超過現在所有誠實節點的工作。我們之後會展示,一個慢速的攻擊者能夠追趕上 (catching up) 的可能性將會指數級的減少,但後續的塊被添加時。這段補充說到 PoW 實際上就是共同決策選擇代表的問題,等價於搶奪記帳權問題,因為搶到了記帳權,就是選出了代表。
這裡附加上說到為什麼中本聰沒有考慮使用 IP 作為決策的原因,是因為他認為 IP 作為投票權比 CPU 作為投票權容易的多 (是否是最好的選擇不知道,但是目前看來是最好的,不過現在的 CPU 投票權都被” 礦池 “所把控,一定程度上產生了動搖性 (但仍然比控制 IP 好的多),當然也有一些礦池公開宣布自己的算力不超過一個值以維持整個體系的穩定 (找到這個新聞我就補充上鏈接))。
隨後文章再次強調,想要更改區塊,那麼攻擊者將要付出極大的代價,而誠實的鏈因為是規則所倡導的,會在博弈中自然的變為最長的鏈 (後文將會描述)。為了補償不斷增長的硬件速度和隨著時間推移不斷變化興趣的運行節點 (varying interest),工作量的困難度是由一個移動的平均目標決定,就是每一個小時的平均區塊 (就是這個平均目標)。如果這些計算力增長的太快,這個困難度就會增加。
這裡指出這 PoW 的難度是隨整個系統的難度而一起提升的,因為計算機計算的硬件能力是不斷提升的,想想現在的 CPU 挖礦 -> 顯卡挖礦 -> 礦機挖礦,這就是 PoW 的精妙之處。但是這同樣也帶來了一個對 bitcoin 不看好的理由:現在的計算機算力因為參與的人太多,而難度提升的很大,整體的算力也水漲船高,近年更是呈指數增長。那麼要是過了若干年後,bitcoin 的激勵 (後文提到) 所產生的效果不能承受這麼高算力的代價,是否會造成算力的斷崖式下跌?隨之帶來的是 bitcoin 信用的崩潰 (能夠被掌控算力的人攻擊) 而導致 bitcoin 最後突然崩盤?
5. 網絡 (Network)#
運行這個網絡的步驟如下:#
-
新的交易被廣播到全部的節點。
-
每一個節點把新的交易收集進入到一個區塊
-
每一個節點都為自己的那塊區塊進行工作去找到那個工作量證明
-
當一個節點找到了這個塊的工作量證明,它把這個塊廣播給所有的節點
-
節點們只能當這個區塊中的所有的交易都是合法的並且都沒有被花費過才會接受這個塊
-
節點們通過轉向下一個塊的工作量證明並使用這個塊的 hash 作為 (下一個塊的) 前一個 hash 來表示接受這塊。
節點們總是只考慮最長的鏈是正確的並且不斷為擴展它進行工作。如果 2 個節點同時廣播不同版本的下一個塊,一些節點會首先收到其中一個塊,在這種情況下,他們為收到第一個塊而工作,不過另一塊保存下來以防它會變得更長。這個平衡 (tie) 將會被打破當下一個工作量證明被發現的時候並且這個時候一條分支會變得更長。在其他分支工作的人將會轉換到這個最長的分支上。
這段實際暗含了 bitcoin 的” 最大規則 “,也就是所有人都默認最長鏈是正確的。如果這條不能保證,那麼可想而知整個系統是不能工作的。而這個最長鏈是正確的是由後文的” 激勵機制 “所保證的,所以這裡就出現了一個博弈場景:如果現在要創建一個區塊鏈應用,那麼要麼要所有人能夠公認一個規則 (強制力),那麼要用某些方法使人們能夠自主的認同一個規則 (激勵),但是總之因為爭奪區塊是要產生代價的,如何在對這個代價進行” 強制力 / 激勵 “進行博弈,就是一個區塊鏈是否能健康成長的關鍵。
後半部說明一個區塊真正能夠被承認的關鍵:有礦工 (大部分) 以這個區塊為 prev 區塊,並為它構成的 hash 納入新的下一個區塊並為新的區塊工作,那麼這個區塊才是被承認的。所以這裡指明,只有產生的下一個區塊,當前的這個區塊才是” 合法的 “。這條相當關鍵,因為所有的攻擊都會指向這個問題,同時收款者與付款者的不平衡點也是這裡所導致。同時這裡也是區塊鏈運用博弈論的精華體現。
後半部說明一種特殊情況,就是說因為分布式網絡的特點,信息溝通不是實時性的,所以會出現一些節點認可一個區塊而另一些節點認可另一個區塊而造成了區塊鏈的分叉問題,但是這裡解釋了因為所有節點都認為只以最長的鏈為唯一鏈,所以這種情況會在多鏈幾個區塊後被打破,發生區塊重組。
新交易的廣播到所有的節點上是不必要的。只要交易到達了許多節點上,它們就會進入到一個區塊中 (在最長的區塊中 (before long))。區塊廣播是有容忍丟失信息的能力的。如果一個節點沒有收到一個塊,它就會在收到下一個塊的時候發現缺失了它並請求這個丟失的塊。
這段是對上段的一個補充,說明了 51%(大多數) 的重要性,這個大多數並不會以一個直觀的數字體現,而是因為所有人都認可最長鏈,隨著時間的迭代而慢慢迭代出來。
同時這裡提到一個關鍵的地方是:“新交易的廣播到所有節點是不必要的”,這裡旗幟鮮明地表明白了交易是不需要泛洪的。因為想擴散交易本身的信息,在區塊鏈系統中可以不止擴散交易,還擴散區塊。而區塊被擴散是系統中的 “規則”(達到最長鏈)。我認為這可以帶來分布式系統中的一些新的思考。
6. 激勵機制 (Incentive)#
按照慣例 (進行約定),一個塊中的第一個交易是一個特殊交易,它由這個塊的創造者擁有一個新貨幣起始。這樣提供了一種激勵機制讓節點們能夠支持這個網絡,並且提供了一個方式來初始化的分發貨幣進入整個系統當中。因為沒有一個中央授權機構來發布他們 (貨幣)。穩定增加一定數量的新貨幣類似於黃金礦工花費資源開採黃金並引入循環系統當中。在我們的情境下,CPU 時間和電力就是被花費的。這段終於說明前面一直回避的一個問題:貨幣從哪來?在 bitcoin 的系統中,中本聰已經規定了總量就是 2100W 個 bitcoin。而這些 bitcoin 的產生是每產生 21000 個區塊就減半 (以現在約定大約每 10 分鐘產生一個區塊的速度大約到 2140 年產生為 0)。而 bitcoin 產生的方法就是給搶到記帳權的人憑空給予一定量的貨幣,這樣就同時解決的貨幣發行和礦工記帳的獎勵 (就像現實中挖黃金的黃金礦工一樣)。
這種憑空獎勵的方法,就是每個區塊的第一交易,是一個特殊的交易,這個交易就是只有 Input,且對於輸入這個 input 的 output (前一個交易的 output) 是個空 (後文會提到)。因為在第 2 章的注解中已經說到,coin 是不存在的,coin 是由 tx 推斷出來的。就像 A 給 B 100 塊錢,在記錄這個信息的時候可以記錄 A 的 “賬戶 - 100,B 的賬戶 + 100” 這個事物,也可以記錄”A 給了 B 100 塊錢 “這一條交易信息。
區塊鏈選擇了後者。而這個憑空出現的錢,就是一條特殊的交易信息,這種激勵機制同樣可以以交易手續費的方式獎勵。如果一個交易的輸出值小於其輸入值,那麼這個差值就是交易的手續費,手續費被附加到包含這個交易的區塊的獎勵中。一旦一個已決定數目的貨幣 (所有貨幣) 進入這個循環中,這個激勵機制就可完全的轉變為交易手續費並且本系統可以完全避免通貨膨脹 (貨幣總數一定,沒有發行貨幣)。這部分就解釋激勵機制的另一個部分,就是除了憑空獎勵以外,手續費也是礦工的一個收入來源。激勵機制可能會幫助鼓勵節點們保持誠實。
如果一個貪婪的攻擊者能夠收集到比起所有誠實節點更多的 CPU 算力,他就面臨一個選擇:要麼用這個算力來用於二次支付來欺騙別人,或者使用算力來生成更多的貨幣。他應該會發現跟著規則來能獲得更多的利益,這樣的規則支撐他比起其他加入進來的人能夠擁有更多的貨幣,而不是破壞這個系統使得自己的財富受損。這裡就體現出前文討論的博弈關係。
7. 回收硬盤空間 (Reclaiming Disk Space)#
一旦一個貨幣最新的交易收入 (buried) 進入足夠的區塊中,那麼在這個交易前面被消費過的交易就能夠被拋棄來節省硬盤資源。為了同時確保不損害區塊的 hash,交易被 hash 為一棵 Merkle Tree [5],這個 Merkel Tree 只有 root 節點被包含進了這個區塊的 hash。老的區塊能夠被壓縮通過將這個樹的分支進行拔除 (stubbing off branches of the tree)。而內部的 hash 是不必被保存的。
這段是針對區塊鏈系統會不斷產生的區塊問題的一個解決方案。如截至目前為止 (2017/1/28),區塊鏈總數已經超過了 90G,雖然存儲是越來越不值錢了,但是要普通公眾使用是不可能的,因為信息在一直膨脹。這裡就體現出區塊鏈系統的精妙之處,它不存儲交易,而是使用 Merkel Hash Tree 的方式存儲 Root Hash,達到”0 知識證明 “。個人並不一定需要這個區塊,而是具有這個區塊的”hash“(索引) 就足夠了,有 IPFS,公共節點,信任度高節點幫助存儲這些區塊。”0 知識證明 “保證了區塊是絕對正確的而不是偽造的。
一個剔除交易的區塊頭大概會是 80byte 大小。如果我們假設區塊每 10 分鐘就生成一個,那麼 80bytes * 6 * 25 * 365 = 4.2MB 每年。2008 年 PC 系統通常的內存容量為 2GB,按照摩爾定理預言的每年增長 1.2GB 的大小,即使將全部的區塊頭存儲在內存之中都不是問題。原文中已經論述的相當清楚了。
8. 簡化支付認證 (Simplified Payment Verification)#
認證支付不需要運行所有的網絡節點是可能的。
一個用戶只需要保存最長工作量證明鏈的區塊頭部的拷貝就行,這條鏈他只需要查詢網絡節點直到他確信他擁有最長鏈為止,並能夠通過 merkle 的分支連接到它 (這個用戶的交易 transaction) 被加上時間戳的那個區塊中的那次交易。他無法自己檢查這筆交易 (因為只有 hash),但是通過連接到鏈中的位置,他可以看到一個網絡節點曾經接受過它 (那筆交易),並且在它後面增加的區塊也進一步證明網絡曾經接收過它。而回收硬盤空間所帶來的問題就是簡化支付認證的問題,因為有些節點已經不會持有全部區塊信息,這裡相當於是一個博弈了,使用空間換認證的便捷。但總之是不會在信息的安全性上出問題的。因為只要持有了 hash 作為標識,無論什麼節點總是能從其他節點上請求到原始信息。
該圖表明只要有 hash 鏈就行。
這樣的情景下,如要誠實節點控制了網絡,那麼這個驗證就是可靠的,但是當一個算力占優的攻擊者控制網絡的時候就變得更容易受攻擊了。因為網絡中的節點能夠自己進行驗證的時候,這個簡化的方法能夠被攻擊者偽造的 (fabricated) 的交易欺騙,當這個攻擊者能夠持續保證超過全網的算力的時候。
一種保護的策略是接受網絡節點們的警告,當這些網絡節點監測到一個非法的區塊,提醒用戶軟件去下載這個有問題的全部區塊,並警告交易去檢查確認一致性。頻繁收到支付信息的商業機構可能會仍然運行他們的全節點以保持更加獨立的安全性和更快的驗證。這種機制感覺有點像是打補丁的方式。但是好像確實是要削減硬盤存儲的一個解決方案,是存儲與安全便捷的一個博弈結果。很可能有機會在這裡做文章,或許是區塊鏈運用推廣的一個障礙。因為要是保留區塊的節點太少了就有可能造成問題。雖然不能竊取篡改網絡,但是卻可導致崩潰。(當然不是說 bitcoin 網絡,是說一些小型區塊鏈網絡)
9. 組合和分割價值 (Combining and Splitting Value)#
雖然可以獨立的處理貨幣,但是在一次轉帳中為每一分錢都成為一個分離的交易是不明智的 (就是說 coin 不是由元單位組合起來的)。為了允許價值能夠分割和組合,交易包含了多個輸入和輸出。正常情況下會有一個從前面一大筆交易而來的一個單筆輸入或者包括很多更小總數的多筆輸入,然後最後會有兩筆輸出,一個是付款,另一個是找零,不管有多少,全部都返回購買者。
這段終於說到了交易 (Tx) 的構成,前面的論述已經說了很多,只要抓住一個關鍵點就新:一個交易是由前面的交易進行驗證,加上轉移的數目和目的地構成。inputs 就是之前的交易的 outputs。對所有的 inputs 進行驗證,就可得到該交易的付款者的餘額是否大於要轉移的數目。
inputs 關聯的所有 Tx 就是之前的” 歷史信息 “,節點可檢索自己的區塊獲得結果。每個區塊的第一個交易 (激勵交易) 就相當於只有 Input 而沒有 output。這裡要注意的額外一點就是:每次的交易必須被花完,只不過是所有 input 的綜合,其中一部分給了收款方,而找零則是全部返回到購買者上 (回想下前文闡述的鑄幣廠的工作流程)。
這種機制在數目的分割上有天然優勢。現有的貨幣總是有一個最小單位作為” 元 “單位 (比如人民幣:1 分),但是 bitcoin 卻沒有這樣的限制,它只關心差額,而不關心最小元單位。所以這就是價值的組合和分割。
應該被注意到那個全部分配 (fan-out),這裡一個交易依托幾個交易,然後這裡交易又依托於更多的。這不是個問題。這裡是沒有必要去提取交易歷史的完整獨立副本。這裡略難翻譯,我不是很清楚這裡的 fan-out 指代的是什麼。
10. 隱私 (Privacy)#
傳統的銀行模型實現隱私的等級是通過限制訪問信息給相關的參與者和第三方。當需要將全部交易公開廣播的時候,就不能使用這種方法了。但是隱私仍然能夠被維護通過打破在另一個地方的信息流:通過使公鑰匿名的形式。公眾可以看到有一個人發送了一筆數目給另一個人,但是沒有信息能把交易和人聯繫在一起。這和股票交易中釋放的信息等級類似,在股票交易中公開發布的時間和個人的交易是記錄在案的 "tape",但是是會告知誰參與進來。這裡指出使用公私鑰的機制是一種偽匿名化。
作為附加的防火牆 (防範機制),在每次交易中都使用一個新的密鑰對能夠保證把這些密鑰和一個人聯系起來。一些多筆輸入的交易的聯系仍然是不可避免的,因為在這點 (多筆輸入) 揭示了上這些輸入是屬於同一個人的。風險就在於,如果只要其中一個 key 的擁有者被發現了,那麼相關聯的屬於這個人的其他交易也會被揭示。
這裡原文中推薦這樣做是相當有道理的。因為橢圓加密算法是能被量子暴力破解的,在整個系統中要是產生的轉帳公鑰是被公開的。
雖然從密碼學上不應該從公鑰推導到私鑰,但是還是有例外嘛。所以這裡中本聰強烈建議,一次轉帳就使用一對新的密鑰對 (因為交易只要被作為 inputs 後那麼作為 inputs 的交易也就沒用了 (注意 9 提到的找零機制,每筆都花完)),那麼就可以保證每次都是新的公私鑰進行交易。後半段是說對於公私鑰和現實中的人的對應關係 (匿名性失效) 的問題,換鑰匙同樣可以防止這點發生,但是要注意因為所有的記錄的全網可查的,所以要是其中一個公私密鑰和人對應起來了,那麼所有關聯的公私密就能和這個人對應起來。
11 計算 (計算)#
我們考慮這樣一個場景:一個攻擊者嘗試去生成一個比現在最誠實鏈還長的替換鏈。即便這樣是可完成的,這也不會拋出這個系統就被任意控制了,比如像憑空創造價值或者拿去本來不屬於攻擊者的錢。節點是無法接受無效的交易作為支付的,並且最誠實鏈從不會接受一個包含無效信息的區塊。一個攻擊者只可以嘗試去改變他自己的一個交易去拿回他最近花掉的錢。最誠實鏈和攻擊者鏈的競爭可以看作是一個 Binomial Random Walk (二叉樹隨機漫步)。成功事件是最誠實鏈擴大了一個區塊,使其 + 1 領先 (lead),同時失敗事件是攻擊者鏈擴大了一個區塊,使得 - 1 差距 (gap)。攻擊者趕上給定的虧損的可能性可以看作是一個 Gambler's Ruin problem (賭博破產問題)。假定一個有無限的信用賭徒從一個虧損開始並且進行潛在無限次的嘗試想要追上保本。我們可以計算他達到保本的可能性 (概率),就是一個攻擊者要追上最誠實鏈,如下所示:
P = 誠實鏈發現下一個區塊的概率
q = 攻擊者發現下一個區塊的概率
qz = 攻擊者花費了 z 個區塊追趕上了
我們假設 p>q,那麼攻擊者追上的概率就會隨著區塊的增加而指數型下降。因為勝算是和他相違背的,如果他不能相當幸運的在早期就趕上,他成功的幾率就會變得更小隨著他落後更多。我們現在考慮一個新的交易能夠被充分的確認讓發送方不能再更改交易的情況要等多久。我們假設付款方就是一個攻擊者,他想要收款方認為他已經付過款了並且之後把這個錢在付款後拿回來,收款方當這件事情發生的時候會被通知警告,但是付款方希望這件事情很久才發生。
接收方生成了一個新密鑰對並把這個公鑰給了付款方在付款方面前很短的時間。這樣就阻止了付款方能夠事先準備好一個在時間之前的區塊鏈,通過持續的工作直到他足夠幸運的走到了很前面,然後在那時執行了這個交易。一個這個交易被發送,這個不誠實的發送者開始為包含替換他交易的版本的並行鏈秘密工作。接收者一直等到這個交易被加入到區塊中並且之後 z 個區塊被附加到著之後。他不知道攻擊者已經做的確切的過程總數 (已經做了多少個塊),但是假設誠實鏈耗費可預期的平均時間產出一個區塊,那麼攻擊者的潛在進展就是一個泊松分布,分布的期望值是
轉換成 c 代码:#
#include<math.h>
double AttackerSuccessProbability(double q, int z){
double p= 1.0 - q;
double lambda = z * (q / p);
double sum = 1.0;
int i, k;
for (k =0; k <= z; k++)
{
double poisson = exp(-lambda);
運行得到結果,我們可以看到概率隨z的指數下降。
q=0.1
z=0 P=1.0000000
z=1 P=0.2045873
z=2 P=0.0509779
z=3 P=0.0131722
z=4 P=0.0034552
z=5 P=0.0009137
z=6 P=0.0002428
z=7 P=0.0000647
z=8 P=0.0000173
z=9 P=0.0000046
z=10 P=0.0000012
q=0.3
z=0 P=1.0000000
z=5 P=0.1773523
z=10 P=0.0416605
z=15 P=0.0101008
z=20 P=0.0024804
z=25 P=0.0006132
z=30 P=0.0001522
z=35 P=0.0000379
z=40 P=0.0000095
z=45 P=0.0000024
z=50 P=0.0000006
求解令P<0.1%的z值:
for (i = 1; i <= k; i++)
poisson *= lambda / i;
sum -= poisson * (1 - pow(q / p, z - k));
}
return sum;
}
P <0.001 q=0.10 z=5 q=0.15 z=8 q=0.20 z=11 q=0.25 z=15 q=0.30 z=24 q=0.35 z=41 q=0.40 z=89 q=0.45 z=340 這裡就是指明,等 6 個區塊是絕對穩妥的方法。 12. 結論 我們提出了一種不依賴信任的電子交易系統。
我們從由數字簽名構成的通常的貨幣框架開始,這提供了一個擁有關係的強控制,但是沒有辦法解決雙重支付的問題。為了解決這個問題,我們提出一種使用工作量證明機制的 p2p 網絡來記錄一個公共的交易歷史,這種機制變為當大多數節點控制主要的 CPU 計算力,那麼攻擊者想要改變是在計算上不可能的。網絡在其非結構化簡單性方面是魯棒的。
節點只需要很少的協同就可以共同工作。他們不需要被認證,因為信息不需要被路由到某個特定的地方而是只需要被盡可能的被發送出去。節點可隨意離開或重加入網絡,接受工作量證明鏈作為當這個節點離開後發生事件的證明即可。
他們根據 CPU 算力投票,表示接受合法的區塊通過擴展這個區塊,拒絕接受非法的塊通過拒絕在這個塊後工作。任何需要的規則和激勵都可以通過這種共識機制來執行。