Zcash挖礦算法深度解析

說明

    本文轉自 https://www.8btc.com/article/126531
    對於equish 算法,作者原論文下載鏈接爲:

zcash 介紹

相比於比特幣,Zcash在挖礦算法方面進行了修改。比特幣使用的挖礦算法是SHA256, Zcash則使用的是Equihash。Equihash算法由Alex Biryukov 和 Dmitry Khovratovich聯合發明,其理論依據是一個著名的計算法科學及密碼學問題——廣義生日悖論問題。
筆者希望通過儘可能通俗的語言論述Zcash是如何運用Equihash算法實現挖礦進程的。

接下里講解Zcash挖礦的一般過程。注:筆者目前仍無法完全脫離代碼進行講解。

①構建區塊頭 執行挖礦算法之前,首先要構建一個區塊頭。Zcash的區塊頭(Block header)結構如下,這一結構與比特幣的區塊頭類似,差異在於隨機數的位數。
在這裏插入圖片描述
圖1 Zcash的Block header
nVersion,區塊版本號,升級時改變。 hashPrevBlock,從前一區塊獲得。 nBits,由全網算力決定,每產生一個新塊都調整一次難度(比特幣每2016個區塊調整),算法爲DigiShield v3/v4。 nTime,基本取機器當前時間軸。 hashMerkleRoot,本字段允許礦工自行調整,變化來自於對包含進區塊的交易進行增刪,或改變順序,或者修改Coinbase交易的輸入字段。 nNonce,Zcash提供2256種可能取值,而比特幣提供232種。 一般來講,hashMerkleRoot和nNonce是發揮挖礦自由度的地方。
Zcash區塊頭構建的一般過程也與比特幣類似:

選擇待確認的交易,因爲礦工可以從交易中獲得手續費,所以一般構建區塊時會選擇儘可能多的交易,但是不能超過容量上限(2M)。
確定Coinbase,這裏記錄假如該區塊構建成功,礦工將獲得的收益(手續費+獎勵)。
構造Merkle樹(集合交易信息),生成隨機數V,寫入其他參數
構建如圖1所示的Block header。
②轉化爲一個廣義生日悖論問題
我們通常把比特幣的“挖礦”過程比作解一道算法題。而這道算法題的題目就是通過對Block header 的函數處理給出。 比特幣的算法:對Block header的參數進行兩次SHA256運算,得到一串256位的字符串,讓它與一個預期值target進行比較,如果這個值小於target,則挖礦成功,即SHA256(SHA256(Block header))<target,否則調整Block header(修改隨機數或者Merkle樹),再重複上述運算。 Zcash的算法:同樣是在構建完Block header以後, Zcash不是做一個不等式判斷,而是以Block header作爲輸入,將挖礦問題轉化爲一個“廣義生日悖論問題”。
什麼是廣義生日問題?
用計算機語言定義廣義生日悖論: 隨機生成一個由N個“n位字符串{Xi}”組成的列表L,
在這裏插入圖片描述
要求在這些字符串中找到2^k個特定的{Xij},使得:
<ignore_js_op>
Zcash挖礦算法深度解析
通俗的表達:從該列表L中找到2k個完全相等的元素,即找到2k個碰撞元素。
注:限於篇幅,本文只講結論,若讀者感興趣,可自行查找“生日問題相關內容”
如何處理Block header得到一個“生日問題” Zcash內有一個專門的哈希函數Equihash Generator。Equihash Generator的功能是將一個輸入和一個索引映射到一個長度爲n位的輸出。 令i ∈ {1 … N},把生成的區塊頭(Block header)以及整數n、k作爲輸入,其中 n、k的值由官方給定,通過在這裏插入圖片描述
Zcash挖礦算法深度解析
的函數過程,可以生成一個由N個“n位字符串{Xi}”組成的列表L。在這裏插入圖片描述
圖3
③ “廣義生日悖論”的解法 用於解決“廣義生日問題”,數學界提出了許多著名的算法,密碼學家Wagner的算法就是其中之一。Zcash團隊以Wagner的算法爲基礎,經過Alex Biryukov和 Dmitry Khovratovich等人的優化後得到了一種名爲“OptimisedSolve”的算法,用於求解上述問題。
理論上,爲了公平起見,用於“工作力證明”的算法必須是對於該問題的最優算法,因爲假如這個算法不是最優的,那麼可能有人會發明並暗地裏使用更優秀的算法挖礦,則在同算力條件下他的挖礦成功概率就會大於其他人。但是若是仔細考察“OptimisedSolve”算法,不難發現它還是存在優化的可能性的。具體如何實現優化,本文不展開思考,筆者的後續文章會就這一點進行單獨討論。
限於篇幅,不詳細介紹“OptimisedSolve”算法的原理,若有興趣,可以參考文獻:《Equihash: Asymmetric Proof-of-Work Based on the Generalized Birthday Problem》
求解過程:

把從Block header派生出的列表“n位字符串”列表L當做“生日問題”的條件,運用改良的算法“OptimisedSolve”,即可從L中找到2^k個完全相等(碰撞)的{Xij},使得:
在這裏插入圖片描述
具體過程如圖4所示
在這裏插入圖片描述
圖4
④難度調整(Difficulty filter)
到第③步爲止,“生日問題”已經被解決了。但是並不是說誰先構造並解決了一個“生日問題”誰就取得了“挖礦”的勝利,若單純以生成並解決一個“生日問題”作爲勝利條件,則有可能出現以下幾個問題:
1.從概率學的角度,生成的列表L中可能不存在2k個完全相等的值,即碰撞的個數少於2k。這會導致有的“礦工”構造出來的“生日問題”是無解的,所以當出現這種情況時必須重構一次“生日問題”。
2.單純的使用“OptimisedSolve”導致“挖礦”難度難以被控制,因爲該算法的運行時間服從泊松分佈。
3.在內存足夠多的情況下,可以使用更復雜的技術迭代產生多個攤銷成本更低的解決方案,即運行這樣的算法會讓單位內存的運行成本降低,有悖於公平“挖礦”的理念。
(Zcash希望實現公平“挖礦”,即羣衆參與挖礦,而不是礦池壟斷挖礦。)
所以,和比特幣一樣,Zcash也應用了一個叫做Difficulty filter的難度調整算法。

Difficulty filter(記爲H)是一個被用來調整工作證明的時間和內存要求的算法。得出“生日問題”的碰撞解{Xij} 之後,還要進行Difficulty filter環節的檢驗。檢驗通過才能算是“挖礦”成功。具體過程如圖5所示。
在這裏插入圖片描述
圖5
1)Difficulty filter的三個判斷條件
注:H(S)表示輸入S 經過Difficulty filter H這一算法過程輸出的結果. -生日算法條件:
在這裏插入圖片描述
-難度算法條件:
在這裏插入圖片描述
的結果有d個前導零
-綁定算法條件:
在這裏插入圖片描述
的結果有n*l/(k+1)個前導零,這對於所有滿足條件的w、l均成立。
注;前導零的個數指的是一串二進制數前若干位爲零的位數(見圖5)。

-生日算法條件表示用來確定上一過程獲得的解是否是滿足條件的碰撞; -難度算法條件用來確定當前難度是否合理,併成爲難度調整的依據; -增加一個綁定算法可以防止有人發明某種算法:該算法使用足夠多內存攤銷成本,使單位內存成本降低。 (這裏只討論結論,具體算法限於篇幅不展開討論)
2)判斷過程
如果某礦工構造的“生日問題”能找到2^k個碰撞解,並且經過難度 調整算法以後仍滿足三個條件,則這個“礦工”挖到了“礦”,即此人成功建成一個新區塊。 如果不能找到足夠數目的解,或者無法全部滿足三個條件,則“挖礦”失敗,此時礦工需要修改隨機數,從頭開始,重新開始新一輪的“挖礦”。 同樣的,這一過程也會成爲Zcash挖礦難度調整的依據,每生成一個新塊,都會進行一次難度調整。
④總結

Zcash挖礦的一般過程即先構造輸入條件(區塊頭以及各項參數),通過特定函數將輸入條件轉化成“廣義生日問題的一般形式”,用優化算法解析該問題並對獲得的解進行難度判斷,同時滿足算法條件和難度條件則判定“挖礦”成功,否則調整隨機數重新運算。

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