導語:比特幣作為近年來最成功的數字加密貨幣,引起了全球高度關注,不同于其它數字貨幣,比特幣使用由眾多節點構成的去中心化的分布式網絡來記錄交易信息,這其中的關鍵就是區塊鏈:一個在未來十年可能給金融業和其它行業帶來巨大改變的技術。今天就結合比特幣來了解一下區塊鏈技術。
1、場景描述
想象一下世界上有兩個銀行:銀行A和銀行B,以及兩個用戶:用戶C和用戶D,用戶C還使用了一款第三方支付軟件E。
銀行A用自己的信息系統為用戶記錄賬戶余額,銀行B也用自己的信息系統為用戶記錄賬戶余額,第三方支付E也用一套系統記錄用戶C的賬戶余額,這基本上就是今天的金融世界里的樣子,如下圖:
我們可以很明顯的看出如下事實:
銀行A的系統中記錄了銀行B欠自己800萬美元,同時銀行B的系統中也記錄了自己欠銀行A 800萬美元的事實,也就是說同樣的信息由兩個銀行的不同系統記錄了兩次。類似的信息也在銀行B和第三方支付E中記錄了。
用戶C在銀行A透支了15,000人民幣,在銀行B有存款68,000人民幣,在第三方支付E上還有5,000人民幣的余額,所以只有通過兩個銀行和一個第三方支付的三個系統才能計算出用戶C真正擁有的財產。
我們可以看到,每個銀行都必須花費大量的時間與金錢去開發和維護系統用來記錄信息,更嚴重的是它們需要花更多的時間和金錢在各銀行之間互相檢查對賬,銀行業的數據需要至少兩個不同的系統去記錄,為了確保各方信息都是正確的,需要有高昂的對賬過程。
下面我們做一個改變,只用一張表來記錄上面例子中的所有數據,如下圖:
上面的一張表和之前的五張表記錄的內容是一樣的,唯一的不同是這個表多了一列。有了這張表,銀行與用戶之間不用維護自己的系統,而且最關鍵的是完全省去了銀行之間對賬的流程。所以,為什么全世界不能有一個統一的賬本呢?有些人可能立刻就會說,哪個單一系統有能力維護這個賬本?系統維護這個賬本的成本得多高啊?這個系統如果出故障了對全世界的影響得多大啊?這個中心系統如果在賬本中作弊怎么辦?
為了維護一個統一賬本創建一個中心系統看來是不可行的,那么我們可不可以創建一個共享網絡,所有銀行和用戶都在這個網絡當中,沒有一個中心系統會維護賬本,取而代之的是網絡中的所有銀行和用戶都有這個賬本的最新內容,賬本由網絡中的所有參與者共同維護,這樣就防止了中心系統故障引起的賬本丟失,而且如果有參與者想作弊其它人也都不會同意的,相當于每個參與者都出一份力來保證賬本的安全與穩定。
上面這項技術方案可行嗎?可行;這個技術方案叫什么?區塊鏈;現在有成功的案例嗎?比特幣。
2、區塊鏈概念
區塊鏈是一個在網絡上的去中心化的分布式共享賬本或者數據庫,通過某些技術,可以保證這個賬本或者數據庫的一致性、安全性及可維護性。比特幣是區塊鏈首次大規模應用到全球性網絡的一個案例,區塊鏈技術本身并不局限于比特幣等數字貨幣中,它還可以應用到支付、證券交易、股票交易、物聯網、身份認證、電子合同等很多領域中。
3、比特幣中的區塊鏈
比特幣概述
2008年,一位神秘人士中本聰發表了一篇論文,闡述了比特幣的概念與相關技術,這篇論文被后人成為《比特幣白皮書》,或者《中本聰白皮書》。2009年,中本聰和其它一些人實現了相關技術,系統正式在互聯網上運行,標志著不受各國中央銀行和任何金融機構控制的比特幣正式誕生。兩年以后,中本聰突然在網絡上銷聲匿跡了,一直到現在也沒人知道這個在比特幣世界中相當于創世先知的人物在現實世界中的真實身份。而他創造出來的比特幣,當前的整體價值已經超過了100億美元,每天有幾百萬比特幣在網絡上被交易。
比特幣原理
比特幣運行在基于互聯網的P2P網絡之上,P2P是一個運行在TCP協議之上的應用層協議,在P2P網絡中,接入網絡的每個設備都彼此對等,網絡中不存在中心節點,每個節點都隨機連接很多其它節點,為這些節點提供服務,同時也從這些節點獲取服務,P2P網絡也因此具有去中心化性、可靠性及開放性等特點。近些年最成功的P2P網絡應用發生在文件分享領域,如國外的BitTorrent、國內的迅雷等,都是通過P2P網絡進行文件下載的。
在比特幣的P2P網絡中,每條交易信息都會以一傳十、十傳百的方式被通知到網絡中的所有節點進行驗證,只有網絡上的大部分節點都驗證通過,這條交易才會被記錄到區塊鏈當前的區塊中,在比特幣網絡中平均每10分鐘會生成一個區塊,區塊中記錄了之前10分鐘在網絡上的所有交易,每個節點都有生成區塊的權利,只要節點在這10分鐘內能計算出一道特定數學題的解,其它節點就會承認這個區塊并且把區塊添加自己的區塊鏈中,得出解的節點會得到一定數量的比特幣作為獎勵。在比特幣網絡中,試圖生成區塊并得到獎勵的節點通常被稱為礦工,生成區塊的過程被稱為挖礦,從2009年開始,動態調整的數學題的難度使得比特幣網絡中平均每10分鐘就會生成一個區塊(有一個礦工得出數學題的解),隨著每次區塊的生成,都會生成一定數量的比特幣作為獎勵付給此礦工,開始時每個區塊生成的比特幣獎勵為50個,這個數量每四年就會減半,到2140年以后比特幣的數量會被固定在2100萬枚,屆時不會再有新的比特幣生成。
任何機器都可以運行一個完整的比特幣節點,一個完整的比特幣節點包括如下功能:比特幣錢包,允許用戶在比特幣網絡上進行交易;完整區塊鏈,記錄了比特幣歷史上的所有交易,通過特殊的結構保證歷史交易的安全性,并且用來驗證新交易的合法性;礦工,通過記錄交易及解密數學題來生成新區塊,如果成功可以賺取獎勵;路由功能,把其它節點傳送過來的交易數據等信息再傳送給更多的節點。在比特幣網絡中的節點,除了路由功能以外,其它的功能都不是必須的,有的節點只有錢包功能,有的節點只負責挖礦。
區塊鏈的數據結構
比特幣的區塊鏈中記錄的是交易信息,每個完整節點都在本地保存有一份完整的區塊鏈,每個完整的區塊鏈中都記錄了從2009年比特幣誕生之日起發生的所有交易信息,每當有一個新交易申請產生時,節點都可以通過完整區塊鏈驗證這筆新交易的正確性,被驗證通過的交易會被記錄到下一個將要生成的新區塊中。每個區塊由包含元數據的區塊頭,以及包含之前一段時間內交易信息的區塊主體組成,區塊頭的大小是80字節,區塊主體通常都很大,如果平均一個區塊包含400筆交易的話,那么區塊主體通常會比區塊頭大1000倍以上。所以區塊主體只負責記錄交易信息,而區塊鏈的大部分功能都是由區塊頭實現的。
區塊頭中主要包括如下信息:
版本號,4字節,標示軟件及協議的相關版本信息;
父區塊哈希值,32字節,引用的區塊鏈中父區塊頭的哈希值,通過這個值每個區塊才首尾相連組成了區塊鏈,并且這個值對區塊鏈的安全性起到了至關重要的作用,在后面會有詳細介紹;
Merkle樹根,32字節,這個值是由區塊主體中所有交易的哈希值再逐級兩兩哈希計算出來的一個數值,主要用于檢驗一筆交易是否在這個區塊中存在;
時間戳,4字節,記錄該區塊產生的時間,精確到秒;
難度值,4字節,該區塊相關數學題的難度目標;
Nonce,4字節,記錄解密該區塊相關數學題的答案的值;
每個區塊的區塊頭中記錄了其引用的父區塊的哈希值,這個哈希值是通過SHA256算法對父區塊的區塊頭進行二次哈希計算得出的。一個區塊鏈的部分區塊的信息如下圖:
區塊鏈的構建過程
生成新區塊并被添加到區塊鏈的過程在比特幣網絡中被稱為挖礦,通過挖礦,交易信息得以被記錄到區塊鏈中,而且正是由于其中的工作量證明機制(解數學題),才保證了區塊鏈中的交易信息的一致性與安全性;對比特幣來說,挖礦成功后的獎勵機制使得新的比特幣得以進入比特幣網絡中流通。在比特幣網絡中,有一些節點被稱為礦工節點,這個礦工節點可以是一個用戶的一臺普通的PC機器,也可以是一個企業機房中上百臺機器組成的計算集群,還可以是多個礦工組成的礦工池,比特幣對礦工節點的機器沒有限制,但是擁有更高計算性能的礦工節點會比其它節點更容易得出數學題的解以獲得記賬的權利和比特幣獎勵。
在礦工努力生成區塊的同時,也會把新的交易信息保存到本地內存中待放入下一個區塊,在當前區塊被自己或者其它礦工生成并驗證通過后,所有礦工就立即開始下一個區塊的生成工作,這時會把在本地內存中的交易信息記錄到區塊主體中,同時在區塊主體中生成此區塊中所有交易信息的Merkle樹,把Merkle樹根的值保存在區塊頭中。Merkle樹是一種哈希二叉樹,使用它可以快速校驗大規模數據的完整性。在比特幣網絡中,Merkle樹被用來歸納一個區塊中的所有交易信息,最終生成這個區塊所有交易信息的一個統一的哈希值,區塊中任何一筆交易信息的改變都會使得使得Merkle樹改變。下面假設一個區塊中有四筆交易,分別是A、B、C和D,首先將交易數據通過兩次SHA256算法生成一個32字節的哈希值,這些值作為葉子節點存儲在Merkle樹中,然后把相鄰葉子節點的兩個32字節的哈希值串聯成一個64字節的字符串,再對這個字符串通過兩次SHA256算法生成一個32字節的哈希值作為這兩個葉子節點的父節點存入Merkle樹中,以此類推,最終生成區塊中所有交易信息的統一的哈希值,這個哈希值就是這個Merkle樹的根節點,區塊頭中存儲的也就是這個跟節點哈希值,如下圖所示:
Merkle根被填入區塊頭中后,系統會把上一個剛剛被生成的區塊的區塊頭的數據通過SHA256算法生成一個32位的哈希值填入到當前區塊的父哈希值中,然后把當前Unix時間保存在時間戳字段中,難度值字段也會根據之前一段時間區塊的平均生成時間進行調整以應對整個比特幣網絡不斷變化的整體計算總量,如果計算總量增長了,則系統會調高數學題的難度值,使得預期完成下一個區塊的時間依然在十分鐘左右。區塊頭中最后一個字段是Nonce,初始值為0。
區塊頭及區塊主體構建完成以后,挖礦也就是解數學題就可以開始進行了,挖礦的目標就是通過不斷改變區塊頭中的Nonce值,使得對區塊頭使用SHA256算法得出的哈希值符合難度值的要求。SHA256算法是一個加密哈希算法,這個算法的特點是不同的輸入會產生完全不同的哈希值,沒有任何規律可循,而且無論輸入的大小是多少,SHA256算法的輸出的長度總是256bit即32位。比特幣挖礦的目標就是找到一個Nonce值,使得在這個值下的區塊頭的SHA256哈希值的輸出必須小于難度值中設定的值,這個難度值通常是以多個0開頭,當前最新難度的要求是得出的256bit的哈希值中前68個bit都必須是0,這要求整個比特幣網絡每秒大概進行6x1020次哈希計算,才能在10分鐘左右的時間內能有礦工找到符合要求的Nonce值。在挖礦過程中,由于每個礦工創建的新區塊頭中的時間戳都可能不一樣,而且由于每個礦工選擇進入本區塊的交易集合不一樣,區塊頭中的Merkle根的值也不一樣,所以即使很多礦工都是從Nonce等于0開始累加尋找符合條件的哈希值,他們也還是在各自不同的位置尋找,挖礦的過程是整個比特幣網絡所有礦工節點的計算能力加在一起尋找答案的過程,每個礦工都有找到正確答案的機會,只不過擁有的更高計算性能的礦工找到答案的概率更大一些。
當一個礦工成功找到使得區塊頭哈希值小于目標難度的Nonce值后,他會立刻把這個區塊廣播到比特幣網絡中,幾秒鐘后,網絡中的所有礦工就會收到這個區塊,當他們驗證成功后,就會立即停止自己生成當前區塊的努力,把那個礦工找到的區塊加到區塊鏈中,完后立刻開始下個區塊的生成過程。這樣,一個區塊就被添加到了完整區塊鏈當中了。
區塊鏈的一致性與安全性
上面講了區塊鏈的數據結構和構建過程,但是還有兩個最關鍵的問題需要解釋:
整個區塊鏈如何在分布式網絡中的所有節點中保持其一致性。
如何保證沒有節點惡意篡改區塊鏈中的信息(在比特幣中為交易信息),也就是說如何讓我們相信區塊鏈中的信息都是真實信息。
對于一致性問題,其實在上面的區塊鏈構建過程的最后已經有所說明,網絡中的所有節點都會通過解數學題爭取得到創建當前區塊的權利,當一個節點解題成功后,就會把題的答案和構建的區塊通過比特幣網絡發送給其它節點,其它節點只要驗證通過了這個答案,就會立刻停止自己創建當前區塊的努力,把傳過來的區塊加到本地區塊鏈中,然后根據這個區塊的區塊頭的哈希值填充下一個區塊的區塊頭中的信息,立刻開始下一個區塊的構建。這樣,網絡中就完成了一個區塊鏈中新區塊的構建過程。
這個過程看似沒有問題,但是考慮一下以下一種情況:同一時間(1秒內)可能有兩個或者更多不同的節點都找到了答案,他們立刻把答案和區塊發送給與他們連接的節點中,這些節點驗證通過后會基于這個區塊立刻開始下個區塊的構建工作,由于每個節點生成的區塊都是不同的(數學題的解有多個),所以每個區塊的哈希值也都不相同,后續區塊的哈希值也會改變,這樣在整個網絡中就形成了多條區塊鏈的分叉,不同的節點在不同的分叉上往后構建新區塊。
分叉問題如何解決,答案是等到下個區塊或者下下個區塊再說,當前區塊有多個節點同時解出了答案,但是下個區塊很可能就會分出先后,先解出下個區塊的分叉被全網認可后,之前在錯誤分叉上的節點會把自己分叉上之前錯誤的區塊替換掉,使得整個網絡重新歸于統一。這也是為什么比特幣會把每個區塊的解題時間控制在10分鐘左右,更難的題和更久的解題時間使得同時解出答案的概率更低,在比特幣歷史上,很少出現分叉中包含兩個區塊的情況。所以,區塊鏈中最新生成的幾個區塊的確可能會出現一致性的問題,但是在6個區塊之前的所有區塊就肯定都一致了。
對于安全與信任問題,主要體現在兩方便,一是有節點試圖更改之前某個區塊上的交易信息,二是有節點試圖控制新區塊的生成,解決這兩個問題的關鍵都在于解數學題背后所代表的巨大計算能力的保證。如果有節點想要更改之前某個區塊的交易信息,只要交易信息一更改,這個信息的哈希值就會更改,最終會引起區塊頭中代表所有交易信息的Merkle樹跟值的更改,這個區塊頭的哈希值也就更改了,之前的Nonce值已經不是這個被改了的區塊頭的解了,這個區塊的數學題需要重新計算,更嚴重的是,這個區塊下一個區塊引用的父哈希值也改變了,所以下一個區塊也需要重新計算,依此類推,后面所有區塊都需要重新計算生成。也就是說,只有重新計算被更改區塊后續所有區塊并且追上網絡中合法區塊鏈的進度后,把這個長的區塊鏈分叉被提交給網絡中的其它節點,才有可能被認可,只重新生成被惡意篡改的區塊并提交是不會被網絡上的誠實節點認可的。在當前全網巨大計算能力的背景下,一個惡意節點想重新計算多個區塊并且追上全網的情況很難出現,一般認為第6個區塊之前的所有區塊就不可能被改變了。那么如果試圖控制新區塊的生成呢,也就是說每個新區塊都是由惡意節點率先得出數學題的解得到認可,這樣由于區塊中包含的交易都是由節點自由決定的,惡意節點可以通過這種方式永遠不讓某個交易加入區塊鏈中得到認可。理論上這種方式是可能的,如果惡意節點的計算能力比網絡中所有其它節點的計算能力的總和都高,也就是惡意節點占據了全網51%的計算能力,他就可以控制新區塊的生成,這種攻擊被稱為51%攻擊。當然在現實當中,一個節點的計算能力超過其它所有節點的總和是非常困難的。由于篇幅所限,還有很多安全問題比如DoS攻擊的解決方案在這里就不一一闡述了。
4、小結
現代互聯網的基礎是TCP/IP技術,基于這項技術,網絡上所有節點都可以公平自由的跟其它任意節點通信,但是這個技術只解決了去中心化的通信問題,沒有解決去中心化的信用問題。區塊鏈技術的出現讓我們看到了解決這個問題的希望,其在比特幣上的大規模應用也讓我們看到了其技術上的可行性。本文基于比特幣介紹了區塊鏈的相關技術,但是區塊鏈技術的應用并不僅僅局限于數字貨幣領域,其在各個行業上的嘗試都已經開始,讓我們跟隨最新的技術,并為其最終成熟做出自己的一份貢獻。
本文作者:羅宇翔(點融黑幫),做過Web,搞過大數據,懂一點數據挖掘,實現過推薦系統,喜歡探索新的技術領域,注重理論與實際相結合。現就職于點融北京團隊。