挖矿那些事儿

BTC篇

什么是挖矿?

BTC节点通过网络收集未打包的交易,产生出candidate block(候选区块),其header包含如下字段:

  • Version 表示当前使用的BTC协议的版本
  • Previous Block Hash 前一个区块的hash值
  • Merkleroot 打包到当前区块的交易组装的merkle tree的root hash
  • Difficulty target 当前BTC网络的难度值,简单说就是要成为合法的区块,区块哈希前面要有多少个0
  • Timestamp 时间戳
  • Nonce 32bit的随机值,矿工可以通过搜寻合适的Nonce值,让区块哈希满足前面的Difficulty target

挖矿就是通过调整区块中的内容,主要是Nonce值,产生出一个符合当前网络难度的合法区块。

挖矿的目的

对于BTC网络来说:挖矿是产生合法区块的唯一途径,保持BTC网络安全持续的运转下去。
对于矿工个人来说:挖矿可以获得BTC奖励。

挖矿历史和演进

挖矿经历了CPU → GPU → FPGA → ASIC 等演进阶段。
BTC自身就带有挖矿程序,但是只支持CPU挖矿,所以最开始是CPU挖矿阶段。
很快大家就发现GPU在挖矿上比CPU效率高的多,于是果断抛弃官方的挖矿程序,开发了基于GPU的专用挖矿软件(比如cgminer)。
通过FPGA过渡之后,最终进入了ASIC(专用芯片)阶段。
相关历史可以参见 Category:History - Bitcoin Wiki

参与挖矿的两种方式

Solo mining 和 加入矿池。
Solo mining顾名思义,就是矿工独自挖矿。只要自己运行一个BTC节点,运行挖矿软件就可以了(现在比较难了,后面再展开)。
但是挖矿是个完全随机的过程,波动比较大。其大致遵循泊松分布,即使矿工的算力达到平均每天能挖到一个块,在具体的某天,也有高达37%的概率挖不到块。这对于每天都要吃饭和交电费的矿工来说风险太大了。

然后矿池模式就诞生了。矿池是将一批矿工的算力聚集到一起挖矿,然后将挖矿收益根据每个矿工的贡献比例进行分配。类似于多人合伙买彩票,中奖之后按出资比例分配奖金。
这样可以降低收益的波动,矿工每天可以有比较稳定的收益,降低了风险。矿池模式很快成为挖矿的主流。
但是矿池模式也是有问题的。从前面的分析可知,矿池聚集的算力越多,收益波动越小。因此矿工会倾向于加入算力更大的矿池,导致矿池的头部效应,全网算力很快就集中到了几个头部的矿池。这导致了网络的中心化和潜在的51%攻击的风险。

矿池运营方只会运行一个全节点和一个矿池服务端。矿工的挖矿设备依然自己管理,通过网络与矿池交互,从矿池那里获取任务,然后只负责尝试计算区块哈希,然后向矿池上报任务完成情况。
此模式下,矿工并不运行节点,挖矿收益是直接进入矿池的账户,然后矿池收取一定比例的手续费后,根据各个矿工的贡献度进行收益分配。
矿池统计矿工贡献度的方式叫share。前面提到过,只有区块哈希前面的0足够多,才是一个合法的区块,才会有挖矿奖励。share就是一个不够格的区块,其哈希前面的0不够多。矿池通过统计矿工提交的share数量来评判其贡献度。类似于我们日常的每日工作汇报,不一定要完成工作之后才去向领导汇报,每天都汇报一下工作进展(完成了一个步骤或者其中一个小任务),这样领导知道你每天都在干活,才会给你记工。
结算模式也有不同的方式,参见 https://f2pool.zendesk.com/hc/zh-tw/articles/360061042332-收益結算模式-PPS-PPLNS-FPPS-PPS

矿机与矿池之间的网络通信逐渐形成了一套矿池协议(这个等下再展开),先回过头来说solo mining。因为矿池模式是挖矿的主流,因此在ASIC时代,矿机厂商直接就在矿机的固件里集成了挖矿协议。
更具体来说矿机的固件其实就是一个挖矿软件,从比特大陆很早之前开源的固件代码来看,其实就是cgminer。对挖矿协议的支持也在cgminer代码里面。Antminer_firmware/sources/meta-antminer/recipes-bitmianer/cgminer/cgminer-1.0/cgminer-3.12.0_bak/util.c at master · bitmaintech/Antminer_firmware · GitHub
因此矿工买到ASIC矿机之后,只要开机之后设置一下连接矿池的配置,马上就可以开始参与挖矿。反而自己挖矿变的困难了,因为矿机默认就是连矿池的,而不能连自己运行的节点了。
当然方法也是有的,就是自己跑一个矿池服务端,相当于一个私有化部署的矿池。但是因为矿池和矿机涉及巨大的经济利益,一般都是不开源的,网上也很少有相关的技术资料。BTC原来有一个开源的BTCPool,但是已经废弃,很多年没有更新了。现在有一个 GitHub - benjamin-wilson/public-pool 可以用,算是给solo ming保留了一丝火种。

矿池协议演进

Getwork。

BTC节点最早为挖矿提供了一个Getwork的RPC接口,但是这个接口并不是返回candidate block(候选块)的完整区块头,而是会将区块头预处理成一段data,矿工拿到之后只是不停的尝试不同的Nonce值并计算哈希。
前面讲过,一个区块是否有效看的是整个区块头的哈希前面是否有足够的0,所以调整区块头的任何一个值都可以。但是Getwrok模式下,矿工只能修改Nonce值,而无法修改区块头的其他内容,而BTC的Nonce字段只有32位。
当矿工的算力达到4.3Ghash/s的时候,1秒就可以遍历所有可能的Nonce。剩下的时间就只能干等着节点给新的任务。如果矿池连接了多个矿工,就更惨了,多个矿工的任务完全是重复的,严重浪费了算力。

GBT(Getblocktemplate)

BTC节点提供了新的RPC接口——Getblocktemplate——返回更多的区块信息,让矿工可以调整的东西更多(比如timestamp和coinbase交易中的无关内容),从而增加了矿工的搜索空间。

大名鼎鼎的Stratum (V1)协议

Stratum与GBT方案差不多时间提出,但是Stratum协议是由首个BTC矿池运营商提出的,他们明显更懂挖矿,而且在吸收了GBT方案的基础上进行了一些改进,因此最终成为了挖矿的事实标准。
现在只要说起挖矿协议,默认指的就是Stratum (V1)协议。
Stratum (V1)协议非常的简单,直接基于TCP连接,内容是以换行隔开的,一行一个json字符串。非常简单易懂,且易于调试,速度快,资源占用小。
最主要的是针对矿池模式进行了很多优化。比如它引入了 extranonce 的概念。前面我们提到过,一个矿池可以接入很多矿工。如果矿池给所有矿工下发同样的任务,让他们随机寻找Nonce,那多个矿工之间可能就会重复搜寻,浪费算力。extranonce 就像hash分桶一样,给每个矿工分配了一个不同的前缀值,这样不同的矿工就在不同的桶力搜索,避免了重复劳动。
更详细的协议内容大家可以看参考资料或者实际的交互例子 Ethereum stratum mining protocol v1.0.0 - 简书
当然这个协议也有一些缺点:

  • 安全风险。因为是明文协议,很容易被攻击。
  • 隐私。矿工的信息完全暴露给矿池,没有任何隐私可言。
  • 鉴权不完善。非常简单的用户名密码机制,而且还明文传输,容易遭受中间人攻击。
  • 带宽消耗大。json格式的消息不够有效。
  • 中心化风险。到目前为止的三个演进阶段,都是为了解决搜索空间,或者挖矿效率的问题。对于矿池模式娘胎力带来的中心化风险没有任何改善。矿工完全就是机器上的齿轮,所有的权力都被矿池掌控。

Stratum (V2)协议。

Stratum (V2)改进了V1的很多缺点:

  • 消息换成了二进制格式,更加紧凑,带宽消耗大大减少。
  • 完善了鉴权和加密,使用公私钥方案,更加安全。
  • 解决了中心化风险。通过复杂的架构,让矿工可以提交自己的区块,包括自己的coinbase,也就是收益可以直接到矿工账户上。实现了solo和矿池两种模式的无缝切换。
  • 效率提升。矿池给矿机下发的各项信息,其变动的周期其实差别很大。比如Previous Block Hash,这个在一个出块周期内都不会变。而transaction相关的信息,一旦有新的交易打包进来,就会变化,变化更频繁。V1协议是每次都全量下发,对变动不频繁的有些浪费,对变动频繁的则不够及时。V2把任务内容进一步拆分,可以以不同的频率下发不同信息,更有效率,更及时。而且如果当前区块被本矿池挖到,那么直接把当前区块的哈希作为Previous Block Hash下发,就可以在下一个块有一些先发优势。

V2协议对BTC节点的RPC也提出了新要求(需要修改BTC节点)。它提出了一个新的概念,templateProvider。不同于原来那些get方法,是在BTC节点中新增加一个服务,采用push的方式主动推送,可以更及时的通知交易池重组,同步区块等信息。参见 doc: explain Stratum v2 design, testing and usage · bitcoin/bitcoin@72b8f59 · GitHub

但是它至今还很少有落地实现。虽然官方做了参考实现( GitHub - stratum-mining/stratum: stratum ),并且提供了兼容和升级方案。
但是跟历史上很多升级换代的技术一样,因为老的技术太成熟,生态太庞大了,新的技术很难冒头。
目前绝大部分矿机的固件和商业矿池都还是V1协议。只有 Braiins OS 提供了部分BTC矿机的V2固件,他们家的Braiins Pool 支持V2协议。

矿机与矿池

这两个对于挖矿来说很重要的东西,在区块链生态里面显得非常神秘。跟区块链生态其他部分各种开源,宣讲,有点进展恨不得满世界宣传,相比之下矿机和矿池是闷声发大财的代表。
因为相互之间有博弈关系,所以大家都非常小心翼翼,好像不太想暴露太多技术细节,但是又相互依赖,需要尽量兼容。矿机要兼容尽量多的矿池,矿池也要兼容尽量多的矿机。
Stratum (V1)协议其实没有特别明确的标准文档,但是大家通过这种相互摸索,逐渐形成了一种类似行业默契的事实标准。
这种默契是Stratum (V2)很难打破的。所以估计在之后很长一段时间,Stratum (V1)协议的地位都很难被动摇。

参考资料

5 Likes

CKB篇

其他POW链在挖矿方面都跟BTC高度相似,CKB也不例外,所以本篇只讲CKB与BTC有差异的点。


Block header结构上,单论挖矿相关的字段,CKB与BTC最大的区别是Nonce大小为128bit。


挖矿历史和演进方面,CKB同样经历了CPU → GPU → FPGA → ASIC 等演进阶段,目前都是ASIC矿机。


CKB在发展到ASIC矿机阶段之后,同BTC一样,矿机固件直接内置挖矿协议,只能连接矿池。
Solo mining方面,目前CKB没有现成的解决方案。之前有一个grants项目( Insight - Automated Stratum V2 mining pool for Nervos ),但是已经很久没更新了。


结算模式方面,CKB的矿池基本上都是PPLNS,即矿工需要承担较大的收益波动风险。因为CKB难度调整比较频繁,相比之下收益波动更大。比特币网络每产生2016 个区块(大约两周)调整一下难度,但是CKB 大约每隔4 小时调整一次挖矿难度。


矿池协议方面

CKB节点提供了GBT(Getblocktemplate)的RPC接口,返回完整的candidate block(候选区块),并且允许挖矿软件任意调整区块的内容,给的自由度很大。

矿池协议方面跟BTC一样,现在都是Stratum (V1)协议,但是CKB相比之下要简单很多。因为CKB的Nonce大小为128bit,单单改变Nonce,搜寻空间就足够大,不存在BTC在Getwork时期的问题,也就不需要矿工去调整区块头的其他字段。

比如BTC中extranonce是coinbase交易中的字段,但是在CKB中直接就是Nonce的前缀,更加简单明了。

因此,CKB的矿池协议实际上只是Stratum (V1)的子集,很多方法和字段都不用。是套着Stratum (V1)壳子,但实际运行跟Getwork差不多。


矿机和矿池交互的实际例子

矿机发起auth
{"id":0,"method":"mining.authorize","params":["ckb1qyqznmjpc30dw337h20l9ukkmlrfkhycgtes0p7lll.bob","X"]}
矿池返回
{"id":0,"result":true,"error":null}

矿机subscribe
{"id":0,"method":"mining.subscribe","params":["ckbminer-v1.0.0",null]}
矿池返回
{"id":0,"result":[null,"665da3e8",12],"error":null}

矿池向矿机下发难度设置
{"id":null,"method":"mining.set_target","params":["000010c6f7000000000000000000000000000000000000000000000000000000"]}

矿池向矿机下发job
{"id":null,"method":"mining.notify","params":["a8be81b7","65634bac6f4d59fdc355008824b45e8e0ecdc0879e00dfbbc4989099a5beb674",2156,"d2f7dc7dcffdcc03a129783d12332b0b02d0453604290f41869ff41bf9c95cef",true]}

矿机向矿池提交share
{"id":0,"method":"mining.submit","params":["ckb1qyqznmjpc30dw337h20l9ukkmlrfkhycgtes0p7lll.bob","a8be81b7","000000000000000000967385"]}
矿池给矿机回复,确认share有效
{"id":0,"result":true,"error":null}

Stratum (V2)相关

其他POW链的挖矿和矿池软件都是BTC修改而来的,所以BTC没有迁移到Stratum V2之前,其他的链几乎不可能迁移。

不过CKB有一个跟stratum v2中templateProvider概念类似的机制,节点可以通过notify主动通知矿池有新的候选块。虽然没有templateProvider那么细化,但是相比于pull的方式已经方便很多


预告一下fi5pool项目

我们团队( https://www.fi5box.com/ )专注于发展Nervos生态,涵盖挖矿,Depin硬件、实物销售等多个领域。

挖矿业务原来都是连接大的矿池的,后来想solo mining,搜寻一圈后发现没有现成的解决方案。抱着自用加为社区做贡献的想法,开启了fi5pool项目。

一开始我们只找到开源的btcpool项目,该项目已经废弃很多年了。但是之前的grants项目为其增加了对CKB的支持,只不过支持的是非常老的CKB版本。

我们先尝试了对其进行修复,经过一些修改之后,勉强能跑起来,但是有非常多的报错,稳定性也比较差,如果要完全修复并长期维护还需要非常大的工作量。

然后我们开始静下心来梳理自己的目标。我们并不想做一个完善的商业矿池,需要的工作量很大,而且竞争非常激烈;也不想做一个多币矿池(btcpool支持很多种币),能填补CKB社区在这方面的空白就好。

最终,fi5pool的目标定为简单的ckb solo minning矿池:

  • 仅支持CKB。
  • 仅支持solo mining,没有分账和前端页面。
  • 深入CKB的特性,拓展自定义挖矿策略和MEV(miner extractable value)的获取能力。

这个目标可以减少项目复杂度,并避免与现有的商业化矿池竞争,使项目更加聚焦和易于长期维持。

  • 代码非常精简,易于维护。
  • 单个可行性文件,且没有持久化状态。
  • 占用资源非常少,可以部署在mini主机上。

CKB社区有了简单的solo mining解决方案后,有如下好处:

  • 矿工可以获得全部挖矿奖励:没有第三方抽成。
  • 自主性更强:矿工可以完全控制自己的挖矿策略。
  • 隐私保护:无需公开个人信息,确保高度的隐私安全。
  • 去中心化:有助于提升整个区块链网络的安全性和分散度。

目前fi5pool项目开发已经接近尾声,正在进行测试,后续会开源出来,敬请大家关注我们的github fi5box · GitHub

目前已经开源出一个挖矿统计工具 GitHub - fi5box/ckb-miner-stat: statistics info about ckb miners
可以统计全网的出块,算力,以及各个矿工的信息,比如

$ ckb-miner-stat history -d 20250104
show history info for date: 2025-01-04
shape: (8, 6)
┌───────────────────────────────────────────────────────────────────────────────────────────────────┬───────┬───────────────┬─────────────┬───────────┬────────────────┐
│ Miner                                                                                             ┆ Count ┆ User_Reward   ┆ Total_Count ┆ Percent   ┆ User_Hash_Rate │
│ ---                                                                                               ┆ ---   ┆ ---           ┆ ---         ┆ ---       ┆ ---            │
│ str                                                                                               ┆ u32   ┆ f64           ┆ u32         ┆ f64       ┆ f64            │
╞═══════════════════════════════════════════════════════════════════════════════════════════════════╪═══════╪═══════════════╪═════════════╪═══════════╪════════════════╡
│ ckb1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqv8cuf7vzh62m9gwyv59lzha9nx6ar5d9qqkp5em ┆ 41    ┆ 25961.235496  ┆ 9600        ┆ 0.427083  ┆ 1.9077e12      │
│ ckb1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqt3vn6g67jm7g5czehcmqdcr6jwjz8pdtg59p03h ┆ 125   ┆ 78593.945498  ┆ 9600        ┆ 1.302083  ┆ 5.8163e12      │
│ ckb1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqvzz8cmjw9pqlx48d3s9nr49fhu89jk8rgycece5 ┆ 149   ┆ 93822.130516  ┆ 9600        ┆ 1.552083  ┆ 6.9330e12      │
│ ckb1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq0dn8gg6ag6uvkl0lr0xpyt0n99dsal47sm7mzyj ┆ 801   ┆ 505831.745397 ┆ 9600        ┆ 8.34375   ┆ 3.7271e13      │
│ ckb1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq22xdj8q4jdql98qkdhnqzgrsk4nqyavdcratvu9 ┆ 813   ┆ 514374.496015 ┆ 9600        ┆ 8.46875   ┆ 3.7829e13      │
│ ckb1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq0259kv0x5jez6h0l5qr52k64weapapgyscsnmhn ┆ 1249  ┆ 790547.790185 ┆ 9600        ┆ 13.010417 ┆ 5.8116e13      │
│ ckb1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqvgqh40v2g5ps3rann79tvw9gq6ewrft7gp909qk ┆ 2390  ┆ 1.5094e6      ┆ 9600        ┆ 24.895833 ┆ 1.1121e14      │
│ ckb1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq0tpsqq08mkay9ewrfrdwlcghv62qw704s93hhsj ┆ 4032  ┆ 2.5470e6      ┆ 9600        ┆ 42.0      ┆ 1.8761e14      │
└───────────────────────────────────────────────────────────────────────────────────────────────────┴───────┴───────────────┴─────────────┴───────────┴────────────────┘

这个工具可以和fi5pool配套使用,因为fi5pool没有前端页面,矿工可以通过这个统计工具查看自己的出块,收益,占比和有效算力。

7 Likes

毫无疑问这是正确的方向,恭喜Fi5团队

矿池矿机和自主矿机之间的发展进化关系,可以大概类比于托管钱包和自管钱包之间的发展进化关系,矿池矿机和托管钱包在一定时期为整个区块链生态的生存和发展做出了其不可磨灭的贡献,但同时我们也明白自主矿机和自管钱包的趋势不可阻挡

不管是矿机,钱包,交易所还是最后的终极目标铸币权,我们会找到“共建共享”的真正涵义

自主矿机(特别是对非技术人员的低门槛矿机产品)是对点对点系统的正确解释和推进

4 Likes

这让我非常兴奋。你们不断改进 CKB L1。我再次感到你们是真正的书呆子。中心矿池运营商需要被克服,每个矿工都应该运行自己的矿池。由于这样的发展,从长远来看,我认为 CKB 是坚如磐石的区块链基础墙,很难被撼动。

2 Likes