鴕鳥區塊鏈實驗室出品
大家好,鴕鳥區塊鏈實驗室今天開始廣播。
這兩天的心情,估計就跟過年一樣的感覺吧。
之前的那些日子,一些人慘淡離場,一些人冷靜下來思考。
但是,無論如何,靜下心來思考,永遠是對的選擇。一方面是,不可避免的價格決定信仰;另一方面是,區塊鏈作為多種技術的組合,有太多概念可被偷換、炒作、混淆。
所以,在這個特殊的時間裡,鴕鳥區塊鏈實驗室,帶著一些問題再來回溯下比特幣的設計邏輯。中本聰的偉大之處在於,將一系列技術巧妙地組合在一起,用經濟學原理解決了技術上無法解決的問題。任何單個的技術特性並不構成區塊鏈的本質。
當對區塊鏈進行不同角度的解讀成為了常態,這使我特別想穿越時空,回到中本聰設計比特幣的現場,探究他是如何思考的?背後的邏輯是什麼?所以我嘗試用這篇文章探討中本聰是如何一步一步設計出一個「點對點的電子現金系統」,如何用邏輯串聯起這些區塊鏈所用到的核心技術:
點對點網路、非對稱加密簽名,哈希函數,UTXO、智能合約、分散式賬本、共識機制、區塊鏈式結構等
其中,中本聰貢獻了UTXO交易記賬方式,並創新地用經濟激勵組合起這些技術。
接下來,我們開始用提出問題,解決問題的思路,組合這些技術。
問題一: 怎麼理解電子現金和記賬?
既然我們要設計的是電子現金系統,我們先來探討一下電子現金的概念。
如果給出以上一筆記賬,我們想有哪些情況可以這樣記賬?
情境1、銀行系統中,V神向本聰支付1元錢
應對這次交易,銀行會在自己的賬目上進行一次劃轉記賬:
這筆記賬本質上是債務的轉移,本來銀行欠V神1元,變成了銀行欠本聰1元。也就是本聰有權利用這筆記賬向銀行兌現1元。
情境2、現實中,本聰問V神借1元錢
這時V神會打一張白條給本聰:
將來,本聰可以用這張白條,向V神索要欠款。
情境3、點對點網路中, V神向本聰發送1元電子現金
這時,V神其實發送的是條記賬,記賬中的1元如果所有人都認可,即所有人都願意兌現,那麼基於比特流的這筆賬目就可以作為電子現金在網路中自由流通。
情境4、V神向本聰支付一元現金
這種情況是,實體現金完成了物理轉移後的記賬,但貨幣本質上也是這樣一種賬目,本聰拿著1元現金,最終要向社會去兌現這1元紙幣的價值。
我們可以看到,雖然四種情境不同,卻可以用相同的記賬方式,而電子現金系統本質上,是在網路上用賬本記錄價值的轉移,但網路的自由屬性,又讓價值的傳輸面臨著必然風險。
問題二:電子現金在單筆轉賬中可能產生哪些問題?
為了方便分析,我們借用情景3「V神向本聰發送1元電子現金」,暫時先不管電子現金的發行問題。
當我們用以下記賬方式,在網路中收發電子現金,會有什麼問題?
1.我們並不知道發出或接收這筆交易的人是本聰或V神本人,即現實身份和網路身份無法真實對應;
2.本聰或V神可以不承認這筆記賬,謊稱未發生交易;
3.本聰或V神篡改交易;
對應這三個問題的實質是:
1.身份(與交易對應)的真實性:確認交易的發起方和接收方。
2.交易的事實性:交易是否真的發生,不可偽造。
3.事實的不可篡改性:交易發生後無法篡改。
針對這些問題,我們尋找解決方案。
問題三:怎樣解決交易的真實性?保證交易不可偽造、無法篡改?
1、傳統思路:中心化擔保記賬
我們常用的方式是用可信第三方擔保,比如,V神和本聰叫好朋友BM來做擔保:
記賬格式(一式三份)
這種記賬方式學術名詞為「三式記賬法」。基於BM的公信力,BM可以認證V神和本聰身份的真實性,雙方交易的事實性,此後任何一方篡改交易都可以找到BM的記賬副本實現仲裁。
但是,如果BM作惡呢?
問題四:如何防止仲裁者作惡?
針對如何防止仲裁者作惡這個問題,實際上我們是在思考,如何在一個網路中進行點對點自由支付,既能夠不藉助中間人,還能保證支付的安全。
為了達到這種安全,我們首先引入一個技術:非對稱加密簽名。
先簡單解釋一下數字簽名生成和校驗的過程:
1 生成:用generateKeys方法把keysize輸入,產生一對公鑰和私鑰。
2 簽名:將一段消息和私鑰作為輸入,輸出簽名消息。
3 校驗:將一段消息和簽名消息和公鑰三者輸入,輸出為真,則簽名屬實。
我們用非對稱加密簽名可以解決兩個問題:
1.公私鑰即身份,解決身份問題,並有一定的匿名性,錢包地址即是公鑰的哈希值;
2.用私鑰對應的公鑰可以校驗交易的真實性。
我們用數字簽名實現以下記賬:
此支付中,本聰可以用V神的公鑰校驗支付,確認是V神支付並簽名的,實現了:
1.真實性:只有私鑰擁有者才能,對自己的支付進行簽名。
2.事實性:公鑰校驗支付,證明支付已發生,並且沒有私鑰,無法偽造。
3.不可篡改性:沒有私鑰,不能修改已確認發生的交易。
那麼又有一個新問題,如果是私鑰擁有者篡改交易呢?
另一方面,以上支付僅在兩人之間發生,實際是,支付發生在更大規模的網路中,網路中各節點如何確認,支付是否被本人篡改,確認賬戶中是否有足夠餘額?
問題五:在P2P網路中,隨著節點和交易的增多,如何保證支付的有序性和不可篡改性?
假設在第一筆交易(交易1「V神向本聰支付1元」)的基礎上多加一些交易:
·交易2V神向本聰支付2元
·交易3本聰向v神支付1元
·交易4本聰向BM支付2元
首先,在P2P網路中,為了讓每個節點,能驗證全網的所有支付,每筆支付必須向全網廣播,每個節點才能收到並記錄下全網支付,進行判斷。
當V神收到交易2和交易3時,因為是兩個節點之間的有限交易,所以比較容易作出判斷交易的有效性。
當引入第三個節,BM收到交易4時,作為新加入的節點,要重新驗證之前所有的交易,判斷本聰賬戶上是否有餘額支付,所以需要對之前的交易進行檢索和引用。而本聰在進行支付4中也需要提供證明,佐證自己的支付能力。
此時,為了已發生交易的不可篡改,校驗支付,我們再引入一個技術哈希指針:
哈希函數簡單解釋,是任意長度輸入經過哈希計算,能生成固定長度的輸出。
哈希函數有三個特性:
1.輸入和輸出有唯一的對應關係,兩個輸入即使差別很小,也得不到同一哈希值。
2.已知哈希值不能反向計算輸入值。
3.哈希計算沒有規律,要得出特定值或者特定域哈希值,只能不斷隨機嘗試輸入。
這些特性可以用來方便地鏈接兩筆支付:
一方面,哈希指針指向的前一筆支付,可以很方便對前一筆交易內容計算哈希值,判斷是否與本哈希值相等,確定前後關係;
另一方面,前一筆交易有任何細微改動,都得無法算出相同的哈希值,保證了確認發生支付的不可篡改性。
如下,用哈希指針將支付1、2、3、4連接成鏈,一方面可以確認所有支付的前後順序,另一方面可以保證已發生的支付不可篡改。
通過前三筆交易可知,本聰賬上還有支付2中收到的2元,本聰可以在支付4用哈希指針直接引用支付2,即用V神支付給他的2元付給BM。
當BM收到這筆支付後:
1.可以通過哈希鏈條,確保之前的每一筆交易未被篡改過。
2.如果不放心,還可以用本聰和V神的公鑰驗證所有交易的真實性。
3.審計所有交易,確認本聰對支付2的引用有效無誤的。
至此,我們用非對稱加密技術、P2P網路廣播和哈希鏈式結構在有限節點系統中實現了:
1、非對稱簽名解決了去中間人的點對點支付,確保了支付對應唯一網路身份(即公私鑰)的真實性,不可偽造性。
2、賬本記錄已發生的支付,可以按照前後順序用哈希指針依次連接,保證不可篡改性,同時方便在賬目中引用支付。
但是在現實中,我么面臨的是更大規模的點對點支付需求,引發我們新的思考:
1.在支付規模極快增長後,我們應該選用什麼樣的記賬才更高效進行交易的記錄和審計校驗。
2.已發生的交易因為哈希鏈式結構不可篡改,但當下發生的雙重支付該如何避免?
例如:本聰在向BM支付2元後,又向第四個人發起支付5,用同一筆2元支付給第四人,而此時第四人有可能還未收到支付4的廣播,甚至全網其它節點收到雙重支付後也無法處理支付4和支付5。
問題六:在大規模、有並行支付需求的情況下,應該如何對交易記賬?
對這個問題,我們通常會選擇基於賬戶來記賬,即對每一筆支付記錄,一個賬戶支付到另一賬戶,並計算支付後賬戶的餘額。
例如,一開始本聰賬戶有3元,V神賬戶有0元,當本聰要支付給V神1元時:
1、檢查本聰賬戶餘額是否充足,如果不充足,就終止交易。
2、在本聰賬戶中減去1元,在V神賬戶中加上1元。
3、此時本聰賬戶有2元,V神賬戶有1元。
而中本聰並沒有用這種記賬方式,而是為比特幣發明了UTXO方案,也是本文開頭介紹的,中本聰運用的少有原創技術之一。
UTXO(Unspent Transaction Output未花費輸出)是基於交易行為的記賬方案。
先簡單做個演示,假設系統獎勵本聰3元,獎勵V神0元,那麼記賬形式為:
由於是系統獎勵,所以這筆支付的輸入(put in)沒有對應的前一筆輸出(put out),只有輸出V神0元,本聰3元。
我們接著用這種格式記錄4筆支付:
分析一下交易1:
基於交易的記賬,就要保障每筆交易的有來源(輸入),有去向(輸出),本交易1中的輸入來源用哈希指針指向了「支付0」中的輸出:本聰的3元。
而輸出則指向V神和本聰的地址,UTXO的特點是,輸入來源(即花費的輸出)作為一個整體輸入,全部消耗,而不是取部分輸入,即在交易1中,輸入的是本聰的3元,而後又向V神地址輸出1元,反向本聰地址輸出2元。
後面的三筆支付的思路一樣,不再贅述。
所以我們說,某人有多少比特幣,指的是此人地址中有多少UTXO(未花費輸出),即我們可以理解為,在UTXO方案中,並沒有我們通常意義上的幣的概念,只有未花費的輸出,一個人可以生成無數的公私鑰對,擁有無數的地址,而這些地址中UTXO的總和需要錢包來管理,本文不對錢包做過多闡述。
UTXO方案在比特幣中的代碼表現為:
1、元數據:交易規模、輸入數量、輸出數量、本次交易哈希值、鎖定時間。
2、輸入:對應之前一筆交易的某個輸出、之前交易的哈希值、前輸出地址和簽名。
3、輸出:接收地址的公鑰哈希值
這種結構中,比特幣腳本代碼能自動處理簽名校驗,支付校驗等工作。對於比特幣的腳本代碼,其實便是智能合約的概念的源頭。
在改進比特幣的歷史上,有過各種對腳本代碼功能擴展的設想,即我們在一個點對點的電子現金系統中,能否通過自動執行的代碼,來實現「滿足某條件下必然執行的代碼」和「點對點支付行為」的結合?
這就是後來的以太坊,本文暫不展開對只能合約進行闡述,有機會在後面的文章推演以太坊的邏輯。
至於為什麼要用到UTXO方案,而不是基於賬戶的方案。我們還是回歸到本節問題四,可能就是對應解決大規模的交易效率,和並行交易的問題。
1、如果我們用基於賬戶的方案,數據記錄的對象是賬戶的狀態,即每個賬戶對應的交易、和對應的餘額。而如果基於交易來記賬,對象則是UTXO,即UTXO對應的地址。
在一個電子現金系統中,公私鑰雖然可實現部分匿名性,但是一旦一個地址和特定的人的行為對應上,匿名性便喪失了,所以大家更願意用更多地址來進行支付交易,由此會產生大量的廢賬戶,和冗餘的數據。
而基於UTXO的方案可以一定意義上保證,每一條記錄的有效性,而從資料庫的層面上,UTXO方案相對而言更節省存儲空間,提高查詢效率。
2、如果,本聰支付給V神1元,和BM支付給本聰1元同時發生,基於賬戶的方案由於沒有辦法同時共享本聰賬戶的狀態,所以沒辦法並行發生。而UTXO方案由於是基於每筆UTXO的狀態,所以可以並行處理關於同一賬戶的多筆交易。
關於UTXO方案,當然還有跟多的點可以深入,包括一些缺點和問題,但本文不展開講,還是回歸到設計的邏輯,我們畢竟是為一種電子現金系統設計資料庫存儲方案,我們對中本聰採用這種方案,偏向於理解為一個支付系統對效率的要求,同時也回答了本節探討的支付系統大規模效率和並行支付問題。
我們接著展開雙重支付的問題。
問題七:如何解決雙重支付的問題?
我們仔細思考雙重支付問題的核心,其實是在大規模的點對點網路中,我們無法解決分散式賬本一致性問題,當一個沒有同步最新最準確賬本的節點時,會受到雙重支付攻擊。
要解決這個問題的本質,是誰來記賬的問題,是所有人都可以來記賬;還是有限的可知節點記賬(pbft、paxos);還是選舉出一個可信的節點,來記錄大家都認可的公共賬本。所以雖然網路是分散式的,但是要解決雙重支付的問題,我們還是選擇用一本可靠的公共賬本來解決。
因為在一個開放的,節點能隨意進出的網路中:
1、無法讓每個節點保持持續更新狀態。
2、節點狀態不可知,無法確認網路中節點是臨時離線還是永久離線。
3、女巫攻擊,及公私鑰生成成本低,如果採用一人一票制,就會有大量低成本節點破壞共識過程。
所以,沒有辦法直接應用有限節點的投票百分比方式,只能選擇一種機制進行競爭記賬。
關於記賬節點是有限的還是無限的,其實牽扯到區塊鏈中常被大家提到的公有鏈、私有連、聯盟鏈問題,和公有鏈競爭公共賬本記賬權的共識機制問題。
此處我們不展開探討,我們還是專註於討論,在一個節點完全自由進出,所有節點都有權利記賬的分散式網路中,怎樣設計一種公式機制進行競爭記賬,通過可靠的分散式公共賬本解決雙重支付問題,達成分散式共識。
提到分散式共識,其實回到了一個點對點的支付網路的本質,即分散式網路的問題,
分散式網路有一個CAP定理:
分散式系統最多在一致性、可用性、分區容錯性之中同時達成兩者。
由於作為一個交易系統,必須達到其中兩者:
可用性:在一些節點故障或作惡的情況下,數據能否正常更新,即支付正常進行。
分區容錯性:因為賬本更新不同步,能否容忍產生錯誤分區(即區塊鏈結構的分叉)。
其中,可用性必然要滿足,分區錯誤必然發生,所以點對點的支付系統必然達不到高度一致性的要求。
至此,我們需要解決的是,在一個低一致性的網路中解決:
怎樣避免女巫攻擊。
怎樣爭奪記賬權(分散式網路的公共賬本),達成共識記賬,避免雙重支付。
問題八:如何解決女巫攻擊的問題?
我們可以這樣理解女巫攻擊,發郵件由於成本非常低,所以我們經常收到垃圾郵件。
所以解決女巫攻擊的核心是,使得攻擊成本大於收益,避免大量低成本的惡意節點爭奪記賬權。此時我們引入工作量證明(POW)的概念。
我們選用哈希函數SHA256,來進行工作量證明。
此時我們回想哈希函數的第三個特性,如果給定下面的哈希函數:
「hash(給定信息+隨機數)=特定域哈希值」
當對給定信息和隨機數進行哈希運算,要得到特定值或者特定域值時,這個隨機數只能用窮舉法得到。
即工作量證明pow的特徵:
1、尋找到特定域的哈希值對應的隨機數很難。
2、用給定信息和隨機值計算哈希值很簡單。
下面列舉一下一些哈希值,有個直觀感受
例:
6797aed6e76de66dcd7ad5fd3fd2d3f4d567
7f6cdc908f908ddae325da4e5acef5fe675ef5
000006e76de66dcd7ad5fd3fd2ae325da4e5
一般哈希運算得到的哈希值類似前兩個,但是當要求得到第三個,甚至第四個哈希值,需要進行大量的窮舉運算,才能試出隨機數。我們一般所說的比特幣挖礦即為尋找隨機數的過程。
再次總結一下POW的特點:
1、只能用窮舉法尋找隨機值。
2、所以尋找隨機值的過程全憑運氣。
3、難度可調:調整0的個數。
4、難度調整可按照一個標準進行:即工作量證明成本高於作惡收益
至此,我們用pow機制解決了女巫攻擊問題,讓爭奪記賬權的行為有了成本。
但同時會出現一個新問題:
如果成本大於收益,怎麼激勵節點去爭奪記賬?
例如:
有一筆1000元的轉賬,記賬的工作量成本調整到1000元,這時候如果花費500元成本才能獲得50%概率的記賬權。對於這種記賬,節點根本沒有足夠的動力,更不用說爭奪記賬。
問題九:怎樣激勵節點爭奪記賬權?
我們想到兩種方式:
·打包交易區塊,對區塊進行記賬。
·對記賬者進行比特幣獎勵,和交易手續費獎勵。
打包交易,使得每次包含的交易變多,收益變多,一定程度上緩解了激勵問題,但是一般一個節點對一個區塊中所有交易進行雙重支付攻擊不現實。
所以中本聰用獎勵比特幣的形式,讓記賬打包這個行為被重金獎勵,使得節點有足夠的激勵去記賬。
這正是比特幣設計最巧妙的地方,在純技術組合之上引入了經濟激勵:
基於這種激勵形式,雖然在技術上雙重支付已被賦予極大的成本,但最終解決雙重支付問題的方式是,讓整個網路中的所有節點有了一致的利益。
1、最開始,記賬節點為了維護比特幣網路,認真記賬,避免每個區塊中的雙重支付和其它問題,使得比特幣支付網路具備了支付功能和價值,而這樣的點對點的支付網路所帶來的價值又讓比特幣本身的擁有了價格,並且由於一定的金融屬性,導致比特幣有價格上漲金融基礎。
2、這時節點礦工們擁有比特幣和算力,如果比特幣網路不可靠,手上持有的幣和挖礦設備會失去價值,所以節點為了一致的利益共識和經濟激勵,會負責地為支付網路記賬,甚至花更巨大成本繼續爭奪記賬權。相應的,全網算力的提升又使得比特幣網路可靠性更強。
3、工作量證明機制和比特幣獎勵機制的結合讓網路所有節點擁有了共同的利益。所以從技術層面來看,工作量證明機制實現的是全網記賬規則的共識;從經濟層面上來看,對通過工作量證明爭奪到記賬權的節點們,又形成可牢不可破的利益共識,所以這兩個層面的共識是相互成全的,缺一都達不到全網形成統一又可靠的賬本。
分析到這,我們對網路運行規則應該有了一個清晰的認識,他的運行原則如下:
1.允許任意節點自由進出網路,節點間進行點對點支付,廣播交易。
2.同時節點可以參與競爭記賬。
3.競爭節點進行窮舉隨機數,進行工作量證明競爭記賬權。
4.試出隨機數的記賬節點打包交易,驗證交易,生成有效區塊,並廣播全網。
5.其他節點收到廣播驗證:交易的有效性和區塊的有效性。
6.節點驗證區塊後更新賬本,並終止工作量證明工作,更新未確認交易池。
7.節點在驗證的區塊後面,尋找新的區塊。
8.循環往複直到永遠。
我們直觀看一下區塊鏈的結構:
針對這個區塊鏈結構提幾個重點:
1.鏈式結構其實有兩層,一層是每筆交易指向前一筆交易,一層是打包交易的區塊,與前一個區塊一相連。我們要意識到一筆交易指向的前一筆交易不一定在區塊鏈的前一個區塊上。
2.Merkle根是,區塊體中記錄的交易用哈希指針一層一層指向一個Merkle根,由於區塊頭很小,區塊體很大,而一個交易只對應一個Merkle根,所以在驗證交易的時候,節點可以通過只下載區塊頭,尋找Merkle根的方式驗證,提高驗證效率。
3.在區塊體的交易中,第一個是幣基交易,記錄著獎勵比特幣的數量和對應記賬礦工的地址。幣基交易即比特幣的發行方式,比特幣每10分鐘打包一個區塊,每個區塊現在獎勵12.5個比特幣,每四年減半。
說到這,雖然為了共同的利益,礦工一般都選擇認真記賬,剔除雙重支付和有問題的交易,但是還會有一個問題:
兩個記賬節點同時發現一個有效區塊怎麼處理?即分叉問題。
問題十:怎樣處理區塊鏈的分叉?
針對這個問題的答案,其實是不處理,區塊鏈有自身的運行規則,區塊鏈網路在運行過程中自然會有一條最長的鏈,而大家都以最長的鏈作為全網的有效公共賬本:
1.不干預,按照交易規則和共識規則自動運行。
2.節點選擇交易最合理,最長的區塊鏈。
3.競爭可能持續多個區塊,最後節點切換到更長的鏈條挖礦。
這種方式的特點:
1、當前區塊並不能保證交易狀態,由最長的鏈條決定
2、確認數越多,新鏈替代成本越高,交易越不可篡改。
所以一般我們會多等一些確認,才認為交易真的成功了,比如比特幣的6次確認。
從本質上講,最長鏈其實是最重的鏈,擁有算力最多的鏈,共識更牢不可破的鏈。
寫在最後:
到這兒,我們已經完整地設計出了一個點對點的電子現金系統。
我們選用點對點的網路,希望構建出,能不通過第三方自由傳輸價值的網路;
我們又用非對稱簽名解決了,點對點網路的身份問題、真實性問題和偽造交易的問題( 只有竊取私鑰才能偽造交易);
在點對點網路中進行記賬、數據存儲時,我們用哈希函數構建了鏈式結構,使得我們的交易有序可追溯,已確認的賬本難以篡改,哈希函數不僅鏈接了支付,更構建了區塊鏈賬本的基礎架構,同時也是後面進行工作量證明的技術方案;
而在解決誰來記賬,構建可靠的公共賬本時,我們運用了工作量證明pow共識機制來進行爭奪記賬權,並創造性地和經濟激勵結合在一起,進一步解決了雙重支付問題,同時使得整個網路有著牢不可破的利益共識。而這種最長鏈代表著有效記賬的機制,又天然解決了區塊鏈分叉問題。
當然,分叉問題其實不需要解決,區塊鏈的世界是個自由的世界,只要有一群節點願意認同其它共識,或者新的技術來構建新的區塊鏈條,完全可以硬分叉出一個新的社區,這也許就是區塊鏈的魅力,它自由,它不懼節點的不一致性和任意進出,我們用一整篇文章來對設計思路進行梳理,最後發現,其實共識才是區塊鏈的靈魂。
而這種共識,正好,也必須是基於利益的。因為,它符合人性;因為,它使共識具有廣泛性。人類社會不缺乏協作,但是鮮有像比特幣這樣,達到如此廣泛和大規模的共識,也許這就是區塊鏈的意義,改變共識的方式,降低共識的成本,提高共識的效率,產生大規模協作的價值。
感謝本文的靈感來源:《最小可行性區塊鏈原理解析》
參考書目:《區塊鏈 技術驅動金融》、《區塊鏈技術指南》
![](https://pic.pimg.tw/zzuyanan/1488615166-1259157397.png)
![](https://pic.pimg.tw/zzuyanan/1482887990-2595557020.jpg)
※美國費城實驗,為證明時空穿梭,真相原來這麼可怕
※中國人民大學啟動大數據區塊鏈與監管科技實驗室!能大力發展創新,又能守住風險底線
TAG:實驗 |