今天我们从技术的角度来讲讲区块链中的“挖矿”是什么意思。
首先说结论,挖矿的本质就是生成一个区块,并将其链接到区块链的分布式存储中。而进行挖矿的人就是矿工。
那什么是区块呢?区块是一种存储空间,可以用来存储数据。就像图中所示的,区块分为区块头(header)和区块体(body)两部分。
区块体存储的数据是与上层应用有关的,就像mysql里存什么数据依赖于上层应用。比如比特币使用的区块链,区块体里存储的是比特币的交易记录。
而区块头则存储了与该区块和整个区块链相关的一些元数据。图中所示的区块头有三个常见的属性,分别是前一个区块的哈希值、区块生成的时间戳和一个随机数。
那么什么是区块链呢?区块链是由一个个区块链接起来的,就像图中所示的链表一样。每个区块的唯一标识就是它的哈希值,下一个区块通过存储上一个区块的哈希值来链接起来。这就是区块链的概念。
讲完了区块和区块链的概念,接下来我们来讲讲挖矿,也就是生成新区块的过程。
在讲挖矿之前,先来说说区块链的三个特性。首先,历史生成的区块是无法改变的,只能像写日志一样追加写,不能像mysql一样随机写。其次,新的区块只能在最新的区块后面生成,必须先完成同步全网最新的区块链数据,才能开始生成新区块。最后,生成新区块很难,必须满足一定的条件才算有效。
那么要满足什么条件才算生成一个新的区块,才算挖矿成功呢?答案是对最新的区块头进行两次SHA256计算,得到的256bit哈希值必须满足高位48bit是0x00000000FFFF才算挖矿成功。
为什么大家都说挖矿很难呢?难道我们不能根据符合条件的哈希值推导出区块头的其他属性吗?额,哈希算法是不可逆的,不能从哈希值反推出数据。就像大家都知道,由字符串计算出对应的md5值很容易,但是反过来却是不可能的。所以要满足前48位是0x00000000FFFF的哈希值,就像连续抛48次硬币,每次都能得到想要的结果一样,概率非常小。
那么怎么才能找到符合条件的区块头,从而成功挖到矿呢?答案是穷举法。区块头中有一个随机属性nonce,从0开始依次遍历到2^32,计算对应的区块头的哈希值,如果得到的哈希值满足条件,就算挖矿成功。
上面是挖矿的伪代码,只要程序运行足够长的时间,理论上总能挖到矿。但是如果其他人的计算能力比你强,在你挖到矿之前,他们可能已经生成了新的区块并将其广播到整个区块链网络,这时你本地的数据就不是最新的了,你挖到的矿就作废了。所以你需要放弃之前的工作,先同步最新的数据,然后重新开始挖矿。
有没有什么方法可以提升挖矿的速度呢?当然有,从架构的角度来看。首先,缓存基本没用,因为每个区块的哈希值都不一样,时间戳也都不一样,无法通过查表来节省时间。其次,提升单个CPU的计算能力,比如使用GPU代替CPU,使用特殊的芯片计算SHA256D等都是有效的优化方法。但是单机的优化总会有极限,所以如果单机性能不够,可以通过并行计算来提升速度,比如建立一个集群。这也是为什么会有很多比特币矿场的原因。
综上所述,区块链中的挖矿就是在最新的区块链数据上生成一个符合条件的区块,并将其链接到区块链中的过程。希望通过这篇文章,你能了解挖矿的本质。接下来,还会继续解答关于区块链和挖矿的其他疑问,比如如何保证数据的一致性,挖矿有什么意义,比特币和挖矿的关系以及比特币的总量是如何保证有限的等等。