title: 共识算法-PoW(工作量证明)算法
tags: 区块链,共识算法
区块链其实就是一个基于互联网去中心化的账本,每个区块相当于一页账本,它记录了交易内容。因为比特币是一个去中心账本,会引发记账一致性问题。一致性问题就是所有的区块,记账内容可能不一样。
在比特币系统中,每一个节点都要保存一份完整交易信息。但是应为每个节点的环境不同,会接受到不一样的信息,如果同时记账,会导致账本不一致。因此我们需要找出一个代表帮我们记账,然后内容分享给其他节点,比特币中通过竞争记账的方法解决记账系统的一致性问题。
在比特币系统中,大约每10分钟进行一轮算力竞赛,竞赛的胜利者,就获得一次记账的权力,并向其他节点同步新增账本信息。因此在比特币中,中本聪设定了只要完成记账的节点给予一定的比特币作为奖励,因此大家把记账形象的称为“挖矿”。
那么怎么判断竞争胜利(记账成功)呢? 中本聪采用了一个PoW(工作量证明)算法来进行判断。工作量证明,顾名思义就是提供一个工作多少的证明。那么这个证明是怎么来的呢?
说工作量证明怎么来之前我们先说下Hash算法,Hash算法有一个特性:通过hash加密的文本或文件,哪怕只有一个字节改变,Hash的值就完全不相同。在区块链中,需要找出一个Nonce,Nonce的值和区块上的信息拼接后进行hash计算,当hash值满足给定条件,第一个找出nonce的节点获得记账权。这个找Nonce值计算Hash值的过程就是工作,找到满足条件的Nonce值就是证明。
举个例子 ,假设我们区块上的信息是 blockchain
,我们要找出一个Nonce
随机数和blockchain
拼接,最后计算的Hash值结果以6个0开头,率先找到随机数的节点就获得此次记账的唯一记账权。
Hash值示例:
00000017504a984ab0339f7d1517691e63099fb83d6ae9d6ebd722c25755f2cc
难度值度值是比特币系统中的节点在生成区块时的重要参考指标,它决定了节点大约需要经过多少次哈希运算才能产生一个合法的区块。比特币的区块大约每10分钟生成一个,如果要在不同的全网算力条件下,新区块的产生都基本保持这个速率,难度值必须根据全网算力的变化进行调整。简单地说,难度值被设定在无论节点计算能力如何,新区块产生速率都保持在每10分钟一个。也就是说,如果区块产生的速率比10分钟快则增加难度,比10分钟慢则降低难度。
以我写这篇文件的时间来看,比特因为越来越少,所有难度越来越高,挖一个比特币的成本需要3W多人民币。为什么成本这么高呢?我们通过比特币来简单分析下挖矿难度有多大。Hash值是由数字和大小写字母构成的字符串,每一位有62种可能性,假设任何一个字符出现的概率是均等的,那么第一位为0的概率是1/62(其他位出现什么字符先不管),理论上需要尝试62次Hash运算才会出现一次第一位为0的情况,如果前两2位为0,就得尝试62的平方次Hash运算,以n个0开头就需要尝试62的n次方次运算。
我们以Block #544228为例,它当前hash为:000 000 000 000 000 000 14d90bb35d84eaf8b5ed2ae85f42b9d37c715ab3a02b06。 可以看到它前面有24个0,那么理论上就需要尝试 64^24 ,大概需要2.230074519853062e43 次这是一个非常大的数字,需要消耗很大的资源(电能、算力)。
比特币PoW的过程,可以简单理解成就是将不同的nonce值作为输入,尝试进行SHA256哈希运算,找出满足给定数量前导0的哈希值的过程。而要求的前导0的个数越多,代表难度越大。比特币节点求解工作量证明问题的步骤大致归纳如下:
1.生成铸币交易,并与其他所有准备打包进区块的交易组成交易列表,通过Merkle树算法生成Merkle根哈希;
2.把Merkle根哈希及其他相关字段组装成区块头,将区块头的80字节数据作为工作量证明的输入
3.不停地变更区块头中的随机数,即nonce的数值,并对每次变更后的区块头做双重SHA256运算(即SHA256,将结果值与当前网络的目标值做对比,如果小于目标值,则解题成功,工作量证明完成。
比特币的工作量证明,就是俗称“挖矿”所做的主要工作。
Merkle 可信树是一棵完全二叉树,应用 Merkle 可信树需要计算并输出Merkle 可信树的每个叶子节点的认证路径上的节点的哈希函数值。
上图展示了一个具有4个交易记录的 Merkle树的根哈希值的计算过程。首先以这4个交易作为叶子结点构造一棵完全二叉树,然后通过哈希值的计算,将这棵二叉树转化为Merkle树。
首先对4个交易记录:TxaTxc,分别计算各自的哈希值HAHC,然后计算两个中间节点的哈希值HAB=Hash(HA+HB)和HCD=Hash(HC+HD),最后计算出根节点的哈希值 ABCD=Hash(HAB+HCD)。
在进行工作量证明之前,记账的节点会做一些工作:
1.客户端产生新的交易,向全网进行广播要求对交易进行记账
2.每一个记账节点一旦收到这个请求,将收到的交易信息纳入一个区块中
3.每个节点都通过PoW过程,尝试在自己的区块中找到一个具有足够难度的工作量证明;
4.当某个节点找到了一个工作量证明,它就向全网进行广播
5.当且仅当包含在该区块中的所有交易都是有效的且之前未存在过的,其他节点才认同该区块的有效性;
6.其他节点表示它们接受该区块,而表示接受的方法则是在跟随该区块的末尾,制造新的区块以延长该链条,而将被接受区块的随机哈希值视为先于新区块的随机哈希值。
关于比特币PoW共识机制能否解决拜占庭将军问题一直在业界有争议。2015年,Juan Garay对比特币的PoW共识算法进行了正式的分析,得出的结论是比特币的PoW共识算法是一种概率性的拜占庭协议(Probabilistic BA)。Garay对比特币共识协议的两个重要属性分析如下。
在不诚实节点总算力小于50%的情况下,同时每轮同步区块生成的几率很少的情况下,诚实的节点具有相同的区块的概率很高。
当不诚实算力具一定规模,超过51%,甚至不用接近50%的时候,比特币的共识算法并不能保证正确性,也就是,不能保证大多数的区块由诚实节点来提供。这就是著名的51%算力攻击。
因此,我们可以看到,比特币的共识算法不适合于私有链和联盟链。其原因首先是它是一个最终一致性共识算法,不是一个强一致性共识算法。第二个原因是其共识效率低,提供共识效率又会牺牲共识协议的安全性。
PoW机制存在明显的弊端。一是浪费大量的算力,只用来竞争挖矿权,并没有更多实际或科学价值。二是它并不完全公平,当计算机硬件升级到一定程度,比如量子计算机可能几秒就计算出了Hash值。