说点闲话
算了下,我大概有10天没有在币乎更文了,那这些天,我干什么去了?我觉得有必要跟大家聊聊。暂时离开币乎,不是因为我偷懒,不想写文章了,而是我想冷静下来,把自己学习区块链这2,3个月以来脑子里混乱的东西给理清楚。我想知道自己为什么要写文章?我学习区块链的目的是什么?我能够坚持多久?事实上,我不是一个喜欢随大流的人,所以我不会见到别人日更就去日更,我更不想为了写作而写作。好了,现在这几个问题,我都找到了我自己的答案,所以我回来继续写作了。关于那几个问题的答案,就暂时不细说了,我想说说我这些天干了什么。我去深入了解了几个我看好的项目,包括eos,gxs,qtum,btm;我还去体验了几个平台,包括,candy.one、pressone、iVeryOne、ONT。我还去把曾经学习过的区块链的书翻过来重新看看,去学习了GO语言的编程(很多区块链项目开发会使用)。
你所知道的工作量证明机制
说的稍微有点多了,现在正式进入到今天的话题比特币挖矿--工作量证明机制的底层原理到底是什么样的?说到挖矿和POW工作量证明机制,我相信有不少朋友都会知道一些,比如,比特币每10分钟会产生一个区块;矿工是根据解答一道系统给出的难题来获得记账的权利的,算力越高,获得记账权利的机会就越大。而我今天主要是想跟大家详细分析一下矿工们是如何竞争记账的,也就是说如何竞争解决这道难题的,以及这个经常被我们提及的区块(block)到底是什么样的?
我们都知道比特币的区块的产生是通过POW(Proof Of Work)工作量证明机制来完成的,整个网络平均10分钟就会产生一个区块,而且伴随着区块的产生,系统会奖励一定数量的比特币给在这个区块上记账的矿工。说道这里,请大家思考2个问题。
-
问题一:系统奖励的比特币的数量是多少?是恒定不变的吗?
比特币的创世区块是在2008年,由中本聪挖出的,按照比特币白皮书的规定,每挖出一个区块,系统就会奖励50个比特币,每四年,奖励减半,到现在的话,奖励是12.5个比特币。注意:这里的每四年是一个大概值,实际上是说每挖出21万个区块奖励就减半,大家可以自己算算,挖出21w个区块的时间是3.99年,所以大致是每4年减半。 -
问题二:系统如何来判断谁拥有这个区块的记账权呢?
为了解决这个问题,比特币系统引入了POW共识机制,也就是工作量证明机制,这也是比特币系统的灵魂所在。这个算法很简单,就是系统出一道数学题,谁能够最先解答出来,谁就会产生一个区块,并在上面记账。其实这种机制,我们生活中处处可见,比如我们的各种考试,考证。它的原理是:既然监督你们工作的过程是非常低效的,那好,我不管你是去如何工作的,我根据考试的结果来判断你是否做了很多的工作。
工作量证明的基本原理
你做了一定难度工作产生了一个结果,系统根据结果来验证你是否做了相应的工作。大致流程如下:
图片来源:《区块链:定义未来金融与经济格局》
举个例子
给定的一个基本的字符串"Hello, world!",我们给出的工作量要求是,可以在这个字符串后面添加一个叫做nonce的整数值,对变更后(添加nonce)的字符串进行SHA256哈希运算,如果得到的哈希结果(以16进制的形式表示)是以"0000"开头的,则验证通过。为了达到这个工作量证明的目标。我们需要不停的递增nonce值,对得到的新字符串进行SHA256哈希运算。nonce的初始值为0
"Hello, world!0" => 1312af178c253f84028d480a6adc1e25e81caa44c749ec81976192e2ec934c64
...............
"Hello, world!4249" => c004190b822f1669cac8dc37e761cb73652e7832fb814565702245cf26ebb9e6
"Hello, world!4250" => 0000c3af42fc31103f1fdc0151fa747ff87349a4714df7cc52ea464e12dcd4e9
结果是需要4251次运算才能解答正确,当然这里只是一个简单的例子,实际上比特币系统的机制与这个小例子类似,但是比它更复杂,也就意味着需要更大的算力才能成功解题。
实际的比特币系统中又是如何出题和解题的呢?
比特币采用的是SHA-256算法,这是哈希运算的一种。矿工要计算的工作量就是通过解决下面这个哈希函数的未知参数,大概数学公式是这样的。
Hash(上一个区块的Hash值,交易记录集,随机数X) = 0000a2a5FD6g
由于比特币网络中节点去生成一个区块是,总是基于目前存在的最新的区块,所以每个矿工在计算之前已经能够获取到上一个区块的所有信息,所以,Hash()函数的前2个参数都是确定的,最后的值也是确定的,矿工要做的就是去做大量的尝试计算,找到一个随机数X,使得Hash的结果以若干个0开头,当然在每道题中0的个数不确定。哪个节点最先算出,就会产生一个新的区块,并记账。
下面是我从https://blockchain.info找的一个区块#516559,你可以看看Hash值,一共18个0,再看看这个Nonce随机数,可以看出这次解题是经过了数亿次运算才成功。
到这里,我们已经知道矿工们为了获取系统给出的比特币,就会去耗费自己的算力和电力来解决难题。这道难题的3个关键点是:工作量证明函数、区块、难度值。
工作量证明函数
工作量证明函数是指这道题的计算方法,在比特币的网络中是SHA-256。SHA是一种安全散列算法,主要用于数字签名。SHA-256是这个函数家族中的一员,它的特点是通过哈希算法运算之后,输出值为256位。到目前为止,还没有出现对SHA-256算法的有效攻击。
区块
区块的作用是记载比特币网络中合法的交易。区块包含的交易列表则附加在区块头后面,其中的第一笔交易是coinbase交易,这是一笔为了让矿工获得奖励及手续费的特殊交易。下面这张图是我自己画的一个关于区块的简图,比特币挖矿都是基于已存在的最新区块去生成下一个区块。区块主要由区块头和交易列表组成。
区块头的详细数据结构如下:
字段 | 描述 | 大小(byte) |
---|---|---|
Version | 版本号 | 4 |
PrevBlockHash | 上一个区块的哈希值 | 32 |
MerkleRootHash | 该区块中的所有交易通过Merkle Tree生成的Hash | 32 |
Time | UNIX时间戳,也就是区块产生的时间 | 4 |
Bits | 难度值,完成比特币工作量证明目标的难度系数 | 4 |
Nonce | 随机数,为了找到满足难度目标所设定的随机数 | 4 |
区块包含的交易列表则附加在区块头后面,其中的第一笔交易是coinbase交易,这是一笔为了让矿工获得奖励及手续费的特殊交易。
所以一个完整的区块数据结构如下:
图片来源:《区块链:定义未来金融与经济格局》
难度值
难度值是矿工挖矿的难度指标,它表示矿工大概需要多少次哈希运算才能产生一个合法区块。我们已经知道比特币的区块大约每10分钟生成一个,而全网的算力是在不断变化的,比特币系统要让产生新区块的时间基本维持在10分钟,就得不断去调整挖矿的难度值。通过去不断的调整难度值,才使得新区块的产生平均保持在10分钟。
难度值的调整是在每个完整的节点中独立发生的,而且是每隔2016个区块(大概2周的时间)才会进行一次自动调整。具体来说就是实际挖矿的时常和期望时常(每个区块10分钟)相比较,如果产生区块的时常大于10分钟,就降低难度值,反之,则增加难度值。
这个公式可以总结为如下形式:
新难度值 = 旧难度值 * ( 过去2016个区块花费时长 / 20160 分钟 )
工作量证明还需要有一个目标值,计算公式如下:
目标值 = 最大目标值/难度值
最大目标值是固定的:0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
目标值是指当前区块生成所达成目标值的hash值,用来表示矿工的工作量证明,只有当矿工计算出来的hash值小于目标值,才表示挖掘区块成功。
通过以上内容,我们可以大致总结下比特币挖矿(工作量证明)的过程。通过不停的变换区块中的nonce随机数的值,并将它作为SHA-256哈希运算的输入,直到找到一个值,可以让运算之后的哈希值有指定个数的0为前导。0的个数越多,挖矿难度越大。
以下总结来自《区块链:定义未来金融与经济格局》
比特币挖矿,也就是解决这道工作量证明难题的步骤大致归纳如下:
1、生成Coinbase交易,并与其他所有准备打包进区块的交易组成交易列表,通过Merkle Tree算法生成Merkle Root Hash
2、把Merkle Root Hash及其他相关字段组装成区块头,将区块头的80字节数据(Block Header)作为工作量证明的输入
3、不停的变更区块头中的随机数即nonce的数值,并对每次变更后的的区块头做双重SHA256运算(即SHA256(SHA256(Block_Header))),将结果值与当前网络的目标值做对比,如果小于目标值,则解题成功,工作量证明完成。
该过程可以用下图表示:
通过以上介绍,我们已经知道,矿工是如何去解题以及怎样才算是解题成功了。现在我们一起来思考一个问题。
Question
按照上面提到的Hash算法,只要矿工计算出来的区块的哈希值小于目标值,就算是完成了工作量证明,那么也就有可能差不多在同一时间,有2个以上的矿工都完成了工作量证明,并且把消息广播出去。那也就意味着同一高度可能存在多个区块,也就是说主链即出现分叉(Fork),但是呢,肯定只能有一个区块来记账,那此时比特币系统又该如何判决呢?
如果遇到分叉时,网络会根据下列原则选举出Best Chain:
- 1、不同高度的分支,总是接受最高(即最长)的那条分支
- 2、相同高度的,接受难度最大的
- 3、高度相同且难度一致的,接受时间最早的
- 4、若所有均相同,则按照从网络接受的顺序
等待Block Chain高度增一,则重新选择Best Chain
产生分叉时,区块链大概是这样的。
从这幅图我们可以看出2点,第一:在同一高度可能会产生分叉(fork),第二:有一条最长的链(黑色的那条就是)。
这里就要稍微简单介绍一下比特币系统的最长链机制了。我们知道,每个新区块的产生是要基于一个以前的区块,而绝大多数矿工会选择最长链的最后一个区块来计算下一个区块,因为只有最长链上的区块才能获得比特币系统的认可,并得到挖矿的奖励。而其他的分支则是无效分枝,不能得到任何奖励,只能白白的浪费自己的算力和电力。这是保证区块链不发生分裂的重要机制。
所以现在会有很多矿工会选择抱团组成矿池,这样才能保持长期成为最长分支。
最后一步,验证机制
在节点(矿工)完成工作量证明(也就是找到满足指定哈希值的随机数nonce)之后,会马上对全网进行广播,网络的节点收到广播打包区块,会立刻对其进行验证。如果验证通过,其他节点(矿工)将不再竞争打包这个区块,而是选择接受这个区块,并将打包后的数据记录在自己的账本中,然后继续进行下一个区块的竞争答题中。
感谢以下作者
https://www.cnblogs.com/tinyxiong/p/7791538.html
http://8btc.com/article-160-1.html
http://www.infoq.com/cn/articles/bitcoin-and-block-chain-part02
网友评论