# 以太坊stratum协议原理

By [watano](https://paragraph.com/@watano) · 2021-12-07

---

参照比特币的[stratum协议](https://link.jianshu.com/?t=http://www.8btc.com/stratum_protocol) 和[NiceHash的stratum协议规范](https://www.jianshu.com/p/7bfe925f3d0a)编写了一版以太坊版本的stratum协议说明.

* * *

stratum协议是目前最常用的矿机和矿池之间的TCP通讯协议。

一、挖矿的网络架构
---------

以太坊是一个去中心化的网络架构，通过安装Mist客户端的节点来转发新交易和新区块。而矿机、矿池也同时形成了另一个网络，我们称之为矿工网络。

矿工网络分成矿机、矿池、钱包等几个主要部分，有时矿池软件与钱包安装在一起，可合称为矿池。

矿机与矿池软件之间的通讯协议是`stratum`，而矿池软件与钱包之间的通讯是`bitcoinrpc`接口。

stratum是`JSON`为数据格式.

二、stratum协议
-----------

### 1\. 任务订阅

矿机启动，首先以`mining.subscribe`方法向矿池连接，用来订阅工作。

矿池以`mining.notify`返回订阅号、ExtraNonce1和ExtraNonce2\_size。

Client:

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

Server:

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

其中：

ae6812eb4cd7735a302a8a9dd95cf71f是`订阅号`；

080c是`extranonce`，Extranonce可能最大3字节；

### 2\. 矿机登录

矿机以`mining.authorize`方法，用某个帐号和密码登录到矿池，密码可空，矿池返回`true`登录成功。该方法必须是在初始化连接之后马上进行，否则矿机得不到矿池任务。

Client:

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

Server:

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

### 3\. 难度调整

难度调整由矿池下发给矿机，以`mining.set_difficulty`方法调整难度，`params`中是难度值。Server:

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

矿机会在下一个任务时采用新难度，矿池有时会马上下发一个新任务并且把清理任务设为true，以便矿机马上以新难度工作。

### 4\. 任务分配

该命令由矿池定期发给矿机，当矿机以`mining.subscribe`方法登记后，矿池应该马上以`mining.notify`返回该任务。

Server:

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

**任务ID**：`bf0488aa`；

**seedhash**：`abad8f99f3918bf903c6a909d9bbc0fdfa5a2f4b9cb1196175ec825c6610126c`。每一个任务都发送一个seedhash来支持尽可能多的矿池，这可能会很快地在货币之间交换。

**headerhash**: `645cf20198c2f3861e947d4f67e3ab63b7b2e24dcc9095bd9123e7b33371f6cc`。

boolean **cleanjobs**: `true`。如果设为true，那么矿工需要清理任务队列，并立即开始从事新提供的任务，因为所有旧的任务分享都将导致陈旧的分享错误。如果是`false`则等当前任务结束才开始新任务。

### 5\. 结果提交

矿工使用seedhash识别DAG，然后带着headerhash,extranonce和自己的minernonce寻找低于目标的share(这是由提供的难度而产生的)。

矿机找到合法share时，就以”`mining.submit`“方法向矿池提交任务。矿池返回true即提交成功，如果失败则error中有具体原因。

Client:

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

**任务ID**: `bf0488aa`

**minernonce**: `6a909d9bbc0f`。注意minernonce是6个字节，因为提供的extranonce是2个字节。如果矿池提供3字节的extranonce，那么minernonce必须是5字节

Server:

*   接受结果:
    

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

*   不被接受:
    

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

三、一般通讯过程
--------

一般的矿机与矿池通讯过程就如下所示：

![](https://storage.googleapis.com/papyrus_images/f6b9b40fc5bc479c21e1119ca67de01f593c5c91578a16ffc98bfeef92c800a9.png)

---

*Originally published on [watano](https://paragraph.com/@watano/stratum)*
