付瑶瑶,李盛恩
山东建筑大学 计算机科学与技术学院,济南250100
区块链因比特币[1]而生,最初作为比特币的底层技术解决比特币系统中各方之间的信任问题。区块链的本质就是一种分布式数据库,具有去中心化、不可篡改、可追溯和集体维护的特点[2]。作为数字加密货币领域的核心支撑技术,区块链通过集成P2P协议、非对称加密、共识机制、块链结构等多种技术,解决了数据的可信问题。通过应用区块链技术,可以在互不信任的多方间无需任何第三方机构实现可信、对等的价值传输[3]。区块链技术作为一种普适性的底层框架,其应用范围已经超出了数字货币领域的范畴。在医疗领域,文献[4-6]针对医疗数据容易发生隐私泄露及不同医疗机构间共享医疗数据困难的问题,提出利用区块链技术实现了医疗数据的安全存储与共享。在数据溯源方面,Liang等人[7]将用户对数据的操作转化成一定格式的源数据,将这些源数据存储在区块的交易字段中实现日志的功能。分布式数据库中首先面临的就是如何解决数据的分布式一致性问题[8]。区块链的共识层中封装了共识算法,共识算法作为区块链的工作引擎,能够使系统中的各参与方在没有中心机构的控制下进行大规模的协同工作,实现数据的分布式一致性[9]。传统的分布式数据只需支持崩溃容错,而区块链系统具有去中心化的特点,部分节点可能并不可信,所以算法需要支持更为复杂的拜占庭容错[10]。随着区块链技术在不同领域的应用,共识机制的研究也成为分布式系统中的一个研究热点,相继出现了多种主流共识机制。
工作量证明(Proof of Work,PoW)机制[11]源于Dwork等人对防范垃圾邮件问题进行的研究,比特币采用PoW 机制解决了系统中存在女巫攻击问题[12]。PoW要求矿工贡献计算资源求解工作量证明问题(俗称“挖矿”),最先挖矿成功的矿工将会获得区块记账权及系统发放的比特币奖励。这种机制的特点是利用节点算力保证系统安全,并能够有效避免区块链分叉问题。但PoW过程会使部分矿工大量浪费算力,并且一些算力低的节点会将彼此的算力联合组成矿池,矿池算力的扩张也会导致系统中算力中心化的现象。2012 年,King 等人[13]在点点币中首次实现权益证明(Proof of Stake,PoS)机制。PoS 中的节点把持有货币的数量和天数作为权益(币龄)竞争区块记账权,权益越大越容易获得记账权,一定程度上缩短了共识达成的时间,提高了共识效率。但是随着币龄的累计,系统长期运行PoS机制可能导致权益集中化的现象[14]。比特股(Bitshares)项目采用了股份授权证明(Delegated Proof of Stake,DPoS)机制,在这种机制中,每个拥有权益的节点都作为一个股东节点具有投票的权利,每个股东节点将票投给自己认为可信的节点,得票数最多且愿意成为代表的前N个节点进入“董事会”成为授权代表节点,代表节点的职责是生产区块并进行区块的验证。节点进入“董事会”之前必须先交纳一定数量的保证金,每一轮选举结束之后,这N 个代表节点会轮流生产区块,并且区块的验证只在代表节点内部进行。如果一个节点错过生产相对应的区块或者恶意篡改区块,股东会收回对该节点的投票从而将该节点“投出”董事会,同时该节点也面临保证金被罚的风险[15]。DPoS 机制可以认为是一种“民主集中式”的记账方式[16],整个共识过程不依靠任何算力,很好地解决PoW 机制中浪费计算资源和PoS 机制中可能出现的权益集中化的现象。这种机制大幅减少了参与区块生成和验证区块的节点的数量,可以实现秒级的共识验证。
但是目前的DPoS 机制仍然存在一些缺陷,不少研究者也对其进行了改进。针对机制中股东节点投票的积极性不高的问题,文献[17]采用一种投票激励方案激励股东节点投票的积极性。在这种方案中,每个股东节点可以根据代表节点的信用分数投反对票,如果一个信用分数低的节点在下一轮的选举中未能成为代表节点,系统将给予对该节点投反对票的节点信用系数奖励。若选民节点在某轮投票选举中未进行投票操作,则会扣除一定信用分数。选民节点通过正确行使投票权为自己赢得信用分数,增大自身日后成为代表节点的可能性。但是这种方案并不能很好地解决节点之间的信任问题,节点可以通过合理生产区块和正确投票两种方式提高自身的信用分数,因而信用分数高的节点并不代表该节点被信任的概率大。EOS 项目为了更好地解决对代表节点的监督问题对DPoS 机制进行了改进,在改进后的机制中每轮只选出21 位代表节点[18]。虽然这种方式可以提高出块速率,但是代表节点数量的减少会导致系统中心化程度加强。像PoW 机制以及PoS 机制中都是挖矿成功的节点获得交易费用和系统发放的货币奖励,而其余付出过工作量或者币龄的节点一无所得。而在DPoS机制中,每次共识过程结束,只有“董事会”中的授权代表节点会获得奖励,最终会导致币的流动性大大减少,加剧系统中“穷者越穷,富者越富”的局面。另外,在DPoS 机制的每次共识过程中,部分节点可能会篡改区块信息、持续生成无效区块等其他作恶行为,由此会给系统的安全性造成一定的威胁。
因此,本文针对以上DPoS 机制中存在的问题提出了一种该机制的改进方案,改进后的机制能够很好地解决以上问题并进行了实验加以验证。
奖励机制是为解决节点投票积极性不高而采取的一种方案。在DPoS 机制中,普通节点投票时需要耗费时间精力等,而且一个节点投票与否对自身来说没有任何的影响。改进后的方案中加入了奖励机制,每次投票选出N 个节点负责出块,并获得一定的奖励,而这其中每一个节点的投票者本身也会从中获得一定的回报。具体来说,每一次共识过程结束之后,成功生产区块的某个代表节点要将获得的奖励按照相应的比例分给为它投票的所有节点。
3.1.1 奖励分配方案
DPoS机制中的每个拥有数字货币的节点都具有投票的权利,且投票时遵循“一币一票”的原则。举个例子,假设Alice 拥有100 个币,那么她每票就拥有100 单位的票权,Bob拥有50个币,那么他每票就拥有50单位的票权。假设Alice 和Bob 同时投票给了节点候选人John,那么John获得的票数就为150票。
奖励机制规定每次代表节点成功出块所得的收益由它本身和为它投票的节点共享,通常会按照投票节点的票权占比分配它们各自的收益,因此票权占比大的节点(大节点)所得的收益相对会多一些。文献[19]提出了如何计算PoS 机制中每个参与区块生成的节点的收益,算法的主要思想是将所有参与区块生成的节点看作一个联盟博弈(N 代表局中人集合,v 称为价值函数)[20],中的每个节点i 称为局中人,联盟博弈中要解决的关键问题就是如何分配每个局中人的权益。中每个局中人所得的收益称为沙普利值,记为。记节点Ni在一次共识过程结束后所得的收益为E,则每个局中人i 所得的收益为:
在这种收益分配算法中,大节点(票权占比大的节点)对应的沙普利值不一定与它们的票权占比成正比。比如,当大节点的票权占比不变而小节点的个数增加时,小节点所得的总体收益会增加,大节点的总体收益会减少。这种分配算法旨在通过增加小节点的收益改善系统中贫富不均的现状,但算法未能考虑大节点会有分散投票权(比如一个节点有1 000 个币,将这1 000 个币分成10份分别投给不同的节点)的行为,大节点可以通过分散投票权将自身的币投给多个节点,这样大节点就变成了多个( )N,v 中的小节点,以此增加大节点自身的总体收益。因此,算法有必要限制节点的投票次数,防止一个投票者通过向多个节点投票获得更大的收益。同时考虑到系统运行DPoS机制时每经过一个时间间隔(目前为1天)代表节点的名单会被更新一次,当系统发起投票时,每个节点投票的时间也是不一样的。为了给积极投票的节点更多的奖励(即如果节点能够保持时时在线,及时响应系统发起的投票任务,则会获得较多的收益),可以在收益分配算法中加入时间因素,节点投票的时间与系统发起投票日期的时间间隔越小,节点所得的收益就越多。因此,对于系统中的所有节点来说,要获得收益不仅要向其他节点投票,还应该在系统发起投票指令后及时投票,这样才有可能获得较多的收益。
本文在文献[19]中的收益分配算法基础上进行了改进,改进后的算法规定每个投票者只能对一个节点进行投票,并在计算节点沙普利值后又加入了时间因素对节点所得收益进行再分配,改进后的收益分配算法如算法1所示。
3.1.2 合理性分析
在奖励分配方案中,每个投票者所得的最终收益不仅取决于它们在整个联盟博弈中的沙普利值,还取决于它们投票的时间与系统发起投票日期的时间间隔。假设系统中存在两个节点a 和b,且两节点对应的沙普利值均为1/3,按计算沙普利值的方式两节点所得的收益都为33%。如果a 节点与发起投票的时间间隔Ta=1,b 节点对应的时间间隔Tb=6,根据算法a 节点所得最终收益仍然为33%,而b 节点的最终收益仅为33%×1/6≈5.5%。由此,可以看出虽然两节点在( )N,v 中的沙普利值相同,但a 节点的投票时间要早于b 节点,所以a节点的最终收益要高于b 节点。因此,节点要想获得较多的收益,应该保持时时在线,及时进行投票。
3.1.3 惩罚措施
针对成功出块的代表节点没有遵守协议独吞收益的情况,系统可以设置惩罚措施约束代表节点的行为。区块奖励只有在代表节点成功生成块时提供,因此投票者有责任跟踪他们支持的代表节点的行为。假设在一次共识过程中由代表节点Ni负责生成区块,当Ni成功生成区块并得到相应的奖励后并没有将奖励分配给它的支持者,那么投票给Ni的节点将收回它们的选票。系统监测到一个代表节点的选票被它的大多数支持者收回时,就会认定此节点做出了违反系统规定的行为,此时系统就会将该节点的保证金没收,以此来表示对该节点的惩罚。一个普通节点成为代表节点时需要缴纳的保证金的金额相当于生产一个区块收入的100倍,因此如果一个节点做出独吞收益的行为,它将损失一笔数量不小的财产,对该节点来说得不偿失。奖励机制流程如图1所示。
图1 奖励机制流程图
在DPoS 机制的选举过程中,系统不希望出现过作恶行为的节点再次成为授权代表节点。因此,为了降低恶意节点成为代表节点的概率,系统有必要对代表节点的行为进行打分,根据它们的行为给予相应的分数,分数高的节点被信任的概率就越大,在下一轮选举中往往占有一定优势。
3.2.1 信誉值
在DPoS 机制中,每轮投票结束后,成功当选“董事会”成员的节点拥有验证并生产区块的权利。系统开始会为每个节点分配100分的信誉值。传统DPoS机制中每个周期内一个代表节点只生产一个新区块,如果一个节点成功生产出一个区块并且经其他节点验证此区块确实有效,系统会给予此节点10分的信誉值奖励;并且信誉值会在以后随着节点的行为逐渐累加,阈值为200分。当一个节点存在作恶行为、未在规定时间段内生产出有效的区块时,此节点会被扣掉10分。
3.2.2 节点状态
根据节点信誉值的大小,本文会给每个节点添加一个状态标识,并设置三种不同的节点状态,每个节点的状态都与它们的信誉值相关:
normal:代表信誉值在区间[100,150]内的节点,此状态的节点未当选过代表节点或在共识过程中表现一般;
good:代表信誉值在区间(150,200]内的节点,此状态的节点在共识过程中表现良好,无作恶行为出现。
bad:代表信誉值小于100分的节点,此节点在共识过程中表现不佳,有作恶或其他不良行为出现;
3.2.3 信誉值重置
为了避免出现由于某些节点信誉值累计过高导致投票结果趋于中心化的现象,信用机制中增加了重置信誉值的功能。DPoS 机制中得票数最多的前N个节点在一个周期内轮流生产区块,当一个周期结束之后,系统又会重新选举代表节点。每轮选举开始时,节点都会保留它们当前的信誉值,只有当每个周期结束之后,节点的信誉值才会发生变化。信誉值重置是针对good状态的节点而言的,一个节点的信誉值最高可以为200分,当一个状态为good 的节点的信誉值达到200 分时,此时系统会将该节点的信誉值重置为100分(为了让其他状态的节点有更多的机会生产区块及在一定程度上缩小贫富差距,综合考虑,重置为100分最合适)。
3.2.4 节点状态变更
状态变更指的是代表节点的状态变化,主要与节点产生的区块数量及有效性相关。开始系统内所有的节点均处于normal状态,当代表节点多次产生有效区块并且产生区块的次数大于累计值(累计值是一个节点状态变更的常量)时可升级为good状态,处于good状态的节点有较高的信誉值,在以后的竞争选举中处于一定优势;当处于good 状态的节点有产生无效区块的记录或信誉值达到阈值时,该节点可能又变为normal 状态;而good状态的节点产生无效区块的次数超过累计值时,该节点可能被降级为bad 状态,bad 状态的节点只有产生有效区块才可能升级为normal 状态。代表节点的状态转换图如图2所示。
图2 节点状态转换图
在DPOS中加入信用机制后,每个节点都拥有一个状态标志,这样在每一轮的投票选举过程中投票节点可以根据其他节点的状态选择自身信任的节点,因此节点的状态可以看作是节点的一个标记。Good状态的节点说明在多次共识过程中都能产生有效区块,其他节点出于对系统安全性的考虑,在投票时会优先考虑这些节点,因此信誉值越高的节点在每轮选举过程中往往占有一部分优势,再次被选为代表节点的可能性较大。整个信用机制的流程图如图3所示。
投票结果统计是选举代表节点的最后一个流程,合理的计票方式能够提升选举结果的公平性及系统的安全性。本文针对DPOS机制的改进方案提出了一种新的投票结果的计算方式,某节点最终得票数的计算公式如下:
总得票数=α×支持票+β×信誉值 (2)
图3 信用机制流程图
在这种计算方式中引入了两个参数α和β(α+β=1),节点处于不同状态时对应的的α和β的值是不同的,所以α和β能够在一定程度上影响节点的最终票数。本文引入信用机制的目的是降低恶意节点成为代表节点的概率,因此系统必须保证信誉值高的节点成为代表节点需要的票数比信誉值低的节点需要的票数要少。基于这种原则,本文为三种状态下的节点对应的α和β设置了不同的值。当一个节点处于normal状态时,α和β的值都置为0.5;对good状态的节点来说,它们的信誉值较高,成为代表节点需要的票数要少,所以β的值理论上要大于0.5,α的值要小于0.5;而bad状态的节点成为代表节点需要的票数最多,所以α的值要大于0.5,而β的值要小于0.5。对处于同一状态的节点来说,它们的信誉值相差无几,得票数多的节点成为代表节点的概率大;对处于不同状态的两个节点来说,信誉值越高的节点对应的β的值越大,这也就意味着信誉值低的节点要成为代表节点需要更多的票数。因此,这种新的投票结果的计算方式保证了选举结果的公平性,从而能够提升系统的安全性。信用机制的具体算法如算法2所示。
基于提出的DPOS机制的改进方案,本文在配置为Intel i5-3320M CPU 2.60 GHz处理器,8 GB内存,64位的Ubuntu 18.04 系统下,在以太坊客户端Geth 上搭建测试用的本地区块链进行实验验证。
假设对某一代表节点进行投票的a节点对应的沙普利值为1/3,即不考虑时间因素的情况下a节点可获得33%的收益。当系统规定的投票周期为1天(即24小时)时,分析a节点与发起投票的时间间隔逐渐增大的情况下,a节点最终所得收益的情况。
从图4中可以看出,当a节点与发起投票的时间间隔从1增大到24的过程中,a节点所得的收益由33%下降到不足1.5%。这说明当节点对应的沙普利值不变的情况下,利用算法对收益再分配时投票时间越早的节点所得的收益就越高,反之就越低。
图4 a 节点收益情况
为了验证在新的投票结果的计算方式中,对于不同状态的节点来说,在获得的投票数相同的情况下,信誉值低的节点要成为代表节点需要更多的票数,本文实验方案中选择了三个信誉值不同的节点:a节点(信誉值为80分)、b节点(信誉值为125分)和c节点(信誉值为175分),分析这三个节点在得票数相同的情况下按投票结果计算方式所得的总得票数情况。实验结果如图5所示。
图5 各节点得票数情况
由节点总得票数的对比图可知,三种节点在得票数相同的情况下,c节点的总得票数明显要高于b节点和a节点,这说明信誉值低的节点只有比信誉值高的节点获得更多的票数才有可能成为代表节点;另外,当投票数超过200 后,a节点的总得票数很可能高于b节点。因此,为了降低信誉值低的节点成为代表节点的概率,可以动态调整α和β的值以保证系统的安全稳定运行。
EOS项目在传统DPOS机制上进行了改进,将代表节点的数量由101个减为21个,并且在共识过程中采用代表节点连续出块的方式提高区块的产成速率。虽然这种方式可在一定程度上缩短交易的确认时间,但仍未解决传统DPOS机制中存在的问题。文献[17]采用基于信用的奖惩方案解决节点投票积极性不高的问题,节点可以通过投反对票的方式获取更多的信用分数,当节点两次投票的时间间隔超过T时,信用分数就会降低。在这种改进方案中,节点会通过投票的方式为自己赢得更多的信用分数,虽然信用分数高的节点被选为代表节点的可能性大,但是节点的信用分数高并不代表被信任的概率大,而且对于那些作恶的节点并没有相应的惩罚措施。
本文提出的改进方案中通过信用机制为节点设置了状态和信誉值,系统根据节点在共识过程中的表现增加/减少它们的信誉值,信誉值的高低代表了不同的状态。good 状态的节点说明它在共识过程中几乎无作恶行为,被信任的可能性较大;而bad 状态的节点说明它在共识过程中有大量作恶行为,被信任的概率小。节点在投票时可根据其他节点的状态判断它们是否能被信任,从而可降低恶意节点成为代表节点的可能性。为提高投票节点的积极性,奖励机制采用为投票节点分配收益的方式而非给予它们相应的信用分数。奖励机制规定代表节点的收益要与为它投票的节点共享,由于每个节点都带有一个状态,投票的节点为了尽可能的获得收益,在投票时更倾向于投给good状态的节点,可在一定程度上保证系统的安全性。
由于每个投票节点手中的权益是不一样的,因此它们为同一个代表节点投票后的票权占比也是不同的。按照每个投票节点的票权占比分配收益的方式看似是一种合理的分配策略,但实际上会让系统中权益越多的节点越有钱,加剧贫富差距。本文实验主要分析在时间间隔T固定的情况下(为了简单起见,可以令T=1),系统中存在两个大节点(每个大节点拥有1/3 的票权且只能投票一次)时,随着小节点的数目逐渐增多,按沙普利值再分配和按票权占比再分配两种方式中小节点所得收益的情况。实验结果如图6 所示。从图6 可以看出,在小节点个数相同的情况下,考虑时间因素进行收益再分配时,小节点按沙普利值再分配所得的收益都要高于按票权占比再分配得到的收益。这说明当所有节点的时间间隔T都相同时,改进的分配算法能够让小节点获得较多的收益,这将有利于小节点的健康发展和缩小大小节点之间的贫富差距。
图6 小节点最终收益情况
文献[17]为降低恶意节点成为代表节点的可能性,提出了一种优化投票结果的统计方案,具体计算公式为:
式中,A的值可根据系统的安全性进行设定,B、C的值是常量,通常取B和C的值是0.5。
为了将本文提出的对投票结果的优化方案与文献[17]中的方案进行对比,分析在考虑评分的情况下恶意节点成功被投票为代表节点的概率,本实验在Geth搭建了一条测试链gttc,设置了20 个账户,并以go语言的方式将改进的DPOS 方案添加进Geth的创世文件genesis.j son中。由于文献[17]中的投票节点可以投反对票,因此为gttc上的每个账户也都设置了投反对票的功能。当gttc启动的时候,会从创世文件中读取相关配置,系统将按照改进的共识机制进行投票、生成区块。第一轮投票结束后各节点所得票数情况如表1所示。
表1 投票结果
开始所有节点都是处于同一状态,所以可直接根据投票结果选出得票数最多的前4 个节点作为代表节点进行第一轮的区块生成及共识过程,并令账户名为“0x30d……51571”的节点在共识过程中产生无效区块,则共识过程结束后此节点变为bad状态,其他节点仍为normal状态。将bad状态的节点命名为B节点,并以第一轮共识过程结束后各节点的状态为基础再次投票,重复进行50 次实验,统计B节点在两种投票结果计算方式中的得票数情况。根据实验结果,绘制出B节点在两种方案中的票数排名对比折线图,如图7所示(方案1是本文提出的投票结果的优化方案,方案2 是文献[17]中的方案)。
图7 B 节点所得票数的排名情况
从B节点在50 次实验中的票数排名情况可以看出,大约30 次实验之后B节点在两种方案中的排名情况逐渐稳定(方案1 中排名17 左右,方案2 中排名11 左右),但从对比情况可得出总体上B节点在方案2 的票数排名要比方案1 中的排名靠后。这说明本文提出的方案能够显著降低B节点成为代表节点的可能性,从而为系统的安全性提供了一定的保障。
本文通过对DPOS共识机制的特点进行分析,针对其中存在的节点投票积极性不高及如何降低恶意节点成为代表节点的概率问题,提出了一种基于奖励机制和信用机制的改进方案。奖励机制中规定投票节点也会获得相应的收益,并采用计算节点沙普利值的方式分配各自的收益,由此普通节点的投票积极性会提高并缩小了节点之间的贫富差距。信用机制为节点设置了信誉值和状态,提出了一种将信誉值考虑在内的投票结果的计算方式。新的投票结果的计算方式能够使信誉值高的节点获得极少的票数便可成为代表节点,而信誉值低的节点要成为代表节点需要更多的票数,从而能够提高系统的安全性。改进后的方案通过在以太坊平台上搭建测试链的方式进行实验验证,未来的工作将在共识机制的吞吐量及共识时延等方面进行探索,寻求共识机制更广的应用领域。