Ethereum stratum mining protocol v1.0.0

revision of this document: R2

  • I. Introduction 簡(jiǎn)介
  • II. Concept 概念
  • III. Specifications (RFC) 規(guī)范(RFC)
  • IV. Real world scenario 真實(shí)場(chǎng)景
  • V. Planned improvements 增強(qiáng)計(jì)劃
  • VI. Contact 聯(lián)系方式

I. 簡(jiǎn)介

以太坊沒(méi)有正式的stratum協(xié)議。它只支持GetWork,這是一個(gè)非常耗資源的問(wèn)題,因?yàn)榈V工需要不斷的投票來(lái)獲得可能的新工作。因此,GetWork會(huì)影響到礦工和礦池的性能。由于需要更專業(yè)的以太坊挖礦,出現(xiàn)了幾個(gè)專為以太坊的“stratum”版本。這些“stratums”利用了服務(wù)器端(礦池端)的GetWork來(lái)獲取工作,如果創(chuàng)建此類協(xié)議時(shí)采取仔細(xì)考慮因素和預(yù)防措施,這將是很好的。但這并沒(méi)有完成。這些協(xié)議有以下問(wèn)題:

  1. 每個(gè)礦工/工人都沒(méi)有唯一的數(shù)據(jù)。Extranonce被忽略(但仍然被發(fā)送)。每一個(gè)礦工都獲取seedhash(每30k塊都是相同的)和headerhash(每個(gè)塊都改變)。然后礦工使用這兩個(gè)值和自己的Nonce來(lái)生成哈希。礦工可能在做重復(fù)的工作(如果他們選擇了相同的Nonce)。
  2. 難度冗余。難度在mining.notify消息中作為已命名目標(biāo)的第三個(gè)參數(shù)被發(fā)送。這是不需要的,因?yàn)榈V工們可以通過(guò)自己的困難來(lái)計(jì)算目標(biāo)哈希。
  3. 整體數(shù)據(jù)冗余。有幾個(gè)字段不需要通過(guò)網(wǎng)絡(luò)發(fā)送。首先, 如果未使用extranonce,則不必發(fā)送。其次,每隔30k個(gè)塊更換一次seedhash,就沒(méi)有必要每次挖礦都發(fā)送。第三,正如在第2條中指出的 - 當(dāng)使用set_difficulty時(shí), 在mining.notify中的目標(biāo)是多余的。第四,mining.submit實(shí)際上只需要發(fā)送一次。礦池需要驗(yàn)證Nonce的有效性,并將計(jì)算哈希和混合哈希(mixhash)。如果刪除所有提及的冗余,可以很容易地減少50%以上的帶寬使用。
  4. 與原有slush的stratum規(guī)范相比,有一些不一致的地方。其中一個(gè)是ids。Ids應(yīng)該增加,以便礦池能夠跟蹤接收到的數(shù)據(jù)。另一件事是HEX標(biāo)記'0x'從每個(gè)字符串字段開(kāi)始。這也是多余的,如果不使用的話,我們將節(jié)省一些帶寬。
  5. 沒(méi)有規(guī)范,只有有實(shí)現(xiàn)的解決方案項(xiàng)目。這通常會(huì)導(dǎo)致幾個(gè)類似的協(xié)議版本;到底發(fā)生了什么。

我們的目標(biāo)是建立一個(gè)可靠的、無(wú)冗余的、刀槍不入的以太坊stratum挖礦協(xié)議, 它沒(méi)有前面指出的這些問(wèn)題。

II. 概念

以太坊的GetWork給我們3個(gè)值:

{ ... "result":[
"0x645cf20198c2f3861e947d4f67e3ab63b7b2e24dcc9095bd9123e7b33371f6cc",
"0xabad8f99f3918bf903c6a909d9bbc0fdfa5a2f4b9cb1196175ec825c6610126c",
"0x0000000394427b08175efa9a9eb59b9123e2969bf19bf272b20787ed022fbe6c"
]}

第一個(gè)值是headerhash,第二個(gè)是seedhash, 第三個(gè)是目標(biāo)。 Seedhash用于識(shí)別DAG文件, headerhash和64為Nonce由我們的礦機(jī)給我們的哈希選擇出, 如果低于提供的目標(biāo),則提供塊/共享。

由于Nonce的寬度為64位(8字節(jié)),并且考慮到非常糟糕的可能情況,以太坊在5分鐘內(nèi)沒(méi)有發(fā)現(xiàn)一個(gè)塊,8個(gè)字節(jié)的Nonce能夠提升礦機(jī)的速度到:

    (2^64 / 300) / 1G ~ 61,489,147 GH/s

這是一個(gè)非常大的數(shù)字,所以我們可以很容易地考慮為我們的stratum協(xié)議拿走一些字節(jié)。

---------------------------------------
| Bytes | Max supported hashing speed |
|   8   |        ~61,489,147.000 GH/s |
|   7   |           ~240,192.000 GH/s |
|   6   |               ~938.000 GH/s |
|   5   |                 ~3.665 GH/s |
|   4   |                 ~0.014 GH/s |
---------------------------------------

只有4個(gè)字節(jié)的Nonce不是一個(gè)選項(xiàng),因?yàn)槲覀円呀?jīng)有了能夠達(dá)到14 MH/s以上的礦工。5個(gè)字節(jié)的Nonce寬度允許最大速度為3.665 GH/s,在相當(dāng)長(zhǎng)的時(shí)間內(nèi)是足夠的,即使ASICs到達(dá)。

礦工需要在礦池中得到seedhash、headerhash、難度和部分nonce(被稱為extranonce)。礦工選擇了它自己的第二部分(稱為minernonce)。Extranonce與minernonce連接,它提供64位的Ethereum nonce。

III. 規(guī)范(RFC)


在礦工到礦池建立TCP連接之后,就會(huì)發(fā)生握手。礦工首先發(fā)送數(shù)據(jù):

{
  "id": 1,
  "method": "mining.subscribe",
  "params": [
    "MinerName/1.0.0", "EthereumStratum/1.0.0"
  ]
}

第一個(gè)參數(shù)是礦工名稱和版本(正如標(biāo)準(zhǔn)stratum協(xié)議)。第二個(gè)參數(shù)必須是“Ethereum Stratum/Version”,版本是根據(jù)該文檔的版本使用的EthereumStratum礦工的版本。如果礦池不支持此版本,它可以終止連接或返回錯(cuò)誤。
注意,礦工可以迭代ids,可以從任何數(shù)字開(kāi)始。從礦工到礦池的每條消息都需要有唯一的id給礦工以正確讀取響應(yīng),因?yàn)榈V池可能不以FIFO方式處理礦工的消息。

服務(wù)器回復(fù):

{
  "id": 1,
  "result": [
    [
      "mining.notify",
      "ae6812eb4cd7735a302a8a9dd95cf71f",
      "EthereumStratum/1.0.0"
    ],
    "080c"
  ],
  "error": null
}

響應(yīng)幾乎與標(biāo)準(zhǔn)stratum協(xié)議具有以下差異;結(jié)果數(shù)組的第一個(gè)參數(shù)的第三個(gè)參數(shù)為“EthereumStratum/Version”;如果礦池沒(méi)有報(bào)告此參數(shù)或版本與礦工支持的不同,礦工可以預(yù)期兼容性問(wèn)題,并終止連接。結(jié)果數(shù)組的第二個(gè)參數(shù)是由礦池設(shè)置的extranonce(在十六進(jìn)制中)。沒(méi)有第三個(gè)參數(shù),因?yàn)闆](méi)有extranonce2(正如標(biāo)準(zhǔn)stratum)。Extranonce可能最大3字節(jié)。

礦工應(yīng)在初次握手時(shí)授權(quán);這與標(biāo)準(zhǔn)stratum協(xié)議相同,在這里將不會(huì)詳細(xì)解釋。

在第一份任務(wù)(工作)提供之前,礦池必須通過(guò)發(fā)送設(shè)置難度:

{
  "id": null,
  "method": "mining.set_difficulty",
  "params": [
    0.5
  ]
}

參數(shù)數(shù)組的第一項(xiàng)是雙重?cái)?shù)據(jù)類型的難度。難度和目標(biāo)之間的轉(zhuǎn)換與比特幣一樣;難度1轉(zhuǎn)化為HEX的目標(biāo):

00000000ffff0000000000000000000000000000000000000000000000000000

如果礦池在第一份工作之前沒(méi)有設(shè)置難度,那么礦工就可以假定難度是1。

當(dāng)難度發(fā)生變化時(shí),礦工們開(kāi)始為每一份到達(dá)的NEXT任務(wù)使用新的難度。

如果礦工已經(jīng)訂閱extranonce通知(詳細(xì)解釋在這里:https://www.nicehash.com/?p=software#devs),然后礦池可能會(huì)改變礦工的extranonce通過(guò)發(fā)送:

{
  "id": null,
  "method": "mining.set_extranonce",
  "params": [
    "af4c"
  ]
}

新的extranonce對(duì)于所有在礦池中發(fā)送的NEXT任務(wù)都有效。

礦池通過(guò)發(fā)送以下數(shù)據(jù)通知礦工工作(工作):

{
  "id": null,
  "method": "mining.notify",
  "params": [
    "bf0488aa",
    "abad8f99f3918bf903c6a909d9bbc0fdfa5a2f4b9cb1196175ec825c6610126c",
    "645cf20198c2f3861e947d4f67e3ab63b7b2e24dcc9095bd9123e7b33371f6cc",
    true
  ]
}

參數(shù)數(shù)組的第一個(gè)參數(shù)是任務(wù)ID(必須是任意大小的十六進(jìn)制數(shù))。第二個(gè)參數(shù)是seedhash。每一個(gè)任務(wù)都發(fā)送一個(gè)seedhash來(lái)支持盡可能多的礦池,這可能會(huì)很快地在貨幣之間交換。第三個(gè)參數(shù)是headerhash。最后一個(gè)參數(shù)是boolean cleanjobs。如果設(shè)為true,那么礦工需要清理任務(wù)隊(duì)列,并立即開(kāi)始從事新提供的任務(wù),因?yàn)樗信f的任務(wù)分享都將導(dǎo)致陳舊的分享錯(cuò)誤。

礦工使用seedhash識(shí)別DAG,然后試著帶著headerhash,extranonce和自己的minernonce尋找低于目標(biāo)的分享(這是由提供的難度而產(chǎn)生的)。

當(dāng)發(fā)現(xiàn)低于目標(biāo)的分享時(shí),礦工將其提交給礦池:

{
  "id": 244,
  "method": "mining.submit",
  "params": [
    "username",
    "bf0488aa",
    "6a909d9bbc0f"
  ]
}

參數(shù)數(shù)組的第二個(gè)參數(shù)是任務(wù)ID,第三個(gè)參數(shù)是minernonce。注意在上面的例子中,minernonce是6個(gè)字節(jié),因?yàn)樘峁┑膃xtranonce是2個(gè)字節(jié)。如果礦池提供3字節(jié)的extranonce,那么minernonce必須是5字節(jié)。

對(duì)于每一個(gè)提交的工作,礦池需要返回標(biāo)準(zhǔn)stratum響應(yīng):

{
  "id": 244,
  "result": true,
  "error": null
}

或者如果分享不被接受(標(biāo)準(zhǔn)stratum響應(yīng)):

{
  "id": 244,
  "result": false,
  "error": [
    -1,
    "Job not found",
    NULL
  ]
}

IV. 真實(shí)場(chǎng)景


礦工連接礦池并發(fā)送:

{
  "id": 1,
  "method": "mining.subscribe",
  "params": [
    "EthereumMiner/1.0.0", "EthereumStratum/1.0.0"
  ]
}

礦池響應(yīng):

{
  "id": 1,
  "result": [
    [
      "mining.notify",
      "ae6812eb4cd7735a302a8a9dd95cf71f",
      "EthereumStratum/1.0.0"
    ],
    "a2eea0"
  ],
  "error": null
}

礦工然后認(rèn)證:

{
  "id": 2,
  "method": "mining.authorize",
  "params": [
    "test",
    "password"
  ]
}

礦池確認(rèn):

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

礦池發(fā)送難度:

{
  "id": null,
  "method": "mining.set_difficulty",
  "params": [
    1.0
  ]
}\n

然后任務(wù):

{
  "id": null,
  "method": "mining.notify",
  "params": [
    "bf0488aa",
    "abad8f99f3918bf903c6a909d9bbc0fdfa5a2f4b9cb1196175ec825c6610126c",
    "fc12eb20c58158071c956316cdcd12a22dd8bf126ac4aee559f0ffe4df11f279",
    true
  ]
}\n

過(guò)了一段時(shí)間,礦工找到了分享并提交:

{
  "id": 3,
  "method": "mining.submit",
  "params": [
    "test",
    "bf0488aa",
    "cfae7df760"
  ]
}\n

礦池響應(yīng):

{
  "id": 3,
  "result": true,
  "error": null
}\n

分享是有效考慮數(shù)據(jù):

seedhash=abad8f99f3918bf903c6a909d9bbc0fdfa5a2f4b9cb1196175ec825c6610126c
headerhash=fc12eb20c58158071c956316cdcd12a22dd8bf126ac4aee559f0ffe4df11f279
nonce=a2eea0cfae7df760

結(jié)果是難度的1.863, 大于1.0.

V. 增強(qiáng)計(jì)劃

以太坊有RPC方法eth_getBlockByNumber,它可以返回一些尚未被挖掘的下塊數(shù)據(jù)。數(shù)據(jù)中有下一個(gè)塊號(hào)(塊高度)。這個(gè)數(shù)字可以代替seedhash;然后,每個(gè)礦工都將計(jì)算自己的seedhash,因此帶寬的使用將會(huì)減少更多。
有一些改造eth_getBlockTemplate方法的計(jì)劃。當(dāng)這種情況發(fā)生時(shí),這種stratum協(xié)議可能與標(biāo)準(zhǔn)stratum非常相似。

VI. 聯(lián)系方式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 簡(jiǎn)介 不管你們知不知道以太坊(Ethereum blockchain)是什么,但是你們大概都聽(tīng)說(shuō)過(guò)以太坊。最近在新...
    Lilymoana閱讀 3,998評(píng)論 1 22

友情鏈接更多精彩內(nèi)容