转发原文标题《白话区块链三:揭开挖矿神秘的面纱——挖矿是什么?为什么要挖矿?谁是我们买不起显卡的罪魁祸首?》
大家关于区块链最耳熟能详的概念可能就是挖矿,可能很多同学听过很多次挖矿,但是不太清楚挖矿到底是什么?那我们这一节插个队,先介绍一下“挖矿”。
简单回顾一下白话区块链一:比特币(区块链革命的先锋与主权货币的挑战者)简介中的内容,中本聪设计的比特币货币系统,把记账奖励和货币发行关联起来,让记账过程自动发行货币,既解决了货币发行问题又提高了记账人参与记账积极性。
现实中的挖矿是矿工在矿山用各种工具凿石头,把藏在石头中的稀有金属开采出来。矿工通过体力劳动挖掘开采了隐藏于大自然的稀有金属的价值。
对于记账有奖励的区块链项目(通常是数字货币项目),网络结点耗费计算资源求解结果,求解出结果后打包区块获得奖励发行货币的这个过程,类似黄金等贵金属从矿石中开采出来产生新货币的过程,所以常被称为“挖矿”,这里的记账人就是矿工,他们通过硬件资源和电力资源竞争打包区块,产生了新货币。
挖矿主要有两大作用:一是验证最近产生的若干笔交易并把交易打包成区块链接到区块链上,二是通过给记账人发放奖励的方式,发行新的货币。下面是细分后的挖矿作用:
每成功打包一个区块上链,矿工可以获得高额奖励,所以很多人愿意参与挖矿。奖励来自 2 部分:
随着时间的推移,区块奖励会越来越少(比如比特币的减半机制,等 2100 万个比特币都被挖完后,大约到 2141年,自动奖励这个收入就没了),交易费用将成为矿工主要收入来源。
比特币以每 10 分钟产生一个区块,最开始每产生一个区块发行 50 个比特币,每 4 年经历一次减半,距今共经历了 4 次减半,现在每个区块产生会发行 3.125 枚比特币,上一次减半是在 2024 年的 4 月,下一次是预计在2028 年,大约需要等到 2141 年左右,比特币会达到其发行量的上限)。
交易费除了跟供需关系有关,还跟交易大小有关,交易费跟交易所占空间大小成正比。
对于矿工来说,参与挖矿很简单,下载一个数字货币钱包客户端,在钱包客户端中点击挖矿按钮,就可以开始挖矿。
对于有区块奖励的区块链项目来说,基本都会把挖矿算法编写成脚本集成到钱包里,矿工只需要点击按钮启动脚本执行即可。
挖矿算法是确定的,矿工只需要持续运行算法,就能得出结果,只是由于算力资源,可能不同的人计算出来需要时间不一样。一旦某个节点计算出了目标值,那么也意味着其他矿工这段时间的工作量都白费了,投入了物理资源结果收益为负。旷工为了让自己不至于白忙活,往往会把自己的算力资源加入矿池结点(这个节点跟普通的节点一样,只是算力资源特别多),矿池挖出矿后,根据算力资源贡献,给参与旷工分配收益,值得一提的是区块链上最终记录的打包区块的旷工其实是矿池结点,其他矿工拿到的是矿池节点分配的收益,不是货币系统的直接奖励。
比特大陆公司生产了专门用于高效挖矿的芯片,巩固了矿池的地位,加深了记账权的中心化程度。
不同区块链项目的挖矿难题可能不太一样,挖矿难度也不太一样,下面以比特币为例。比特币所采用的挖矿算法是工作量证明(Proof of Work, PoW)算法,算法的字面意思是想要得到结果,需要付出一定的工作量来证明。
挖矿难题并不是传统意义上的数学题目,而是寻找一个随机数 nonce,使得这个随机数拼接上区块中的数据后再经过一个哈希函数运算,产生的哈希值满足一个特定的条件。通常,这个条件是哈希值必须小于一个特定的目标值(也有说法是目标值的前 n 个比特位都是0,其实是同一个意思)。hash(nonce + block_data) <= target。
比特币采用的哈希函数是SHA-256,它可以将任意长度的输入转换成一个256比特位的固定长度输出(相当于64 个16进制数,或者32 字节),输出是近乎随机的(但是可以保证相同的输入一定得到相同的输出)。挖矿就是通过不断变换随机数 nonce,对新区块的区块头数据,进行SHA-256计算,直到找到符合条件的目标哈希值。
000000000000000000000000000000111111010000011011000100100110111011000110100010011011000110100010110110101010011101011010100100011011010001111101001111110101001101111101011110011100011110011110000111000100110000001011011010001110011100110010111010010010010001101010110010110
00000003f41b126ec689b1a2da9d5d46d13d0fd1bece47983d59c5d32eb4ac90
简单理解一下,会发现,如果要求目标值的前 n 个比特位都是0,得到符合要求的数据的概率是 1/2n,n 越大,0 的比特位越多,对应的概率越低,n每加一,难度提升一倍。n=30,目标结果被计算出来的概率是10亿分之一,n 最大可以达到 256。
n=10,目标结果被计算出来的概率:千分之一
n=20,目标结果被计算出来的概率:百万分之一
n=30,目标结果被计算出来的概率:十亿分之一
n=40,目标结果被计算出来的概率:万亿分之一
n=50,目标结果被计算出来的概率:千万亿分之一
…
n=256,以人类目前的算力,不考虑量子计算机的情况下,地球爆炸之前应该是算不出来了
由于SHA-256的输出特性,唯一的方法是暴力穷举,即不断尝试,直到满足条件。这就是为什么需要高性能计算设备参与挖矿的原因。
由于你不知道随机数加上区块数据后,产生的hash值是多少,比如设置hash值目标值是10000,你不知道哪个随机数数叠加上区块数据,经过SHA-256算法计算出来的hash值会小于10000,也不知道按照自己的枚举思路,得到 hash 值将会更大还是更小,hash结果和趋势无法预测,完全随机,只能不断枚举,多个值符合条件则取hash值小的,因为 hash值越小,其产生的概率越低,难度越大。
而验证产生的 hash 值是否满足要求非常容易,只需要做一次比较运算即可,但是想要找到经过哈希运算后的 hash 值小于等于目标值,却只能通过暴力枚举来实现。这种验证计算结果容易但是获得计算结果困难的算法我们一般称之为称之为计算不对称特性。
代码案例来自:第12讲 | 深入区块链技术(四):PoW共识-深入浅出区块链-极客时间[1]
假设区块头部的数据内容为“geekbang”,从 nonce 值 10000 开始自增搜索,直到找到符合条件的 nonce 值。
import hashlib
def main():
base_string = "geekbang"
nonce = 10000
count = 0
while True:
target_string = base_string + str(nonce)
pow_hash = hashlib.sha256(target_string).hexdigest()
count = count + 1
if pow_hash.startswith("0000"): # 前4个16进制位是0,相当于前16个比特位是0
print pow_hash
print "nonce: %s scan times: %s" % (nonce, count)
break
nonce = nonce + 1
if name == ‘main‘:
main()
当要求哈希结果前 4 位(每位是一个16进制数)为 0 时,计算次数为 5.8 万次;要求前 5 位为 0 时,计算次数增加到 123 万次;当要求前7位为0时,计算次数达到了 1.6 亿次。可以看出,每增加一个哈希结果前缀 0的个数,计算次数是原来的很多倍(约为 16 倍)。
0000250248f805c558bc28864a6bb6bf0c244d836a6b1a0c5078987aa219a404
nonce: 58828 scan times: 58829s
0000067fc247325064f685c32f8a079584b19106c5228b533f10c775638d454c
nonce: 1231205 scan times: 1231206s
00000003f41b126ec689b1a2da9e7d46d13d0fd1bece47983d53c5d32eb4ac90
nonce: 165744821 scan times: 165734822s
省流:比特币系统通过调整hash值前 n 位 0 的个数来调整难度。
难度调整机制是比特币系统的一部分,旨在确保区块生成的时间大约每 10 分钟一次。比特币系统会根据过去 2016 个区块的生成时间来调整挖矿的难度值,如果这些区块生成的时间小于两周,通过增加 0 的个数(相当于调小目标值) 来上调难度;相反,如果生成时间超过两周,则会适当减少 0 的个数(相当于调大目标值) 让难度自动降低。这个机制确保了比特币网络整体的哈希率增长或减少时,区块生成时间仍然保持大约在10分钟。
这种难度调整机制是由比特币的创造者中本聪在最初的设计中就已经规划好的,难度值会根据全网的总计算能力自动调整,以此来维持挖矿的平均速度及其开销,避免货币发行太快扰乱市场经济。
不同区块链项目的挖矿算法可能不一样,这里以最有名的比特币挖矿算法为例。
比特币底层挖矿算法的执行过程如下:
区块头各字段大小如下:
默克尔树结构如下:
争议主要讨论的是比特币和从比特币分叉出去的数字货币的挖矿算法,他们一般都采用 POW 工作量证明算法,记账人需要调度大量计算资源来求解大家认可的计算结果,同一时间很多人都在计算,但是只有最先求解出来的能获得奖励,其他人投入的电力资源和计算资源都浪费了,没有产生新的价值。
资源浪费有2个优化方向,一个是切换不那么耗费资源的挖矿算法,另一个是利用闲置电力的资源来进行挖矿。
目前像以太坊已经完成了从 POW 工作量证明算法向 POS 权益证明算法的切换,切换后大大降低了资源的浪费。
挖矿结点已经在尝试去风能发电的地区利用无法使用的电力来挖矿。另一个重要的进展是闲置天然气的使用。最后,有机构正在尝试回收利用比特币挖矿产生的余热。
回顾本文“为什么需要挖矿”小节,挖矿的直接意义是支撑了相关数字货币的发行,挖矿奖励让更多人愿意参与到数字货币的维护中,让数字货币变得更加稳定,同时挖矿算法维护了数字货币的交易一致性,让货币系统更加健壮,降低内部和外部攻击的影响。
挖矿的间接意义是数字货币带来的,数字货币构建的全球性去信任化货币系统,在不需要中心化机构背书的前提下,让人与人之间可以安全交易,继而避免了中心化机构带来的种种弊端,数字货币的全球性也使得跨境交易变得高效和低成本。
这里可能认为挖矿收益仅有系统奖励一条路径,从这单一路径来看,确实随着时间的流逝,收益在不断降低,但是其实挖矿收益还有一个很大的收入来源是交易手续费。并且随着人们对数字货币认可度的提升,基于数字货币进行交易的市场份额会越来越大,继而导致交易被打包进区块变更愈发激烈,会有很多人愿意支付手续费来让自己的交易优先被打包,所以矿工能获得的手续费会逐渐变高,因此交易打包能持续进行下去。
会有交易手续费来补偿成本。
如果多人同时挖矿成功向全网广播各自的新区块,某些节点收到2个同样高度的合法区块后,会尝试把2个区块都暂存下来,等待下个高度的区块产生,此时区块链发生暂时分叉,当节点收到下个高度的区块后,选择维护更长的链作为主链,因为区块链越长,付出的工作量越多,抛弃刚才暂存的孤块。
对于多个矿工来说,所属更长区块链的区块矿工获得收益。
如果部分节点抛弃孤块A选择链1为主链,部分节点抛弃孤块B 选择链2为主链,那么这 2 部分节点会暂时维护各自的主链,区块链持续分叉,直到下个区块产生,所有节点自动抛弃短链。
对于超过 50% 的算力节点记假账,我们一般称之为 51% 攻击。
首先拥有 51% 算力的超级节点基本不存在,假设存在,超级节点也无法成功在区块链中附加双花交易的非法区块,因为网络的其他结点收到区块后会校验区块中每笔交易的合法性,不合法则不认可该区块,即使超级算力节点利用自己的算力优势在这个非法节点上附加了合法节点,其他结点会主动抛弃该非法链。
超级节点发起的攻击,其实打包的区块都是合法的,只是他可能利用其优势对网络或者其他参与者进行某种形式的操纵或干扰,比如发起阻止交易确认、自挖矿攻击、时间戳攻击、空块攻击等攻击行为,破坏网络的公平性和去中心化特性。(后面会有文章介绍这些攻击行为)
所以超级节点是无法通过作弊获得收益,但是可以通过通过算力影响网络和操纵网络,区块系统在不断迭代升级,超级节点更难发起这些攻击。
故意捣乱做假账的话,区块分发给邻近节点时,邻近节点会发现区块中有不合法的交易,就不会继续扩散分发了。
其次,比特币网络中的共识机制是基于最长链原则的。所有参与网络的节点都尝试扩展最长的合法链。如果有人试图篡改历史记录(比如删除某笔交易),他们需要修改被篡改区块链接的所有区块,并且区块长度需要大于当前主链长度。这需要巨大的计算资源,实际上是不可能实现的。
每个矿工无法在短时间内找到多个有效的值,所以不可能同时分发不同的合法区块,分发非法的区块会被临近结点丢弃。
在区块链网络中,所有传播的但尚未被打包到区块中的交易都会暂时存储在网络节点的内存池中,这个内存池通常被称为交易池(mempool)。矿工会监视自己内存中的交易池,从中挑选交易来构造新的区块。
交易选择策略:矿工可以根据自己的策略从交易池中选择交易。一般会优先选择手续费高的交易,但一些矿工可能会考虑其他因素,如交易的年龄(即在交易池中停留的时间)。
除去用户外,比特币系统有三个参与方:矿工、开发人员、节点运营商。矿工通过挖矿获得奖励和交易费用。开发人员和节点运营商不从比特币系统中直接获得收入,大部分都是出于理想来维护系统,通过其他方式获得收入,是否参与挖矿取决于他们自己。他们也能获得一些社会赞助和捐赠。
因为大量矿工购买显卡用于挖矿,导致显卡供大于求,所以涨价。
矿卡指的是曾经用于挖矿的显卡,这些显卡因为经过高强度的计算,也就是经过高强度的充放电,性能有所下降,所以大部分人不愿意买矿卡。
需要全量冗余存储,因为需要校验一个代币是否曾经被花费过,以及保证账本的安全性。对于非常早产生的区块,只需要存储区块头就行,不用存储区块内容。
理论上是的,但是肯定会有用户愿意支付手续费的。所以肯定能继续运营下去。
另外社区还可以发起提案修改共识,调整比特币总量上限,从而有新币产生。
比特币的比特币数量上限是 2100w 个,不代表区块高度上限是 2100w,区块高度是没有上限的。只要有人愿意挖矿和打包区块,区块高度就会增加。
在比特币区块链中,支付给矿工的奖励是通过一个特殊的交易实现的,称为“coinbase交易”或“区块奖励”。这个交易有几个独特之处:
矿工的收益是每个区块被挖出时计算一次,交易产生时不会计算矿工收益。
当一个矿工或矿工集群(矿池)成功挖出一个区块,并通过网络的共识机制得到确认后,他们将获得该区块的区块奖励和所有交易的累积费用。系统会用 coinbase 特殊交易的形式来把交易费和奖励转换成 UTXO 发放到矿工账户。
区块之间是顺序产生的,打包完上个区块,才开始打包下个区块。
打包一般会多条交易,而不是每笔交易打包一次。
会有未满的区块,而且大部分区块都是没有被100%利用。取决于矿工计算的速度,什么时候计算出来了符合要求的 hash 值,就立刻打包,不管区块是否被完全利用。
不是,只要有矿工成功计算出了结果,就可以打包区块,只不过这个区块是一个空块,也会有系统奖励。
如果作弊需要对抗其他所有人的算力,由于最“长”链原则,其他多数诚实会挖比你快。如果两个节点同时广播了不同的下一个区块,有些节点可能先收到其中一个而其他节点先收到另一个。这种情况,节点基于他们收到的第一个区块工作,但是也保存另一个分支以防它变为更长的链。当下一个工作量证明被找到后僵局就会被打破,从而其中一个分支变得更长;在另一个分支上工作的节点将切换到更长的链上来。
不会出现双花交易都被确认的情况,只会有一方被打包确认有效,如果两个交易存在于不同区块,那么先被打包的交易是有效的(后被打包的区块不会被认可),如果两个交易存在于同一个将要被打包的区块,那么打包时会发现同一个代币被花费了2次,发现同一个代币作为2笔交易的输入,此时会优先保留交易费用高的交易,交易费用相同则保留先产生的交易,抛弃另一笔交易。
为了使自己的交易被更快地确认,用户会额外支付交易费用来激励矿工优先处理自己的交易。比特币的规则是:
手续费=付款金额-收款方收款金额-付款方找零金额,付款方通过设置付款金额和找零金额来控制手续费。
矿池会根据算力贡献,分配自己的收益,分配的方式就是给其他结点转账。
自私挖矿(Selfish Mining)是指超级节点找到新区块后不立即广播,而是继续在自己的一条链上挖矿(隐瞒链)。当找到多个区块后,再一起广播,使得其他矿工的工作无效。
这会浪费全网的算力,一部分矿工的工作会变得无效,可能会导致算力和区块奖励向有优势的超级节点倾斜。
比特币网络可以通过改进广播协议来减少自私挖矿的影响。
比特币矿工节点对交易的校验主要发生在两个时间点:交易被广播到节点时和打包区块时。两个时间点的校验内容基本相同,但在打包区块时可能会有更严格或额外的检查。具体如下:
当一个交易被广播到节点时,节点会进行以下校验,以决定是否将交易添加到内存池(mempool):
当矿工节点收到新区块时,会校验区块的每笔交易和区块本身的合法性,以确保区块的合法性和有效性:
[1] 第12讲 | 深入区块链技术(四):PoW共识-深入浅出区块链-极客时间: https://time.geekbang.org/column/article/5963
转发原文标题《白话区块链三:揭开挖矿神秘的面纱——挖矿是什么?为什么要挖矿?谁是我们买不起显卡的罪魁祸首?》
大家关于区块链最耳熟能详的概念可能就是挖矿,可能很多同学听过很多次挖矿,但是不太清楚挖矿到底是什么?那我们这一节插个队,先介绍一下“挖矿”。
简单回顾一下白话区块链一:比特币(区块链革命的先锋与主权货币的挑战者)简介中的内容,中本聪设计的比特币货币系统,把记账奖励和货币发行关联起来,让记账过程自动发行货币,既解决了货币发行问题又提高了记账人参与记账积极性。
现实中的挖矿是矿工在矿山用各种工具凿石头,把藏在石头中的稀有金属开采出来。矿工通过体力劳动挖掘开采了隐藏于大自然的稀有金属的价值。
对于记账有奖励的区块链项目(通常是数字货币项目),网络结点耗费计算资源求解结果,求解出结果后打包区块获得奖励发行货币的这个过程,类似黄金等贵金属从矿石中开采出来产生新货币的过程,所以常被称为“挖矿”,这里的记账人就是矿工,他们通过硬件资源和电力资源竞争打包区块,产生了新货币。
挖矿主要有两大作用:一是验证最近产生的若干笔交易并把交易打包成区块链接到区块链上,二是通过给记账人发放奖励的方式,发行新的货币。下面是细分后的挖矿作用:
每成功打包一个区块上链,矿工可以获得高额奖励,所以很多人愿意参与挖矿。奖励来自 2 部分:
随着时间的推移,区块奖励会越来越少(比如比特币的减半机制,等 2100 万个比特币都被挖完后,大约到 2141年,自动奖励这个收入就没了),交易费用将成为矿工主要收入来源。
比特币以每 10 分钟产生一个区块,最开始每产生一个区块发行 50 个比特币,每 4 年经历一次减半,距今共经历了 4 次减半,现在每个区块产生会发行 3.125 枚比特币,上一次减半是在 2024 年的 4 月,下一次是预计在2028 年,大约需要等到 2141 年左右,比特币会达到其发行量的上限)。
交易费除了跟供需关系有关,还跟交易大小有关,交易费跟交易所占空间大小成正比。
对于矿工来说,参与挖矿很简单,下载一个数字货币钱包客户端,在钱包客户端中点击挖矿按钮,就可以开始挖矿。
对于有区块奖励的区块链项目来说,基本都会把挖矿算法编写成脚本集成到钱包里,矿工只需要点击按钮启动脚本执行即可。
挖矿算法是确定的,矿工只需要持续运行算法,就能得出结果,只是由于算力资源,可能不同的人计算出来需要时间不一样。一旦某个节点计算出了目标值,那么也意味着其他矿工这段时间的工作量都白费了,投入了物理资源结果收益为负。旷工为了让自己不至于白忙活,往往会把自己的算力资源加入矿池结点(这个节点跟普通的节点一样,只是算力资源特别多),矿池挖出矿后,根据算力资源贡献,给参与旷工分配收益,值得一提的是区块链上最终记录的打包区块的旷工其实是矿池结点,其他矿工拿到的是矿池节点分配的收益,不是货币系统的直接奖励。
比特大陆公司生产了专门用于高效挖矿的芯片,巩固了矿池的地位,加深了记账权的中心化程度。
不同区块链项目的挖矿难题可能不太一样,挖矿难度也不太一样,下面以比特币为例。比特币所采用的挖矿算法是工作量证明(Proof of Work, PoW)算法,算法的字面意思是想要得到结果,需要付出一定的工作量来证明。
挖矿难题并不是传统意义上的数学题目,而是寻找一个随机数 nonce,使得这个随机数拼接上区块中的数据后再经过一个哈希函数运算,产生的哈希值满足一个特定的条件。通常,这个条件是哈希值必须小于一个特定的目标值(也有说法是目标值的前 n 个比特位都是0,其实是同一个意思)。hash(nonce + block_data) <= target。
比特币采用的哈希函数是SHA-256,它可以将任意长度的输入转换成一个256比特位的固定长度输出(相当于64 个16进制数,或者32 字节),输出是近乎随机的(但是可以保证相同的输入一定得到相同的输出)。挖矿就是通过不断变换随机数 nonce,对新区块的区块头数据,进行SHA-256计算,直到找到符合条件的目标哈希值。
000000000000000000000000000000111111010000011011000100100110111011000110100010011011000110100010110110101010011101011010100100011011010001111101001111110101001101111101011110011100011110011110000111000100110000001011011010001110011100110010111010010010010001101010110010110
00000003f41b126ec689b1a2da9d5d46d13d0fd1bece47983d59c5d32eb4ac90
简单理解一下,会发现,如果要求目标值的前 n 个比特位都是0,得到符合要求的数据的概率是 1/2n,n 越大,0 的比特位越多,对应的概率越低,n每加一,难度提升一倍。n=30,目标结果被计算出来的概率是10亿分之一,n 最大可以达到 256。
n=10,目标结果被计算出来的概率:千分之一
n=20,目标结果被计算出来的概率:百万分之一
n=30,目标结果被计算出来的概率:十亿分之一
n=40,目标结果被计算出来的概率:万亿分之一
n=50,目标结果被计算出来的概率:千万亿分之一
…
n=256,以人类目前的算力,不考虑量子计算机的情况下,地球爆炸之前应该是算不出来了
由于SHA-256的输出特性,唯一的方法是暴力穷举,即不断尝试,直到满足条件。这就是为什么需要高性能计算设备参与挖矿的原因。
由于你不知道随机数加上区块数据后,产生的hash值是多少,比如设置hash值目标值是10000,你不知道哪个随机数数叠加上区块数据,经过SHA-256算法计算出来的hash值会小于10000,也不知道按照自己的枚举思路,得到 hash 值将会更大还是更小,hash结果和趋势无法预测,完全随机,只能不断枚举,多个值符合条件则取hash值小的,因为 hash值越小,其产生的概率越低,难度越大。
而验证产生的 hash 值是否满足要求非常容易,只需要做一次比较运算即可,但是想要找到经过哈希运算后的 hash 值小于等于目标值,却只能通过暴力枚举来实现。这种验证计算结果容易但是获得计算结果困难的算法我们一般称之为称之为计算不对称特性。
代码案例来自:第12讲 | 深入区块链技术(四):PoW共识-深入浅出区块链-极客时间[1]
假设区块头部的数据内容为“geekbang”,从 nonce 值 10000 开始自增搜索,直到找到符合条件的 nonce 值。
import hashlib
def main():
base_string = "geekbang"
nonce = 10000
count = 0
while True:
target_string = base_string + str(nonce)
pow_hash = hashlib.sha256(target_string).hexdigest()
count = count + 1
if pow_hash.startswith("0000"): # 前4个16进制位是0,相当于前16个比特位是0
print pow_hash
print "nonce: %s scan times: %s" % (nonce, count)
break
nonce = nonce + 1
if name == ‘main‘:
main()
当要求哈希结果前 4 位(每位是一个16进制数)为 0 时,计算次数为 5.8 万次;要求前 5 位为 0 时,计算次数增加到 123 万次;当要求前7位为0时,计算次数达到了 1.6 亿次。可以看出,每增加一个哈希结果前缀 0的个数,计算次数是原来的很多倍(约为 16 倍)。
0000250248f805c558bc28864a6bb6bf0c244d836a6b1a0c5078987aa219a404
nonce: 58828 scan times: 58829s
0000067fc247325064f685c32f8a079584b19106c5228b533f10c775638d454c
nonce: 1231205 scan times: 1231206s
00000003f41b126ec689b1a2da9e7d46d13d0fd1bece47983d53c5d32eb4ac90
nonce: 165744821 scan times: 165734822s
省流:比特币系统通过调整hash值前 n 位 0 的个数来调整难度。
难度调整机制是比特币系统的一部分,旨在确保区块生成的时间大约每 10 分钟一次。比特币系统会根据过去 2016 个区块的生成时间来调整挖矿的难度值,如果这些区块生成的时间小于两周,通过增加 0 的个数(相当于调小目标值) 来上调难度;相反,如果生成时间超过两周,则会适当减少 0 的个数(相当于调大目标值) 让难度自动降低。这个机制确保了比特币网络整体的哈希率增长或减少时,区块生成时间仍然保持大约在10分钟。
这种难度调整机制是由比特币的创造者中本聪在最初的设计中就已经规划好的,难度值会根据全网的总计算能力自动调整,以此来维持挖矿的平均速度及其开销,避免货币发行太快扰乱市场经济。
不同区块链项目的挖矿算法可能不一样,这里以最有名的比特币挖矿算法为例。
比特币底层挖矿算法的执行过程如下:
区块头各字段大小如下:
默克尔树结构如下:
争议主要讨论的是比特币和从比特币分叉出去的数字货币的挖矿算法,他们一般都采用 POW 工作量证明算法,记账人需要调度大量计算资源来求解大家认可的计算结果,同一时间很多人都在计算,但是只有最先求解出来的能获得奖励,其他人投入的电力资源和计算资源都浪费了,没有产生新的价值。
资源浪费有2个优化方向,一个是切换不那么耗费资源的挖矿算法,另一个是利用闲置电力的资源来进行挖矿。
目前像以太坊已经完成了从 POW 工作量证明算法向 POS 权益证明算法的切换,切换后大大降低了资源的浪费。
挖矿结点已经在尝试去风能发电的地区利用无法使用的电力来挖矿。另一个重要的进展是闲置天然气的使用。最后,有机构正在尝试回收利用比特币挖矿产生的余热。
回顾本文“为什么需要挖矿”小节,挖矿的直接意义是支撑了相关数字货币的发行,挖矿奖励让更多人愿意参与到数字货币的维护中,让数字货币变得更加稳定,同时挖矿算法维护了数字货币的交易一致性,让货币系统更加健壮,降低内部和外部攻击的影响。
挖矿的间接意义是数字货币带来的,数字货币构建的全球性去信任化货币系统,在不需要中心化机构背书的前提下,让人与人之间可以安全交易,继而避免了中心化机构带来的种种弊端,数字货币的全球性也使得跨境交易变得高效和低成本。
这里可能认为挖矿收益仅有系统奖励一条路径,从这单一路径来看,确实随着时间的流逝,收益在不断降低,但是其实挖矿收益还有一个很大的收入来源是交易手续费。并且随着人们对数字货币认可度的提升,基于数字货币进行交易的市场份额会越来越大,继而导致交易被打包进区块变更愈发激烈,会有很多人愿意支付手续费来让自己的交易优先被打包,所以矿工能获得的手续费会逐渐变高,因此交易打包能持续进行下去。
会有交易手续费来补偿成本。
如果多人同时挖矿成功向全网广播各自的新区块,某些节点收到2个同样高度的合法区块后,会尝试把2个区块都暂存下来,等待下个高度的区块产生,此时区块链发生暂时分叉,当节点收到下个高度的区块后,选择维护更长的链作为主链,因为区块链越长,付出的工作量越多,抛弃刚才暂存的孤块。
对于多个矿工来说,所属更长区块链的区块矿工获得收益。
如果部分节点抛弃孤块A选择链1为主链,部分节点抛弃孤块B 选择链2为主链,那么这 2 部分节点会暂时维护各自的主链,区块链持续分叉,直到下个区块产生,所有节点自动抛弃短链。
对于超过 50% 的算力节点记假账,我们一般称之为 51% 攻击。
首先拥有 51% 算力的超级节点基本不存在,假设存在,超级节点也无法成功在区块链中附加双花交易的非法区块,因为网络的其他结点收到区块后会校验区块中每笔交易的合法性,不合法则不认可该区块,即使超级算力节点利用自己的算力优势在这个非法节点上附加了合法节点,其他结点会主动抛弃该非法链。
超级节点发起的攻击,其实打包的区块都是合法的,只是他可能利用其优势对网络或者其他参与者进行某种形式的操纵或干扰,比如发起阻止交易确认、自挖矿攻击、时间戳攻击、空块攻击等攻击行为,破坏网络的公平性和去中心化特性。(后面会有文章介绍这些攻击行为)
所以超级节点是无法通过作弊获得收益,但是可以通过通过算力影响网络和操纵网络,区块系统在不断迭代升级,超级节点更难发起这些攻击。
故意捣乱做假账的话,区块分发给邻近节点时,邻近节点会发现区块中有不合法的交易,就不会继续扩散分发了。
其次,比特币网络中的共识机制是基于最长链原则的。所有参与网络的节点都尝试扩展最长的合法链。如果有人试图篡改历史记录(比如删除某笔交易),他们需要修改被篡改区块链接的所有区块,并且区块长度需要大于当前主链长度。这需要巨大的计算资源,实际上是不可能实现的。
每个矿工无法在短时间内找到多个有效的值,所以不可能同时分发不同的合法区块,分发非法的区块会被临近结点丢弃。
在区块链网络中,所有传播的但尚未被打包到区块中的交易都会暂时存储在网络节点的内存池中,这个内存池通常被称为交易池(mempool)。矿工会监视自己内存中的交易池,从中挑选交易来构造新的区块。
交易选择策略:矿工可以根据自己的策略从交易池中选择交易。一般会优先选择手续费高的交易,但一些矿工可能会考虑其他因素,如交易的年龄(即在交易池中停留的时间)。
除去用户外,比特币系统有三个参与方:矿工、开发人员、节点运营商。矿工通过挖矿获得奖励和交易费用。开发人员和节点运营商不从比特币系统中直接获得收入,大部分都是出于理想来维护系统,通过其他方式获得收入,是否参与挖矿取决于他们自己。他们也能获得一些社会赞助和捐赠。
因为大量矿工购买显卡用于挖矿,导致显卡供大于求,所以涨价。
矿卡指的是曾经用于挖矿的显卡,这些显卡因为经过高强度的计算,也就是经过高强度的充放电,性能有所下降,所以大部分人不愿意买矿卡。
需要全量冗余存储,因为需要校验一个代币是否曾经被花费过,以及保证账本的安全性。对于非常早产生的区块,只需要存储区块头就行,不用存储区块内容。
理论上是的,但是肯定会有用户愿意支付手续费的。所以肯定能继续运营下去。
另外社区还可以发起提案修改共识,调整比特币总量上限,从而有新币产生。
比特币的比特币数量上限是 2100w 个,不代表区块高度上限是 2100w,区块高度是没有上限的。只要有人愿意挖矿和打包区块,区块高度就会增加。
在比特币区块链中,支付给矿工的奖励是通过一个特殊的交易实现的,称为“coinbase交易”或“区块奖励”。这个交易有几个独特之处:
矿工的收益是每个区块被挖出时计算一次,交易产生时不会计算矿工收益。
当一个矿工或矿工集群(矿池)成功挖出一个区块,并通过网络的共识机制得到确认后,他们将获得该区块的区块奖励和所有交易的累积费用。系统会用 coinbase 特殊交易的形式来把交易费和奖励转换成 UTXO 发放到矿工账户。
区块之间是顺序产生的,打包完上个区块,才开始打包下个区块。
打包一般会多条交易,而不是每笔交易打包一次。
会有未满的区块,而且大部分区块都是没有被100%利用。取决于矿工计算的速度,什么时候计算出来了符合要求的 hash 值,就立刻打包,不管区块是否被完全利用。
不是,只要有矿工成功计算出了结果,就可以打包区块,只不过这个区块是一个空块,也会有系统奖励。
如果作弊需要对抗其他所有人的算力,由于最“长”链原则,其他多数诚实会挖比你快。如果两个节点同时广播了不同的下一个区块,有些节点可能先收到其中一个而其他节点先收到另一个。这种情况,节点基于他们收到的第一个区块工作,但是也保存另一个分支以防它变为更长的链。当下一个工作量证明被找到后僵局就会被打破,从而其中一个分支变得更长;在另一个分支上工作的节点将切换到更长的链上来。
不会出现双花交易都被确认的情况,只会有一方被打包确认有效,如果两个交易存在于不同区块,那么先被打包的交易是有效的(后被打包的区块不会被认可),如果两个交易存在于同一个将要被打包的区块,那么打包时会发现同一个代币被花费了2次,发现同一个代币作为2笔交易的输入,此时会优先保留交易费用高的交易,交易费用相同则保留先产生的交易,抛弃另一笔交易。
为了使自己的交易被更快地确认,用户会额外支付交易费用来激励矿工优先处理自己的交易。比特币的规则是:
手续费=付款金额-收款方收款金额-付款方找零金额,付款方通过设置付款金额和找零金额来控制手续费。
矿池会根据算力贡献,分配自己的收益,分配的方式就是给其他结点转账。
自私挖矿(Selfish Mining)是指超级节点找到新区块后不立即广播,而是继续在自己的一条链上挖矿(隐瞒链)。当找到多个区块后,再一起广播,使得其他矿工的工作无效。
这会浪费全网的算力,一部分矿工的工作会变得无效,可能会导致算力和区块奖励向有优势的超级节点倾斜。
比特币网络可以通过改进广播协议来减少自私挖矿的影响。
比特币矿工节点对交易的校验主要发生在两个时间点:交易被广播到节点时和打包区块时。两个时间点的校验内容基本相同,但在打包区块时可能会有更严格或额外的检查。具体如下:
当一个交易被广播到节点时,节点会进行以下校验,以决定是否将交易添加到内存池(mempool):
当矿工节点收到新区块时,会校验区块的每笔交易和区块本身的合法性,以确保区块的合法性和有效性:
[1] 第12讲 | 深入区块链技术(四):PoW共识-深入浅出区块链-极客时间: https://time.geekbang.org/column/article/5963