天天看點

比特币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

混合挖礦

ASIC礦機

參考文章

繼續閱讀