@@ -3,3 +3,192 @@ sidebar_position: 10
3
3
---
4
4
5
5
# Stratum挖矿协议
6
+
7
+ 本文介绍Stratum挖矿协议,当前最主流的加密货币挖矿协议。
8
+
9
+ ## 什么是Stratum挖矿协议?
10
+
11
+ Stratum挖矿协议是一种用于加密货币挖矿的协议,旨在优化矿工与矿池之间的通信。该协议由Slush Pool在2012年引入,取代了早期的HTTP挖矿协议,解决了效率和扩展性的问题。
12
+
13
+ 在Stratum协议出现之前,加密货币挖矿主要使用[ RPC挖矿协议] ( ../config/set-up-your-own.md ) ,例如` getwork ` , ` getblocktemplate ` 等。这种协议在早期的比特币挖矿中非常常见,但随着挖矿难度和矿工数量的增加,RPC协议暴露出了一些显著的缺点。
14
+
15
+ ### RPC(或HTTP)协议挖矿的方式与缺陷
16
+
17
+ #### 挖矿流程
18
+
19
+ 1 . ** 连接矿池** :
20
+ - 矿工通过RPC连接矿池的服务器,通常使用标准的RPC POST请求来获取挖矿任务。
21
+
22
+ 2 . ** 任务请求** :
23
+ - 矿工发送包含钱包地址和其他相关信息的请求,向矿池索要挖矿任务。
24
+ - 矿池返回一个包含区块头、目标难度等信息的任务。
25
+
26
+ 3 . ** 计算哈希** :
27
+ - 矿工开始使用给定的数据进行哈希计算,试图找到符合目标难度的哈希值。
28
+
29
+ 4 . ** 提交结果** :
30
+ - 当矿工找到有效的哈希值时,使用RPC POST请求将结果提交给矿池。
31
+ - 矿池验证结果,如果有效,则将其纳入区块链。
32
+
33
+ 5 . ** 循环任务** :
34
+ - 由于RPC协议是无状态的,矿工在每次任务完成后需要重新建立连接请求新任务。
35
+
36
+ #### RPC协议的缺点
37
+
38
+ 1 . ** 连接开销高** :
39
+ - RPC协议是无状态的,每次获取任务和提交结果都需要重新建立连接,这增加了网络开销和延迟。
40
+ - 频繁的连接建立和关闭操作,导致矿工和矿池服务器的资源浪费。
41
+
42
+ 2 . ** 实时性差** :
43
+ - RPC协议无法实时推送新任务,矿工可能会因为任务更新不及时而进行无效计算。
44
+ - 矿工在获取新任务的过程中可能会浪费计算资源,降低挖矿效率。
45
+
46
+ 3 . ** 延迟问题** :
47
+ - 由于每次任务请求和结果提交都需要重新建立连接,网络延迟会显著影响挖矿效率。
48
+ - 矿工在高延迟网络环境下,可能会错失有效任务,导致收益减少。
49
+
50
+ 4 . ** 扩展性差** :
51
+ - RPC协议设计用于网页浏览,初衷并非高频次的任务请求和结果提交,难以适应大规模矿工的高并发需求。
52
+ - 随着矿工数量增加,矿池服务器的负载会显著增加,导致性能瓶颈。
53
+ - 随着区块数量增大,生成一次工作任务所需要耗费的网络带宽和计算资源也会增加。
54
+
55
+ 5 . ** 容错性低** :
56
+ - RPC协议缺乏对连接中断的容错处理,矿工在网络波动时容易丢失任务或结果,影响挖矿的稳定性。
57
+ - 矿池和矿工之间的通信容易受到网络故障和攻击的影响。
58
+
59
+
60
+ ## Stratum协议细节
61
+
62
+ [ Stratum] ( https://en.bitcoin.it/wiki/Stratum_mining_protocol ) 协议通过优化矿工与矿池之间的通信,解决了RPC协议的缺点,提高了挖矿效率和稳定性。它采用长连接方式,使用JSON-RPC格式进行通信,实现了实时任务更新、容错性强和扩展性好等优点。
63
+
64
+ 1 . ** 连接建立** :
65
+ - 矿工通过TCP连接矿池的Stratum服务器,并使用JSON-RPC格式进行通信。
66
+ - 连接成功后,矿工向矿池发送“mining.subscribe”请求,以订阅任务。
67
+
68
+ 2 . ** 任务分配** :
69
+ - 矿池接收到订阅请求后,发送“mining.notify”消息,包含挖矿任务的详细信息,如区块头、目标难度等。
70
+ - 矿工收到任务后,开始进行哈希计算,寻找符合目标难度的解。
71
+
72
+ 3 . ** 提交结果** :
73
+ - 当矿工找到符合条件的哈希值时,向矿池发送“mining.submit”消息,提交计算结果。
74
+ - 矿池验证结果,如果符合要求,则将其纳入区块链。
75
+
76
+ 4 . ** 任务更新** :
77
+ - 矿池会周期性地发送新的任务给矿工,确保矿工始终在最新任务上进行计算。
78
+ - 通过“mining.notify”消息,矿池可以动态调整任务参数,提升挖矿效率。
79
+
80
+ ### 协议优势
81
+
82
+ 1 . ** 高效通信** :
83
+ - Stratum协议采用长连接方式,减少了HTTP协议中频繁建立和关闭连接的开销。
84
+ - 使用轻量级的JSON-RPC格式,使得消息传输更加高效。
85
+
86
+ 2 . ** 实时任务更新** :
87
+ - 矿池能够实时向矿工推送新任务,确保矿工始终在最新的区块数据上进行计算,避免无效工作。
88
+ - 动态调整难度参数,提高挖矿效率和公平性。
89
+
90
+ 3 . ** 容错性强** :
91
+ - Stratum协议支持多次尝试提交结果,容错性强,确保矿工的工作不会因为偶尔的网络波动而丢失。
92
+ - 支持冗余服务器,矿工可以在主服务器故障时自动切换到备用服务器,保证挖矿不中断。
93
+
94
+ 4 . ** 扩展性好** :
95
+ - Stratum协议设计简洁,易于扩展,可以支持多种加密货币和不同的挖矿算法。
96
+ - 矿池可以根据需求开发定制化的Stratum服务器,以适应不同的矿工和硬件配置。
97
+
98
+ 5 . ** 易于分割任务** :
99
+ - Stratum协议将挖矿任务分割为多个小任务,矿工可以并行处理这些小任务,提高挖矿效率。矿工无需提交一整个区块所需要的工作量证明,而是可以分别提交每个小任务的工作量证明。这样可以让低算力的矿工也有机会获得挖矿奖励。
100
+ - 通过Merkle树的性质,挖矿所需的数据量是对数级别的,而非线性级别的,降低了带宽和负载。
101
+
102
+ 6 . ** 支持AsicBoost** :
103
+ - Stratum协议支持AsicBoost技术,通过扩展协议和消息类型,为矿工提供更高效的挖矿方式。
104
+ - 矿池可以通过Stratum协议向矿工发送AsicBoost相关的配置信息,实现更高效的哈希计算。
105
+
106
+ ## Stratum交互例
107
+
108
+ 以下是一个简单的Stratum挖矿协议交互示例,包括矿机订阅、认证、任务推送和提交结果等过程。
109
+
110
+ 以下所有报文均使用\n做为行结束符。
111
+
112
+ ----------
113
+
114
+ 矿机订阅:
115
+ ``` json
116
+ {"id" : 1 , "method" : " mining.subscribe" , "params" : []}
117
+ ```
118
+
119
+ 服务器回应:
120
+ ``` json
121
+ {"id" : 1 , "result" : [ [ [" mining.set_difficulty" , " b4b6693b72a50c7116db18d6497cac52" ], [" mining.notify" , " ae6812eb4cd7735a302a8a9dd95cf71f" ]], " 08000002" , 4 ], "error" : null }
122
+ ```
123
+
124
+ 如果没有收到该回应,则可能原因有:
125
+ 1 . 连接的不是Stratum服务器。
126
+ 2 . Stratum服务器工作状态异常。
127
+ 3 . 请求报文的行结束符不为\n,在粘贴多行文本到终端时可能发生这种现象,此时请单行粘贴并手动按回车。
128
+
129
+ ----------
130
+
131
+ 订阅成功后,矿机进行矿工名认证
132
+ ``` json
133
+ {"params" : [" 把它替换为你真实的矿工名" , " password" ], "id" : 2 , "method" : " mining.authorize" }
134
+ ```
135
+
136
+ 服务器回应:
137
+ ``` json
138
+ {"error" : null , "id" : 2 , "result" : true }
139
+ ```
140
+
141
+ 若回应不为true,则 result 字段包含错误信息。
142
+ 若没有收到任何回应,可能的原因有:
143
+ 1 . Stratum Server状态异常。
144
+ 2 . 行结束符问题。
145
+ 3 . 订阅和认证相隔太久,服务器放弃认证矿机。
146
+
147
+ ----------
148
+
149
+ 认证成功后,Stratum Server会主动推送挖矿难度和挖矿任务等信息,如下:
150
+
151
+ (难度)
152
+ ``` json
153
+ {"id" : null , "method" : " mining.set_difficulty" , "params" : [16384 ]}
154
+ ```
155
+
156
+ (任务)
157
+ ``` json
158
+ {"params" : [" 0" , " 4d16b6f85af6e2198f44ae2a6de67f78487ae5611b77c6c0440b921e00000000" , " 01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff20020862062f503253482f04b8864e5008" , " 072f736c7573682f000000000100f2052a010000001976a914d23fcdf86f7e756a64a7a9688ef9903327048ed988ac00000000" , [], " 00000002" , " 1c2ac4af" , " 504e86b9" , false ], "id" : null , "method" : " mining.notify" }
159
+ ```
160
+
161
+
162
+ 如果没有收到难度推送,则说明Stratum Server工作不正常。
163
+ 如果没有收到任务推送,则说明Stratum Server可能此时没有可推送给你的任务。对于BTCPool,可能是它没有从Kafka中读取到可用的任务,这可能是因为jobmaker没有产生对应的任务,或者kafka状态异常。当然,也有可能是Stratum Server状态异常。
164
+
165
+ ----------
166
+
167
+ 当矿机挖到一个符合矿池设定难度的share之后,它会进行share提交:
168
+ ``` json
169
+ {"params" : [" slush.miner1" , " 0" , " 00000001" , " 504e86ed" , " b2957c02" ], "id" : 4 , "method" : " mining.submit" }
170
+ ```
171
+
172
+ 服务器回应:
173
+ ``` json
174
+ {"error" : null , "id" : 4 , "result" : true }
175
+ ```
176
+
177
+ 若result不为true,则会包含拒绝该share的理由。
178
+
179
+ ----------
180
+ 请注意,不是每个submit都会挖到区块。对于一个正常的矿池来说,矿机提交的大部分submit都是挖不到区块的,但是偶尔个别的submit达到了全网难度要求,因此能够挖到区块。
181
+
182
+ 当矿机挖到区块时,矿机的提交动作和平常不会有什么不同。但是,矿机和矿池均可对share难度和job中的bits/target进行比较来发现它挖到了一个符合全网难度的share。
183
+
184
+ 对于联合挖矿也是如此,检查share难度是否满足job中联合挖矿币种的难度。若正在联合挖多个币种,只需检查是否满足最低难度。
185
+
186
+ 需要注意的是,联合挖矿的币种可能比正在挖掘的比特币难度高,或者难度低。
187
+
188
+ 若比特币难度高,则挖到比特币区块则必然挖到联合挖矿币种区块,而反过来则不一定。
189
+
190
+ 若联合挖矿币种难度高(比如BCH联合挖掘域名币),则在挖到比特币时不一定能挖到联合挖矿币种,但反过来则是一定能挖到。
191
+
192
+ ## 总结
193
+
194
+ Stratum挖矿协议通过优化矿工与矿池之间的通信,提高了挖矿效率和系统的稳定性。它的高效通信、实时任务更新、强大的容错性和良好的扩展性,使得它成为目前加密货币挖矿的主流协议。随着技术的发展,Stratum协议也在不断演进,进一步提升挖矿的效率和安全性。
0 commit comments