比特幣和區塊鏈(2):比特幣中區塊鏈的實現

雪花又一年發表於2018-04-18
1620

0

上一篇我們討論電子貨幣的時候提出了由一個寡頭負責對所有人的電子貨幣和交易進行記賬,記錄到只能增加不可修改的賬本里,並且把賬本公開給所有的人看的這樣一個電子貨幣模式。

這個模式解決了很多的問題。最主要的是電子貨幣被複制使用的問題。但是這個模式有兩個比較大的問題。第一是這個賬本怎麼實現。第二是一個寡頭是不是靠譜。

今天我們重點來講賬本的實現。這個賬本的實現其實就是區塊鏈這個名詞的由來。可能對懂的人來說節奏有點慢,但是對不懂的人來說,慢工出細活。這篇的內容依然不是很精彩。但是這些仍然是為了講清楚後面更精彩的內容所必須的準備工作。

下一篇我們將開始討論怎麼樣從一個寡頭到民主社會的過程。如何達成一致性,如何防止壞人,以及挖礦到底是什麼都會逐漸清楚。這篇文章會用到比較多的計算機相關的術語。而我也只能盡力用通俗易懂的方式給大家解釋了。

1

在一個寡頭負責記錄,所有人都可以查賬的系統裡。我們第一個需要解決的問題是,大家怎麼確定一筆交易確實是由某個人發起的。比如說,張三發起說給李四付了5塊錢。大家怎麼能夠知道這個交易確實是張三發起,而不是王五冒充的。

這個問題在計算機密碼學裡被叫做數字簽名。我們可以設想一下現實世界裡的簽名有什麼樣的特點。一般來說,簽名是由特定的人簽在特定的檔案上的。更通俗一點來說。每個簽名應該有如下幾條要求:

  1. 由特定的人籤。
  2. 大家可以辨識。
  3. 簽名附屬於特定的檔案,壞人無法把一份檔案的簽名挪到另外一份檔案上。

在數字簽名的世界裡,這些特點也同樣需要滿足。數字簽名通常使用非對稱加密演算法實現。簡單來說,有一個公鑰一個私鑰。前者用於解密後者用於加密。

如果張三想要發起交易付給李四5塊錢,張三可以用自己的私鑰對這個交易簽字,然後傳送給寡頭。等寡頭把交易寫進賬本以後,吃瓜群眾王二麻子等等都可以用張三公開發布的公鑰去驗證這個交易是不是張三發起的。

2

最早的數字簽名演算法叫RSA,是以三個發明人的首字母命名的。這三位也同時獲得了電腦科學界的最高獎圖靈獎。RSA演算法主要基於大質數分解問題。這個演算法自誕生以來幾十年時間裡被廣泛的檢驗,簡單來說,裡面有無數的坑。要實現一個安全可用的RSA,需要很多的技巧。即便如此,它的安全性還是受到各方面的質疑。

而比特幣使用的數字簽名演算法是橢圓曲線演算法,而不是目前常用的RSA。這個演算法目前為止還沒有好的破解方式,哪怕是針對特定情況的。這是非常安全的一個數字簽名演算法。

在數字簽名的使用上,我們還有一個問題沒有解決。這些數字簽名的公鑰是怎麼樣釋出出去的。比特幣採用了一個非常聰明的機制。這個機制也同樣適用於我們這個一個寡頭負責記錄所有交易的簡化版的系統。簡單一點來說,比特幣系統認為,一對私鑰和公鑰代表了一個人。

儘管我們知道在背後無法杜絕一個人使用多對私鑰和公鑰,而一對私鑰和公鑰也可能被多個人使用。但是在比特幣系統裡,每個獨立的個體是以不同的私鑰和公鑰對來區分的。私鑰自己藏著不可見,而公鑰就成了這個人的身份證號碼和地址。所以,如果各位有玩過各種加密貨幣,錢包的地址是一串雜亂無章的字串,這個其實就是橢圓曲線演算法產生的公鑰。總結一下,比特幣系統裡,每個參與的客戶端把自己的公鑰作為地址,參與系統交易。其他人要驗證一條訊息是否是這個人傳送的,只需要拿其地址作為公鑰去驗證即可。

3

下面我們討論賬本的不可篡改問題的實現。我們把這個問題的定義改一下。換個說法就是這個賬本如果出現了任何的篡改,任意一個查賬的吃瓜群眾都可以獨立的發現這個賬本已經被篡改了。所以賬本不可被篡改,在區塊鏈裡,實際上是一種保障賬本一旦被篡改,大家都可以迅速發現的機制。而不是說賬本寫進去之後就無法被改變了。

這裡需要用到計算機領域的另外一項技術:雜湊(Hashing)。用通俗一點的話來說,雜湊使用一個雜湊函式,對一段輸入的東西生成一個輸出的東西。這裡我們需要用一下中學數學的一些知識。

如果y=f(x)是一個函式的話,x的取值範圍是定義域,y的取值範圍是值域。對於任意一個在定義域裡面的x,值域範圍內有且僅有一個y對應。但是,對於不同的x,可能會對應到相同的y。這種現象在雜湊裡面叫做衝突(conflict)。

密碼學上的雜湊有一些要求。這裡我們還是以比特幣使用的雜湊函式SHA256為例來說明這些要求。SHA256通過一系列複雜的數學變化,對輸入的任意長度的文字,生成256位元大小的輸出。

這個函式有很多的特殊性,我們先來看第一點:衝突必然存在。因為值域是256位元固定大小的輸出,而輸入是任意長度的。所以值域其實是定義域的真子集。定義域的大小比值域要大。根據鴿洞原理,10只鴿子,9個鴿洞,必然存在一個鴿洞裡面至少有兩支鴿子。如果值域是定義域的真子集,衝突必然存在。

4

但是所有密碼學上的雜湊函式,包括SHA256滿足如下幾個特點。這幾個特點構成了區塊鏈技術檢測篡改的核心。

第一點,給定x算出y不是一件特別困難的事情。對於SHA256來說,如果我們給定輸入,得到256位元的輸出,是一件計算上相對很廉價的,只要文字不是太誇張,1秒以內肯定大部分計算機應該能算出來。

第二點,僅僅給定y,找到能夠生成y的x候選者,是一件計算上幾乎不可能的事情。考慮一下函式y=x+1,對於這種函式來說,每個y算出可能的X候選者是很容易的。SHA256不同,如果僅僅知道y要推算出可能的x,只能靠近似窮舉的辦法。也許運氣不好幾百年也不一定能找到一個合適的x。

第三點,對於相鄰的x,產生的y的距離是很隨機的在y的值域裡的。這句話通俗一點講,也就是說我們無法通過對有限對x和y值的研究去推測出一個新的x可能會產生出什麼樣的y來。

這幾個特點結合起來,我們就有了這樣的一個現實的應用。我們可以公佈系統使用的雜湊函式的細節。然後把y值也公佈出去。這樣每次不管是誰想要檢驗是不是某個輸入產生了這個對應的y值,只需要把這段輸入x用這個函式跑一下,結果出來如果是y,那麼大概率就是對的,如果不是y那麼大概率就是不對的。用人話翻譯一下,就是說真的遇到了另外一個x居然也能產生同樣y的概率很低,遇到了只能自己認倒黴了。

所以,如果我們記住了x的雜湊值y,又知道雜湊函式是什麼,當x被篡改之後,只要雜湊值y無法被同時篡改,我們就可以很迅速的知道,x是被篡改的。這是區塊鏈防止篡改的基礎。

5

現在,我們可以給大家介紹區塊鏈是什麼了。區塊鏈是一個單項鍊表。它由若干個連線的區塊構成。每個區塊包含了若干條交易記錄,還有一個表頭。表頭裡面存了很多東西,但是對於我們理解來說,最重要的是兩個:1前一個區塊的地址,2前一個區塊的雜湊值。這個區塊鏈就是這個不可篡改的賬本了。而區塊鏈的第一個區塊的地址和雜湊則被髮送給系統裡面 每一個成員。

系統剛開始的時候只有一個區塊:如下面所示區塊A

   A

A裡面包含了若干交易記錄。這些交易記錄都被數字簽名了。而A的地址和雜湊值則廣播給了整個系統裡面的所有吃瓜群眾。

這種情況下,A如果被篡改,每個吃瓜群眾去查賬的時候,只要跑一下SHA256就會發現極大概率的情況下,雜湊對不上了。所以這個賬本被篡改了。吃瓜群眾可以拒絕相信這個賬本。

那麼隨著時間的執行,這個系統裡一個區塊存不下去了,現在我們有了兩個區塊A和B

  A<—B

這個時候,B的表頭記錄了A的雜湊和地址。而B的地址和雜湊被廣播給了所有的吃瓜群眾。我們知道如果B被篡改了,那麼B的雜湊值和吃瓜群眾手裡的雜湊值就無法對應了。假設B沒有被篡改,那麼A被篡改了會怎麼樣呢?

B裡面存了A的雜湊值,所以吃瓜群眾也可以順著鏈條發現A被篡改。那麼我們是不是可以同時篡改A和B表頭的A對應的雜湊值呢?答案當然是不可以。因為篡改了B表頭的雜湊值,等同於篡改了B。這個被篡改以後的區塊算出來的雜湊值,和吃瓜群眾手裡拿著的雜湊值是不一樣的。

如果系統繼續擴張,有了A, B, C呢?

A<—B<—C

道理是一樣的,只要吃瓜群眾手裡拿著原始的C的雜湊值,那麼寡頭的任何篡改都是沒有希望不被發現的。當然如果哪天電腦科學發展到了一定程度,或者數學上證明了SHA256不安全,寡頭可以偽造出另外一個區塊,使得它的雜湊值和吃瓜群眾手裡拿著的原始的C的雜湊值是一樣的,那麼整個系統就再也不安全了。

6

下面這段內容,如果沒有計算機背景可以略過。

在比特幣的區塊鏈系統裡。每個區塊的交易記錄是存成為一顆二叉樹。二叉樹的葉子節點是每條交易記錄,上面的每個父節點的左右指標分別指向左右子樹。但是這個二叉樹和我們平時常用的二叉樹有一點不同,它不但儲存左右子樹的地址,同時也儲存左右子樹的雜湊值。這種樹叫做Merkle Tree。

Merkle Tree的一個重要特點是可以在O(Log n)的時間複雜度裡檢驗一筆具體的交易是否被篡改。O(Log n)的複雜度什麼意思呢?簡單來說,如果一個區塊裡面存了2的100次方交易,那麼計算機系統大致上只需要做100次的雜湊比較,就可以確定一筆具體的交易是否被篡改。這是非常高效的演算法。

但是Merkle Tree只是交易記錄在區塊內的一種儲存形式。它是密碼學上常用的一個資料結構。也是比特幣的發明者中本聰選取的。這並不代表著我們必須,只能用這種結構去儲存區塊裡面的交易。

7

我們來總結一下今天的內容。今天主要講區塊鏈這個不可篡改的賬本是什麼。

我們首先講了數字簽名技術。數字簽名由私鑰和公鑰對組成,使用者用私鑰簽名,公鑰在比特幣系統裡面是每個參與者的身份號碼和地址。任意的人可以通過公鑰去確認一筆交易確實由某個特定的人發起。比特幣使用橢圓曲線數字簽名演算法。

我們接下來講了密碼學上的雜湊。密碼學上的雜湊的特點是從輸入x算出輸出y很容易,從輸出y找到可能的輸入x很難,雜湊函式對相鄰的x的值域y很散,通過已知的若干對x和y的關係,在給定新的y的情況下,去尋找新的x也是沒有任何幫助的。窮舉法幾乎是唯一的尋找特定的y對應的輸入x的辦法。而以今天的計算機能力,窮舉法需要漫長的時間。所以,y可以作為驗證x是否被篡改的標記。比特幣使用SHA256雜湊演算法。

我們接下來講了區塊鏈的結構。每個區塊存了若干交易記錄。區塊們從老到新連結起來,後一個區塊記住前一個區塊的地址和雜湊值,而表頭最新的區塊的地址和雜湊值則廣播給所有在網路裡的人。我們證明了,因為在網路裡的人手頭的雜湊值無法被篡改,所以任何針對整個區塊鏈的篡改都會被吃瓜群眾發現。

最後我們講了區塊鏈內交易記錄的儲存。在比特幣的區塊鏈裡,用的是改良的二叉樹Merkle Tree。它提供了O(Log n)的時間複雜度去檢驗一條具體的交易是否被篡改。

順便提一下,山寨幣和比特幣的不同,其中一部分就體現在區塊的大小,雜湊函式的選擇等等。但是這篇文章主要講述比特幣的技術實現,我們就不再比較其他的了。

下面我會開始講分散式一致性的問題,也就是比特幣如何去除這個寡頭的問題。

有讀者問本人對數字貨幣的態度到底是什麼。簡單一點說,我拿身價5%的錢投資數字貨幣。投資組合裡以大幣為主,小幣則按照我自己對區塊鏈技術的理解選擇。理解體現在小幣使用的區塊鏈技術的各個方面是否靠譜。本公眾號的任何文章都只代表個人觀點,不構成投資建議。

原文釋出時間為:2018-01-21
本文作者:使用者1564362
本文來源:騰訊雲 雲+社群,如需轉載請聯絡原作者。


相關文章