跳过正文

4. 比特币挖矿

·105 字·1 分钟
Chuck Chan
作者
Chuck Chan
分享技术、思考与生活

比特币共识
#

在文章开始之前,必须先聊聊共识。共识是在某个群体或系统中,针对特定问题或规则达成的普遍一致意见或共同认识

为什么需要共识
#

通过前面的知识我们知道,比特币是一个去中心化的账本,在这个世界上的每一个节点都可以打包交易的信息,即获得比特币的记账权

  • 究竟以哪个节点打包的信息为主?
  • 如何让所有用户都认可某个节点打包的账单信息?
  • 打包交易有什么利可图?

如何达成共识
#

在日常生活中,投票是一个达成共识的好办法。那在比特币中能否使让用户投票,来决定记账权呢?答案自然是否定的,因为在比特币中的账号可以无限产生,只要生成一对公私钥对就相当于生成了一个账户,如果有人恶意生成足够多账户,那他就可以控制投票的结果(女巫攻击)。

在比特币中也是利用投票机制,但不是按照账户投票,而是按照计算力来投票

挖矿
#

发行货币
#

在讨论挖矿之前,我们先来说说如何发行比特币。前面的文章中我们讨论的交易都是在两个用户之间进行的,例如A转给B,B转给C,但在这些交易自始至终都没有产生新的货币,那这些货币最开始是从哪里产生的呢?答案就是出块奖励

接着我们来说说如何获得出块奖励。在比特币系统中,每个用户都可以自行组装一个候选区块,然后不断地尝试 block header 中的各种nonce值,当用户的候选区块的 block header 满足下列公式时,就可以将区块广播到其他节点中去,其他节点接收到这个候选区块,验证合法性,当大多数节点验证通过,则将这个候选区块纳入到区块链中。用户将区块写入区块链中,就能获得一定的出块奖励,这就是大家对打包区块链交易趋之若鹜的原因。 $$ hash(block header) < target $$ 在上述的区块中包含一笔出块奖励,也叫 coinbase transaction,在这比交易中不需要说明币的来源,因为这就是系统给该用户的奖励。下图 block body 中绿色的交易即为出块奖励。

在blochchain.info查询到 coinbase transaction 详细信息如下:

按照比特币协议的规定,出块奖励从2009 年 1 月 3 日创世区块,每挖出21万个区块(约4年半),就会减少一半。

在上述不断尝试的过程就像是矿工在挖金矿一样,具有不确定性,但一旦挖到就有丰厚的回报(记账权),所以这个不断尝试的过程也叫挖矿,尝试的用户就叫矿工。这种挖矿机制解决了上篇文章所述的比特币货币发行问题,同时让矿工通过提供算力获得奖励,这种经济激励促使大量节点参与维护网络,保障了整个系统的安全与稳定。

挖矿概率分析
#

挖矿的本质是不断尝试各种nonce值,来满足 hash(block header) < target 。每次尝试,都可以视为一次伯努利试验。在挖矿过程中,每次都是成功率极小,失败率极大。矿工一次次进行挖矿,则构成了一系列的伯努利试验。伯努利试验本身具有无记忆性。也就是说,无论之前做多少大量试验,对后续继续试验没有任何影响。这样我们可以用泊松分布来进行近似分析,通过概率推导,出块时间是符合指数分布的。

比特币的协议中规定了系统平均出块时间是10分钟,如何将出块时间限定在10分钟,下一篇文章会详细讲述。

比特币总量
#

在中心化的金融系统中,货币的数量是可以通过中央政府控制的,例如政府可以加印或者少印货币,从而实现对金融市场的控制。

而在去中心化的比特币系统中,比特币的数量是固定的。上面我们谈到,矿工每挖出21万个区块(约4年半)就会减少一半,这样比特币的产生数量就会构成一个几何序列,从这个序列可以用等比数列求和公式来推算出比特币的总数。 $$ \begin{align} 总量&=21万50+21万25+21万12.5+… \ &=21万50*(1+1/2+1/4+1/8+…)\ &=21万502 \ &=2100万 \end{align} $$ 因为发行总量固定,比特币的一个很大优势就是在于具有很强的抗通胀属性

比特币的安全性
#

1. 能否偷币?
#

能否偷币,即把别人账号上的钱转给自己?答案是不能,转账交易需要签名,而有恶意的人无法伪造别人的签名。

假如这个有恶意的人挖矿成功获得记账权,并将这个偷钱的转账交易硬写到新区块的交易列表里呢?答案任然是不能,因为诚实的节点不会接收这个区块,因为区块包含了一个非法的的交易,后续诚实的节点会继续沿着原区块继续挖矿。事实上这种做法很愚蠢,因为这样做相当于白白浪费了一个出块奖励。

2. 能否把已经花过的钱再花一次?
#

如下图,M将钱转给A,在下一个区块再将这边钱转回给他自己M’。

这种情况其实我们在上篇文章中双花攻击时已经讨论过了,有uxto交易模型的保障,这种方式是不可行的 。

如果是利用分叉攻击,将M转给M’的区块与M转给A的区块产生分叉呢?

这种攻击往往会在一些会产生不可逆的外部效果的交易中。假设在一个支持比特币支付的交易商城中,M将钱转给A,A根据订单进行发货。当M收到货的同时,产生一个M->M’的交易,如果这个区块与M->A的区块同时发布,并且包含M->M’交易的区块被大多数节点接受,相当于M->A的交易被回滚了,那么M将白嫖到这个商品,A将损失一件商品。

如何防范这种攻击?

如果M->A的区块后面又延续了一些区块,那么M->M’的区块再想回滚交易,就变得很困难了,因为大多数诚实的节点不会沿着下面的链挖下去。所以一种简单的防范这种攻击的方式就是多等几个区块确认,比特币协议中缺省需要等待6个区块确认,平均出块时间10分钟,也就是说要等待一个小时才可以认为区块不会被篡改。

3. 发布交易时能否故意不包含合法的交易?
#

当然可以这么做,但是你不干,有的是区块干,总有诚实的节点会将这些合法的交易会被写到区块中去。

4. selfish mining ?
#

即挖到区块先掖着藏着不发布,且继续沿着这条链挖下去,等待6个区块确认后再将整条链发布出去,试图回滚之前的交易。同时这样有个好处,就是区块都被掖着藏着,没人跟你竞争。

这种case理论上可行,但前提是需要掌握大量的算力,因为你是再跟世界上所有其他的算力做对抗。

5. 思考
#

从上述中我们可以知道,其实比特币并不是100%安全的,如果恶意节点掌握了世界上50%以上的算力的话,是可以进行一些恶意攻击的。但是,我们可以反过来思考下,假设你掌握了世界上50%以上的算力,在这个每个国家都为算力争破头脑的时代,能轻易地创造大量的合法收益,还有必要进行恶意攻击吗?

在世界上的大部分算力都掌握在合法的节点手中的这个前提下,可以说比特币是安全的