您好,登錄后才能下訂單哦!
這篇文章主要講解了“區塊鏈的兩種挖礦方式是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“區塊鏈的兩種挖礦方式是什么”吧!
挖礦的演進是硬件的演進過程,同時也是軟件的演進過程,尤其是軟硬件對接協議的改進過程,本文重點通過與挖礦有關的幾個核心協議解析其中的邏輯設計和技術實現。
Setgenerate協議接口代表了CPU挖礦時代。
中本聰在論文里描述了“1 CPU 1 Vote”的理想數字民主理念,在最初版本客戶端就附帶了挖礦功能,客戶端挖礦非常簡單,當然,需要同步數據結束才可以挖礦。現在有很多算力很低的山寨幣還是直接使用客戶端挖礦,有兩種方式可以啟動挖礦:
在配置文件設置gen=1,然后啟動客戶端,節點將自行啟動挖礦。
客戶端啟動后,利用RPC接口setgenerate控制挖礦。
如果使用經典QT客戶端,點擊“幫助”菜單,打開“調試窗口”,在“控制臺”輸入如下命令:setgenerate true 2,然后回車,客戶端就開始挖礦,后面的數字代表挖礦線程數,如果想關閉挖礦,在控制臺使用如下命令:setgenerate false,可以使用getmininginfo命令查看挖礦情況。
節點挖礦過程也非常簡單:
構造區塊,初始化區塊頭各個字段,計算Hash并驗證區塊,不合格則nNonce自增,再計算并驗證,如此往復。在CPU挖礦時代,nNonce提供的4字節搜索空間完全夠用(4字節即4G種可能,單核CPU運算SHA256D算力一般是2M左右),其實nNonce只遍歷完兩個字節就返回去重構塊。
getwork協議代表了GPU挖礦時代,需求主要源于挖礦程序與節點客戶端分離,區塊鏈數據與挖礦部件分離。
使用客戶端節點直接挖礦,需要同步完整區塊鏈,數據和程序緊密結合,也就是說,如果有多臺電腦進行挖礦,需要每臺電腦都單獨同步一份區塊鏈數據。這其實沒有必要,對于礦工來說,最少只需要一個完整節點就可以。而以此同時,GPU挖礦時代的到來,也需要一個協議與客戶端節點交互。
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,返回數據如下:
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)字節數據。
Hash2字段
比特幣挖礦每次都需要連續執行兩次SHA256,第一次執行結果32字節,需要再補充32字節數據湊足64字節作為第二次執行SHA256的輸入。hash2就是補全數據,同理,hash2也是固定不變的。
外部挖礦程序挖到合格區塊后再次調用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協議誕生于2012年中葉,此時礦池已經出現。礦池采用getblocktemplate協議與節點客戶端交互,采用stratum協議與礦工交互,這是最典型的礦池搭建模式。
與getwork相比,**getblocktemplate協議最大的不同點是:getblocktemplate協議讓礦工自行構造區塊。**如此一來,節點和挖礦完全分離。對于getwork來說,區塊鏈是黑暗的,getwork對區塊鏈一無所知,他只知道修改data字段的4個字節。對于getblocktemplate來說,整個區塊鏈是透明的,getblocktemplate掌握區塊鏈上與挖礦有關的所有信息,包括待確認交易池,getblocktemplate可以自己選擇包含進區塊的交易。
getblocktemplate 在被開發出來后并非一成不變,在隨后發行的各個版本客戶端都有所升級改動,主要是增添一些字段,不過核心理念和核心字段不變。目前比特幣客戶端返回數據如下,考慮到篇幅限制,交易字段(transactions)只保留了一筆交易數據,其實根據當前實際情況,待確認交易池實時有上萬筆交易,目前區塊基本都是塞滿的(1M容量限制),加上額外信息,因此每次調用getblocktemplate基本都有1.5M左右返回數據,相對于getwork的幾百個字節而言,不可同日而語。
來簡單分析一下其中幾個核心字段, Version,Previousblockhash,Bits這三個字段分別指區塊版本號,前一個區塊Hash,難度,礦工可以直接將數值填充區塊頭對應字段。
Transactions,交易集合,不但給了每一筆交易的16進制數據,同時給了hash,交易費等信息。 Coinbaseaux,如果有想要寫入區塊鏈的信息,放在這個字段,類似中本聰的創世塊宣言。
Coinbasevalue,挖下一個塊的最大收益值,包括發行新幣和交易手續費,如果礦工包含Transactions字段的所有交易,可以直接使用該值作為coinbase輸出。
** Target**,區塊難度目標值。
Mintime,指下一個區塊時間戳最小值,Curtime指當前時間,這兩個時間作為礦工調節nTime字段參考。
Height,下一個區塊難度,目前協議規定要將這個值寫入coinbase的指定位置。
礦工拿到這些數據之后,挖礦步驟如下:
構建coinbase交易,涉及到字段包括Coinbaseaux,Coinbasevalue,Transactions,Height等,當然最重要的是要指定一個收益地址。
構建hashMerkleRoot,將coinbase放在transactions字段包含的交易列表之前,然后對相鄰交易兩兩進行SHA256D運算,最終可以構造交易的Merkle樹。由于coinbase有很多字節可供礦工隨意發揮,此外交易列表也可隨意調換順序或者增刪,因而hashMerkleRoot值空間幾乎可以認為是無限的。其實getblocktemplate協議設計的主要目標就是讓礦工獲得這個巨大的搜索空間。
構建區塊頭,利用Version,Previousblockhash,Bits以及Curtime分別填充區塊頭對應字段,nNonce字段可默認置0。
挖礦,礦工可在由nNonce,nTime,hashMerkleRoot提供的搜索空間里設計自己的挖礦策略。
上交數據,當礦工挖到一個塊后當立即使用submitblock接口將區塊完整數據提交給節點客戶端,由節點客戶端驗證并廣播。
**需要注意的是:**與上文提到的GPU采用getwork挖礦一樣,雖然getblocktemplate給礦工提供了巨大搜索空間,但礦工不應對一份請求數據挖礦太久,而應循環適時向節點索要最新區塊和最新交易信息,以提高挖礦收益。
**挖礦有兩種方式,一種叫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秒,如果礦工在一秒之內完成了幾次任務,說明礦池當前給到的難度低了,需要調高,反之。如此下來,經過一段時間調節,礦池能給礦工分配合理難度,并計算出礦工的算力。
礦池一直都是一個矛盾的存在,毫無疑問,礦池是中心化的,如上圖所示,全網算力集中在幾個礦池手里,網絡雖然幾千個節點同時在線,但只有礦池鏈接的幾個點擊擁有投票權,其他節點都只能行使監督權。礦池再一次將礦工至于“黑暗”之中,礦工對于區塊鏈再次變得一無所知,他們只知道完成礦池分配的任務。
關于礦池,還有一個小插曲,在礦池剛出現時,反對聲特別強烈,很多人悲觀的認為礦池最終會導致算力集中,危及系統安全,甚至置比特幣于死地。于是有人設計并實現了P2P礦池,力圖將“抱團挖礦”去中心化,代碼也都是開源的,但由于效率遠不如中心化的礦池沒能吸引太多算力,所謂理想很豐滿,現實很骨感。
推薦幾個比較成熟的開源礦池項目,有興趣的讀者可自行研究:
PHP-MPOS,早期非常經典的礦池,很穩定,被使用最多,尤其山寨幣礦池,后端使用Stratum Ming協議,源碼地址
node-open-mining-portal,支持多幣種挖礦,源碼地址
Powerpool,支持混合挖礦,源碼地址
運行一個礦池需要考慮的問題很多,比如為了得到最及時的全網信息,礦池一般對接幾個網絡節點,而且最好分布在地球的幾大洲。另外提高出塊率,降低孤塊率,降低空塊率等都是礦池的核心技術問題,本文不能一一展開討論,接下來只詳細討論一個問題,即礦池與礦工的具體配合工作方式——stratum協議。
礦池通過getblocktemplate協議與網絡節點交互,以獲得區塊鏈的最新信息,通過stratum協議與礦工交互。此外,為了讓之前用getwork協議挖礦的軟件也可以連接到礦池挖礦,礦池一般也支持getwork協議,通過階層挖礦代理機制實現(Stratum mining proxy)。須知在礦池剛出現時,顯卡挖礦還是主力,getwork用起來非常方便,另外早期的FPGA礦機有些是用getwork實現的,stratum與礦池采用TCP方式通信,數據使用JSON封裝格式。
先來說一下getblocktemplate遺留下來的幾個問題:
**礦工驅動:**在getblocktemplate協議里,依然是由礦工主動通過HTTP方式調用RPC接口向節點申請挖礦數據,這就意味著,網絡最新區塊的變動無法及時告知礦工,造成算力損失。
數據負載:如上所述,如今正常的一次getblocktemplate調用節點都會反饋回1.5M左右的數據,其中主要數據是交易列表,礦工與礦池需頻繁交互數據,顯然不能每次分配工作都要給礦工附帶那么多信息。再者巨大的內存需求將大大影響礦機性能,增加成本。
Stratum協議徹底解決了以上問題。
Stratum協議采用主動分配任務的方式,也就是說,礦池任何時候都可以給礦工指派新任務,對于礦工來說,如果收到礦池指派的新任務,應立即無條件轉向新任務;礦工也可以主動跟礦池申請新任務。
現在最核心的問題是如何讓礦工獲得更大的搜索空間,如果參照getwork協議,僅僅給礦工可以改變nNonce和nTime字段,則交互的數據量很少,但這點搜索空間肯定是不夠的。想增加搜索空間,只能在hashMerkleroot下功夫,如果讓礦工自己構造coinbase,那么搜索空間的問題將迎刃而解,但代價是必要要把區塊包含的所有交易都交給礦工,礦工才能構造交易列表的Merkleroot,這對于礦工來說壓力更大,對于礦池帶寬要求也更高。
Stratum協議巧妙解決了這個問題,成功實現既可以給礦工增加足夠的搜索空間,又只需要交互很少的數據量,這也是Stratum協議最具創新的地方。
再來回顧一下區塊頭的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方法鏈接礦池
返回數據很重要,礦工需本地記錄,在整個挖礦過程中都用到,其中: b4b6693b72a50c7116db18d6497cac52:給礦工指定初始難度, ae6812eb4cd7735a302a8a9dd95cf71f:訂閱號ID 08000002:學名Extranonce1 ,用于構造coinbase交易 4:學名Extranonce2_size ,即Extranonce2的長度,這里指定4個字節Extranonce1,和 Extranonce2對于挖礦很重要,增加的搜索空間就在這里,現在,我們至少有了8個字節的搜索空間,即nNonce的4個字節,以及 Extranonce2的4個字節。
2. 礦池授權
在礦池注冊一個賬號 ,添加礦工,礦池允許每個賬號任意添加礦工數,并取不同名字以區分。礦工使用mining.authorize 方法申請授權,只有被礦池授權的礦工才能收到礦池指派任務。
3. 礦池分配任務
以上每個字段信息都是必不可少,其中: bf:任務號ID,每一次任務都有唯一標識符
前一個區塊hash值,hashPrevBlock:
4d16b6f85af6e2198f44ae2a6de67f78487ae5611b77c6c0440b921e00000000:
學名coinb1 ,構造coinbase的第一部分序列數據:
01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff20020862062f503253482f04b8864e5008
學名coinb2 ,構造coinbase的第二部分序列數據:
072f736c7573682f000000000100f2052a010000001976a914d23fcdf86f7e756a64a7a9688ef9903327048ed988ac00000000
學名merkle_branch,交易列表的壓縮表示方式,即上圖的黑點:
["76cffd68bba7ea661512b68ec6414438191b08aaeaec23608de26ac87820cbd02016","e5a796c0b88fe695949a3e7b0b7b1948a327b2f28c5dbe8f36f0a18f96b2ffef2016"]
00000002:區塊版本號,nVersion 1c2ac4af:區塊難度nBits 504e86b9:當前時間戳,nTime 有了以上信息,再加上之前拿到的Extranonce1 和Extranonce2_size,就可以挖礦了。
4. 挖礦
構造coinbase交易
用到的信息包括Coinb1, Extranonce1, Extranonce2_size 以及Coinb2,構造很簡單:
Coinbase=Coinb1 + Extranonce1 + Extranonce2 + Coinb2
為啥可以這樣,因為礦池幫礦工做了很多工作,礦池已經構建了coinbase交易,系列化后在指定位置分割成coinb1和coinb2,coinb1和coinb2包含指定信息,比如coinb1包含區塊高度,coinb2包含了礦工的收益地址和收益額等信息,但是這些信息對于礦工來說無關緊要,礦工挖礦的地方只是Extranonce2 的4個字節。另外Extranonce1是礦池寫入區塊的指定信息,一般來說,每個礦池會寫入自己礦池的信息,比如礦池名字或者域名,我們就是根據這個信息統計每個礦池在全網的算力比重。
構建Merkleroot
利用coinbase和merkle_branch,按照上圖方式構造hashMerkleroot字段。
構建區塊頭
填充余下的5個字段,現在,礦池可以在nNonce和Extranonce2 里搜索進行挖礦,如果嫌搜索空間還不夠,只要增加Extranonce2_size為多幾個字節就可輕而易舉解決。
5. 礦工提交工作量 當礦工找到一個符合難度的shares時,提交給礦池,提交的信息量很少,都是必不可少的字段:
slush.miner1:礦工名字,礦池用以識別誰提交的工作量 bf:任務號ID,礦池在分配任務之前,構造了Coinbase等信息,用這個任務號唯一標識 00000001:
Extranonce2 504e86ed:nTime字段 b2957c02:nNonce字段
礦池拿到以上5個字段后,首先根據任務號ID找出之前分配任務前存儲的信息(主要是構建的coinbase交易以及包含的交易列表等),然后重構區塊,再驗證shares難度,對于符合難度要求的shares,再檢測是否符合全網難度。
6. 礦池給礦工調節難度
礦池記錄每個礦工的難度,并根據shares率不斷調節以指定合適難度。礦池可以隨時通過mining.set_difficulty方法給礦工發消息另其改變難度。
如上,Stratum協議核心理念基本解析清楚,在getblocktemplate協議和Stratum協議的配合下,礦池終于可以大聲的對礦工說,讓算力來的更猛烈些吧。
在挖礦的發展歷史上,還出現了一個天馬行空的事情,即混合挖礦(Merge Mining)。域名幣(Namecoin)最先使用混合挖礦模式,掛靠在比特幣鏈條上,礦工挖比特幣時,可以同時挖域名幣,后來狗狗幣(Dogecoin)也支持混合挖礦,掛靠在萊特幣(Litecoin)鏈條上。混合挖礦使用Auxiliary Proof-of-Work (AuxPOW)協議實現,雖然混合挖礦不怎么流行,但是協議設計的很精巧,最初看到協議時我不禁感嘆社區的力量之偉大,這種都能想出來。
以域名幣的混合挖礦舉例,比特幣作為父鏈(Parent Blockchain),域名幣作為輔鏈(Auxiliary Blockchain),AuxPOW協議的實現無需改動父鏈(比特幣當然不會為了域名幣做任何改動),但輔鏈需要做針對性設計,比如狗狗幣改為支持混合挖礦時就進行了硬分叉。
AuxPOW的實現得益于比特幣Coinbase的輸入字段,中本聰當初不知有意無意,在此處只規定了長度限制,留了一片未定義區域。這片區域后來對比特幣的發展產生深遠影響,很多升級和優化都盯上這片區域,比如上文講的Stratum協議。中本聰類似的有意無意情況還有很多,比如交易的nSequence字段,也是因為沒有明確定義,被黑客盯上引發的“延展性”問題成了“門頭溝”倒閉的替罪羊。再比如說nNonce,如果一開始定義的字節大一些,你比方說32字節,挖礦的演進就不需要以上討論的那么多協議。
AuxPOW協議核心理念不同的地方在于:
對于經典的POW區塊,規定只有難度符合要求才算一個合格的區塊,AuxPOW協議對區塊難度沒有要求,但附加兩個條件:
輔鏈區塊的hash值必須內置于父鏈區塊的Coinbase里。
該父鏈區塊的難度必須符合輔鏈的難度要求。
將輔鏈區塊的hash值內置于父鏈的Coinbase,其實是利用父鏈作存在證明。這樣就可以實現間接依靠父鏈的算力來維護輔鏈安全。一般來說,父鏈的算力比輔鏈大,因而滿足父鏈難度要求的區塊一定同時滿足輔鏈難度要求,反之則不成立。這樣一來,很多本來在父鏈達不到難度要求的區塊,卻達到輔鏈難度要求,礦工g=廣播到輔鏈網絡,在輔鏈獲得收益,何樂而不為。
AuxPOW協議對兩條鏈都有一些數據結構方面的規定,對于父鏈,要求必須在區塊的coinbase的scriptSig字段中插入如下格式的44字節數據:
對于輔鏈,對原區塊結構改動比較大,在nNonce字段和txn_count之間插入了5個字段,這種區塊取名AuxPOW區塊。
**混合挖礦要求父鏈和輔鏈的算法一致,是否支持混合挖礦是礦池的決定,礦工不知道是否在混合挖礦。**礦池如果支持混合挖礦,需要對接所有輔鏈的節點。
將輔鏈區塊hash值內置在父鏈的Coinbase,意味著礦工在構造父鏈Coinbase之前,必先構造輔鏈的AuxPOW 區塊并計算hash值。如果只挖一條輔鏈,情況較為簡單,如果同時挖多條輔鏈,則先對所有輔鏈在挖區塊構造Merkleroot。礦池可以將特定的44字節信息內置于上文Stratum協議中提到的Coinb1中,交給礦工挖礦。對礦工返回的shares重構父鏈區塊和所有輔鏈區塊,并檢測難度,如果符合輔鏈難度要求,則將整個AuxPOW區塊廣播到輔鏈。
輔鏈節點驗證AuxPOW區塊邏輯過程如下:
依靠父鏈區塊頭(parent_block)和區塊Hash值(block_hash,本字段其實沒必要,因為節點可以自行計算),驗證父鏈區塊頭是否符合輔鏈難度要求。
依靠Coinbase交易(coinbase_txn)、其所在的分支(coinbase_branch)以及父鏈區塊頭(parent_block),驗證Coinbase交易是否真的被包含在父鏈區塊中。
依靠輔鏈分支(blockchain_branch),以及Coinbase中放Hash值的地方(aux_block_hash),驗證輔鏈區塊Hash是否內置于父鏈區塊的Coinbase交易中。
通過以上3點驗證,則視為合格的輔鏈區塊。
中本聰最初設計比特幣時希望所有節點都采用CPU挖礦,一般認為只有這樣才能充分保證區塊鏈的去中心化特征,比特幣在CPU時代安全度過了萌芽階段。getwork和cgminer將挖礦帶入GPU時代,國內顯卡曾經一度脫銷,全網算力迅速提升了一個檔次,CPU挖礦慘遭淘汰。隨著越來越多人參與挖礦,全網算力不斷上升,催生了抱團挖礦(礦池)。然而GPU時代的繁榮歷史也沒能持續多久就被getblocktemplate,stratum以及礦機帶入了ASIC時代。
getwork實現了數據與挖礦分離,getblocktemplate給外部挖礦程序提供了最大自由度,徹底解決了外部挖礦程序與節點交互的可擴展性問題(scalability problems),主要用于礦池與網絡節點對接。stratum不但解決了搜索空間不足的問題,同時也解決了礦池與礦機交互數據量大的問題。getblocktemplate和stratum這兩個協議使大型礦池,大規模礦場,大算力礦機成為可能,從此挖礦產業進入一個全新階段,此后挖礦的演進主要集中于幾個方向:礦池的設計優化與穩定運行,礦場的科學部署,以及礦機工藝升級,提升算力,降低功耗等。
感謝各位的閱讀,以上就是“區塊鏈的兩種挖礦方式是什么”的內容了,經過本文的學習后,相信大家對區塊鏈的兩種挖礦方式是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。