区块链解读3-密码学

解读区块链,共识机制
分布式架构保障系统满足不同程度的一致性,往往通过共识算法来达成。对于区块链上的共识机制可以理解成由谁来构造区块,并维护区块链的统一,提到这个问题一定会提到拜占庭容错-Byzantine Fault-Tolerant,BFT。
拜占庭将军问题:Byzantine failures,这个可追溯到当年罗马帝国战争时期,帝国拥有众多军队,每个军队之间距离都比较远,那时候没有电话、也没有微信、qq群,军队之间的命令传输必须通过信差,战争开始前所有军队必须达成一致的共识,但是军队中可能有叛徒或者敌军的间谍,甚至信差也有可能被策反,导致军队行动时无法保证一致。这个就是现实中的拜占庭将军问题。

延续到现时,在拜占庭将军问题上提出一个拜占庭容错,拜占庭容错是对现实世界的一种模型化假设,在点对点分布式网络系统中,节点由于硬件设备故障、网络延时或故障、恶意攻击导致整个系统中出现不可预知的错误,拜占庭容错协议必须处理这些未知的错误,但同时也要满足规避或解决这些未知错误的规范。
区块链中的共识机制有一个演变过程,一开始的时候中本聪大神并没有使用BFT,在比特币中使用的是被称为证明方式的proof-of-work,POW工作量证明和最长链机制,比特币中共识的最终体现就是比特币的最长链。“证明”和“共识”随着区块链技术的发展、“证明”逐渐被概括为共识机制。其实目的都是为了通过共识算法来保证系统的一致性。

首先,共识机制在分布式系统中是无解的,为什么说是无解,众多的节点之间通信,必然存在网络自身不可靠的原因、主机故障原因、恶意操控等原因,故是无法保证实现完全的共识,这里不是笔者随便下的结论,Fischer, Lynch 和 Patterson三位在1985年就提出了一个FLP不可能原理:在网络可靠的前提下,任意节点失效,一个或者多个的最小化异步模型系统中,不可能存在一个解决一致性问题的确定性算法。这三位的论文后来获得了Dijkstra奖。这一理论已被可靠的论证过,所以不用再花大力气在异步分布式系统中去设计一个完全一致的共识算法。(这里不深究FLP原理,有兴趣可以百度Lynch的)
FLP说明在异步分布式系统中完全一致性是不可能的,但这是一个科学理论,应用到现实工程中,我们可以牺牲一些代价把不可能变成可能,这就是科学和工程的最大区别,就像你炒股吧,官方肯定会告诉你股市有风险,入市需谨慎,但你肯定认为在你高超的操作下还是能赚钱的。那在计算机工程领域中2000年 Eric Brewer在ACM 研讨会提出猜想,CAP猜想,CAP拆解后就是一致性(Consistency)所有节点上的数据时刻保持同步、可用性(Availablity)每个请求都能接受到一个响应不论响应成功或失败、分区容忍性(Partition)系统内部有消息失效的情况下仍能提供持续服务。
这里写图片描述
实际运用在工程环境下,适当取舍这三者,一致性、可用性和分区容错性三者无法在分布式系统中被同时满足,并且最多只能满足其中两个。这样就出现了以下三种情况:
CA without P:如果不要求P(不允许分区),则C(强一致性)和A(可用性)是可以保证的。但其实分区不是你想不想的问题,而是始终会存在,因此CA的系统更多的是允许分区后各子系统依然保持CA。Zookeeper为此类设计。
CP without A:如果不要求A(可用),相当于每个请求都需要在Server之间强一致,而P(分区)会导致同步时间无限延长,如此CP也是可以保证的。很多传统的数据库分布式事务都属于这种模式。MongoDB、Redis为此类设计。
AP wihtout C:要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。CouchDB、cassandra为此类设计。
CAP猜想出现至今都一直存在很多质疑,有人提出概念的混乱、不适应数据库事务架构等各种质疑,2002年对CAP猜想被证实为一个定理,证明了CAP三者不可能同时满足,但没有证明任意两者都可满足,对C\A\P作了更明确的声明:(论文原文:http://lpd.epfl.ch/sgilbert/pubs/BrewersConjecture-SigAct.pdf),最初这个辩证是在webserver集群环境下的。
C:一致性被称为原子对象,任何的读写都应该看起来是“原子“的,或串行的。写后面的读一定能读到前面写的内容。所有的读写请求都好像被全局排序。
A:对任何非失败节点都应该在有限时间内给出请求的回应。(请求的可终止性)
P:允许节点之间丢失任意多的消息,当网络分区发生时,节点之间的消息可能会完全丢失。
质疑一直存在。2012年lynch重写论文,再次对CAP做了进一步的解释:
1.把CAP理论的证明局限在原子读写的场景,并申明不支持数据库事务之类的场景。
2.一致性场景不会引入用户agent,只是发生在后台集群之内。
3.把分区容错归结为一个对网络环境的陈述,而非之前一个独立条件。这实际上就是更加明确了概念。
4.引入了活性(liveness)和安全属性(safety),在一个更抽象的概念下研究分布式系统,并认为CAP是活性与安全熟悉之间权衡的一个特例。其中的一致性属于liveness,可用性属于safety。
5.把CAP的研究推到一个更广阔的空间:网络存在同步、部分同步;一致性性的结果也从仅存在一个到存在N个(部分一致),引入了通信周期round,并引用了其他论文,给出了为了保证N个一致性结果,至少需要通信的round数。
(论文原文:http://groups.csail.mit.edu/tds/papers/Gilbert/Brewer2.pdf
谈论了以上CAP原理,目的就是为了说明共识机制是相对的,目前没有一种决对完美的共识机制,所有各种共识机制都是理论结合工程实践产生的。
区块链的最成功案例-比特币中的共识机制POW和最长链机制,针对非拜占庭错误一般有PAXOS、RAFT算法,对于容忍拜占庭错误的有PBFT(拜占庭容错)算法-Fabric采用的共识算法(pow算法也是容忍拜占庭错误的,只是PBFT系列算法是确定的,一旦达成共识不可逆转,POW算法是不确定的,只能随时间推移,被推翻概率越来越小)。
POW:proof-of-work工作量证明,这个最简单的理解就是多劳多得,说的书面化,“通过工作以获得指定成果,成果证明付出的努力”,工作量证明最早出现的应用场景是哈希现金,Adam Back于1997年发明用于抵抗邮件的拒绝服务及垃圾邮件网管滥用。比特币中通过计算哈希函数(Hash Function)来作工作量证明,这里简要说明下哈希函数:也称为散列函数,给定一个输入x,它会算出相应的输出H(x),输入x可以是任意长度的字符串,输出结果即H(x)的长度是固定的,计算H(x)的过程是高效的(对于长度为n的字符串x,计算出H(x)的时间复杂度应为O(n)关于函数碰撞等具体问题将来另作一文说明)。比特币中计算方式是SHA256(Secure Hash Algorithm)输出为256位的哈希算法,比特币中区块结构如下:
这里写图片描述
比特币的区块由区块头及该区块所包含的交易列表组成。区块头的大小为80字节,由4字节的版本号、32字节的上一个区块的散列值、32字节的Merkle Root Hash、4字节的时间缀(当前时间)、4字节的当前难度值、4字节的随机数组成。区块包含的交易列表则附加在区块头后面,其中的第一笔交易是coinbase交易,这是一笔为了让矿工获得奖励及手续费的特殊交易(目前旷工奖励12.5比特币)。
这里写图片描述

拥有80字节固定长度的区块头,就是用于比特币工作量证明的输入字符串。因此,为了使区块头能体现区块所包含的所有交易,在区块的构造过程中,需要将该区块要包含的交易列表,通过Merkle Tree算法生成Merkle Root Hash,并以此作为交易列表的摘要存到区块头中。其中Merkle Tree的算法图解如下:
这里写图片描述
难度值(difficulty)是矿工们在挖矿时候的重要参考指标,它决定了矿工大约需要经过多少次哈希运算才能产生一个合法的区块。比特币的区块大约每10分钟生成一个,如果要在不同的全网算力条件下,新区块的产生保持都基本这个速率,难度值必须根据全网算力的变化进行调整。简单地说,难度值被设定在无论挖矿能力如何,新区块产生速率都保持在10分钟一个。
难度的调整是在每个完整节点中独立自动发生的。每2016个区块,所有节点都会按统一的公式自动调整难度,这个公式是由最新2016个区块的花费时长与期望时长(期望时长为20160分钟即两周,是按每10分钟一个区块的产生速率计算出的总时长)比较得出的,根据实际时长与期望时长的比值,进行相应调整(或变难或变易)。也就是说,如果区块产生的速率比10分钟快则增加难度,比10分钟慢则降低难度。这里有一个误区,不是每个区块产生的时间都是10分钟左右,有时候区块的产生要时间久很多或者很快生成,故这个10分钟是一个平均值。难度公式:新难度值 = 旧难度值 * ( 过去2016个区块花费时长 / 20160 分钟 ),而工作量证明的目标值(target)计算公式:
目标值 = 最大目标值 / 难度值(其中最大目标值为一个恒定值:0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF新难度值 = 旧难度值 * ( 过去2016个区块花费时长 / 20160 分钟 ))
整个工作量计算公式具体为:
这里写图片描述

POW工作量证明一直运行在比特币上,但越来越多职责POW,一,资源的浪费,大量计算节点通宵达旦的计算,对于资源是很大程度的浪费。二、比特币的收益促使联合挖矿,矿池的集中是对去中心化的一种威胁(51%算力威胁)。
(参考http://www.infoq.com/cn/articles/bitcoin-and-block-chain-part02/
FABRIC中的PBFT算法:PBFT(拜占庭容错)算法,假设全网节点中有问题的节点数量为n,那全网节点数必须>3n+1,这个PBFT算法的基础,PBFT算法通过论文中的一张图来详细说明:
这里写图片描述
这张图在之前的文章中也出现过。
C我们认为是客户端,0、1、2、3是分布式系统中的节点成员,0是主节点、1、2是备份节点,3也是备份节点但已发生故障,默认3发送信息为无效。
1.C发起一笔请求到0号主节点。
2.主节点0开始对请求排序编号,并把请求序号发送到1、2、3节点。
3.1、2节点互相之间和0主节点之间发送消息。
4.0、1、2、之间确认0主节点的分配序号,互相确认。
5.0、1.、2、确认信息回复C。
6.客户端C判断收到确认是否在f+1内,确认结果。
PBFT算法中三个阶段达成共识:Pre-Prepare、Prepare 和 Commit,整个流程如下:
1.从全网节点选举出一个主节点(Leader),新区块由主节点负责生成。
2.每个节点把客户端发来的交易向全网广播,主节点将从网络收集到需放在新区块内的多个交易排序后存入列表,并将该列表向全网广播。
3.每个节点接收到交易列表后,根据排序模拟执行这些交易。所有交易执行完后,基于交易结果计算新区块的哈希摘要,并向全网广播。
4.如果一个节点收到的2f(f为可容忍的拜占庭节点数)个其它节点发来的摘要都和自己相等,就向全网广播一条commit消息。
5.如果一个节点收到2f+1条commit消息,即可提交新区块及其交易到本地的区块链和状态数据库。
(针对PBFT算法http://www.docin.com/p-1793654303.html有完整说明有兴趣可深入)
着重介绍了比特币和fabric的两种共识机制,其余还有pos、paxos、raft等算法有兴趣可再深入了解下。笔者初学区块链,很多东西也是慢慢摸索,之所以写下这些概念一方面作为自己学习的整理,另一方面也希望更多交流学习的机会。如有兴趣可以关注公众号或者加我微信。
这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/sxjinmingjie/article/details/77119989
今日推荐