比特幣CPU挖礦、GPU挖礦、礦池及礦機挖礦技術原理

比特幣挖礦原理

 
  比特幣的區塊頭,共含6個字段,如下:
 
  int32_t nVersion,4字節,版本號,一般固定不變,僅在升級時改變。
  uint256 hashPrevBlock,32字節,前一個區塊的區塊頭哈希,由前一個區塊決定。
  uint256 hashMerkleRoot,32字節,包含進區塊的所有交易構造的Merkle根,調整區塊中的交易次序、增刪交易、或修改Coinbase交易時改變。
  uint32_t nTime,4字節,時間戳,後一個區塊時間略早於前一個區塊是被允許的,但必須在合理的時間區間,一般會直接使用機器當前時間戳。
  uint32_t nBits,4字節,挖礦難度,由全網決定,每2016個區塊按算法重新調整。
  uint32_t nNonce,4字節,隨機數,提供2^32種取值。即4,294,967,296。
 
  其中nVersion、hashPrevBlock、nBits是固定的,其他hashMerkleRoot、nTime、nNonce爲可變的。
 
  比特幣挖礦原理即,不斷變更區塊頭中的可變值,使得對區塊頭做雙重SHA256哈希,結果小於挖礦難度目標值。即:
  SHA256D(BlockHeader) < F(nBits)
  其中SHA256D(BlockHeader)即對區塊頭做雙重SHA256哈希,F(nBits)即按nBits計算的難度目標值。
 

算力的表示

 
  1 H/S = 每秒一次運算
  1 KH/S = 1000 H/S,即每秒1千次運算
  1 MH/S = 1000 KH/S,即每秒100萬次運算
  1 GH/S = 1000 MH/S,即每秒10億次運算
  1 TH/S = 1000 GH/S,即每秒1萬億次運算
  1 PH/S = 1000 TH/S,即每秒1000萬億次運算
  1 EH/S = 1000 PH/S,即每秒100萬萬億次運算
 

CPU挖礦原理

 
  CPU挖礦,即利用RPC接口setgenerate控制挖礦。
  控制檯輸入setgenerate true 2,即開始挖礦,後邊的數字表示代表的挖礦線程數,當然前提先完成同步數據。
  由於單CPU運算SHA256D算力約爲2 MH/S,因此nNonce提供的4字節搜索空間完全夠用,即支持4G種取值。
 

GPU挖礦原理

 
  GPU運算SHA256D算力約爲200M-1G,nNonce提供4G搜索空間,如果僅調整nNonce取值,可以支持4秒左右。因此可以調整nTime,每調整一次nTime,可以繼續挖礦4秒。
 
  GPU挖礦使用GETWORK協議,即挖礦程序和節點分離,也即挖礦部件與區塊鏈數據分離。GPU挖礦時代,使用GETWORK協議,使得挖礦程序與節點交互。
 
  核心思路爲:節點構造區塊,將區塊頭數據交給挖礦程序,挖礦程序遍歷nNonce進行挖礦。驗證合格交付給節點,節點提取nNonce和nTime驗證區塊,如果符合要求即向全網廣播。遍歷結束將調用GETWORK,節點構造新區塊,然後重複上述過程。
 
  GPU經典挖礦驅動爲cgminer,源碼爲https://github.com/ckolivas/cgminer。
 
  GPU挖礦缺陷:GETWORK協議給挖礦程序提供的搜索空間爲4G,結束後需再次調用GETWORK RPC接口。礦機出現後,礦機算力已達10 TH/S,繼續使用GETWORK協議將頻繁調用RPC接口,顯然不太合適。因此需轉向更高效的getblocktemplate協議。
 

礦池挖礦原理

 
  礦工通過getblocktemplate協議與節點交互,或礦池採用stratum協議與礦工交互,即爲礦池的兩種典型搭建模式。
 
  與getwork相比,getblocktemplate協議讓礦工自行構造區塊,因此使得節點與挖礦完全分離。礦工拿到一系列數據後,開始挖礦:
  1、構建coinbase交易。
  2、coinbase交易放在交易列表之前,構建hashMerkleRoot。因coinbase、以及交易次序均可調整,因此hashMerkleRoot空間可以認爲無限大。因此getblocktemplate協議也使礦工獲得了巨大的搜索空間。
  3、構建區塊頭。
  4、挖礦,即礦工可以在nNonce、nTime、hashMerkleRoot提供的搜索空間中涉及任意的挖礦策略。
  5、上交數據,如果挖礦成功即提交給節點,由節點驗證並廣播。
 
  getblocktemplate協議的問題:
  1、礦工通過HTTP方式調用RPC接口向節點申請挖礦數據,因此網絡中最新區塊變動無法告知礦工,造成算力浪費。
  2、每次調用getblocktemplate,節點都會返回1.5M左右數據,因頻繁交互將因此增加大量成本。
  Stratum協議將解決上述問題。
 

Stratum協議

 
  Stratum協議,採用主動分配任務的方式,也即礦池任何時候都可以給礦工分派任務。對於礦工,如收到新任務,將無條件轉向新任務。另外礦工也可以向礦池申請新任務。
 
  最核心問題爲,如何使得礦工獲得更大的搜索空間。如果僅礦工僅可改變nNonce和nTime,交互數據少但搜索空間不足。如果允許礦工構造coinbase,搜索空間大但代價是需要將所有交易交給礦工,因此對礦池帶寬要求較高。
 
  Stratum協議巧妙解決了這個問題。即:基於Merkler樹的原理,無需將全部交易發給礦工,只需將構造hashMerkleroot所需的少數幾個節點交給礦工即可。同時將構造coinbase所需信息交給礦工,礦工可基於少數信息構造hashMerkleroot。照此方式,如果包含N筆交易,僅需將log2(N)個hash值交給礦工。因此可大大降低交互的數據量。
 
  礦池的核心即給礦工分派任務,統計工作量並分發收益。礦池可以將區塊難度分成更小的任務發給礦工,礦工完成任務提交礦池。如果全網區塊難度要求前70位爲0,那麼礦池可以給礦工分派難度爲前30位0的任務,礦池再判斷是否碰巧前70位都爲0。
 
  幾個開源礦池:
  PHP-MPOS:https://github.com/MPOS/php-mpos
  node-open-mining-portal:https://github.com/zone117x/node-open-mining-portal
  Powerpool:https://github.com/sigwo/powerpool
 

混合挖礦

 
  混合挖礦,即某種幣的挖礦掛靠在另一種幣的鏈條上。輔鏈需要做針對性設計(如域名幣和狗狗幣)。混合挖礦,使用AuxPOW協議實現。AuxPOW的實現得益於比特幣Coinbase的輸入字段。
 
  經典的PoW區塊,規定符合要求才算合格的區塊。AuxPOW協議附加兩個要求:
  1、輔鏈區塊的hash值必須內置於父鏈區塊的Coinbase裏。
  2、父鏈區塊的難度比較符合輔鏈的難度要求。
 
  一般來說,父鏈的算力比較輔鏈大,滿足父鏈難度要求的區塊一定滿足輔鏈的難度要求。因此過去很多達不到父鏈難度要求的區塊,可以達到輔鏈難度,可以在輔鏈獲得收益。
 

ASIC礦機

 
  FPGA,Field-Programmable Gate Array,譯爲現場可編程門陣列。是在PAL、GAL、CPLD等可編程器件的基礎上進一步發展的產物。是作爲專用集成電路(ASIC)領域中的一種半定製電路而出現的,既解決了定製電路的不足,又克服了原有可編程器件門電路數有限的缺點。能用FPGA實現各種AISC、DSP和單片機。FPGA作爲挖礦硬件,對於ASIC來說屬於必然的過度技術。
 
  ASIC,Application Specific Integrated Circuits,即專用集成電路。是指應特定用戶要求和特定電子系統的需要而設計、製造的集成電路。
 

參考文章

 
  區塊鏈核心技術演進之路——挖礦演進
  #比特幣挖礦part1# 挖礦算法
  #比特幣挖礦part2# 礦池協議
  比特幣挖礦機在中國的前世今生,礦機發展歷程完整簡史
  三天就回本?起底比特幣礦機逆天發展史
  比特幣礦機:什麼是ASIC礦機

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