BTC-挖矿
约 2239 字大约 7 分钟
2021-09-13
相关术语
boycott boycott攻击(分叉攻击的一种)
share almost valid block 共享几乎有效的块
pool manager 矿主
难度调整
相关信息
不断的尝试block header里面的nonce
值,使得整个block header
的hash值小于等于给定的目标域值target:H(block header) <= target
。这个target
越小,挖矿难度越大。挑战挖矿难度就是挑战目标空间在整个输出空间中所占的比例。
比特币采用的哈希算法是SHA-256
(Secure Hash Algorithm - 256 bit),产生的hash值是256位的。所以整个输出空间是2256个可能的取值。
挖矿难度和目标域值成反比的。挖矿难度最小就是1,这时候对应的target
是一个很大一个数。
为什么调整挖矿难度呢?如果系统里的算力越来越强,难度不变的话,这个出块时间会越来越短。 出块时间太短,会有什么问题呢?由于网络传输原因,出块时间太短,容易形成分叉,且成为常态。分叉太多的话,又会导致难以达成共识,危害系统的安全性。因为诚实节点的算力被分散了,可能不用51%就能分叉攻击,可能31%就行。
以太坊前瞻
以太坊出块时间仅为15s,是比特币出块速度的40倍。所有对于这么快的速度,它还有一套对应的共识协议,成为GHOST
。分叉产生的orphan block
就不能简单的丢弃了,也会给一些奖励,叫做uncle reward
。同样的,以太坊的出块时间也是需要保持稳定的,不能无限的减小。
比特币规定,每个2016个区块,调整一次目标域值,大概是每俩个星期时间调整一次。
60分钟∗24小时2016∗10分钟=14天
target
目标域值迭代的方法如下(这里的expected time
就是俩个星期):
target=target∗expected timeactual time
actual time
即time spent mining the last 2016 blokcs
。当然时间代码中,也是有上下限的,最多4倍,也就是8个星期,避免有特殊的情况。 最小也是半个星期,不会再低。
怎么让所有矿工同时都调整目标域值。这个计算target的代码是写在比特币系统内部的。每挖到2016个区块,就会自动调整。当然代码是开源的,如果有恶意的节点就是不调整会有什么问题么?
其实block header
中有个一个nBits
域,这个其实是target的一个编码的版本,block header
中没有直接存储target
域,因为这个域是256位,直接存需要32个字节。而nBits
在block header
中只有4个字节,可以认为是target
的一个压缩编码。如果遇到有恶意的矿工没调整难度,这个时候检查区块合法性就通不过。另外以太坊,调整难度比这个可复杂的多,且每发布一个区块都有可能调整难度。
其实在比特币之前,有很多加密货币,最终都是失败的。比特币的成功不是因为他更实用,从某种意义来说应该是因为它更不实用。之前的加密货币基本都有现实货币背书,而BTC不同,它没有任何合法货币背书,凭空创造。但其实比特币的整体设计还是比较保守的。
历史数据
相关信息
接下来看一些历史数据
算力增长曲线
可以看到16年开始大幅提升,但即使是这段时间,也不是单调递增,有所反复。
挖矿难度曲线
和算力增长基本同步,也符合调整难度的预期,算力提高难度也随之提高,以保持出块时间稳定。如果出现某个加密货币的难度越调越小,说明这个加密货币基本要凉了。
出块时间
可以看出,相对稳定,说明难度调整达到了目的。
全节点
特征
full node:
- 一直在线
- 在本地硬盘上维护完整的区块链信息
- 在内存里维护UTXO集合,以便快速检验交易的正确性
- 监听比特币网络上的交易信息,验证每个交易的合法性
- 决定哪些交易会被打包到区块里
- 监听别的矿工挖出来的区块,验证其合法性
- 挖矿
- 决定沿着哪条链挖下去?
- 当出现等长的分叉时候,选择哪一个分叉?
轻节点
特征
light node or SPV (Simplified Payment Verification) :
- 不是一直在线
- 不用保存整个区块链,只要保存每个区块的头部
- 不用保存全不交易,只保存与自己相关的交易
- 无法检验大多数交易的合法性,只能检验与自己相关的交易的合法性
- 无法检测网上发布到区块的正确性
- 可以验证挖矿的难度
- 只能检测哪个是最长链,不知道哪个是最长合法链。
设备
cpu 通用
最早的时候都是用cpu,家里的笔记本电脑都可以。但是专门买一个计算机来挖矿是很不划算的,大部分内存都是闲置的。cpu大部分也是闲置的,因为挖矿的计算哈希的操作只用到通用cpu的很少一部分指令。硬盘什么的也都是闲置的。
gpu 通用并行
所有转入第二代,gpu主要用于大规模的并行计算。但是还是有些浪费,用来挖矿,它里面很多部件仍然处于闲置状态,比如用于浮点数计算的部件,这些对于深度学习是很重要的,深度学习计算梯度是要用到浮点数计算的。但是比特币的挖矿只用到了整数操作。所以gpu对于cpu效率有很大提高,但依然有不小的浪费。
ASIC 专用
现在一般都用ASIC
芯片(Application Specific Integrated Circuit),专门为挖矿设计的芯片。上没没有多余的电路逻辑, 整个芯片就为了计算哈希而已。也就是除了挖矿之外别的什么都干不了。而且为某一种加密货币设计的芯片只能挖这一种,挖不了其他的加密货币。除非俩个加密货币用同一个mining puzzle。有些新发的币,为了吸引用户,可能专门采用比特币的mining puzzle,这种情况称为merge mining。ASIC芯片研发周期是很长的,比如比特币的可能需要1年。定制的ASIC芯片也可能用了几个月就过时了,又要买新的芯片,相当于是军备竞赛。所以从中盈利的可能是芯片生产厂商。
矿池
就那种大机房。一个矿主(pool manager
)驱动很多矿工。矿工只负责计算,全节点负责组织、验证已经发布区块。如果矿工都是一个结构还好,不涉及利益分配。如果是不同机构,不同个人,通过一定的协议加入一个矿池。那么利益怎么分配。平均分配肯定不合适,干多干少一个样。所以有一个工作量证明。根据工作量来分配。矿工单个利益不稳定,所以有个机制叫share almost valid block
,找到一个接近的,交给矿主,作为矿工的工作量证明。所以矿主就记得每个矿工提交的share数目进行利益分配。
矿池分布
算力如果很强,除了之前说过的各种攻击,还会存在boycott
攻击,本质还是forking attack
,只不过是领出块中不包含不想要的交易,与其他分叉攻击的区别是,Boycott
攻击不需要等待交易获得多个确认区块。攻击者一旦发现目标交易,就会立即进行分叉,因为目的是让其他节点沿着攻击者创建的链继续挖矿,而不是让受害者交易的链成为最长链。
总结
矿池的出现有利有弊。对于单个矿工来说,从原来很难获得一次大奖,变成通过share almost valid block
来不断的获取小奖,收入变得稳定。但如果矿池超过51%算力,使得51%攻击更加容易,而且如果发动攻击,矿主下面的矿工还不知情,因为只是负责解矿主分配的区间的puzzle。