1. 程式人生 > >深度解析挖礦的邏輯和技術實現

深度解析挖礦的邏輯和技術實現

挖礦是作演算法運算的過程,從計算機和程式碼的角度來說,是反覆執行Hash函式並檢測執行結果的具體過程。與討論演算法一樣,挖礦也是在採用POW共識機制前提下討論。

大家已經非常清楚挖礦是由最開始的CPU挖礦,過度到GPU挖礦,最終演化到當前的ASIC(專業礦機)挖礦時代,本篇解析其中的邏輯設計和技術實現。挖礦的演進是硬體的演進過程,同時也是軟體的演進過程,尤其是軟硬體對接協議的改進過程,因此本文直接將與挖礦有關的幾個核心協議作為小標題,一步步深入討論。

在複查文章時我發現“礦工”一詞用的比較模糊,這種情況在英文文獻也差不多,日常交流中一般指擁有挖礦機器的人,本篇著眼於區塊鏈,挖礦的程式或者機器都統稱礦工(Miner)。

MINING

本小節討論挖礦原理,首先解析比特幣區塊頭(Blockheader)結構,我們說挖礦本質是執行Hash函式的過程,而Hash函式是一個單輸入單輸出函式,輸入資料就是這個區塊頭。比特幣區塊頭共6個欄位:

int32_t nVersion; //版本號,4位元組

uint256 hashPrevBlock; //前一個區塊的區塊頭hash值,32位元組

uint256 hashMerkleRoot; //包含進本區塊的所有交易構造的Merkle樹根,32位元組

uint32_t nTime; //Unix時間戳,4位元組

uint32_t nBits; //記錄本區塊難度,4位元組

uint32_t nNonce; //隨機數,4位元組

如上,比特幣每一次挖礦就是對這80個位元組連續進行兩次SHA256運算(SHA256D),運算結果是固定的32位元組(二進位制256位)。

以上6個欄位情況又各不相同,

nVersion,區塊版本號,只有在升級時候才會改變。

hashPrevBlock,由前一個區塊決定。

nBits,由全網決定,每2016個區塊重新調整,調整演算法固定。

因此以上3個欄位可以理解為是固定的,對於每個礦工來說都一樣。礦工可以自由調整的地方是剩下的3個欄位,

nNonce,提供2^32種可能取值

nTime,其實本欄位能提供的值空間非常有限,因為合理的區塊時間有一個範圍,這個範圍是根據前一個區塊時間來定,比前一個區塊時間太早或者太超前都會被其他節點拒絕。值得一提的是,後一個區塊的區塊時間略早於前一個區塊時間,這是允許的。一般來說,礦工會直接使用機器當前時間戳。

hashMerkleRoot,理論上提供2^256種可能,本欄位的變化來自於對包含進區塊的交易進行增刪,或改變順序,或者修改Coinbase交易的輸入欄位。

根據Hash函式特性,這3個欄位中哪怕其中任意1個位的變化,都會導致Hash執行結果巨大變化。在CPU挖礦時代,搜尋空間主要由nNonce提供,進入礦機時代,nNonce提供的4個位元組已經遠遠不夠,搜尋空間轉向hashMerkleRoot。

\

比特幣挖礦的邏輯過程如下:

1. 打包交易,檢索待確認交易記憶體池,選擇包含進區塊的交易。礦工可以任意選擇,甚至可以不選擇(挖空塊),因為每一個區塊有容量限制(當前是1M),所以礦工也不能無限選擇。對於礦工來說,最合理的策略是首先根據手續費對待確認交易集進行排序,然後由高到低儘量納入最多的交易。

2. 構造Coinbase,確定了包含進區塊的交易集後,就可以統計本區塊手續費總額,結合產出規則,礦工可以計算自己本區塊的收益。

3. 構造hashMerkleRoot,對所有交易構造Merkle數。

4. 填充其他欄位,獲得完整區塊頭。

5. Hash運算,對區塊頭進行SHA256D運算。

6. 驗證結果,如果符合難度,則廣播到全網,挖下一個塊;不符合難度則根據一定策略改變以上某個欄位後再進行Hash運算並驗證。

合格的區塊條件如下:

SHA256D(Blockherder) < F(nBits)

其中,SHA256D(Blockherder)就是挖礦結果,F(nBits)是難度對應的目標值,兩者都是256位,都當成大整數處理,直接對比大小以判斷是否符合難度要求。

為了節約區塊鏈儲存空間,將256位的目標值通過一定變換無失真壓縮儲存在32位的nBits欄位裡。具體變換方法為拆分利用nBits的4個位元組,第1個位元組代表右移的位數,用V1表示,後3個位元組記錄值,用V3表示,則有:

此外難度有最低限制,也就是說 有個最大值,比特幣最低難度取值nBits=0x1d00ffff,對應的最大目標值為:0x00000000FFFF0000000000000000000000000000000000000000000000000000

因此挖礦可以形象的類比拋硬幣,好比有256枚硬幣,給定編號1,2,3……256,每進行一次Hash運算,就像拋一次硬幣,256枚硬幣同時丟擲,落地後要求編號前n的所有硬幣全部正面向上。

SETGENERATE

Setgenerate協議介面代表了CPU挖礦時代。

中本聰在論文裡描述了“1 CPU 1 Vote”的理想數字民主理念,在最初版本客戶端就附帶了挖礦功能,客戶端挖礦非常簡單,當然,需要同步資料結束才可以挖礦。現在有很多算力很低的山寨幣還是直接使用客戶端挖礦,有兩種方式可以啟動挖礦:

1) 在配置檔案設定gen=1,然後啟動客戶端,節點將自行啟動挖礦。

2) 客戶端啟動後,利用RPC介面setgenerate控制挖礦。

如果使用經典QT客戶端,點選“幫助”選單,開啟“除錯視窗”,在“控制檯”輸入如下命令:setgenerate true 2,然後回車,客戶端就開始挖礦,後面的數字代表挖礦執行緒數,如果想關閉挖礦,在控制檯使用如下命令:setgenerate false,可以使用getmininginfo命令檢視挖礦情況。

節點挖礦過程也非常簡單:

構造區塊,初始化區塊頭各個欄位,計算Hash並驗證區塊,不合格則nNonce自增,再計算並驗證,如此往復。在CPU挖礦時代,nNonce提供的4位元組搜尋空間完全夠用(4位元組即4G種可能,單核CPU運算SHA256D算力一般是2M左右),其實nNonce只遍歷完兩個位元組就返回去重構塊。

GETWORK

getwork協議代表了GPU挖礦時代,需求主要源於挖礦程式與節點客戶端分離,區塊鏈資料與挖礦部件分離。

使用客戶端節點直接挖礦,需要同步完整區塊鏈,資料和程式緊密結合,也就是說,如果有多臺電腦進行挖礦,需要每臺電腦都單獨同步一份區塊鏈資料。這其實沒有必要,對於礦工來說,最少只需要一個完整節點就可以。而以此同時,GPU挖礦時代的到來,也需要一個協議與客戶端節點互動。

780b2009d3cb4561a8cc6120d5d95e72_th

getwork核心設計思路是:

由節點客戶端構造區塊,然後將區塊頭資料交給外部挖礦程式,挖礦程式遍歷nNonce進行挖礦,驗證合格後交付回給節點客戶端,節點客戶端驗證合格後廣播到全網。

如前所述,區塊頭共80個位元組,由於沒有區塊鏈資料和待確認交易池,nVersion,hashPrevBlock,nBits和hashMerkleRoot這4個欄位共72個位元組必須由節點客戶端提供。挖礦程式主要是遞增遍歷nNonce,必要時候可以微調nTime欄位。

對於顯示卡GPU來說,其實不用擔心nNonce的4位元組搜尋空間不足,而且挖礦程式從節點客戶端那裡拿到一份資料後,不應該埋頭工作太久,不然很有可能這個塊已經被其他人挖到,繼續挖只能做無用功,對於比特幣來說,雖然設計為每10分鐘一個區塊,良好的策略也應該在秒級內重新向節點申請新的挖礦資料。對於顯示卡來說,執行SHA256D算力一般介於200M~1G,nNonce提供4G搜尋空間,也就是說再好的顯示卡也能支撐4秒左右,調整一次nTime,又可以再挖4秒,這個時間綽綽有餘。

節點提供RPC介面getwork,該介面有一個可選引數,如果不帶引數,就是申請挖礦資料,如果帶一個引數,就是提交挖到的塊資料。

不帶引數呼叫getwork,返回資料如下:

{

“midstate” : “9226a024e0b77f61d49fd5ffdf828c6b5c4330c61ea2778c606a8e49d4ad8bd6″,

“data” :”00000002e9337bac28ee28a949d2140f9fb0a0ab740acfd739d7bcf67ca31c2301db858ad2ca54d92c8c1cded715922c4df2b07d9f10fa1a6cf3db7e949b320615761ed4581c76f21b12d87500000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000″,

“hash1″ :”00000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000010000″,

“target” : “00000000000000000000000000000000000000000000000075d8120000000000″

}

Data欄位

共128位元組(80區塊頭位元組 + 48補全位元組),因為SHA256將輸入資料切分成固定長度的分片處理,每個切片64位元組,輸入總長度必須是64位元組的整數倍,輸入長度一般不符合要求,則根據一定規則在元資料末端補全資料。其實對於挖礦來說,補全資料是固定不變的,這裡沒必要提供,外部挖礦軟體可以自行補齊。甚至連nNonce欄位都不需要提供,data最少只需要提供前面的76位元組就夠了。nTime欄位也是必不可少的,外部挖礦程式需要參照節點提供的區塊時間來調節nTime。

Target欄位

即當前區塊難度目標值,採用小頭位元組序,需要翻轉才能使用。

其實對於外部挖礦程式來說,有data 和 target這兩個欄位就可以正常挖礦了,不過getwork協議充分考慮各種情況,儘量幫助外部挖礦程式做力所能及的事,提供了兩個額外欄位,data欄位返回完整補全資料也是出於此理念。

Midstate欄位

如上所述,SHA256對輸入資料分片處理,礦工拿到data資料後,第一個分片(頭64位元組)是固定不變的,midstate就是第一個分片的計算結果,節點幫忙計算出來了。

因此,在midstate欄位輔助下,外部挖礦程式甚至只需要44位元組資料就可以正常挖礦:32位元組midstate + 第一個切片餘下的12(76-64)位元組資料。

Hash1欄位

比特幣挖礦每次都需要連續執行兩次SHA256,第一次執行結果32位元組,需要再補充32位元組資料湊足64位元組作為第二次執行SHA256的輸入。hash1就是補全資料,同理,hash1也是固定不變的。

外部挖礦程式挖到合格區塊後再次呼叫getwork介面將修改過的data欄位提交給節點客戶端。節點客戶端要求返回的資料也必須是128位元組。

每次有外部無參呼叫一次getwork時,節點客戶端構造一個新區塊,在返回資料前,都要把新區塊完整儲存在記憶體,並用hashMerkleRoot作為唯一識別符號,節點使用一個Map來存放所有構造的區塊,當下一個塊已經被其他人挖到時,立即清空Map。

getwork收到一個引數後,首先從引數提取hashMerkleRoot,在Map中找出之前儲存的區塊,接著從引數中提取nNonce和nTime填充到區塊的對應欄位,就可以驗證區塊了,如果難度符合要求,說明挖到了一個塊,節點將其廣播到全網。

getwork協議是最早版本挖礦協議,實現了節點和挖礦分離,經典的GPU挖礦驅動cgminer和sgminer,以及cpuminer都是使用getwork協議進行挖礦。getwork + cgminer一直是非常經典的配合,曾經很多新演算法推出時,都快速被移植到cgminer。即便現在,除了BTC和LTC,其他眾多競爭幣都還在使用getwork協議進行挖礦。礦機出現之後,挖礦速度得到極大提高,當前比特幣礦機算力已經達到10T/秒級別。而getwork只給外部挖礦程式提供32位元組共4G的搜尋空間,如果繼續使用getwork協議,礦機需要頻繁呼叫RPC介面,這顯然不可行。如今BTC和LTC節點都已經禁用getwork協議,轉向更新更高效的getblocktemplate協議。

GETBLOCKTEMPLATE

getblocktemplate協議誕生於2012年中葉,此時礦池已經出現。礦池採用getblocktemplate協議與節點客戶端互動,採用stratum協議與礦工互動,這是最典型的礦池搭建模式。

與getwork相比,getblocktemplate協議最大的不同點是:getblocktemplate協議讓礦工自行構造區塊。如此一來,節點和挖礦完全分離。對於getwork來說,區塊鏈是黑暗的,getwork對區塊鏈一無所知,他只知道修改data欄位的4個位元組。對於getblocktemplate來說,整個區塊鏈是透明的,getblocktemplate掌握區塊鏈上與挖礦有關的所有資訊,包括待確認交易池,getblocktemplate可以自己選擇包含進區塊的交易。

getblocktemplate 在被開發出來後並非一成不變,在隨後發行的各個版本客戶端都有所升級改動,主要是增添一些欄位,不過核心理念和核心欄位不變。目前比特幣客戶端返回資料如下,考慮到篇幅限制,交易欄位(transactions)只保留了一筆交易資料,其實根據當前實際情況,待確認交易池實時有上萬筆交易,目前區塊基本都是塞滿的(1M容量限制),加上額外資訊,因此每次呼叫getblocktemplate基本都有1.5M左右返回資料,相對於getwork的幾百個位元組而言,不可同日而語。

3287c071bff44d7e9fcb1d4349564dbc_th

來簡單分析一下其中幾個核心欄位,

Version,Previousblockhash,Bits這三個欄位分別指區塊版本號,前一個區塊Hash,難度,礦工可以直接將數值填充區塊頭對應欄位。

Transactions,交易集合,不但給了每一筆交易的16進位制資料,同時給了hash,交易費等資訊。

Coinbaseaux,如果有想要寫入區塊鏈的資訊,放在這個欄位,類似中本聰的創世塊宣言。

Coinbasevalue,挖下一個塊的最大收益值,包括髮行新幣和交易手續費,如果礦工包含Transactions欄位的所有交易,可以直接使用該值作為coinbase輸出。

Target,區塊難度目標值。

Mintime,指下一個區塊時間戳最小值,Curtime指當前時間,這兩個時間作為礦工調節nTime欄位參考。

Height,下一個區塊難度,目前協議規定要將這個值寫入coinbase的指定位置。

礦工拿到這些資料之後,挖礦步驟如下:

1. 構建coinbase交易,涉及到欄位包括Coinbaseaux,Coinbasevalue,Transactions,Height等,當然最重要的是要指定一個收益地址。

2. 構建hashMerkleRoot,將coinbase放在transactions欄位包含的交易列表之前,然後對相鄰交易兩兩進行SHA256D運算,最終可以構造交易的Merkle樹。由於coinbase有很多位元組可供礦工隨意發揮,此外交易列表也可隨意調換順序或者增刪,因而hashMerkleRoot值空間幾乎可以認為是無限的。其實getblocktemplate協議設計的主要目標就是讓礦工獲得這個巨大的搜尋空間。

3. 構建區塊頭,利用Version,Previousblockhash,Bits以及Curtime分別填充區塊頭對應欄位,nNonce欄位可預設置0。

4. 挖礦,礦工可在由nNonce,nTime,hashMerkleRoot提供的搜尋空間裡設計自己的挖礦策略。

5. 上交資料,當礦工挖到一個塊後當立即使用submitblock介面將區塊完整資料提交給節點客戶端,由節點客戶端驗證並廣播。

需要注意的是,與上文提到的GPU採用getwork挖礦一樣,雖然getblocktemplate給礦工提供了巨大搜索空間,但礦工不應對一份請求資料挖礦太久,而應迴圈適時向節點索要最新區塊和最新交易資訊,以提高挖礦收益。

POOL

挖礦有兩種方式,一種叫SOLO挖礦,另一種是去礦池挖礦。前文所述的在節點客戶端直接啟動CPU挖礦,以及依靠getwork+cgminer驅動顯示卡直接連線節點客戶端挖礦,都是SOLO挖礦,SOLO好比自己獨資買彩票,不輕易中獎,中獎則收益全部歸自己所有。去礦池挖礦好比合買彩票,大家一起出錢,能買一堆彩票,中獎後按出資比率分配收益。理論上,礦機可以藉助getblocktemplate協議連結節點客戶端SOLO挖礦,但其實早已沒有礦工會那麼做,在寫這篇文章時,比特幣全網算力1600P+,而當前最先進的礦機算力10T左右,如此算來,單臺礦機SOLO挖到一個塊的概率不到16萬分之一,礦工(人)投入真金白銀購買礦機、交付電費,不會做風險那麼高的投資,顯然投入礦池抱團挖礦以降低風險,獲得穩定收益更加適合。因此礦池的出現是必然,也不可消除,無論是否破壞系統的去中心化原則。

礦池的核心工作是給礦工分配任務,統計工作量並分發收益。礦池將區塊難度分成很多難度更小的任務下發給礦工計算,礦工完成一個任務後將工作量提交給礦池,叫提交一個share。假如全網區塊難度要求Hash運算結果的前70個位元位都是0,那麼礦池給礦工分配的任務可能只要求前30位是0(根據礦工算力調節),礦工完成指定難度任務後上交share,礦池再檢測在滿足前30位為0的基礎上,看看是否碰巧前70位都是0。

礦池會根據每個礦工的算力情況分配不同難度的任務,礦池是如何判斷礦工算力大小以分配合適的任務難度呢?調節思路和比特幣區塊難度一樣,礦池需要藉助礦工的share率,礦池希望給每個礦工分配的任務都足夠讓礦工運算一定時間,比如說1秒,如果礦工在一秒之內完成了幾次任務,說明礦池當前給到的難度低了,需要調高,反之。如此下來,經過一段時間調節,礦池能給礦工分配合理難度,並計算出礦工的算力。

a6f5528aabc344e2898dcec2204f5efb_th

礦池一直都是一個矛盾的存在,毫無疑問,礦池是中心化的,如上圖所示,全網算力集中在幾個礦池手裡,網路雖然幾千個節點同時線上,但只有礦池連結的幾個點選擁有投票權,其他節點都只能行使監督權。礦池再一次將礦工至於“黑暗”之中,礦工對於區塊鏈再次變得一無所知,他們只知道完成礦池分配的任務。

關於礦池,還有一個小插曲,在礦池剛出現時,反對聲特別強烈,很多人悲觀的認為礦池最終會導致算力集中,危及系統安全,甚至置比特幣於死地。於是有人設計並實現了P2P礦池,力圖將“抱團挖礦”去中心化,程式碼也都是開源的,但由於效率遠不如中心化的礦池沒能吸引太多算力,所謂理想很豐滿,現實很骨感。

推薦幾個比較成熟的開源礦池專案,有興趣的讀者可自行研究:

PHP-MPOS,早期非常經典的礦池,很穩定,被使用最多,尤其山寨幣礦池,後端使用Stratum Ming協議,原始碼地址https://github.com/MPOS/php-mpos

u node-open-mining-portal,支援多幣種挖礦,原始碼地址https://github.com/zone117x/node-open-mining-portal

u Powerpool,支援混合挖礦,原始碼地址https://github.com/sigwo/powerpool

執行一個礦池需要考慮的問題很多,比如為了得到最及時的全網資訊,礦池一般對接幾個網路節點,而且最好分佈在地球的幾大洲。另外提高出塊率,降低孤塊率,降低空塊率等都是礦池的核心技術問題,本文不能一一展開討論,接下來只詳細討論一個問題,即礦池與礦工的具體配合工作方式——stratum協議。

STRATUM

礦池通過getblocktemplate協議與網路節點互動,以獲得區塊鏈的最新資訊,通過stratum協議與礦工互動。此外,為了讓之前用getwork協議挖礦的軟體也可以連線到礦池挖礦,礦池一般也支援getwork協議,通過階層挖礦代理機制實現(Stratum mining proxy)。須知在礦池剛出現時,顯示卡挖礦還是主力,getwork用起來非常方便,另外早期的FPGA礦機有些是用getwork實現的,stratum與礦池採用TCP方式通訊,資料使用JSON封裝格式。

26fac8404bdd4e818f8dbcf3a732d820_th

先來說一下getblocktemplate遺留下來的幾個問題:

礦工驅動:在getblocktemplate協議裡,依然是由礦工主動通過HTTP方式呼叫RPC介面向節點申請挖礦資料,這就意味著,網路最新區塊的變動無法及時告知礦工,造成算力損失。

資料負載:如上所述,如今正常的一次getblocktemplate呼叫節點都會反饋回1.5M左右的資料,其中主要資料是交易列表,礦工與礦池需頻繁互動資料,顯然不能每次分配工作都要給礦工附帶那麼多資訊。再者巨大的記憶體需求將大大影響礦機效能,增加成本。

Stratum協議徹底解決了以上問題。

Stratum協議採用主動分配任務的方式,也就是說,礦池任何時候都可以給礦工指派新任務,對於礦工來說,如果收到礦池指派的新任務,應立即無條件轉向新任務;礦工也可以主動跟礦池申請新任務。

現在最核心的問題是如何讓礦工獲得更大的搜尋空間,如果參照getwork協議,僅僅給礦工可以改變nNonce和nTime欄位,則互動的資料量很少,但這點搜尋空間肯定是不夠的。想增加搜尋空間,只能在hashMerkleroot下功夫,如果讓礦工自己構造coinbase,那麼搜尋空間的問題將迎刃而解,但代價是必要要把區塊包含的所有交易都交給礦工,礦工才能構造交易列表的Merkleroot,這對於礦工來說壓力更大,對於礦池頻寬要求也更高。

Stratum協議巧妙解決了這個問題,成功實現既可以給礦工增加足夠的搜尋空間,又只需要互動很少的資料量,這也是Stratum協議最具創新的地方。

1f584860b2264df6a305dac707e4b704_th

再來回顧一下區塊頭的6個欄位80位元組,這個很關鍵,nVersion,nBits,hashPrevBlock這3個欄位是固定的,nNonce,nTime這兩個欄位是礦工現在就可以改變的。增加搜尋空間只能從hashMerkleroot下手,這個繞不過去。Stratum協議讓礦工自己構造coinbase交易,coinbase的scriptSig欄位有很多位元組可以讓礦工自由填充,而coinbase的改動意味著hashMerkleroot的改變。從coinbase構造hashMerkleroot無需全部交易,如上圖所示,假如區塊將包含13筆交易,礦池先對這13筆交易進行處理,最後只要把圖中的4個黑點(Hash值)交付給礦工,同時將構造coinbase需要的資訊交付給礦工,礦工就可以自己構造hashMerkleroot(圖中的綠點都是礦工自行計算獲得,兩兩合併Hash時,規定下一個黑點代表的hash值總是放在右邊)。按照這種方式,假如區塊包含N筆交易,礦池可以濃縮成log2(N)個hash值交付給礦工,這大大降低了礦池和礦工互動的資料量。

Stratum協議嚴格規定了礦工和礦池互動的介面資料結構和互動邏輯,具體如下:

1. 礦工訂閱任務

啟動挖礦機器,使用mining.subscribe方法連結礦池

{“id”: 1, “method”: “mining.subscribe”, “params”: []}\n //申請連結

{“id”: 1, “result”: [ [ ["mining.set_difficulty", "b4b6693b72a50c7116db18d6497cac52"], ["mining.notify", "ae6812eb4cd7735a302a8a9dd95cf71f"]], “08000002″, 4], “error”: null}\n //返回資料

返回資料很重要,礦工需本地記錄,在整個挖礦過程中都用到,其中:

u b4b6693b72a50c7116db18d6497cac52:給礦工指定初始難度,

u ae6812eb4cd7735a302a8a9dd95cf71f:訂閱號ID

u 08000002:學名Extranonce1 ,用於構造coinbase交易

u 4:學名Extranonce2_size ,即Extranonce2的長度,這裡指定4個位元組

Extranonce1,和 Extranonce2對於挖礦很重要,增加的搜尋空間就在這裡,現在,我們至少有了8個位元組的搜尋空間,即nNonce的4個位元組,以及 Extranonce2的4個位元組。

2. 礦池授權

在礦池註冊一個賬號 ,新增礦工,礦池允許每個賬號任意新增礦工數,並取不同名字以區分。礦工使用mining.authorize 方法申請授權,只有被礦池授權的礦工才能收到礦池指派任務。

{“params”: ["slush.miner1", "password"], “id”: 2, “method”: “mining.authorize”}\n

{“error”: null, “id”: 2, “result”: true}\n

3. 礦池分配任務

{“params”: ["bf", "4d16b6f85af6e2198f44ae2a6de67f78487ae5611b77c6c0440b921e00000000",

"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff20020862062f503253482f04b8864e5008",

"072f736c7573682f000000000100f2052a010000001976a914d23fcdf86f7e756a64a7a9688ef9903327048ed988ac00000000", ["76cffd68bba7ea661512b68ec6414438191b08aaeaec23608de26ac87820cbd02016","e5a796c0b88fe695949a3e7b0b7b1948a327b2f28c5dbe8f36f0a18f96b2ffef2016"],

“00000002″, “1c2ac4af”, “504e86b9″, false], “id”: null, “method”: “mining.notify”}

以上每個欄位資訊都是必不可少,其中:

u bf:任務號ID,每一次任務都有唯一識別符號

u 4d16b6f85af6e2198f44ae2a6de67f78487ae5611b77c6c0440b921e00000000:前一個區塊hash值,hashPrevBlock

u 01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff20020862062f503253482f04b8864e5008:學名coinb1 ,構造coinbase的第一部分序列資料

u 072f736c7573682f000000000100f2052a010000001976a914d23fcdf86f7e756a64a7a9688ef9903327048ed988ac00000000:學名coinb2 ,構造coinbase的第二部分序列資料,

相關推薦

深度解析邏輯技術實現

挖礦是作演算法運算的過程,從計算機和程式碼的角度來說,是反覆執行Hash函式並檢測執行結果的具體過程。與討論演算法一樣,挖礦也是在採用POW共識機制前提下討論。 大家已經非常清楚挖礦是由最開始的CPU挖礦,過度到GPU挖礦,最終演化到當前的ASIC(專業礦機

深度解析邏輯技術實現*****

挖礦是作演算法運算的過程,從計算機和程式碼的角度來說,是反覆執行Hash函式並檢測執行結果的具體過程。與討論演算法一樣,挖礦也是在採用POW共識機制前提下討論。 大家已經非常清楚挖礦是由最開始的CPU挖礦,過度到GPU挖礦,最終演化到當前的ASIC(專業礦機)挖礦時代,

新的加密惡意軟體攻擊Linux機器,殺死其他軟體反惡意軟體

俄羅斯Dr.Web反惡意軟體製造商發現了一種新的Linux下惡意軟體,該惡意軟體體現在一個特洛伊木馬程式中,可以作為加密貨幣挖礦軟體,也可以作為DDoS後門程式和rootkit等其他惡意軟體有效負載的通道。 Dr.Web團隊為新木馬病毒命名為Linux.BtcMine.174,是一個1000行shell指令

記錄初次跑ETH程式的技術review

p { margin-bottom: 0.1in; line-height: 115% } Mining review 在開始工作之前我對挖礦還處於一個很淺顯的概念: 公式機制Pow工作量,通過計算得到某個數值獲得報酬:報酬是得到的區塊通過轉賬到區塊鏈錢包 獲得。但是實際running程式起來還是一頭

web3j 程式碼控制開始停止

Geth geth = Geth .build(new HttpService("http://localhost:8545/")); geth.minerStart(1).send();

C++深度解析 布林型別bool 引用 &(3)

C++深度解析 布林型別和引用(3)     1 布林型別 bool 在C++中,bool型別只有true(非0)和false(0)兩個值,且bool型別只佔用了一個位元組 true:非0 false:0  示例一: #include &

深度解析Java 8:AbstractQueuedSynchronizer的實現分析(下)

前言 經過本系列的上半部分JDK1.8 AbstractQueuedSynchronizer的實現分析(上)的解讀,相信很多讀者已經對AbstractQueuedSynchronizer(下文簡稱AQS)的獨佔功能瞭然於胸,那麼這次我們通過對另一個工具類:CountDo

深度解析區塊鏈POWPOS的區別

                深度解析區塊鏈POW和POS的區別   前言 如果你是一名資深的區塊鏈礦工或商人,你一定聽說過POW和POS,但是當前在國內,卻幾乎沒有人明白這到底是什麼意思,也幾乎

ZEC 軟體教程 含可用

最近比特幣炒沸沸揚揚,眾人都聚集到加密貨幣市場,然而現在用家裡的PC挖比特幣是不現實的,不過有一個幣ZEC用PC還是可以挖的玩的,而且ZEC的熱度也越來越高,在此給大家發個教程僅供娛樂。 作者也不容易,歡迎大家來捐贈作者ZEC,地址為 :t1KfRNYNd2oteyRF

徐東山:騰訊雲安全的使命技術實現

徐東山:騰訊雲安全副總監, 2005 年進入騰訊並服務至今,歷任後臺開發、後臺策略安全等崗位。從 2010 年騰訊開放平臺和騰訊雲啟動迄今,一直從事騰訊雲安全相關的業務規劃和系統建設工作。對海量服務系統開發、後臺策略安全設計等有較強烈興趣和一定積累。 分享主概要 : 1、騰訊雲安全在騰訊雲不同發展階段,承擔

【我的區塊鏈之路】- 以太坊原始碼剖析之Geth 1.8.14版本邏輯調整

今天為什麼寫這個文章呢,首先,前段時間有朋友問過我,說現在geth的1.8.14版本的程式碼和網上各路大神們的分析不一樣了。我就趕緊看了下,確實,親的geth程式碼中的mine部分的邏輯有所改動,想必看過原始碼的都知道,之前的miner真正挖礦是由worker把所需挖礦的

深度解析 PouchContainer 的富容器技術

PouchContainer 是阿里巴巴集團開源的高效、輕量級企業級富容器引擎技術,擁有隔離性強、可移植性高、資源佔用少等特性。可以幫助企業快速實現存量業務容器化,同時提高超大規模下資料中心的物理資源利用率。 PouchContainer 源自阿里巴巴內部場景,誕生初期,在

spring原始碼深度解析— IOC 之 容器的基本實現

概述 上一篇我們搭建完Spring原始碼閱讀環境,spring原始碼深度解析—Spring的整體架構和環境搭建 這篇我們開始真正的閱讀Spring的原始碼,分析spring的原始碼之前我們先來簡單回顧下spring核心功能的簡單使用 容器的基本用法 bean是spring最核心的東

spring5 原始碼深度解析----- AOP目標方法增強方法的執行(100%理解AOP)

上一篇博文中我們講了代理類的生成,這一篇主要講解剩下的部分,當代理類呼叫時,目標方法和代理方法是如何執行的,我們還是接著上篇的ReflectiveMethodInvocation類Proceed方法來看 public Object proceed() throws Throwable { //

區塊鏈技術應用趣步IWC運動大資料免費模式解析,區塊鏈系統定製開發

如果我們把資料庫假設成一本賬本,讀寫資料庫就可以看做一種記賬的行為,區塊鏈技術的原理就是在一段時間內找出記賬最快最好的人,由這個人來記賬,然後將賬本的這一頁資訊發給整個系統裡的其他所有人。這也就相當於改變資料庫所有的記錄,發給全網的其他每個節點,所以區塊鏈技術也

Golang的sync.WaitGroup 實現邏輯源碼解析

信號 啟動 blocks done 多少 set spa eas golang 在Golang中,WaitGroup主要用來做go Routine的等待,當啟動多個go程序,通過waitgroup可以等待所有go程序結束後再執行後面的代碼邏輯,比如: func Main(

百度Apollo計劃跟蹤:深度解析Apollo無人車感知定位技術

有關無人車的定位有兩種,一種稱之為絕對定位,不依賴任何參照物,直接給出無人車相對地球座標或者說WGS84座標系,也就是座標(B,L,H),其中B為緯度,L為經度,H為大地高即是到WGS-84橢球面的高度, WGS-84座標系是美國國防部研製確定的大地座標系,是一種協議地球座標

哈夫曼編碼(Huffman coding)的那些事,(編碼技術介紹程序實現)

信號 truct 依次 while 交換 需要 .text 示例 system 前言   哈夫曼編碼(Huffman coding)是一種可變長的前綴碼。哈夫曼編碼使用的算法是David A. Huffman還是在MIT的學生時提出的,並且在1952年發表了名為《

產品經理如何與強勢的技術溝通? 技術比較有資歷,會以技術無法實現等方面的原因拒絕處理產品提出的需求。 你們是否遇到這樣的技術? 產品懂技術的話,是不是會好一些,因為可以和技術說“行話”了,並且產品懂技術就不會被忽悠了。

intern 世界 自己人 做好自己 最重要的 叠代開發 對比 不一定 制造 PM在YY...作為強勢的技術來回答一下吧。說明白WHY,HOW,WHAT就好了。 我想點兩個贊,u can u up,no can no bb 什麽的。 微軟的win8之父年輕時候也是一個PM應

  程序minerd,wnTKYg入侵分析解決

linux wntkyg minerd 挖礦程序minerd,wnTKYg入侵分析和解決 作者:CYH一.起因:最近登陸一臺redis服務器 發現登陸的時間非常長,而且各種命令敲大顯示出的內容延遲