PDF论文链接:https://arxiv.org/pdf/1905.09655.pdf
本文为精读解读,想读这篇文章的朋友请耐心看完。(都是干货)旨在让你对最新的区块链研究方向和思路有所了解。
该篇文章出自2019年8月信息安全四大顶会的Usenix Security,所以绝对值得一读,是对PoW共识算法的一种改进,主要引入了透明度与合作机制,激励参与者合作而不是竞争。核心设计是将之前造成大量资源浪费的算力变得有用起来。以此提出了StrongChain的设计。
1、介绍
比特币的Nakamoto共识是基于工作证明(PoW),以减轻西比尔攻击(Sybil Attack: 在对等网络中,攻击者通过伪造多个身份标识,以控制网络中大部分节点来削弱冗余备份)。
文章中提出了比特币是激励不相容的,在某些情况下,矿商暂时不发布这个区块, 而是继续挖下一区块, 当发现网络上别人也挖出新区块时再发布这个区块, 这时出现分叉的情况,恶意节点可采用女巫攻击sybil attack 来伪造多个节点身份,使其他诚实节点相信他,可以获得更高的收益.(自私挖矿策略)
激励相容:没有人可以通过损害集体利益去实现自己利益的最大化。个人的利益和集体的利益是一致的,每个人努力为实现自己利益的目标工作,得到的结果也是集体利益的最大化。
自私挖矿:恶意节点将其发现的区块保密,从而有意分叉该链。在适当时候公布私有分支。诚实节点继续在公共链上进行挖掘,而恶意节点在其自己的私有分支上进行挖掘。如果该恶意节点发现了更多的区块,它将在公共链上拥有更长领先优势,并继续将这些新区块保密。当公共分支的长度接近恶意节点的私有分支时,自私的矿工就会将私有分支公布,获得其他矿工的认可,使得诚实挖矿的区块无效,进而获得更多的收益。这样也会使其矿池越来越大,从而破坏整个网路。
注:当一个连接着“自私采矿”的网络的计算能力超过某个阈值(大约超过30%)时,这种攻击会更有效。
另一个问题是,比特币系统的日益普及趋向于其集中化。
研究结果表明,从长期来看,比特币可能是不可持续的,主要原因是矿商的报酬下降,最终将完全停止。除此之外,对于一个交易系统来说,比特币的设计更注重可用性而非一致性,这是很不寻常的。
该篇文章从以上这些问题出发,提出了一种挖矿过程更透明和合作的系统设计。提出了弱解的设计:
1、弱解是协议的一部分。
2、发现弱解的矿商会获得独立的奖励。
3、矿商有动力立即宣布自己的解决方案和附加别人的方案。
2、背景和问题定义
该部分主要讲解比特币挖矿存在的一些问题,以便引出本文设计。
比特币是一种通货紧缩的货币,按照协议规则,大约在2140年,将不会产生新的硬币(上限为2100万),这意味着矿工们将只能获得交易费作为收入。
图中可得,当最后的2016个块(代表最近的块)产生的时间更长时,T会变大,也就意味着之前2016个块的计算难度偏大,需要降低难度,所以T变大,相反依然。
比特币还有很多问题需要解决。截至2018年11月,只有5个最大的比特币池占整个比特币网络的采矿权的65%以上。这样的矿坑不仅破坏了系统的分散性,还会产生各种池内或池间的安全问题。
比特币的最长链选择原则并不能完美地解决分叉问题,它会带来一些不安全的影响。
本文设计应考虑的因素:
1、安全性:该计划应该是激励兼容的,以便矿工从遵循共识规则中受益,而从违反共识规则中得不到任何收益。
2、奖励差异:最小化奖励的差异。这项要求对于权力下放至关重要,因为高奖励差异是个体矿工加入集中式矿池的主要动机。集中化是不可取的,因为足够大的矿池会攻击比特币协议。
3、链质量:应保证高质量:
(1)采矿功率利用率:主链上的挖掘能力与整个区块链网络的挖掘能力之间的比率。此属性描述了挖掘的性能,其理想值为1。
(2)公平性:即矿工应按与其在采矿中投入的资源成比例地获得奖励。
4、效率和实用性:该方案不应引入任何重大的计算,存储或带宽开销。
3、设计概述
设计理念:
比特币的开采并不透明。很难快速估计不同参与者的计算能力,因为唯一的指标是找到的块。毕竟,块以较低的频率到达,每个块的隐含计算能力均相等。
同时,比特币开采会遭受自私挖矿的攻击。在实践中,检测并证明解决方案是隐藏的具有挑战性,应推广可见的解决方案。这将激励矿工立即发布其解决方案,因为将其保密可能会带来太大风险,其他矿工可能会随着时间的推移加强潜在的竞争解决方案。
——>以此推出:须重新设计比特币的奖励机制,增加透明度、合作性。
概述:
本文设计提出了弱解相关机制,弱解对于标准解决方案具有很重要的作用,但又不能完全满足标准方案的解。弱解也在一定程度上代表着矿工的计算能力。
设计中会让弱解进行交换,来达到透明性,具体来说,首先还是会解决一个难题(PoW做一道计算题),然后发布解决方案的同时还会发布一个与解决方案相关的弱解决方案,这个方案可嵌入其他矿工的弱解决方案,这样的方案和计算能力会不断聚集在同一个分支上,避免分叉。
同时,更重要的是,发布弱解决方案的矿工会得到一份额外的奖励。这就不是矿池中的矿商之间获取利益,而是发现弱解的矿工都会获得。而且是按对于给定区块的贡献比例来发放奖励,所有奖励均独立于该区块的其他解决方案,这样可以避免矿工因为收入而加入大型矿池。
这样的设计的作用:
首先,一个自私的矿工发现一个新的区块会给这个区块保密,这将冒着很高的风险。这是因为由于诚实的矿工交换部分解决方案并增强了他们的预期区块,因此区块具有更好的粒度,在使用分叉的情况下,这将比保密的较旧区块(即自私矿工的区块)更强大。
其次,激励矿工通过以下方式进行协作:a)交换他们的弱解,b)附加其他矿工提交的弱解。前一种情况会获得奖励,如若自私挖矿,则无利可图,后一种情况可以壮大自身力量。
通俗来讲,假想在一间教室里,每个同学都在做数学题,做对了的会有奖励,按照本文的设计,做对了的人会给出他的答案(解决方案),同时还会给出他的解决思路(弱解方案),其他的同学不光可以借鉴他的答案,还可借鉴他的解决思路来解决自己的题,同时他们还可以互相交换他们的思路,最后的提交时附加上他们自己的思路,只要他们提交了自己的思路就能获取一定的独立的奖励,这样的话,一不会存在一些人故意隐瞒自己答案(自私挖矿),因为那样他没法获取独立的奖励,二也加强了同学们之间的合作性。对整个班级(系统)有一定的积极影响。
4、StrongChain设计细节
本章展示了本文设计StrongChain的各种细节。
(1)算法:
首先是算法部分,每一个function都有它的作用和设计,要理解设计思想,务必耐心看完:
方法一:
解释:首先还是PoW机制,先找一个nonce,找nonce需要不断对头部hash直到hash值小于某个目标(算法中为Ts),过程都是基于头部的。不同的是加入了弱解机制,即解出的hash值只需小于另一更大的目标就满足弱解要求(算法中为Tw),很明显,需满足:
满足htmp < Tw条件时会将弱解头部加入到头部数组中(倒数第二行代码),最后会根据头部、弱头部数组、交易数据Txs一起创建区块B,并广播B。
方法二:
解释:各个节点会收到广播的弱头部,然后进行验证:
1、是否满足Ts<=hw
3、标头是否指向一个强标头。(Prehash满足)
方法三、四:
解释:奖励方法分两种奖励,一种是基本奖励和交易费,另一种是根据弱头部数量来进行成比例的奖励,这个比例值由Ts/Tw决定。
Coinbase:代表将获得奖励的矿工地址
R:代表全额奖励,发现强头部的矿工可获得(只有很少一部分“幸运”的矿工能获得)
γ :弱头部相对影响因子
c:缩放常数
注:一个区块的弱解的数量是无限的,它们是独立奖励的(即不共享任何奖励)。并且系统中的所有区块奖励都与贡献的PoW成正比
验证区块方法主要是验证头部hash
方法五、六:
解释:方法五主要获取区块链上的Tmax(最大目标)与各个区块的Tartget(Ts)或弱解Tartget(Tw)的比值和sum。在之后也叫PoW值,主要表示该链分支的计算能力,以解决分叉问题(详见后面的分叉讨论)。
方法六获取区块时间戳。StrongChain对于时间戳的设计也有一定的改进,这样的改进能使时间戳更适用于强弱解机制,更加的可靠。
(2)、块布局与验证
其他字段不用多说,Coinbase字段主要是存储打包该块的节点以及发出弱解的节点的地址,以此一一对应,防止某些节点未给出弱解而获取弱解奖励的情况发生。
弱头部PreHash、Target与版本字段与指向的强头部相同,可以删减这些字段来节省空间。
为了保护与强头部相关联的所有弱头部的完整性,文章引入了绑定事务,以保护所有相关联的弱头部(图中的弱头部集合虚线框)。
(3)、分叉
对于分叉问题,设计采用最强链原则,其主要指标是上述算法中chainPoW方法计算出的PoW值,根据该值是Tmax与Ts或Tw的比值,代表了整个链上的计算能力,Ts或Tw较小则表明计算能力更强。所以PoW值能反映不同链的计算能力,以此解决分叉。
(4)、奖励机制(具体参考方法3 rewardBlock)
在奖励计划中,新铸造的硬币数量始终至少为R,因此,与比特币或以太坊不同,协议中货币的总供应量没有上限。该设计决策是根据有关通缩加密货币长期不稳定性的最新结果做出的。
5、分析
本章主要说明StrongChain对于效率和实用性的影响,以及之前讨论的奖励差异、链质量和安全性的影响。
效率和实用性
主要讨论增加的额外负载:弱头部。文章中利用概率分布等说明了每个弱标头60个字节和每个比特币块1MB,最后负载会增加%6以上。
文中证明了当γ = 1时,则强头部区块奖励和弱头部奖励几乎等于矿工的总奖励。所以跟传统比特币奖励实用性是一致的。
奖励差异
如上图所示,Tw/Ts表示弱解目标与强解目标比值,比值=1表示比特币,随着比值的增加,更多的节点可以通过给出弱解来获得小份的奖励,这意味着奖励差异会缩小。α表示占全球挖矿能力的多少。
链质量
衡量区块链“质量”的一种方法是过时的块率,即在分叉过程中出现但未进入主链的块的百分比。即stale rate。
如表中所示,强区块过时率部分StrongChain与比特币是差不多的,而弱区块过时率也是比较低的。在公平性方面,高延迟和低延迟两种情况下的确要差于比特币,但是中延迟时有一定的优势。
安全性
文章中主要利用实验证明了StrongChain为自私挖矿策略增加了鲁棒性,矿工的自私挖矿意图将会大大降低。
6、讨论
本章主要讨论之前涉及到的参数的选择。
γ确定了弱头部对总采矿奖励的相对贡献
方案一:γ和难度因子都低的时候,对采矿者的奖励方差的影响将是温和的,因为强大的区块奖励仍占采矿奖励的50%(也就是说作用不大)。
方案二:当γ高但难度因子低的时候有利于小型矿工减少集中化(缩减贫富差距)。
方案三:当γ和难度因子都高时,恶意开采的影响将会减轻,因为区块能够迅速积累足够多的弱头部以获得高γ对应的丰富奖励。
本文设计中选择了第二种方案:γ高难度因子低,原因是方案二的减少集中化比方案三的恶意开采要重要一些,减少集中化也更加符合StrongChain的设计思想,而且恶意开采并不能为攻击者带来很明显的收益。
最终设定参数:Tw / Ts = 1024时的γ= 10
此外,还讨论了集中式挖矿与StrongChain的对比:
图中可以看到StrongChain很好地解决了矿池资源集中化的问题,最后一列是对比的倍数。
7、实际中的实现
文章中给出了github的demo链接:https://github.com/ivan-homoliak-sutd/strongchain-demo/
8、总结
在本文中,提出了一个透明且协作的工作量证明协议。方法基于Nakamoto共识和比特币,但是修改了其核心设计。与它们相反,本文设计利用了弱解决方案,尽管一些节点最终没有完成区块创建,但对区块链属性有积极贡献。此外本文还提出了一种奖励计划,使矿工可以通过交换和附加弱解决方案而受益。这些修改可产生一个更安全,公平和高效的系统。最后,本文设计的实施表明了方法的效率和可部署性。共识协议的面向激励分析是一个相对较新的主题,将来,本文希望使用新颖的框架和工具对协议进行建模来扩展接下来的工作。将来值得研究的另一个主题是如何将StrongChain与解决Nakamoto共识的其他缺点的系统结合起来,或者如何在权益证明环境中模仿协议。
Demo实现
以下是自己编写的一个小Demo,主要实现了上述算法中的各种方法并串联(chainPow与timestamp方法未考虑):
from hashlib import sha256
Ts = 6 # 强头部目标
Tw = 5 # 弱头部目标 小于Ts的原因:原文是大于Ts,但这里模拟是hash值前T位为0,T目标与复杂度成正比,便于展示运行
# 区块类
class Block:
def __init__(self, name, hdr, data, weakHdrsTmp):
self.name = name
self.hdr = hdr
self.data = data
self.weakHdrsTmp = weakHdrsTmp
self.hash = self.caculateHash()
def caculateHash(self):
result = str(self.hdr) + str(self.data) + str(self.weakHdrsTmp)
return sha256(result.encode("utf-8")).hexdigest()
def __str__(self):
return str(self.__dict__)
# 哈希
def Hash(value):
return sha256(str(value).encode('utf-8')).hexdigest()
# 创建头部
def createHeader(nonce):
return Hash(nonce)
# 开采一个区块
def mineBlock():
weakHdrsTmp = []
nonce = 0
while (True):
hdr = createHeader(nonce)
h_tmp = Hash(hdr)
if h_tmp[0:Ts] == str(0).zfill(Ts):
B = Block("一号区块", hdr, "区块数据", weakHdrsTmp)
print("得到强解,nonce:" + str(nonce))
print("hash value: " + str(h_tmp))
broadcast(B, 0)
return
if h_tmp[0:Tw] == str(0).zfill(Tw):
weakHdrsTmp.append(hdr)
print("得到弱解,nonce:" + str(nonce))
print("hash value: " + str(h_tmp))
broadcast(hdr, 1)
nonce += 1
# 广播强弱解,type=0代表强解广播,1代表弱解广播
def broadcast(info, type):
if type == 0:
print("广播强解\n")
# 验证区块
validateBlock(info)
else:
print("广播弱解")
# 处理收到的弱解头部
onRecvWeakHdr(info)
# 验证区块
def validateBlock(block):
assert Hash(block.hdr)[0: Ts] == str(0).zfill(Ts) and validHeader(block.hdr)
assert validTransactions(block)
print("区块强解验证正确")
# 奖励,0代表强解奖励
rewardBlock(block, 0)
# 处理弱解
for weakHdr in block.weakHdrsTmp:
assert Hash(weakHdr)[0:Tw] == str(0).zfill(Tw) and validHeader(weakHdr)
rewardBlock(weakHdr, 1)
# 模拟其他节点接收交换弱解
def onRecvWeakHdr(hdr):
hw = Hash(hdr)
assert hw[0:Tw] == str(0).zfill(Tw) and validHeader(hdr)
print("接收弱解\n")
# 奖励机制
def rewardBlock(info, type):
# info根据type决定,可以是区块可以是弱头部hdr
R = 10 # 全额奖励假设为10
if type == 0:
print(info.name + "发现者获得全额奖励R与交易费TxFees:" + str(R))
else:
y = 1
c = 1 # 缩放常数
w = y * Tw / Ts # 弱解奖励比例
print(info + "弱头部发现者获得奖励:" + str(w * c * R))
# 模拟验证头部正确性
def validHeader(hdr):
# 模拟验证头部正确性
return True
# 模拟验证交易数据正确性
def validTransactions(block):
# 模拟验证交易数据正确性
return True
mineBlock()
运行结果
由于Ts目标设为6,Tw设为5,所以必须找到hash值前6位为0才算找到强解,前5位为0算找到弱解。