作者寄言:毫無疑問,區塊鏈將顛覆既有認知,敬那些偉大的前行者。
Part 1. 站在巨人的肩膀上,密碼朋克(CypherPunk)
在數字貨幣的探索實踐中,比特幣是目前表現最好的一個。說到比特幣的緣起,就不得不談到一個略顯神秘的團體:密碼朋克(CypherPunk)。這個團體是密碼天才們的松散聯盟。在比特幣的創新中,大量借鑒了密碼朋克成員的貢獻。
探路者:
亞當·貝克(Adam Back)是一位英國的密碼學家,1997年,他發明了哈希現金(hashcash)[i],其中用到了工作量證明機制(proof of work)。這個機制的原型是用于解決互聯網垃圾信息問題的[ii]。工作量證明機制后來成為比特幣的核心要素之一。
哈伯和斯托尼塔(Haber and Stornetta)在1997年提出了一個用時間戳的方法保證數字文件安全的協議[iii],這個協議成為比特幣區塊鏈協議的原型。
戴偉(W Dai)是一位興趣廣泛的密碼學專家,他在1998年發明了B-money[iv],B-money強調點對點的交易和不可更改的交易記錄。不過在B-money中,每臺計算機各自單獨書寫交易記錄,這很容易造成系統被賬本的不一致。戴偉為此設計了復雜的獎懲機制以防止作弊,但是并沒有能從根本上解決問題。中本聰發明比特幣的時候,借鑒了很多戴偉的設計,并和戴偉有很多郵件交流。
哈爾·芬尼(Hal Finney))是PGP公司的一位頂級開發人員,也是密碼朋克運動早期和重要的成員。2004年,芬尼推出了自己版本的電子貨幣,在其中采用了可重復使用的工作量證明機制(RPOW)。哈爾·芬尼是第一筆比特幣轉賬的接受者,在比特幣發展的早期與中本聰有大量互動與交流。由于身患絕癥,哈爾·芬尼已于2014年去世。
患了(ALS,即“漸凍人癥“)的芬尼
Part 2. 創世塊 - “財政大臣站在第二次救助銀行的邊緣”
2008年10月31日紐約時間下午2點10分,在一個普通的密碼學郵件列表中,幾百個成員均收到了自稱是中本聰的人的電子郵件。
“我一直在研究一個新的電子現金系統,這完全是點對點的,無需任何可信的第三方”
然后他將他們引向一個九頁的白皮書,其中描述了一個新的貨幣體系。同年11月16日,中本聰放出了比特幣代碼的先行版本。
2009年1月3日,中本聰在位于芬蘭赫爾辛基的一個小型服務器上挖出了比特幣的第一個區塊——創世區塊(Genesis Block),并獲得了首礦”獎勵——50個比特幣。在創世區塊中,中本聰寫下這樣一句話:
“The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"
“財政大臣站在第二次救助銀行的邊緣”
這句話是當天泰晤士報頭版的標題。中本聰將它寫進創世區塊,不但清晰地展示著比特幣的誕生時間,還表達著對舊體系的嘲諷。
**Part 3. **去中心化的賬本系統
我們能不能構建一個去中心化的不依賴任何第三方的但卻可信的記賬系統呢?
這里,我們把記賬系統中接入的每一臺計算機稱為“節點”。由于一致性的要求,每個節點卻不能同時記賬。因為節點所處的環境不同,接收到的信息自然不同,如果同時記賬的話,必然會導致賬本的不一致,造成混亂。
既然節點不能同時記賬,那我們就不得不選擇哪個節點擁有記賬的權力。但是,如果指定某些特殊節點擁有記賬的權力,勢必又會與我們去中心化的初衷相違背。
這似乎成了不可能解決的問題。
**Part 4. **競爭記賬和激勵機制
中本聰設計的比特幣區塊鏈通過競爭記賬的方式解決了去中心化的記賬系統的一致性問題。
為了解釋這個問題,我們引入一個新的名詞“算力”。
所謂的競爭記賬,就是以每個節點的計算能力即“算力”來競爭記賬權的一種機制。在比特幣系統中,大約每十分鐘進行一輪算力競賽(算力大小會決定贏得一輪競爭的概率,算力高的節點贏得算力競爭的概率更大),競賽的勝利者,就獲得一次記賬的權力,這樣,一定時間內,只有競爭的勝利者才能記賬并向其他節點同步新增賬本信息。
那么問題來了,在去中心化的系統中,誰來評定這個競爭結果呢?
比特幣系統是通過一個稱為“工作量證明”(proof of work, POW)的機制完成的。這個過程其實類似解決一到數學難題,我不需要知道你的解題過程,核對結果就可以了。
Part 5. 貨幣發行
算力競爭是要付出成本的,沒有激勵,節點就沒有進行競爭的動力。在中本聰的設計里,每輪競爭勝出并完成記賬的節點,將可以獲得系統給予的一定數量的比特幣獎勵。而這個獎勵的過程,同時也是比特幣的發行過程。這種設計相當巧妙 —— 它將競爭的激勵機制與貨幣的發行完美結合到一起,在引入競爭的同時,解決了去中心化貨幣系統中發行的難題。
Part 6. 所以什么是工作量(POW)證明?
工作量證明的基本含義其實很好理解,就是給計算機出一道難題,叫它去算出正確解。這個過程與驗證碼不同,驗證碼是易于被人理解,卻不易被計算機理解。
比特幣的工作量證明(難題的計算方法)都是圍繞SHA256的,因為哈希值的偽隨機特性可以幫助我們做概率估算。
現在我們為計算機出一道題,通過這道題,我會順帶關聯出,比特幣工作量證明的三個要素(證明函數、區塊及難度值):
比如,我們設計工作量是這樣的:
基本的字符串"Hello, world!" 加上(+) 多大的 nonce(X)可以得到(=) 以 “0000” 開頭的哈希結果(以16進制的形式表示)。
計算機的工作流程:
"Hello, world!0" => 1312af178c253f84028d480a6adc1e25e81caa44c749ec81976192e2ec934c64
"Hello, world!1" => e9afc424b79e4f6ab42d99c81156d3a17228d6e1eef4139be78e948a9332a7d8
"Hello, world!2" => ae37343a357a8297591625e7134cbea22f5928be8ca2a32aa475cf05fd4266b7
...
"Hello, world!4248" => 6e110d98b388e77e9c6f042ac6b497cec46660deef75a55ebc7cfdf65cc0b965
"Hello, world!4249" => c004190b822f1669cac8dc37e761cb73652e7832fb814565702245cf26ebb9e6
"Hello, world!4250" => 0000c3af42fc31103f1fdc0151fa747ff87349a4714df7cc52ea464e12dcd4e9
那么 nonce 為 4521 就可以通過驗證。
現在再給計算機增加難度(工作量)
我們將輸入簡單的變更為"Hello, world+整數值",整數值取1到1000,也就是說,將輸入變成一個由1000個值組成的數組:"Hello, world!1、Hello, world!2……Hello, world!1000"。然后對數組中的每一個輸入依次進行上面例子中要求的工作量證明——找到前導為4個0的哈希散列。
我們會發現,進行計算的平均次數為66958次,十分接近2^16(65536)。數學期望的計算次數,就是我們要求的“工作量”。
Part 7. 區塊 - 分布式賬本
比特幣的區塊由區塊頭及該區塊所包含的交易列表(賬本)組成。區塊頭的大小為80字節,由4字節的版本號、32字節的上一個區塊的散列值、32字節的Merkle Root Hash、4字節的時間綴(當前時間)、4字節的當前難度值、4字節的隨機數組成。
其中的第一筆交易是coinbase交易,這是一筆為了讓礦工獲得獎勵及手續費的特殊交易(見貨幣發行)。
為了表明這個區塊的多個交易,這里采用了Merkle Tree的數據結構。
這是為了解決,如果從一個穩定的服務器進行下載,采用單一Hash是可取的。但如果數據源不穩定,一旦數據損壞,就需要重新下載,這種下載的效率是很低的。而MT樹的特性, 可以通過Merkle Root的HASH值,驗證各個節點的完整性。
理解 Merkle Tree (MT樹)
MT是一種樹,大多數是二叉樹,也可以多叉樹,無論是幾叉樹,它都具有樹結構的所有特點;
Merkle Tree的葉子節點的value是數據集合的單元數據或者單元數據HASH。
-
非葉子節點的value是根據它下面所有的葉子節點值,然后按照Hash算法計算而得出的。
image.gif
Part 8. 動態變化的難度值(difficulty)
難度值(difficulty)是礦工們在挖礦時候的重要參考指標,它決定了礦工大約需要經過多少次哈希運算才能產生一個合法的區塊。比特幣的區塊大約每10分鐘生成一個,如果要在不同的全網算力條件下,新區塊的產生保持都基本這個速率,難度值必須根據全網算力的變化進行調整。簡單地說,難度值被設定在無論挖礦能力如何,新區塊產生速率都保持在10分鐘一個。
難度的調整是在每個完整節點中獨立自動發生的。每2016個區塊,所有節點都會按統一的公式自動調整難度,這個公式是由最新2016個區塊的花費時長與期望時長(期望時長為20160分鐘即兩周,是按每10分鐘一個區塊的產生速率計算出的總時長)比較得出的,根據實際時長與期望時長的比值,進行相應調整(或變難或變易)。也就是說,如果區塊產生的速率比10分鐘快則增加難度,比10分鐘慢則降低難度。
新難度值 = 舊難度值 * ( 過去2016個區塊花費時長 / 20160 分鐘 )
工作量證明需要有一個目標值。比特幣工作量證明的目標值(Target)的計算公式如下:
目標值 = 最大目標值 / 難度值
其中最大目標值為一個恒定值:
0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
**Part 9. **驗證工作量
我們可以把比特幣礦工解這道工作量證明迷題的步驟大致歸納如下:
生成Coinbase交易,并與其他所有準備打包進區塊的交易組成交易列表,通過Merkle Tree算法生成Merkle Root Hash
把Merkle Root Hash及其他相關字段組裝成區塊頭,將區塊頭的80字節數據(Block Header)作為工作量證明的輸入
不停的變更區塊頭中的隨機數即nonce的數值,并對每次變更后的的區塊頭做雙重SHA256運算(即SHA256(SHA256(Block_Header))),將結果值與當前網絡的目標值做對比,如果小于目標值,則解題成功,工作量證明完成。
該過程可以用下圖表示:
Part 10. 生成錢包地址
橢圓曲線算法生成的公鑰信息比較長,壓縮格式的有33字節,非壓縮的則有65字節。地址是為了減少接收方所需標識的字節數。比特幣地址的生成步驟如下:
生成私鑰與公鑰
將公鑰通過SHA256哈希算法處理得到32字節的哈希值
后對得到的哈希值通過RIPEMD-160算法來得到20字節的哈希值 —— Hash160
把版本號+Hash160組成的21字節數組進行雙次SHA256哈希運算,得到的哈希值的頭4個字節作為校驗和,放置21字節數組的末尾。
-
對組成25位數組進行Base58編碼,就得到地址。
下圖以非壓縮格式的65字節公鑰示意上述過程:image
由于橢圓曲線乘法以及哈希函數的特性,我們可以從私鑰推導出公鑰,也可以從公鑰推導出地址,而這個過程是不可逆的。也正因如此,在整個比特幣系統中,私鑰是最關鍵的部分。私鑰泄露也就意味著丟失了一切。
我們要花掉一個地址上的資產,需要構造一筆交易,同時使用這個地址對應的私鑰簽名。而如果我們要將資產轉移到某個地址上,只需要轉賬給他公開的地址就行了。
最后一段小字,寫給想看的人…
我們正生活在一個社會,這個社會,壓抑,無趣,和缺少真相。
The game is on, the fight for net neutrality is long.
Toast for freedom.
**Final. **想了解更多
@作者 WeChat ID: MONFUR