跳到主要内容

Stratum挖矿协议

本文介绍Stratum挖矿协议,当前最主流的加密货币挖矿协议。

什么是Stratum挖矿协议?

Stratum挖矿协议是一种用于加密货币挖矿的协议,旨在优化矿工与矿池之间的通信。该协议由Slush Pool在2012年引入,取代了早期的HTTP挖矿协议,解决了效率和扩展性的问题。

在Stratum协议出现之前,加密货币挖矿主要使用RPC挖矿协议,例如getwork, getblocktemplate等。这种协议在早期的比特币挖矿中非常常见,但随着挖矿难度和矿工数量的增加,RPC协议暴露出了一些显著的缺点。

RPC(或HTTP)协议挖矿的方式与缺陷

挖矿流程

  1. 连接矿池

    • 矿工通过RPC连接矿池的服务器,通常使用标准的RPC POST请求来获取挖矿任务。
  2. 任务请求

    • 矿工发送包含钱包地址和其他相关信息的请求,向矿池索要挖矿任务。
    • 矿池返回一个包含区块头、目标难度等信息的任务。
  3. 计算哈希

    • 矿工开始使用给定的数据进行哈希计算,试图找到符合目标难度的哈希值。
  4. 提交结果

    • 当矿工找到有效的哈希值时,使用RPC POST请求将结果提交给矿池。
    • 矿池验证结果,如果有效,则将其纳入区块链。
  5. 循环任务

    • 由于RPC协议是无状态的,矿工在每次任务完成后需要重新建立连接请求新任务。

RPC协议的缺点

  1. 连接开销高

    • RPC协议是无状态的,每次获取任务和提交结果都需要重新建立连接,这增加了网络开销和延迟。
    • 频繁的连接建立和关闭操作,导致矿工和矿池服务器的资源浪费。
  2. 实时性差

    • RPC协议无法实时推送新任务,矿工可能会因为任务更新不及时而进行无效计算。
    • 矿工在获取新任务的过程中可能会浪费计算资源,降低挖矿效率。
  3. 延迟问题

    • 由于每次任务请求和结果提交都需要重新建立连接,网络延迟会显著影响挖矿效率。
    • 矿工在高延迟网络环境下,可能会错失有效任务,导致收益减少。
  4. 扩展性差

    • RPC协议设计用于网页浏览,初衷并非高频次的任务请求和结果提交,难以适应大规模矿工的高并发需求。
    • 随着矿工数量增加,矿池服务器的负载会显著增加,导致性能瓶颈。
    • 随着区块数量增大,生成一次工作任务所需要耗费的网络带宽和计算资源也会增加。
  5. 容错性低

    • RPC协议缺乏对连接中断的容错处理,矿工在网络波动时容易丢失任务或结果,影响挖矿的稳定性。
    • 矿池和矿工之间的通信容易受到网络故障和攻击的影响。

Stratum协议细节

Stratum协议通过优化矿工与矿池之间的通信,解决了RPC协议的缺点,提高了挖矿效率和稳定性。它采用长连接方式,使用JSON-RPC格式进行通信,实现了实时任务更新、容错性强和扩展性好等优点。

  1. 连接建立

    • 矿工通过TCP连接矿池的Stratum服务器,并使用JSON-RPC格式进行通信。
    • 连接成功后,矿工向矿池发送“mining.subscribe”请求,以订阅任务。
  2. 任务分配

    • 矿池接收到订阅请求后,发送“mining.notify”消息,包含挖矿任务的详细信息,如区块头、目标难度等。
    • 矿工收到任务后,开始进行哈希计算,寻找符合目标难度的解。
  3. 提交结果

    • 当矿工找到符合条件的哈希值时,向矿池发送“mining.submit”消息,提交计算结果。
    • 矿池验证结果,如果符合要求,则将其纳入区块链。
  4. 任务更新

    • 矿池会周期性地发送新的任务给矿工,确保矿工始终在最新任务上进行计算。
    • 通过“mining.notify”消息,矿池可以动态调整任务参数,提升挖矿效率。

协议优势

  1. 高效通信

    • Stratum协议采用长连接方式,减少了HTTP协议中频繁建立和关闭连接的开销。
    • 使用轻量级的JSON-RPC格式,使得消息传输更加高效。
  2. 实时任务更新

    • 矿池能够实时向矿工推送新任务,确保矿工始终在最新的区块数据上进行计算,避免无效工作。
    • 动态调整难度参数,提高挖矿效率和公平性。
  3. 容错性强

    • Stratum协议支持多次尝试提交结果,容错性强,确保矿工的工作不会因为偶尔的网络波动而丢失。
    • 支持冗余服务器,矿工可以在主服务器故障时自动切换到备用服务器,保证挖矿不中断。
  4. 扩展性好

    • Stratum协议设计简洁,易于扩展,可以支持多种加密货币和不同的挖矿算法。
    • 矿池可以根据需求开发定制化的Stratum服务器,以适应不同的矿工和硬件配置。
  5. 易于分割任务

    • Stratum协议将挖矿任务分割为多个小任务,矿工可以并行处理这些小任务,提高挖矿效率。矿工无需提交一整个区块所需要的工作量证明,而是可以分别提交每个小任务的工作量证明。这样可以让低算力的矿工也有机会获得挖矿奖励。
    • 通过Merkle树的性质,挖矿所需的数据量是对数级别的,而非线性级别的,降低了带宽和负载。
  6. 支持AsicBoost

    • Stratum协议支持AsicBoost技术,通过扩展协议和消息类型,为矿工提供更高效的挖矿方式。
    • 矿池可以通过Stratum协议向矿工发送AsicBoost相关的配置信息,实现更高效的哈希计算。

Stratum交互例

以下是一个简单的Stratum挖矿协议交互示例,包括矿机订阅、认证、任务推送和提交结果等过程。

以下所有报文均使用\n做为行结束符。


矿机订阅:

{"id": 1, "method": "mining.subscribe", "params": []}

服务器回应:

{"id": 1, "result": [ [ ["mining.set_difficulty", "b4b6693b72a50c7116db18d6497cac52"], ["mining.notify", "ae6812eb4cd7735a302a8a9dd95cf71f"]], "08000002", 4], "error": null}

如果没有收到该回应,则可能原因有:

  1. 连接的不是Stratum服务器。
  2. Stratum服务器工作状态异常。
  3. 请求报文的行结束符不为\n,在粘贴多行文本到终端时可能发生这种现象,此时请单行粘贴并手动按回车。

订阅成功后,矿机进行矿工名认证

{"params": ["把它替换为你真实的矿工名", "password"], "id": 2, "method": "mining.authorize"}

服务器回应:

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

若回应不为true,则 result 字段包含错误信息。 若没有收到任何回应,可能的原因有:

  1. Stratum Server状态异常。
  2. 行结束符问题。
  3. 订阅和认证相隔太久,服务器放弃认证矿机。

认证成功后,Stratum Server会主动推送挖矿难度和挖矿任务等信息,如下:

(难度)

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

(任务)

{"params": ["0", "4d16b6f85af6e2198f44ae2a6de67f78487ae5611b77c6c0440b921e00000000", "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff20020862062f503253482f04b8864e5008", "072f736c7573682f000000000100f2052a010000001976a914d23fcdf86f7e756a64a7a9688ef9903327048ed988ac00000000", [], "00000002", "1c2ac4af", "504e86b9", false], "id": null, "method": "mining.notify"}

如果没有收到难度推送,则说明Stratum Server工作不正常。 如果没有收到任务推送,则说明Stratum Server可能此时没有可推送给你的任务。对于BTCPool,可能是它没有从Kafka中读取到可用的任务,这可能是因为jobmaker没有产生对应的任务,或者kafka状态异常。当然,也有可能是Stratum Server状态异常。


当矿机挖到一个符合矿池设定难度的share之后,它会进行share提交:

{"params": ["slush.miner1", "0", "00000001", "504e86ed", "b2957c02"], "id": 4, "method": "mining.submit"}

服务器回应:

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

若result不为true,则会包含拒绝该share的理由。


请注意,不是每个submit都会挖到区块。对于一个正常的矿池来说,矿机提交的大部分submit都是挖不到区块的,但是偶尔个别的submit达到了全网难度要求,因此能够挖到区块。

当矿机挖到区块时,矿机的提交动作和平常不会有什么不同。但是,矿机和矿池均可对share难度和job中的bits/target进行比较来发现它挖到了一个符合全网难度的share。

对于联合挖矿也是如此,检查share难度是否满足job中联合挖矿币种的难度。若正在联合挖多个币种,只需检查是否满足最低难度。

需要注意的是,联合挖矿的币种可能比正在挖掘的比特币难度高,或者难度低。

若比特币难度高,则挖到比特币区块则必然挖到联合挖矿币种区块,而反过来则不一定。

若联合挖矿币种难度高(比如BCH联合挖掘域名币),则在挖到比特币时不一定能挖到联合挖矿币种,但反过来则是一定能挖到。

总结

Stratum挖矿协议通过优化矿工与矿池之间的通信,提高了挖矿效率和系统的稳定性。它的高效通信、实时任务更新、强大的容错性和良好的扩展性,使得它成为目前加密货币挖矿的主流协议。随着技术的发展,Stratum协议也在不断演进,进一步提升挖矿的效率和安全性。