區塊鏈中的密碼學(3):密碼學Hash算法和挖礦

接上文:

區塊鏈中的密碼學(1):提升密碼學的認知

區塊鏈中的密碼學(2):密碼學基本介紹

​談及挖礦,首選浮現在腦海中的應該是:

 

但區塊鏈中的挖礦其實這樣的:

 

機架上排滿礦機,不停地在做運算,而且是是在做Hash運算。有人稱這種挖礦爲能源黑產,把電能轉化爲數字貨幣。那我們今天就來談談Hash算法和POW共識算法的關係。

 

01 Hash算法

談及Hash,我們要區分普通的Hash算法和密碼學中的Hash算法。

普通的Hash算法,一般也稱之爲散列表或哈希表,屬於一種基本的數據結構。一般用於實現O(1)的查詢條件之中, 涉及哈希函數的選取和解決哈希碰撞問題。

它的應用十分廣泛,像C++標準庫中的hashmap, Java中的HashMap,Python中的dict,都採用Hash算法實現。另外想很多緩存產品, memecached, redis都是hash算法的大規模應用。

而密碼學中的Hash算法,可以用一個公式來描述:

摘要/散列值/指紋 = hash(消息)

算法的輸入是消息,或者一堆二進制內容。最終輸出的是固定長度的一個二進制串,可稱之爲摘要,散列值,指紋等。hash算法也有很多種。密碼學的hash算法有五大重要特徵:

  1. 消息是輸入相同,輸出值相同,而且所有的輸出都是等長;

  2. 不管輸入多長,運算速度快;

  3. 算法具備單向性,極難通過輸出值獲取輸入值;

  4. 輸入信息一旦被修改,即使很輕微的修改,輸出值也不一樣;

  5. 不存在hash碰撞。也就是很難找到兩個不同的消息,他們的輸出值是一樣的;

密碼學Hash算法很多,比如MD4, SHA。但MD5被中國的王小云教授證明是不安全的,所以目前使用廣泛的是SHA族類算法。比特幣中使用的是SHA-256算法。

我們可以演示一下Python中使用SHA-256的過程:

 % pythonPython 3.7.3 (default, Nov 15 2019, 04:04:52)>>> import hashlib>>> hashlib.sha256("hello world!".encode('utf-8')).hexdigest()'7509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9'>>> hashlib.sha256("hello world".encode('utf-8')).hexdigest()'b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9'>>> hashlib.sha256("hello world, bitcoin ethereum consusus".encode('utf-8')).hexdigest()'39a0a566f63869830e769533c4efabd31cba7cf624cd23e67638a25354fa5c10'
 
密碼學的Hash算法的特性決定了它的應用範圍,經常被用於身份驗證,文件指紋,消息防篡改等各個方面。

下面,我們講跟區塊鏈極其相關的一種應用,HashCash。

 

02 HashCash

 

HashCash我們在文章《從區塊技術的發展歷史看區塊鏈是什麼?》中提到,由Adam Back設計,具體論文見:http://www.hashcash.org/papers/hashcash.pdf。Adam Back在今天的區塊鏈行業仍然具有巨大的影響力。他是Blockstream公司的創始人和CEO,比特幣核心開發者大部分都是Blockstream公司的僱員。

 

HashCash最早出現是爲了解決網絡中的資源被大量濫用,特別是垃圾郵件氾濫。怎麼辦呢?

 

HashCash的思路很簡單,在發郵件前能不能先乾點小活兒,做對了我才接收你的郵件。這個活兒不能太重,但至少要佔用發送方的一些資源。

 

這個流程其實大家應該很熟悉:

 

12306佔用的是人的注意力,HashCash是CPU的算力,他的方式是:

 

  1. 在電子郵件的消息頭中,增加一個 hashcash 戳記(hashcash stamp)散列值;

  2. 該散列中包含收件人地址,發送時間,salt,該散列值特別之處在於它至少前20位必須是0纔是一個合法的hashcash戳記

  3. 爲了得到合法的散列值,發送者必須經過許多次嘗試(改變salt值)才能獲得。

 

 HashCash背後的設計思路就是希望基於的數學難題,希望你做一些的工作,也就是付出CPU的計算代價(這個概念很重要,比特幣中這個也是關鍵),得到正確的結果,才能獲取某些資源(比方說往你的郵箱發送垃圾郵件)。

 

Hash算法速度相對快,輸入數據相差一點點,都會導致散列值千差萬別的特性,被Adam Back選中。用cash代表付出算力之後的資源回報,用詞非常精當,特別延用到比特幣中作爲POW共識算法的核心,才合適不過。

 

 

03 比特幣挖礦

以比特幣爲代表的區塊鏈技術稱之爲分佈式賬本。既然是賬本,就存在非常核心的問題,賬房先生在哪裏?誰來負責記賬呢?

在傳統的中心化應用中,處理這個問題很簡單,在應用的賬戶系統系統裏面,設置不同的權限即可,把這種核心權限賦予極少部分的人來處理。

但比特幣是一個純粹的P2P系統,每個節點的權限和地位都是一樣的,相當於很多人要一起決策一件事情,這個過程在區塊鏈裏面稱之爲共識(Consensus),共識的機制也就成稱之爲共識算法。

中本聰在設計比特幣算法的時候,受到HashCash的啓發,採取工作量證明的方式來實現記賬過程,參與記賬的節點,稱之爲礦工。工作量證明在比特幣白皮書中明確提到,具體見:

https://github.com/ConsensusDev/whitepaper/blob/master/bitcoin.md(整理了各種版本),有詳細的描述。

礦工合併收到的交易形成一個完整的區塊,區塊頭由一些字段構成,其中最後一個字段nonce是可變的,礦工不斷修改nonce的值,並計算整個區塊頭的hash值,當hash值小於某個目標值的時候,纔算記賬成功,本區塊是一個合法區塊,廣播到全網,礦工獲得記賬獎勵。目標值跟難度值相關聯。難度值越大,目標值越小(hash值前面的0越多),挖礦難度越高。

核心尋找nonce的過程類似於下面一段代碼:

def proof_of_work(header, difficulty_bits):      # calculate the difficulty target      target = 2 ** (256-difficulty_bits)       for nonce in xrange(max_nonce):             hash_result = hashlib.sha256(str(header)+str(nonce)).hexdigest()             # check if this is a valid result, below the target             if long(hash_result, 16) < target:                   print "Success with nonce %d" % nonce                   print "Hash is %s" % hash_result                   return (hash_result,nonce)        print "Failed after %d (max_nonce) tries" % nonce        return nonce

完整的代碼見:

https://github.com/ConsensusDev/code/blob/master/pow/proof_of_work.py

運算難度隨難度的增加指數增加,筆者電腦爲2018年款的macbook,截取一些運算結果如下:

Difficulty: 1048576 (20 bits)Starting search...Success with nonce 237723Hash is 000005720acd8c7207cbf495e85733f196feb1e3692405bea0ee864104039350Elapsed Time: 0.5485 secondsHashing Power: 433381 hashes per secondDifficulty: 2097152 (21 bits)Starting search...Success with nonce 687438Hash is 000003a6eeee97491a9183e4c57458172edb6f9466377bf44afbd74e410f6eefElapsed Time: 1.5282 secondsHashing Power: 449829 hashes per secondDifficulty: 4194304 (22 bits)Starting search...Success with nonce 1759164Hash is 0000008bb8f0e731f0496b8e530da984e85fb3cd2bd81882fe8ba3610b6cefc3Elapsed Time: 3.9695 secondsHashing Power: 443166 hashes per secondDifficulty: 8388608 (23 bits)Starting search...Success with nonce 14214729Hash is 000001408cf12dbd20fcba6372a223e098d58786c6ff93488a9f74f5df4df0a3Elapsed Time: 32.6874 secondsHashing Power: 434868 hashes per secondDifficulty: 16777216 (24 bits)Starting search...Success with nonce 24586379Hash is 0000002c3d6b370fccd699708d1b7cb4a94388595171366b944d68b2acce8b95Elapsed Time: 55.3770 secondsHashing Power: 443981 hashes per second

我們這裏只闡述了核心的挖礦過程,更詳細的流程描述可以見:《精通比特幣》一書。隨着比特幣價格的一路走高,越來越多的礦工加入算力軍備競賽,目前整個算力也達到恐怖的110.18 EH/s。比特幣網絡本身隨着算力的變化,動態調整難度值。比特幣網絡的運行10年的難度曲線如下:

 

當然比特幣網絡也是這場算力競爭中最大的收益者,算力越大,系統越安全,越能形成最大的共識,因而讓比特幣的市值長期超過整個數字貨幣市場的50%。

密碼學Hash算法在區塊鏈技術中運用廣泛,除了挖礦,在區塊打包中也大放異彩,區塊鏈不可篡改的算法保障就是Hash算法決定的。下次探討這個問題,敬請期待。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章