最近在VPS上搭建unomp礦池,主要參考的文檔是官網上的README,遇坑無數,以后有機會再專門寫一篇。在最后一步測試礦工與礦池之間能否正常完成挖礦工作時,需要了解一些stratum這個協議的細節。
當前的主流挖礦協議是stratum,以前還有GBT(getblocktemplate)、getwork、getwork with rollntime extension等幾種協議,它們都過時了,見bitcointalk上這篇貼子的討論。
我用unomp搭建好礦池之后,不舍得把正在工作的ASIC礦機停下來用于這個測試,先用免費的Cpuminer軟件把協議調通。cpuminer在 https://sourceforge.net/projects/cpuminer/files 下載,我使用的是win64的2.5.0版本。
這款小軟件在2009年比特幣誕生的時候還可以挖礦,現在它存在的意義就在于測試礦池協議了。軟件包中的minerd需要幾個命令行參數,為了清楚地看到通訊協議的詳細內容,我只用了一個線程,并打開了調試選項,用戶名是錢包的地址,這里的地址是比特幣測試網絡的地址。
minerd --algo=sha256d --threads=1 --url=stratum+tcp://my_pool_ip_address:3008 --user=myAzQj4bH4mMF2GpoLSY2v4qVquASTpzR4 --pass=x --debug --protocol-dump
Stratum協議的內容比較多,這篇貼子里有詳細的介紹,這里只是給出我試驗時的一些數據實例,有些內容暫時也不理解,需要以后再學習。以下內容中的客戶端表示礦工miner,服務器表示礦池pool。
1. 客戶端首先向服務器發送subscribe指令
{"id": 1, "method": "mining.subscribe", "params": ["cpuminer/2.5.0"]}
參數中指名礦工軟件的名稱和版本號。
2. 服務器端返回信息
比特幣挖礦實際上就是去尋找隨機數nonce,有時所有的隨機數都試遍了,仍無法滿足目標,就需要用到extra nonce。
{
"id":1,
"result":
[
[
["mining.set_difficulty","deadbeefcafebabe0100000000000000"], //后面是stratum session id
["mining.notify","deadbeefcafebabe0100000000000000"]
],
"70000000", // ExtraNonce1 十六進制
4 // ExtraNonce2_size 字節
],
"error":null
}
3. 客戶端發送認證信息
用戶名是錢包的地址,我這里使用的是比特幣測試網絡的地址,并沒有以1開頭。
{
"id": 2,
"method": "mining.authorize",
"params": ["myAzQj4bH4mMF2GpoLSY2v4qVquASTpzR4", "x"]
}
4. 服務器返回true,表示用戶驗證通過
{"id":2,"result":true,"error":null}
5. 服務器端發回難度設置消息
{"id":null,"method":"mining.set_difficulty","params":[8]}
6. 服務器發送通知消息
{
"method":"mining.notify",
"params":[
"3d", // 作業ID
"af8cecebf98...43100000000", //previous block hash
"010000000100000....0000000", //generation tx part1
"0d2f6e6f646.....5b36ec88ac00000000", //generation tx part2
["6fb6....80cb","d4464...49a5a290", ... ,"68d803...4ec79d161"], // merkle branches 默克爾樹分支
"20000000", // block version
"1a3fffc0", // nBits encoded network difficulty
"5a158226", //nTime,時間戳
false // clean jobs,如果是true,則表示其它礦工爆塊了,開始新一輪計算
]
}
礦工可能用到了多線程,所以需要job id來區分不用的線程,后面是一堆用于區塊生成的信息。
7. 客戶端發現一個nonce,提交給服務器
{
"method": "mining.submit",
"params": [
"myAzQj4bH4mMF2GpoLSY2v4qVquASTpzR4", //worker name
"4c", //job id
"00000000", //extranonce2
"5a158557", //nTime
"6ae65681" //nonce
],
"id":4
}
8. 服務器返回結果,返回true表示服務器認可客戶端的工作
{
"id":4,
"result":true,
"error":null
}
今天用ASIC礦機測試了3個小時的通訊協議,在比特幣testnet上挖了60多個新塊,錢包中收幣也沒問題,nuomp架起來了。