導讀
區塊鏈是中本聰為了實現比特幣的交易而發明的一種技術。支付的本質是「將帳戶A中減少的金額增加到帳戶B中」,比特幣即是隱含在轉帳交易記錄中的數額概念。比特幣的持有者通過在一套公共帳本上公告一條交易記錄,從而實現價值的轉移。這個公共帳本就是區塊鏈。
從技術的角度看,區塊鏈相當於定義了一條時間軸,確保記錄在這條時間軸上的數據可以被查詢但不可更改,建立了一種基於算法、可被驗證的「信任」。在區塊鏈之前沒有任何其它技術可以做到這一點。對於比特幣來說,區塊鏈相當於把每個時間段形成的帳本按時間順序一本一本的串聯起來,形成了一套完整可查的而又不容篡改的超級公共帳本。
從經濟學的角度看,「信任」是一種高昂的隱形成本,區塊鏈技術作為一種信用基礎設施,可以在經濟活動乃至社會管理中發揮巨大的作用。
1
起源
2008-10-31
一位化名為中本聰的人(Satoshi Nakamoto 目前仍然無法知道中本聰到底是誰,文中埋有一個彩蛋,告訴我們如何找到中本聰)發表了一篇論文《比特幣:一種點對點的電子現金系統》,中本聰結合以前多項數字貨幣發明的技術,提出了一種去中心化共識的解決方案,它使用一種可驗證的數據塊的鏈條,解決比特幣現金(Bitcoin)數據的防篡改的問題。
2009-01-04
2:15
AM,網際網路上產生了第一個這樣的數據塊,它採用了一個嚴苛的規則對一筆網絡轉帳交易數據(這是一個方便理解但並不嚴謹的說法)進行了打包。這個高度結構化的數據塊被稱之為區塊(Block),從那之後,大約每10分鐘,就有一個區塊產生,一直延續到現在(2019-11-09
12:28
PM)是第602941個區塊,這些區塊按照一個引用規則排列成一條長鏈,稱之為區塊鏈(Blockchain)。這個位於區塊鏈中0位置的區塊後來被稱之為創世區塊,現在的所有有關比特幣區塊鏈的軟體,都會包含這個創世區塊的數據。
2010-05-22
美國佛羅裡達一位名為Laszlo Hanyecz的程式設計師,用10,000 BTC(比特幣的貨幣單位,取值範圍為10-8 ~
2.1*107)買了兩個「約翰爸爸」(Papa John)的披薩優惠券。這是第一次有人願意承認比特幣在現實世界中具有價值。10,000
BTC按當前的匯率價值88,107,600美元。2018-02-25,Laszlo
Hanyecz再次購買了兩塊價值62美元的披薩,僅花費0.00649 BTC的比特幣。
2015-07-30
俄羅斯程式設計師Vitalik
Buterin發布了以太坊(Ethereum),把智能合約的概念引入區塊鏈。人們逐漸認識到,區塊鏈的去中心化、可透明溯源、不可篡改等特性,有著遠超過比特幣本身的潛在應用價值,越來越多的個人、公司、金融機構和政府開始關注和應用區塊鏈技術。
2016-12-20 國務院發布《「十三五」國家信息化規劃》首次將區塊鏈納入新技術範疇並作前沿布局,標誌著我國開始推動區塊鏈技術的應用和發展。
2019-10-25 中共中央政治局提出把區塊鏈作為核心技術自主創新重要突破口,加快推動區塊鏈技術和產業創新發展。
2
公共帳本上的轉帳交易記錄——區塊鏈和比特幣是什麼
區塊鏈最初是為了實現比特幣的交易而發明的技術,比特幣的區塊鏈帳本是理解其技術原理的最佳方式。
圖2-1 比特幣交易記錄
支付的本質是「將帳戶A中減少的金額增加到帳戶B中」,比特幣即是隱含在轉帳交易記錄中的數額概念。比特幣的持有者通過在一個點到點網絡(也稱對等網絡,這種網絡上每一個節點都是平等的)上發布一條公告,把一個地址上的比特幣的所有權移交給另一個比特幣地址。新的持有者將來若想要花掉這一筆錢,則需要提供一個有效的證明,這個證明類似於在支票上的籤名,稱之為數字籤名,然後再次發布一條帶有這個數字籤名的公告,把所有權移交給其它比特幣地址。任何人通過這個比特幣地址即可以驗證對應的數字籤名的有效性,卻不能通過這個公開的比特幣地址偽造出有效的數字籤名。
一段時間區間內的交易記錄匯集起來,被裝訂到一個公開的帳本上,本質上這個帳本是一個高度結構化的數據塊,即區塊。新增區塊總是連結到前一區塊,因此這些區塊可以按順序排列成一條長鏈,即區塊鏈。
對等網絡上的每個節點都可以試圖把接收到的這些交易記錄打包稱新的區塊,但最後會通過一個競選機制自動達成共識,從而最終確定一套所有節點都認可的公共帳本。該競爭機制同時也使得這些交易記錄被永久的刻寫在區塊鏈上而不容更改。
要如何打包這些交易記錄成為區塊,以及如何達成共識,生成區塊鏈呢?這主要與哈希算法相關。
3
哈希算法
哈希算法(Hash)即哈希函數,哈希算法在區塊鏈的實現中無處不在,準確理解哈希算法的特點,是深入理解區塊鏈技術原理的關鍵。區塊鏈通過哈希算法確保了每一筆交易的完整性,每個區塊的完整性和區塊鏈自身的可靠性。
3.1 一個確定的隨機值——哈希算法簡介
哈希函數把任意長度的輸入數據,通過該函數創建一個對應的固定長度的輸出,這個短輸出稱之為哈希值。
圖3-1 哈希函數
不論長度只是一句話,還是包含整本《西遊記》內容的數據,經過SHA256哈希函數計算之後的輸出值都是256位(表示為64位十六進位數)。而且輸入數據中哪怕只改變一個字,其輸出值也會徹底的不同。
哈希函數具有以下特點:
根據輸入數據在有限的時間和資源內很容易計算出哈希值,這稱為正向快速。而根據哈希值,完全無法推斷出原始輸入數據是什麼,這稱之為不可逆(或者單向性)。輸入數據只需要發生最微小的改變,哈希值也會徹底不同,這稱之為雪崩效應(或輸入敏感)。
對於同一個哈希函數來說,相同的輸入數據會有相同的哈希值,若哈希值不同,那麼輸入數據一定不同,這稱之為哈希函數的確定性。另一方面,若兩個不同的輸入數據,得到了相同的哈希值,這種極不可能發生的事件被稱之為「哈希碰撞(Collision)」。只應選用當前還無法人為刻意製造出「哈希碰撞」的哈希函數。由於中國密碼學家王小雲的卓越工作,證明了MD5、SHA-1等函數已不再安全,比特幣的區塊鏈使用了目前仍然十分安全的SHA256函數。
圖3-2 真假美猴王
哈希值相當於是對輸入數據的一種背書,它承諾了一個對應的原始數據。就像是使用一句咒語,用來驗明大聖的真身。
3.2 多重哈希——默克爾樹
哈希值也被稱之為數據指紋、散列值或者數據摘要,這是因為可以把這個短的哈希值看成是原始數據的「身份代表」和承諾。如果我們已知某個我們關心的數據的哈希值,就可以用它來驗證之後才拿到的原始數據的真實性,哪怕是極小的改動也會導致驗證失敗。
如果需要對很多個這樣的原始數據進行真實性確認,那就需要事先知道很多個對應的哈希值,管理很多個哈希值再一次成為了沉重的負擔。如果把這些哈希值排布起來,把它們視為一般數據進行迭代哈希,最後可以得到一個「根」哈希值,如下圖所示:
圖3-3默克爾樹
對每一個原始數據計算哈希值得到HashA、HashB、……HashH,對這些哈希值兩兩配對再計算一次哈希值得到HashAB……HashGH,若出現不足兩個的情況,則複製一份自身再計算哈希值。重複以上過程,直到最後得到的唯一的哈希值。這些哈希值的排列方法就像是一棵樹,被稱之為默克爾樹(Merkle tree 默克爾樹是一種完全二叉樹),樹根哈希值稱之為Merkle Root。
有了Merkle Root這個哈希值,對於大量分布式存儲的數據也能進行驗證。比如我們現在要驗證[數據/交易記錄D],只需要得到數據本身和它路徑上相鄰節點的哈希值HashC、HashAB、HashEFGH,計算出HashD並依次與這些值配對,就可以驗算最終結果是否等於Merkle Root,即驗證了[數據/交易記錄D]的真實性。即使包含1000條記錄,也只需要額外傳輸10條哈希值即可驗證其中任意一條(想一想這是為什麼)。
簡單的說,只需要一個哈希值Merkle Root,就能夠用非常小的代價,對默克爾樹中的任意一個數據進行驗證。在區塊鏈中,可用該方法驗證區塊中的數據記錄。
3.3 尋找一個極小哈希值——區塊鏈的信任根基
由於哈希函數的雪崩效應和確定性,如果把哈希函數中的輸入數據看成是產生隨機數的種子,那麼哈希值可以看成是一個隨著輸入數據的改變而改變的隨機值。但對於同一個哈希函數來說,一個確定的「種子」對應唯一確定的「隨機值」。
既然我們可以把哈希值看成是一個隨著輸入數據改變而改變的隨機值,我們能構造出一個輸入數據,使它的哈希值為某個指定值嗎?因為哈希函數的不可逆性,尋找特定的哈希值所對應的原始數據這件事情使我們陷入用猴子列印出莎士比亞全集一樣的窘境之中,我們唯一能夠使用的方式跟那些猴子一樣,只能隨機輸入一個值,然後看看它的結果是什麼。
圖3-3《辛普森一家》劇中的猴子印表機
猴子印表機思想實驗:讓這些猴子在打字機上隨機地按鍵,當按鍵次數為無窮多次時,就能列印出莎士比亞全集。不幸的是,如果這些猴子從宇宙大爆炸那一刻就開始這項工作,一直不吃不喝的每秒能列印出10個字母,到現在為止還沒能列印出這套全集中第一冊第一頁中的第一句話。
通過隨機方式得到一個指定的256位的數,平均需要2255次的嘗試才能夠成功,以計算機當前的算力,在宇宙時間範圍內都無法成功。如果我們只是想要得到一個以「0」開頭的哈希值呢?這就簡單多了,比如,我們簡單的在一個字符串數據「something_」後面嘗試加上一個Nonce值(Number once的縮寫,在密碼學中Nonce是一個只被使用一次的任意或非重複的隨機數值)作為輸入數據,使用SHA256函數進行哈希計算,看看結果是什麼,如下所示:
圖3-4 通過改變Nonce值來尋找極小哈希值
當輸入數據為「something_11」的時候,我們看到哈希值「0996c9ed……」滿足以「0」開頭的要求。那麼,如果我們想要得到一個以「00」開頭的哈希值呢?我們就不得不進行更多次數的嘗試。當輸入數據為「something_540」的時候,其哈希值「0037891b……」滿足這個要求。
哈希值前面的「0」的個數可以表示為一個閾值,閾值越小,則難度呈指數迅速增加。當Nonce值為25705014時,才找到一個小於「0000000F……」的哈希值,這在我的計算機上花了79秒。雖然尋找滿足要求的Nonce值的工作量十分龐大,但別人要驗證其對應的哈希值是否小於目標閾值卻永遠只需要一次哈希計算即可。
區塊鏈中把這個閾值用難度目標(DIFFICULTY值)來表示,從以上演示我們可以看到,通過約定一個更難的難度目標,找到滿足要求的輸入數就必須消耗更多的工作量。如果硬體算力大幅增加,我們還是「期望」計算過程必須消耗這麼多時間呢?只需要約定一個更難的難度目標就可以了。
這種通過添加一個Nonce值,從而使輸入數據的哈希值滿足難度目標要求的計算,看起來就是一個費時費力又沒有捷徑可走的無用功。然而區塊鏈正是利用該算法,在打包數據時用工作量設置了一個無法逾越的障礙,使之無法被篡改,這使區塊鏈成為了一個可以建立「信任」的基礎設施。下面我們來看看具體是如何做到的。
4
區塊鏈
依靠網絡通訊的電子現金永遠存在兩個問題:你怎麼證明那筆錢是你的(真偽問題);如何保證同一筆錢沒有被多次支付給不同的人(雙重支付問題)?金銀現鈔等實物貨幣天生具有唯一性,而對於計算機來說,數據的複製品和原數據則是完全等價的。
比特幣的轉帳交易記錄通過數字籤名技術來證明所有權(見附錄8.1密碼學與數字籤名),通過全網對一個無法被篡改的公共帳本達成共識來防止雙重支付。這個公共帳本就是區塊鏈。
4.1把交易記錄登記到帳本——打包區塊
安裝了比特幣軟體的所有用戶節點構成了一個點對點的網絡,每個用戶節點如果收到一條新的交易數據,都會在驗證其有效性之後把它廣播到全網。這些新交易數據構成了一個交易池,每隔10分鐘左右,交易池中的所有新交易記錄會被打包進一個新區塊,新區塊會被加入到區塊鏈的末端。
如果我們是比特幣網絡上的一臺計算機,要如何把這些交易記錄打包成區塊呢?
首先應該驗證每一條交易數據本身是否有效(見5.3比特幣交易的生成和驗證),然後計算其哈希值,把這些哈希值兩兩配對,構造成一棵完整的默克爾樹。如果把每一條交易記錄看成是帳本中的一頁,那麼默克爾樹就是這個帳本的目錄頁。通過Merkle
Root值把這些交易記錄緊緊的捆綁到了一起,構成了一本可以驗證其中任何一筆交易記錄數據的帳本。(見3.2 默克爾樹)。
這很簡單,任何人在任何時候都可以用默克爾樹打包出一個包含有多條交易記錄的帳本,如果每個人就這樣把自己構建的帳本上傳到比特幣網絡,那麼網絡上很快就會充斥著混亂不堪的各種帳本,一筆交易可能在不同的帳本中被反覆的登記很多次。
為了能讓全網達成共識,需要對這個帳本稍作修改,給這個帳本添加一個封面,並通過一項基於工作量證明(Proof of Work簡稱PoW)的競賽機制選出唯一的帳本。
這個封面就是區塊頭,區塊頭除了包含有Merkle
Root值之外,還包含版本號、時間戳和前一個區塊頭的哈希值——其中並不包含本區塊頭的哈希值,因為哈希值無法自我引用而且也不需要自我引用,每次在需要驗證時會重新計算該區塊頭的哈希值。然後在這個區塊頭數據的最後添加一個合適的Nonce值,使區塊頭的的哈希值小於一個約定的難度目標。完整的區塊頭包含如下數據:
圖4-1區塊鏈結構圖解
通過前文我們知道,在區塊頭數據中添加一個Nonce值,從而使該數據的哈希值小於一個極小閾值,這需要消耗極大的工作量(見3.3尋找一個極小哈希值),這使得全網約需要10分鐘左右(每2016個區塊之後會自動調整一次DIFFICULTY值以適應網絡當前算力)才能產生一個合格的區塊。最先構造出的新區塊即贏得了這場競賽,這個新區塊會被迅速廣播到全網,並添加到區塊鏈的最末端,成為這個超級帳本中最新的一本。
除創世區塊外的每個區塊頭都包含有前一區塊頭的哈希值,這使區塊按照形成的先後順序,排列成了一條長鏈,每產生一個新區塊,這個鏈條就會被延長,包含在這個區塊鏈上的總的工作量也相應的增加了。
4.2挖礦競爭——區塊鏈的自動共識機制
在比特幣網絡中,每產出一個新區塊都會新增一筆比特幣。事實上,這也是比特幣發行新幣的唯一方式,因此人們把這項工作形象的稱之為挖礦。挖礦的競爭異常激烈,有時候由於網絡延遲或者其它原因導致最新的區塊沒能及時同步,這時可能會發生不同的礦工用不同的區塊分別延長了區塊鏈,這稱之為區塊鏈的分叉。因為最長的分叉鏈上被認為包含了最多的工作量,每個節點接收到分叉的區塊時,會自動選擇最長鏈上的區塊而忽略較短的鏈上的區塊,這個機制使分叉區塊一般會在一兩個區塊周期內被自動修正,自動重新達成了共識。
圖4-2區塊鏈的分叉與重新達成共識
在這個競爭機制下,礦工一旦挖出一個合格的新區塊就會立即廣播到全網,以免白白蒙受損失。其它礦工一旦接收到有效的最新區塊,會立即接受它並更新區塊鏈數據,並馬上投入到尋找下一個區塊的工作,以免自己的工作量被忽略。
每個節點會自動選擇累積的工作量最多的區塊組成的區塊鏈,這使全網在分叉區塊的選擇上最終一定能夠達成共識,通過這個自動協調機制,最終全網同步了一個公共帳本。
截止現在(2019-11-09
12:28)比特幣的區塊鏈帳本上共產生了602941個區塊,所有區塊的數據總和為232.6GB。任何一個用戶節點可以選擇保存從創世區塊到最新區塊的完整數據,這樣的節點稱為全節點,全節點能直接在本地完成所有驗證。也可以選擇只保存這些區塊的區塊頭數據並使用簡易支付驗證(Simplified
Payment Verification簡稱SPV),截止當前所有區塊頭數據
4.3篡改歷史交易數據——區塊鏈的驗證
基於明確的規則驗證的區塊結構,對於所有節點來說都是平等的,這使得任何病毒和黑客對於區塊鏈數據都無能為力。現在假設某個與網絡上眾多節點保持連接且算力異常強大的網絡節點,試圖偷偷更改歷史區塊鏈中某一筆交易的數據,比如把某個未消費的交易輸出(見5.1比特幣的交易)中的比特幣數額添加一個「0」,並嘗試把篡改過的數據擴散給其它原本不包含有區塊鏈數據的新節點。
這個微小的改動,立即改變了該筆交易數據的哈希值,要使新的哈希值能通過其它節點的驗證,那麼包含有該哈希值的Merkle Root值就必須改變,Merkle Root值的改變會引起區塊頭哈希值的改變,這時需要重新挖出一個新的區塊,才能使其滿足難度目標的要求。
然而這並沒有結束,因為該區塊頭的哈希值被連結到了下一個區塊頭的數據中,所以下一個區塊頭的哈希值也必須改變……這個連鎖反應,使得篡改者必須重新構造所篡改區塊之後的所有區塊。
這個行為本質上等價於從篡改點產生一個分叉鏈從而與主鏈競爭。因為主鏈上的區塊總是累積了當時的最大工作量,而且長度仍然在不斷增長,這使得惡意分叉的區塊會被忽略。如果一個區塊後面已添加了五六個新的區塊(約需要一個小時),那麼其中的交易就可以認為「永遠」無法被推翻了。如果只是推翻最新的一兩個區塊呢?根據共識機制,如果發起攻擊的這個節點的算力超過了全網整體算力的51%,那麼攻擊是有一定機率成功的,但攻擊的機會成本十分高昂,因為強大的算力原本可以用來挖礦而正當獲利。
如果有人用比特幣交易了價值數億元的名畫或者房地產,那麼不妨等待一個小時,就可以認為該交易已經足夠安全了。如果只是一筆價值數萬元的交易,只要查看到該交易已被登記到區塊鏈,就可以認為交易已經生效了(約需等待10分鐘左右)。如果只是買一本書一杯咖啡這樣微小的交易額,只要該交易能通過驗證進入交易池,即使尚未被登記進任何一個區塊,也可以認為該交易是安全的(立即,不需要等待)。
對於比特幣網絡上的每一個用戶,不需要信任除自己之外的任何其它人,不管這些數據來自於誰、通過什麼線路、是以什麼方式發送的,只要接收的數據滿足驗證規則(錢包軟體可以自動完成這一切),就可以確信它是沒有經過篡改的有效數據。
5
再說比特幣
既然任何人都可以查看區塊鏈上的所有交易記錄的完整數據,那麼比特幣的持有人如何證明自己的所有權呢?了解比特幣交易的機制,可以更深入的理解區塊鏈是怎樣運行的。
5.1什麼是貨幣
除金銀等貴重金屬外,普通貨幣為什麼被視為貨幣?現代信用貨幣理論認為,貨幣的價值跟用來流通的介質本身的價值無關,而是由於它背後的信用擔保。法幣一般以國家主權為其進行信用擔保。
個人能夠提供貨幣的這種信用擔保嗎?奧地利經濟學派的代表人物之一哈耶克在《貨幣的非國家化》一書中,從徹底的經濟自由主義出發,論證了競爭性貨幣制度的可行性。他認為政府對貨幣發行權的壟斷,是世界各國通貨膨脹的不斷發生和加劇以致破壞經濟的根源。在此基礎上哈耶克提出了貨幣非國家化的設想。
哈耶克的這種觀點在現實中成立嗎?設想你開了一個連鎖理髮店,讓顧客購買一種理髮券,顧客憑券可以到你的店裡理髮一次,這種券就起到承兌作用。如果是大型連鎖超市發行的購物券,則可以承兌種類更多的商品。也就是說,如果一種交易方式具有足夠可靠的信用保障,那麼它事實上就承擔了貨幣的部分職能。例如,在很多古代文化中,都曾經把貝殼當作貨幣使用(資費、貴賤、賄賂、財貿等和錢有關的漢字大都含有「貝」字偏旁就是這個原因)。
目前美國、歐洲和日本等國家把比特幣視為貨幣,包括中國、印度和俄羅斯等其它國家則把比特幣視為一種虛擬商品,不論是哪一種情況,人們對比特幣的購買行為,會產生一個「價格」,該價格即可代表比特幣的即時匯率。
5.2比特幣的交易
比特幣本質上只是登記在區塊鏈上的轉帳交易記錄,交易是比特幣的核心組成部分,其它部分都是為了確保交易能夠被生成、傳播、記錄和驗證。
下面是其中一筆交易的詳細信息:
https://www.blockchain.com/BTC/tx/61057e09233bb943bcbb50eb890eef76412844f8332da2597f5bac73bb29dab3
圖5-1一筆比特幣交易的詳細信息
比特幣的交易採用了複式記帳法,每一筆交易會包含一個或者多個資金輸入,並創建一個或者多個未消費的交易輸出(Unspent
transaction
output簡稱UTXO)。這些UTXO可以用作之後其它交易中的資金輸入,這樣就完成了價值的轉移。上圖的交易消耗一個UTXO作為輸入,新增了兩個UTXO輸出。
UTXO是比特幣交易的基本組成部分,每個UTXO可以包含10-8~2.1*107 BTC之間的任意金額,但不論是什麼金額的UTXO都不可再分,而只能作為整體一次性消耗掉。如果需要找零,在交易中增加一筆輸出到自己的比特幣地址的UTXO即可。
比特幣的區塊鏈帳本中只存在交易而不存在帳戶,取而代之的是比特幣地址。比特幣地址是一串數字和字符(例如1KbbroX7dUDeXKaGJQJo4dcgFskqaTet19)。通過軟體,每個人可以創建任意多個比特幣地址,從安全的角度,建議每一筆交易使用不同的比特幣地址。當然,如上圖的交易中輸入和找零都使用相同的比特幣地址也是允許的。
UTXO中的金額相當於被鎖定到一個比特幣地址上,比特幣地址不僅充當了收款人的臨時帳戶,同時它也是用來證明所有權的一把鑰匙,這需要通過密碼學中的數字籤名來實現。
根據密碼學中的公鑰數字籤名技術,可以定義一對具有特殊關係的數字,其中一個數字完全保密,稱之為私鑰,而把另一個數字公開,稱之為公鑰。使用者用私鑰對一段數據進行加密,其他人用公鑰可以對這段加密數據進行驗證,驗證成功則表明這段加密數據只可能來自於對應的私鑰持有者,這個方法非常類似於在紙質文件上簽名,因此被稱之為數字籤名(見附錄8.1密碼學與數字籤名)。
比特幣地址就是其中的那個公鑰(基於一些原因,比特幣地址實際上是以公鑰哈希值的Base58Check編碼形式出現)。用戶若想要消耗鎖定在某個比特幣地址上的UTXO作為其它交易的資金輸入,只需用對應的私鑰提供一個有效的籤名,即可解鎖該UTXO。(彩蛋:當今世上曾有多個人企圖證明自己就是中本聰,然而迄今為止,創世區塊中包含的UTXO依然沒有被消耗掉,誰若能夠使用該UTXO進行交易,那麼他一定是中本聰。)
事實上,比特幣定義了一種簡易的交易腳本來完成上述操作。每個UTXO可以看成由兩部分構成,第一部分是以Sotashi為單位(比特幣的基本單位1
Sotashi = 10-8 BTC)表示的比特幣金額的數字,另外一部分是一個鎖定腳本,鎖定腳本中通常包含有公鑰哈希值(與比特幣地址等價)。
比特幣的持有者在之後的交易中要消耗該UTXO作為資金輸入時,需要提供一個對應的解鎖腳本,解鎖腳本一般包含由私鑰籤署的數字籤名。僅當鎖定腳本和對應的解鎖腳本聯合執行的結果為真,該筆輸入資金才是有效的。鎖定腳本相當於在UTXO上設置了一個「難題」,只有擁有對應私鑰的人才能夠提供解答該難題的解鎖腳本,從而確保了資金的安全。
圖5-2P2PKH的解鎖腳本與鎖定腳本
比特幣內置了五個標準交易腳本:P2PK、P2PKH、MS、P2SH和OP_Return。在上一節的交易詳細信息中,觀察兩個UTXO中的Pkscript欄位,可以看到第一個使用了P2SH鎖定腳本,第二個使用了P2PKH鎖定腳本。(見附錄8.2比特幣的交易腳本)
5.3 比特幣交易的生成和驗證
創建和管理比特幣地址及對應私鑰的軟體被形象的稱之為錢包,比特幣網絡上絕大多數節點都包含錢包功能。錢包可以計算你能夠解鎖的資金總額(對應傳統的帳戶餘額)、生成交易、傳輸數據和進行交易驗證。
在創建一筆新交易的時候,錢包會自動選擇自己能夠解鎖的最合適金額的UTXO作為交易輸入,並按照以下清單的要求構建交易數據,為交易提供有效的數字籤名,然後把它發送給與自己相連的節點。
圖5-3 交易有效性驗證清單
全節點的錢包軟體含有區塊鏈的完整數據,可以對任何一筆交易獨立的進行驗證。它會把區塊鏈中所有的UTXO數據收集起來放到內存中等待交易,稱之為UTXO池。當接收到其它節點傳來的交易數據之後,會按照以上清單逐項檢查,包括驗證其輸入UTXO是否在等待交易的UTXO池中,解鎖腳本是否有效。有效的交易會被廣播到全網,礦工會把這些新的交易收集起來,打包到區塊鏈中。其它節點在接收到新的區塊數據後,會把已經消耗的UTXO從內存的UTXO池中清除,但區塊鏈中的數據不會受到影響。無效的交易會被簡單的忽略,不會對它所引用的UTXO造成任何影響。
對於只保存了區塊頭數據的錢包來說,可以使用簡易支付驗證(SPV),它從對等網絡上其它節點獲取相關信息來構建交易,並等待和觀察該交易是否被區塊連結受。相當於讓其它全節點幫忙驗證了交易的有效性。最基礎功能的錢包僅保存密鑰,甚至可以列印在紙上,與任何計算機和網絡都脫離聯繫,這被稱為冷錢包,冷錢包仍然可以接收資金輸入。
需要說明的是,錢包本質上與區塊鏈數據沒有直接的關聯,用戶可以選擇任何一種自己喜歡的錢包軟體。
5.4比特幣的新幣發行機制
最初的比特幣是從那裡來的呢?
每個區塊中包含有一筆稱為COINBASE的特殊交易,比特幣規定該交易僅包含新增UTXO,而不需要消耗其它的UTXO作為輸入,早期的區塊該交易輸出中新增50
BTC的比特幣,每210000個區塊之後(約需4年)該值減半,當前每個區塊的COINBASE交易輸出新增12.5
BTC比特幣,按當前匯率價值110,134.5美元。預計在2020-05-13左右該值會再次減半為6.25
BTC。你可能已經注意到在正常的交易中,交易輸入的總額也並不等於交易輸出的總額,這個差額作為交易手續費也會被計入到COINBASE交易中,成為礦工收入的一部分。
礦工會把該筆交易輸出到自己的比特幣地址上,這也是打包區塊的工作被稱之為挖礦的原因,這筆不菲的收入使得挖礦成為一個極具競爭性的行業,每年比特幣的算力都在呈指數增長。比特幣規定每2016個區塊之後,會根據之前2016個區塊的出塊時間自動調整一次DIFFICULTY值,無論算力的增減,使全網都能保持在約每10分鐘產出一個新區塊。
這項把經濟激勵與打包區塊相結合的機制,是比特幣的一大創舉,使之得以實現了徹底的去中心化的運營模式,同時也使得比特幣的區塊鏈帳本累積的算力無法被推翻。
COINBASE交易使比特幣的總量不斷增加,事實上這也是比特幣發行新幣的唯一方式,發行量減半的機制使比特幣的總量最後會收斂於一個固定值21,000,000 BTC。到目前為止區塊鏈上已產出18,036,775 BTC的比特幣。
圖5-4 已開採和未開採的比特幣數量
6
總結與展望
回顧區塊鏈的核心算法,它通過哈希值保證每一條[數據/交易記錄]的完整性,通過默克爾樹把這些哈希值變成一個整體,通過工作量證明(PoW)來選舉區塊,通過引用前一區塊頭的哈希值使所有區塊連接起來,由高度結構化的區塊組成了一條可驗證、防篡改的區塊鏈。
區塊鏈相當於定義了一條時間軸,確保記錄在這條時間軸上的數據可以被查詢但不可更改,建立了一種基於算法、可被驗證的「信任」。在區塊鏈之前沒有任何其它技術可以做到這一點。對於比特幣來說,區塊鏈相當於把每個時間段形成的帳本按時間順序一本一本的串聯起來,形成了一套完整可查而又不容篡改的超級公共帳本。
從區塊鏈的技術原理來看,雖然它是為了實現比特幣的交易而發展出來的一項技術,但是對於在區塊鏈上記錄什麼種類的數據並沒有特殊的要求。這使得區塊鏈可以和其它多種技術結合,從而為其它應用提供區塊鏈的這種獨一無二的無法被篡改的信用特徵。用戶可以使用區塊鏈來記錄自己感興趣的任何數據,甚至可以只記錄這些數據的哈希值而不記錄數據本身,這其實是把哈希值也看成是普通數據。近些年來,人們正嘗試把區塊鏈用於公證、金融結算、數字政務、數據服務等多種用途。
比特幣作為最早、最典型的區塊鏈應用,也有它的局限性:
針對經典區塊鏈的這些不足,過去10年出現了成百上千種競爭幣或者競爭鏈。除了比特幣使用的基於工作量證明(PoW)機制以外,還有基於權益證明(PoS:Proof of Stake簡稱PoS)、股份授權證明(Delegated Proof of Stake簡稱DPoS)等的區塊鏈。致力於提供分散式應用程式託管、智能合約功能與分散式儲存的企業方案的EOS.IO平臺等。
中國2016年發布的《「十三五」國家信息化規劃》首次將區塊鏈納入新技術發展規劃。2016-12-20 平安集團、招商銀行、微眾銀行等 40 多家金融機構共同成立首個中國深圳FinTech 數字貨幣聯盟。2019-08-10 中國人民銀行支付結算司副司長穆長春在金融四十人伊春論壇上介紹央行法定數字貨幣的實踐。外界普遍猜測中國將發行自己的數字貨幣(Digital Currency Electronic Payment簡稱DCEP),推斷DCEP將具有如下特性:
從經濟學的角度看,「信任」會產生實實在在的社會成本,區塊鏈技術作為一種信用基礎設施,可以在經濟活動乃至社會管理中發揮重大的作用。
7
參考資料
《Mastering Bitcoin: Unlocking Digital Cryptocurrencies》Andreas M. Antonopoulos
《Bitcoin: A Peer-to-Peer Electronic Cash System》
《密碼學基礎教程:秘密與承諾》 [美] Philip N. Klein 機械工業出版社
《應用密碼學:協議、算法與C源程序》[美] Bruce Schneier 機械工業出版社
《貨幣的非國家化》[英] 弗裡德裡希·馮·哈耶克 新星出版社
《區塊鏈技術指南》鄒均等 機械工業出版社
https://cloud.tencent.com/developer/article/1046761
https://en.wikipedia.org/wiki/Blockchain
https://en.wikipedia.org/wiki/Bitcoin
8
附錄
8.1密碼學與數字籤名
密碼學是一門以數學為基礎的學科,它繼承了數學的嚴謹性。密碼學假設通信線路上永遠潛伏著不懷好意的竊聽者,默認一切都是不可信任的,並以此為前提,用數學方法來重建可以被信任的通信。
8.1.1對稱加密
假設Alice要傳輸一個字母』a』給Bob,而在通訊線路上潛伏著竊聽者Eve,我們知道在計算機裡一切都是表達為二進位,字母a表示為01100001(受影視劇影響,可能有人認為變為二進位這就叫密碼,其實它是一種ASCII編碼,莫斯「密碼」其實也只是一種編碼,對於計算機來說它就是字母a),現在Alice和Bob共同擁有一個密鑰01011010,Alice把字母a與這個密鑰進行一個叫做「異或」的二進位運算(異或運算符為⊕)。異或的運算規則是,兩個相同的值異或結果是0,兩個不同值異或結果為1,該運算只有四種情況,如下圖所示:
如果對字母a和密鑰進行按位異或運算,可以得到密文00111011,通過通信線路傳輸該密文,Bob收到密文之後,把它與密鑰01011010再次進行按位的異或運算,我們驚奇的發現結果又還原成了01100001,即字母a。
圖8-1 異或運算
對於不知道密鑰的人來說,密文00111011可以代表任何值,它只有與對應的密鑰解密之後才具有意義。真實的密鑰長度通常為256位或者512位,而明文比密鑰要長得多,最簡單的方法可以把明文切分成很多段與密鑰一樣長的小段,對每一段明文分別進行加密。實際加密方法比這還要複雜一點,這裡不再贅述。
在這種加密和解密過程中,因為加密和解密使用同一個密鑰,密鑰的使用具有對稱性,因此也叫對稱加密。對稱加密和解密過程如下圖所示:
圖8-2 基於異或運算的對稱密鑰系統
對稱加密系統最大的問題是Alice和Bob需要共用一個相同的密鑰,如何傳輸密鑰是一個很大的問題。如果能夠及時安全的傳輸密鑰,那麼為什麼不直接安全的傳輸它的明文呢?這在很長一段時間裡,是所有使用密鑰來傳輸信息的人們面對的一大困擾。
8.1.2非對稱加密
1977年發明的RSA非對稱密鑰可以說是密碼學上具有裡程碑意義的事件,與對稱密鑰系統不同,非對稱密鑰提出了一種算法,該算法定義了一個密鑰對,使用其中的一個密鑰加密,只能用另一個密鑰才能解密(所以稱之為非對稱密鑰),如此一來,人們可以公開其中一個密鑰,稱之為公鑰,而保密另外一個密鑰,稱之為私鑰。
比如Alice需要向Bob發送一段消息,Alice不需要事先和Bob共享一個密鑰了,而是直接用Bob公開的公鑰,對消息進行加密之後傳輸,該密文只有擁有私鑰的Bob才能解密,其它任何人都無法根據密文還原出原文。相同的道理,Bob如果要向Alice發送消息呢?就換用Alice的公鑰進行加密之後再傳輸。如下圖所示。
圖8-3 RSA非對稱加密密鑰系統
8.1.3數字籤名
利用非對稱加密的這個原理,甚至可以完成更加複雜的事情。比如現在Alice的需求並不是要加密傳輸任何信息,而是需要向其它人說明,這個文件的確是我Alice發出的,這個需求非常類似於在紙質文件上簽名,因此被稱之為數字籤名。
數字籤名是如何實現的呢?如下圖所示,首先Alice在網絡上公布了自己的公鑰,讓所有人都知道這個公鑰是Alice的。
圖8-4 數字籤名
現在Alice把她需要籤署的文件計算其哈希值,用私鑰對該哈希值進行加密,該加密數據稱之為Alice對原文的籤名,然後Alice把文件原文和該籤名一起公布出來。任何人接收到該數據後,用Alice的公鑰對該籤名進行解密,會得到一個哈希值,然後計算原文的哈希值,如果這兩個哈希值相等,那我們就可以十分肯定的說,該密文的計算只有擁有Alice私鑰的人才能完成。因此可以肯定是說,這個文件的確是擁有Alice私鑰的人籤發的,這就是數字籤名的原理。需要說明的一點是,使用同一對公鑰和私鑰,對不同的數據產生的籤名數據是不一樣的,但都能夠被公鑰正確解密通過驗證。
為了方便理解,我們使用了RSA算法來講解非對稱加密和數字籤名。在比特幣區塊鏈中實際採用的是橢圓曲線數字籤名算法ECDSA,相同強度下該算法比RSA的密鑰要更短,理解起來稍微複雜一些,但最後實現的目的和效果是一致的。
8.2比特幣的交易腳本
比特幣定義了一種基於堆棧的非圖靈完備的簡易腳本,專門用於對交易的驗證。交易腳本由兩部分構成,創建UTXO時使用一個鎖定腳本,鎖定腳本一般包含有一個公鑰。要消耗該UTXO作為交易輸入時,需要提供一個對應的解鎖腳本,解鎖腳本一般包含有一個數字籤名,該數字籤名是由對應的私鑰對交易數據進行籤名產生。鎖定腳本和對應的解鎖腳本聯合執行的結果為真,才能通過交易驗證。交易腳本可以完成非常複雜的交易驗證,比特幣內置了五個標準交易腳本:P2PK、P2PKH、MS、P2SH和OP_Return。
P2PK(Pay-to-Public-Key)是最簡單的標準交易腳本。
該腳本只是簡單的調用CHECKSIG操作符,檢查該數字籤名是否正確。因為只有比特幣的持有者才擁有對應的私鑰,才能提供正確的數字籤名,從而證明了自己對該UTXO的所有權。
P2PKH(Pay-to-Public-Key-Hash)是比特幣網絡上用得最多的腳本。
它包含有一個公鑰的哈希值,公鑰的哈希Key Hash>與我們很熟悉的比特幣地址是等價的,但我們看到的兩者的字符串並不相同,這是因為比特幣地址為了方便日常交流使用進行了Base58Check編碼。公鑰的哈希值隱藏了公鑰本身,而且字節數要少得多。MS(Multiple Signatures)表示多重籤名。多重籤名腳本設置了這樣一個條件,假如記錄在腳本中的公鑰個數為N,則至少需提供其中的M個公鑰才可以解鎖。這也被稱為M-N組合。多重籤名可以用於公司組織等設置複雜的支付條件。P2SH(Pay-to-Script-Hash)是2012年引入的一種強大而同時又保持了簡潔的交易類型,它把複雜的鎖定條件簡化為一個哈希值代替,縮短了交易的字節數,減輕了區塊鏈的負擔。是推薦使用的一種新型交易腳本。
OP_RETURN是一種非交易型的輸出,它被設計用來僅僅返回一個小於40位元組的數,常常用來返回一個哈希值。OP_RETURN創建的輸出不能作為其它交易的輸入,該輸出雖然包含在區塊鏈的數據中,但是不會被包含在UTXO池中。簡單說來,它還是會佔用硬碟,但是不會佔用內存,這降低了區塊鏈的負擔。
來源: 觀察者網