03.16 區塊鏈技術學習筆記

區塊鏈技術學習筆記

部分一:鏈表,哈希,挖礦等

開篇

很多年沒有看到像區塊鏈這樣有生命力的事物了。它像一個欣欣向榮的新大陸一樣,把技術理想主義者,圍觀者,投資者,投機者,甚至流氓騙子各色人等聚集在一起。

在此亂象中,我深感於現在區塊鏈,觀點太多,事實太少。我作為一個個體去摸這頭大象的時候,比較擅長的是以技術的角度切入,看它到底是如何工作,如何發展的,從而把這一隻象腿摸清楚。我把自己的學習記錄下來。這些記錄可能很入門,甚至有錯誤,但是或許對於同樣感興趣的人有所幫助。

鏈表

從技術角度看,區塊鏈的底層是精妙設計的鏈表數據結構①。

什麼是鏈表呢?就是有順序的一串數據塊,一個跟在另一個後面,這個順序是嚴格規定的,不能亂。區塊鏈,食物鏈,供應鏈,資金鍊,甚至鄙視鏈,描述的就是這樣有順序的一串物品②。

我們以比特幣為例,來剖析這個鏈表。

為了構成鏈表,鏈表的數據塊裡面有兩個基本的部分:區塊頭,和數據本身。區塊頭裡面有一個字段指明瞭上一個區塊的id,而所有區塊的id既不是順序的,也不是隨機的,而是區塊頭這80個字節的兩次哈希值。

哈希 Hash

這可能是區塊鏈裡面最讓非理工科出身的學習者費解的概念了。聽起來很嚇人,實際很簡單。哈希就是一個算法,能把任意長度的內容(無論是一個數,還是文章,圖像,視頻,總之就是任何數字化的信息)轉換成一串看似沒有規律的固定長度的數字(哈希值),並保證結果唯一,而從這個結果幾乎沒有辦法推算出原始數據。比特幣用的是叫做SHA256的哈希算法。

比如:1 的SHA256哈希結果是: 0x6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b

2 的SHA256哈希結果是:

0xd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35

我們把這個哈希值看成亂碼好了,因為唯一的規律就是沒有規律。同時,在原始數據中哪怕有一點點改動,產生的哈希就會產生巨大的變化。這個特性常常用來做“數字指紋”。

用日常例子來打個比方。比如按照配方做菜就是個哈希過程:有了配方精確的做菜容易,而從菜品推測出配方難得多。給出兩個數算出他們的平方和比較容易,給出一個數求是哪兩個數的平方和就難很多。哈希算法就大概這麼個意思。

區塊頭和id

剛才講到,每個區塊的id從它的區塊頭的80個字節數據兩次SHA256哈希得到。區塊鏈的一個精妙的設計就是,它對於的id是有要求的。只有滿足特定的規則的id才是合法的。這個規則就是:區塊頭的哈希值必須小於一個數,直觀看到的就是,每個新的區塊的長達64個字符的id必須以比如18個零開頭④,一個合法的區塊id是長成這個樣子的:0000000000000000003c19cdbebe2df5c7f82558e2c80a0c7341e25072b732a2

區塊頭這80個字節裡面的6個字段,5個是不能改的,它們是:

1. 版本號         最近一直是0x20000000 ⑥

2. 上一個塊的哈希值    這個是排隊時候的隊尾,改了就排不到隊裡了

3. 數據的哈希       這個是區塊裡的交易數據,也不能改③

4. 時間          不能改,就是現在的時間。

5. 難度          每個給定的時間全網的難度是一樣的④

只有第六個字段是隨便寫的,這個數字叫做No nce

6. No nce

網絡上任何一臺機器只要找到一個合適的數字填到自己的這個區塊的No nce位置,使得區塊頭這6個字段(80個字節)的數據的哈希值的哈希值以18個以上的0開頭,誰就找到了那個金子⑦!既然我們無法事先寫好一個滿足18個0的數字然後反推Nounce,唯一的做法就是從0開始一個一個的嘗試,看結果是不是滿足要求,不滿足就再試下一個,直到找到。

這個過程被戲稱為挖礦。其實我覺得這個過程和淘金更像。淘金者做的事情很簡單,卻很重複,就是對於河裡所有沙子,拿起來一個,判斷是不是金子。如果不是,扔掉再拿一個。如此重複幾百萬次,總有一個是金子。而在區塊鏈世界,那64個十六進制的字符串,第一個是0的概率是1/16,第二個也是0的概率再乘以1/16,第18個還是零的概率可想而知。所以大家為了找到這個金子一般的No nce一般要花費十幾億次嘗試,雖然每次算哈希的工作並不那麼費時間,重複十幾億次還是要耗費巨大的計算機資源和電力資源。

比特幣體系的另外一個精妙設計就是它動態的調整難度,以無論有多少臺礦機在尋找那個珍貴的正確的No nce,都保證大約每10分鐘產生一個塊。這也是一個類似經濟學的算法。它每2016的塊(也就是2周)就計算一下前面2016個塊平均每個塊花了多少時間,如果低於10分鐘就按照低的比例調高難度,如果高於10分鐘調低難度。這樣礦機無論增減,比特幣都可以按照每10分鐘找到一個塊的金數字並且生成一個合法的塊。

找到了那個金子一樣的數字以後呢?

誰找到了那個數字,誰都可以向全網廣播這個新塊了。而真正的財富秘密在於在這個新塊的數據區的交易數據裡面,第一條交易中,挖礦的人可以憑空的給一個地址(通常是自己的)發放12.5個比特幣。這是規則認可的,就好像賭場裡荷官可以合法的從桌上拿一部分錢進自己的口袋一樣。這12.5個比特幣是比特幣網絡上唯一沒有發款人,只有收款人的交易,新的比特幣就這樣憑空誕生了。這個激勵每4年減半,再過兩年就只有6.25個了,這樣2140年左右兩千一百萬個比特幣就基本上全產生了並且不會增加了。

區塊鏈的網絡

剛才描述的是在一臺電腦上的樣子。實際上,這一串數據是通過P2P網絡分佈在無數的電腦(節點)上的。任何礦工找到了那個金子數字後就立刻全網絡剛播新找到的塊。如果所有節點在一個大的聊天室裡面倒也簡單,但實際上這個廣播是跟烽火臺一樣接力的傳遞的。每個節點告訴周圍的,然後它再告訴周圍的。有意或無意的,就會有兩個或多個礦工近似同時對於網絡的一部分分別宣佈發現了新塊。這個時候的規則就是,每個節點只會接受最長(多)的鏈並且丟棄較短的鏈⑤。經過幾個節點後一定有一個勝出,另外一個被拋棄,而添加新塊是需要算力的,最終一定是擁有最大算力的一方獲勝。這也就是如果沒有人掌超過50%的算力就無法控制區塊鏈。

小結

以比特幣體系為例,最底層就是一串這樣以80個字節的區塊頭開始,約1M的數據跟著的數據。用哈希這樣的算法,一層一層的鎖定,形成了固若金湯的鏈條。再把它分佈在成千上萬的節點上,再又成千上萬的礦機通過挖礦來保持算力高壓,讓篡改數據需要算力門檻。同時,任何人對於歷史數據,哪怕就改了很小的一部分,數據的哈希就變了,區塊頭就變了,它的兩次哈希結果就變了,它後面的塊就連不上來了,就會被立刻發現。如此幾層嵌套,一個人類到現在為止最為安全和防篡改的公共信息系統誕生了。

下面幾篇會記錄一下錢包,公鑰密鑰,智能合約,發放通證(Token),區塊鏈應用,區塊鏈對於組織的影響等等方面繼續記錄學習過程。感謝阮一峰,華宏偉,王哲,趙君,Tim Chen的指正和幫助。

後注

注①:這個跟其他的各種“本質是”並不矛盾,比如區塊鏈本質是分佈式賬本也對,這個是在鏈表結構上面構建的,也有人說本質是加密貨幣,這也對,因為貨幣是在分佈式賬本之上構建的。這些說法之間不是非此即彼的矛盾關係,而是不同層次的應用的問題。

注②:自然界誰吃誰的順序,生產中的誰供貨給誰,再組裝後工會給誰的順序,資金從哪裡流到哪裡,再流到哪裡等等,都是這樣的數據結構。

注③: 區塊頭的第三個字段其實不是數據的直接哈希,而是一個樹狀結構Merkle根。

注④:剛才所說的18個零是一種近似的說法。嚴格地說,是算出來的本塊的ID必須小於一個叫做叫做目標數的數。這個數越小(就是開始的0越多),就越難。

注⑤:嚴格的意義說最長的鏈不是最多區塊的鏈,而是鏈上的所有塊的難度總量最大的鏈。

注⑥:只給感興趣的人看:0x20000000 (十進制536870912)是從BIP9開始規定的新的版本號規則,開始用一個位數表示一個獨立的功能,以區分未來的軟分叉。0x20000000 相當於block的第五個版本。

注⑦:以我寫文章的時候最新的一個塊為例,它的80位區塊頭是這樣的:

000000205d9a3e3dec3e207c3afa9c0be901eaece34b99973a50330000000000000000008565d5bf3819014d521429f02b8cf9d27e226b80998f61d87cd51846c9ab6f9551eb9c5aa3895517ed52e1d4

非常不方便的地方在於比特幣選擇了小端存儲,就是習慣意義的倒著寫數字的方式。按照顏色,如上就是:版本號上一個塊的哈希數據哈希時間難度Nounce 。這個80位數字的兩次SHA256哈希就是這一個塊的id,18個零開頭,滿足要求:00000000000000000043752089261f2b6699cd988d9f5b1732a5a259b50984cf

區塊鏈技術學習筆記

部分二:智能合約,代幣(Token)等

智能合約(Smart Contract)是區塊鏈一個重要的功能。說到智能合約,我們得把視野從比特幣轉到以太坊,因為完整的支持智能合約是以太坊和比特幣的重大差別。

讓我們發個幣吧

聽說區塊鏈上可以發幣,想發行一個自己的幣 ①?來,直接上代碼!

我希望你即使不懂代碼,也要放下對未知的恐懼,靜下心來一行一行讀。畢竟這代碼簡單到大多數人都能看懂。

contractXMT {

mapping (address => uint) public balanceOf;

functionXMT() public {

balanceOf[msg.sender] = 1000;

}

functiontransfer(address to, uint value) public {

require(balanceOf[msg.sender] >= value);

require(balanceOf[to] + value >= balanceOf[to]);

balanceOf[msg.sender] -= value;

balanceOf[to] += value;

}

}

驚人之處來了。如上代碼不是概念性的偽代碼,而是可以運行的真實代碼。

首先它定義了一個記錄每個賬戶有多少餘額的數組:balanceOf

mapping (address => uint) public balanceOf;

看不懂的同學就把它當作有兩列的表格,第一列是賬號,第二列是餘額。用 balanceOf [ 賬號 ] 就可以查到這個賬號的餘額,也可以更改餘額。

接下來是兩個功能:初始化和轉賬。

初始化函數XMT( )很簡單,就是合約建立的時候,任性的把1000個幣全都給創建者。

balanceOf[msg.sender] = 1000;

大家要問,幣是怎麼產生的?沒什麼產生過程,想給誰多少就是多少。初始的時候寫一個億也就有了一個億的幣。如此隨意的就能產生幣,希望會引發大家在夜深人靜的時候,對於貨幣到底是什麼這樣的深層思考。

我們接著看:

轉賬代碼 transfer( ) 核心是兩句:

balanceOf[msg.sender] -= value;

balanceOf[to] += value;

誰發起的轉賬,就把他(msg.sender)的賬戶餘額減去轉賬金額(value)那麼多,然後把收款人(to)的餘額加上那麼多②。

別小看這兩句話。仔細琢磨一下,這其實就是賬戶和轉賬的本質。這簡單的兩句話是銀行體系這麼多年花了多少的硬件軟件,人力物力才能達到的效果。

大家常常聽說誰誰誰又發幣了。從技術角度,就是在以太坊上部署了包含這三行代碼的一個合約。在以太坊的官方網站上就有一段100多行的標準代碼:https://ethereum.org/token。這段代碼裡面還有其他一些功能,比如可以給這個代幣指定名稱,符號,還有授權轉賬,銷燬等功能。大家只要拷貝這個代碼,指定你的新幣的名稱(比如 Xiaomao Token),符號(比如:XMT) ⑦,還有初始發行量比如:1,000,000,000),一個新的幣就誕生了。整個過程3分鐘應該夠了。把參數改一下再部署一下代碼,第二個新幣又誕生了。

這新生的貨幣,雖然沒啥用,但在安全性方面和以太幣天生是一樣的。這就像家長給孩子發了一些飯票,而這飯票的防偽技術和美元一模一樣。看起來相當的大材小用,但如果把發貨幣成本降到幾乎為零,把防偽能力提升到已知的最高水平,隨著時間的推移,難說不會產生什麼重要的應用。

部署代碼

代碼看懂了,下一步呢?怎麼運行這代碼?這代碼到底在哪裡運行呢?接著我們看部署過程。

部署代碼,你需要在以太坊的客戶端裡,把這段代碼粘貼進去,並且按“部署”按鈕。客戶端就會把這種人可以讀懂的代碼③編譯成字節碼,然後生成一筆從你的地址,發給一個空地址(0x0)的交易,並把字節碼存在一個給定的字段裡面(叫input),簽名後發到整個網絡上。接下來的操作和普通交易完全一樣。礦工收到了以後立刻開始打包,算nonce,找到了以後再發送給全網絡。這個可以被執行的代碼,就永久的以只可讀取不可更改的方式,存在了區塊鏈上。

智能合約建立後會返回一個地址。每個幣都唯一的對應於一個智能合約,也就是對應於一個地址。比如著名的EOS幣,就是地址為 0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0 的智能合約發行的。你可以把這個地址想象成以太坊世界裡的門牌號。幣是以這個唯一的門牌號來區分的,而不是那三位的名字。

調用合約

現在,合約的代碼安全的存在區塊鏈上了。那麼接下來這些代碼什麼時候執行呢?

一個智能合約裡面有多個函數。調用智能合約裡的一個函數,和發起一筆普通轉賬交易一樣。很多的客戶端已經內置進去了。你提供合約的地址,提供調用的函數,以及傳入參數,然後發送消息就開始執行了⑤。你可以把它理解為從門牌號的屋子裡面拿東西或者放東西進到給定的屋子。

消息發出以後,所有的礦工都執行這段代碼,並且試圖把結果打包到自己的數據塊中,勝出的礦工獲得挖礦的收益。所有的節點收到這個新的區塊,也用自己的虛擬機執行一遍代碼,確認結果和收到的塊內結果無異之後才當作合法區塊接受。

區塊鏈就是通過這種超額的浪費,看似無意義的算nonce,看似無意義的反反覆覆,沒完沒了的執行同一段代碼,來保證了一個安全的系統。這事兒就跟早上疊被子晚上還得展開一樣,看似不產生價值,實則是房(shu)間(ju)整(an)潔(quan)不可或缺的一環。

花費 Gas

既然代碼要被所有節點反覆執行,那麼問題就來了:要是誰寫了巨長無比的代碼,或者誰寫了有問題的代碼,死循環不結束了怎麼辦?以太坊的解決方法就是引入gas,每執行一個操作都是收費的。怎麼收費呢?

首先每個交易的代碼執行量越大,需要的gas就越多。字節碼每一個操作都有固定的gas花銷。以發幣代碼為例,如下是以太坊給我發的賬單。總共執行了320步字節碼的操作。有的操作很便宜,比如壓棧(PUSH1),只要3個單位的gas,有的就很貴,比如在區塊鏈上存數據(SSTORE)就一下子花了20,000個單位,而讀取數據(SLOAD) 中等, 200個單位。如下加在一起就是1,300,213個單位的gas。只要執行這段代碼,就是要這麼多gas,好像汽車修理店工時的概念。

提交的時候每個人都可以出價,聲明自己願意為每個單位gas付多少錢(price)。這個有點像修理店的每工時的價錢。比如你可以出8 gwei/gas,或20 gwei/gas ⑥。礦工們大多數都是按照這個價錢排序優先打包出錢多的。出錢少就慢,甚至沒人理。

礦工的費用 = gas單位數 * 單位價格。

如下圖所示交易,1,300,213 gas * 2 gwei/gas = 2,600,426 gwei,或0.002600426 以太幣,摺合1.832美元。最終把這筆交易打包進區塊鏈的礦工獲得這部分費用。

除了價格以外,還需要指定一個gas limit,就是你為了這段代碼最多願意付多少單位的gas。這就是為了預防代碼出現問題,無限循環下去,直到把你的賬戶裡的錢耗盡為止。如上圖,gas limit設為1,300,213個,這段代碼實際上也只用了1,300,213個單位的gas,還好,正好沒有超過限制。否則超過了程序執行會嘎然而止,已經花的gas不退。

智能合約的價值

智能合約第一次認可了代碼的自主權。代碼可以擁財產,可以和人一樣平等的在區塊鏈上交易。一個合約的代碼一旦發佈,誰都改不了了,連上帝都無能為力。這就是信任的來源。大家可以像堅信自然定律一樣堅信這個合約如代碼所寫的執行。你不需要相信任何人,只需要認真的讀智能合約的代碼,就可以確定性的知道這個合約將如何執行。

如上從技術層面簡單的介紹了一下智能合約的過程。但智能合約和區塊鏈真正的價值不在技術,而是它們對於價值傳遞以及信任建立的貢獻。

我們看到的人類發展總是多條線並進,一條是生產效率,蒸汽機,電力,計算機,互聯網,人工智能等都在這條線上;區塊鏈是生產關係的進步這條線上的,這條線上曾經有過貨幣,現代公司制度,股票,現在有了區塊鏈。

晚一些我再聊一下它對信任的貢獻,還有可能對於社會的改變。

後注

① 很多專業人士希望把token翻譯成通證,而不是代幣。“通證”更加符合單詞原意,符合事物本質,也希望避免被當作貨幣監管。這像極了“網誌”和“博客”兩個譯名之爭。結果博客被接受,更加準確,拗口,後來出現的網誌不再有人提起。這個結果或許可以預測通證這個翻譯的結果。

②Transfer函數前面的兩句require,第一個是要求你的餘額必須大於轉賬金額,第二個是要求轉賬金額不要過大以至於大於256位整數能容納的數字。msg.sender 是內置的,可以獲取消息的發送人的地址。

③可以搜索Remix,或MyEtherWallet。Solidity的語法和JavaScript很像,專門用於以太坊上編寫智能合約。

④這裡解釋一下技術細節。建立合約的時候,用戶發起一筆發款人為自己,收款人為空地址 0x0 的交易,並把字節碼放到交易裡面叫做輸入(Input)的字段裡面。礦工就會生成一個新的合約地址並把代碼存在這個地址裡。

⑤技術實現,其實是在交易數據的Input字段加上了一個編碼後的數字。比如這串數字:a9059cbb00000000000000000000000007fdf7518745170e3d9de26874578b6c0a72b9dc0000000000000000000000000000000000000000000000000000000000000010

顏色是我為了區分加的,前四字節a9059cbb是函數名 ,"transfer(address,uint256)"這個字符串的SHA3-256哈希結果a9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b的前4位,用來指定是哪一個函數,根據函數定義,就知道後32位是第一個參數:地址 ,也就是0x07fdf7518745170e3d9de26874578b6c0a72b9dc。接下來32個字節是

金額 ,相當於十進制16。大家看得出,現在的區塊鏈從抽象水平上基本上還停留在計算機的DOS和彙編語言的時代。

⑥ 1 gwei 就是 1,000,000,000 個wei。這個g就跟內存單位多少GB的G是一個概念,就是10億的意思。10的18次方個wei就等於一個以太幣。所以1 gwei看起來很大,其實也就是10的9次方分之1個以太幣而已。一個以太幣在我寫這篇文章的時候是764美元,你大概有概念了是多少錢了吧。

⑦ 發幣時候指定的名稱,符號,僅僅就是一個字付串,是可以重複的。你可以發一個幣叫USD,RMB,或任何你能想象的名字。Token是以發行這個Token的智能合約的地址唯一指定的,和名字無關。

部分三:錢包,私鑰,地址等

錢包

判斷一個人是否真的瞭解區塊鏈的一個簡單的測試是問一句:“我轉錢給你。你的錢包地址是啥?” 這個試金石可以輕鬆區分很多偽專家。在成熟的互聯網世界,沒有郵件地址還說得過去,畢竟沒有郵件地址也可以點外賣,但是現在百廢待興的區塊鏈世界,一切都如此原始,沒有自己的錢包地址就是一個旁觀者。

要開始,先要搞一個錢包,獲得自己的地址。比如這就是一個合法的比特幣地址:

1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm

這就像銀行賬戶一樣,有了它任何人都可以給你轉賬了。有非常多的軟件可以幫你生成自己的地址。

受互聯網網站的思維慣性影響,還有銀行開戶程序的影響,很多人以為要搞一個錢包地址還需要到什麼地方註冊一下。其實不然。任何人都可以自己獨立的,不聯網的生成自己的錢包。這是怎麼做到的呢?錢包裡面到底包含什麼呢?

公鑰私鑰

這涉及到一個密碼學上的一個基本概念:公鑰密鑰。公鑰和密鑰一對一對兒的出現,公鑰加密的東西可以拿私鑰解開,私鑰加密的東西可以用公鑰解開。大家就想像成一個帶鎖的盒子和一把鑰匙的關係吧。這個特性用來加密和簽名。

加密的過程好像是把自己的盒子寫上自己的地址發的全世界都是,誰都可以免費要一個。誰要給你寄信就把信放到盒子裡面鎖上,然後寄給你。寄件人和收件人都很放心,因為路途上沒有任何人(包括寄件人)可以打開盒子了。世界上能夠知道信的內容就只有你和寄信的人。

簽名的過程也很容易理解。就是寫著你名字的鑰匙發的滿世界都是,誰都可以免費拿一個。而這把鑰匙能打開的盒子只有你有,誰都不給。如果有人得到了一個盒子,拿你發的鑰匙可以打開,盒子裡的東西一定是你發的,因為這把鑰匙能夠打開的盒子,這個世界上只有你有,你無法抵賴。

區塊鏈世界用了這個精妙設計的公鑰私鑰體系,但是不是用來加密,主要用於簽名。你手裡面握著私鑰,打死你也不說的私鑰。而你的地址,就是那個滿世界皆知的公鑰。鑰匙信息可以被公鑰打開,則說明一定是知道私鑰的人加密的。所以任何的交易一旦用你的私鑰加密了,收到的人驗證一下用你的公鑰可以解密,那就認為是你授權的操作。

錢包地址的生成

比特幣世界幾個關鍵的信息是按照這個順序生成的:先生成私鑰,再由私鑰算出公鑰,再由公鑰經過一系列哈希算出錢包地址。

私鑰 ---> 公鑰 --> 錢包地址

上面的推導次序是單向的,反向不可能。就是說從錢包地址無法得到公鑰,從公鑰無法得到私鑰。

比特幣的公鑰變形出來的錢包地址,可以想象成用戶名,這全世界都可以知道;私鑰可以想象成密碼,這個只有自己可以知道。

私鑰是一切的開端

私鑰一個大於零,小於2的256次方的一個任意數字①。你就隨便挑吧。挑中了這就是你的了。比如,你可以任性的把私鑰設置成這樣:

0000000000000000000000000000000000000000000000000000000000000001

就是數字1。好記吧?(千萬別真的真麼做。我舉著個例子就是為了演示用一個大家能猜到的私鑰是多麼危險)

然後通過橢圓曲線函數,就可以對應的公鑰②:

0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8

然後經過一系列讓人眼花繚亂的哈希,最終形成比特幣地址如下:

1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm

私鑰就像《阿里巴巴和四十大盜》的故事裡面的“芝麻開門”。世界上任何人只要知道“芝麻開門”這個咒語,就可以在那座大山裡面找到那個山洞並且打開大門。比特幣的世界就是這樣無情。一個人是否擁有一個賬戶,不看他是誰,就是看他是不是知道那個秘密。四十大盜知道咒語可以拿寶貝,阿里巴巴知道也可以拿。至於這個山洞裡面有沒有金銀財寶是另外一件事情了。

既然所有看這篇文章的人都知道了這個地址的私鑰(數字1),我們就共同擁有了這個地址裡面的錢,任何一個人都可以花裡面的全部的錢。

在比特幣的世界,雖然無法知道地址背後的人是誰,但這個地址歷史上所有的交易都是公開信息。很多網站和工具可以讓你查詢。來,讓我們來查詢一下這個賬戶,看看咱們有多少錢 :-)

真可惜,餘額為零。這個並不驚訝。

但讓我驚訝是,這個地址從2011年到最近的2018年3月9日,居然有過1201筆交易,總共收到過7.8個比特幣,即便按照最近跳樓的幣價,也是24萬塊錢人民幣呢。這期間任何一個時間點,這個地址裡的錢,就是放在大馬路上任何人都可隨手拿走的錢。多危險呀!

所以所有的錢包軟件都是儘量的生成一個越隨機越好的私鑰。好在隨機生成的私鑰足夠安全。有多安全呢?我們的大腦是無法理解256位私鑰到底能存多大的數字。這麼說吧,2的256次方大約是10的78次方,也就是10後面78個零。而現在人類觀測到的全宇宙的所有的原子才10的78到80次方左右。也就是說私鑰的可能性大約是全宇宙的原子數那麼多。從整個宇宙中隨機找出一個原子給你,這是你的私鑰,你覺得和別人衝突,或者被別人猜中的可能性有多少?

錢到底存在哪裡?

首先,錢不存在錢包裡。

很多錢包軟件可以顯示餘額,完成交易,但錢不在錢包裡。錢包唯一記錄就是一個私鑰 ③,大多數的私鑰不像例子裡面那麼容易猜,看起來就是亂碼。如果誰有本事背的下來這個密碼,其實你就不需要任何錢包。有些工具允許你交易的時候直接輸入私鑰就可以了。

那錢存在哪裡呢?

錢的數量存在區塊鏈上,而區塊鏈的鏈表結構存在成千上萬的電腦上。如果你下載一個比特幣的客戶端,同步以後有大約100多G的數據。裡面包含了從第一筆交易到現在快10年的所有數據。所以回答這個問題,錢並不存在在任何地方(不存在一種刻著中本聰頭像的紙幣或金幣),錢的餘額存在無數的電腦共同維護的一個賬本里。

密碼和助記詞

既然唯一重要的是私鑰,為什麼很多錢包還需要密碼呢?這是一個雙重保護。把私鑰明文的存在電腦硬盤或手機上不是個好主意,對於黑客甚至是親近的朋友拿到硬件一個簡單的搜索就能找到錢包文件。所以大多數錢包是把私鑰再用一個密碼加密一下,然後只存儲加密過的私鑰。沒有密碼就無法容易的訪問私鑰。因為人類起的密碼就那麼8-10位常常是有規律的文字,其安全性遠低於機器生成的256位的私鑰,但也總比沒有好。但千萬不要以為這個密碼就是你的比特幣或以太幣密碼。它僅僅是是一個保護密碼的密碼。丟了存私鑰的文件,有密碼也沒有用了。

還有一個大家使用錢包中經常遇到的,就是錢包幫你生成一串12個單詞的句子,讓你把這個句子抄下來保存好。比如這樣的:

voice again pupil thumb strategy toss extend unusual neutral shuffle claim cave

這是什麼呢?和私鑰又是什麼關係呢?

它叫助記詞(mnemonic code),其實就跟以前地下工作者用的密碼本一樣,也跟“A for alpha, B for Brave, C for Charlie ”的原理類似。,BIP39(Bitcoin Improvement Proposal 39)定義了2048個單詞的列表,每個單詞都有編號,比如

voice ==>1964

again ==> 38

...

cave ==> 295

然後把這些數字按照一些複雜的算法拼起來就可以還原出來私鑰了 ④。

現有錢包的問題

如上就是比特幣等的錢包,私鑰,地址等的現有運作方式。但問題是很明顯的:

密碼不可改。密碼改了,公鑰就變了,地址就變了,也就是另外一個錢包了。密碼一旦洩露,也沒有辦法改變。

密碼忘了。如果你的私鑰忘了怎麼辦?無解。忘了就是忘了。沒有找回密碼功能。大量早年的比特幣都隨著一次不小心的電腦格式化消失了。嚴格的說,那些比特幣沒有消失,我們還能看到它們就在自己曾經擁有的那個地址裡面,但我們就像忘記密碼的四十大盜,只能看不能花了。此事現在無解。

假裝不記得密碼。典型例子就是離婚的時候,夫妻雙方有一大筆財產在比特幣裡,一方堅持說把私鑰弄丟了,法官無法證明這個人是真的忘了還是假的。另外的情況就是有些公司宣稱被黑客偷走了比特幣,而沒有任何人可以證明小偷是另有其人還是就是自己。

這些問題都需要未來的創新來解決。

總結

前面幾篇文章介紹了區塊鏈的一些最基本的技術,從鏈表,哈希,挖礦等 到 智能合約,代幣(Token)等,還有本文的錢包,私鑰和地址等。

我花時間先談技術的本意不是為了證明技術多重要,而是通過抽絲剝繭來幫助大家理解區塊鏈的底層技術是多麼的簡潔,容易理解。希望這可以緩解很多人的區塊鏈焦慮。因為從底層來說,技術沒有什麼複雜,但是設計的非常精妙,而且像互聯網底層技術一樣實用。

接下來,我想我會把視野更多的放到技術背後的商業和哲學的層面了。畢竟,區塊鏈對於世界的影響,不是技術本身,而是它對於生產關係,對於價值傳遞等等的巨大改變。這裡面牽扯到代幣經濟(Token Economy),代幣促進的網絡效應,ICO,區塊鏈應用等等好多的內容。

後注

注①:嚴格地說是 1.158 * 10^77,比2^256稍微小一點點

注②:這個公鑰其實是一個座標。0x04是標記位,後面兩個256位的數字是橢圓曲線上的座標值: (79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)

③:雖然公鑰,地址都是可以從私鑰確定的算出來,很多錢包軟件裡面為了方便也存儲了公鑰和地址。

④:技術細節:實際上不是簡單的拼接。2048個可能性就是11位,所以是很多個11位拼出來。還有最後幾個單詞是有可能是校驗位,以發現用戶輸入錯誤。同時最終拼出來的也不是私鑰本身。但大家只要知道這個東西最終可以找到私鑰就好。

感謝王建碩,華宏偉,趙君,宮亮,Tim,王哲對本文的幫助。如果感興趣可以訂閱公眾號token經濟”以後一起學習交流。

區塊鏈技術學習筆記


分享到:


相關文章: