作者:王翔
前言
说起当今最具代表性的数据通信技术,区块链无疑在列。作为当下最受关注的次世代分布式系统,区块链可谓众说纷纭,莫衷一是。有人视之为引爆下一次互联网技术革命的突破口,也有人称其为投机工具,惊世局。本文旨在于尽可能悬置那些游离于技术层面之外的价值判断,将视角重新移回到区块链技术本身,完整回溯区块链1.0到3.0的技术原理和设计理念之沿革,为读者揭开笼罩在区块链之上那层神秘的面纱。
第一章区块链网络与数字货币系统
一、区块链的技术背景
1.区块链的起源
2008年,美国次贷危机爆发,金融海啸席卷全球,经济萧条延宕数年之久。对2008危机的溯源性研究指向了多个可能的诱发性因素。除了次级贷款市场的过度放贷和杠杆率居高不下,主权货币的滥发也成为了金融危机的一个重要诱因。
同年11月1日,某化名为“中本聪(SatoshiNakamoto)”的网络极客发表了一篇名为《比特币:一种点对点的电子现金系统》的技术论文,也即后来人们所称的《白皮书》。《白皮书》在基于主权信用背书的货币系统基础上进一步提出了一种能够规避主权货币滥发,而且完美解决了货币信用问题的电子支付系统——比特币。该书完整阐述了筑基于点对点传输技术,密码学算法,区块链技术之上的比特币分布式网络的架构理念。
2009年,序号为0的区块——创世区块诞生。时隔不久,序号为1的第二个区块诞生,并与创世区块相连,世界首条区块链面世。
需要澄清的一点是,与其说区块链是一种技术工具,毋宁谓其为一种理念。无论是构成区块链技术核心的共识算法,容错算法,加密技术,传输技术,存储技术,其都是构筑于完备的数学和密码学基础,而非工程学技术。正是因此,区块链技术并不强依赖于物理基础设施,在最极端的情况下,理论上我们甚至可以只借助于二战时期的无线电技术来搭建一个简易的区块链网络。就广义范畴而言,比特币只是区块链技术的一种具体实现形式,只要具备去中心化,全网共识,防篡改,可回溯这几个核心要素,都可视为区块链技术理念的横向延伸。
一言以蔽之,区块链的本质是一种基于密码学算法的“电子契约”。
2.区块链的技术优势
十数年间区块链技术历经了数次迭代发展。从以比特币为代表的区块链1.0到以以太坊为代表的区块链2.0再到以Hyperledger,EOS为代表的区块链3.0,区块链技术所能承载的业务场景和应用范围愈加广泛。其功能已不仅仅局限于电子货币系统,而是进一步推广到了企业,机构间数据共享,高敏感性数据存储等诸多场景。
目前区块链的技术优势在于:
去中心化(或多中心化),每个节点都保存了完整的区块链信息,解决了敏感数据的备份问题和传统分布式系统的信息不对称问题。去信任化,通过密码学基础和区块链网络解决了中心化系统的信任机制问题,由整个区块链网络而非某个中心服务器提供信用担保。不可篡改,所有持久化的区块永久保存,交易记录可随时回溯,一笔交易只能通过另一笔交易进行追偿,无法单方面取消。规避了传统数据库的数据丢失和恶意篡改风险,更加适用于高敏感性数据(如金融数据,企业核心业务数据等)。二、比特币的基础数据结构与交易集验证机制
1.区块与区块链
作为一种数据存储系统,区块链的本质仍然是一个数据库,只不过是由整个网络共同维护的分布式数据库。不同于传统的结构化关系型数据库,区块链为了实现时间维度的永久可回溯性,在底层数据结构中并不存储数据的状态,而只存储对数据的变更。
以比特币为例,作为一般等价物的货币本身只是一个价值符号,其意义在于对交易的额度标记。因此比特币网络就是一个大型的电子记账系统。而区块链中存储的便是网络中用户之间的交易记录。
图一:区块链结构一个区块主要由区块头和区块体两部分构成,大小约为1M左右。区块头主要用于存储版本号(用于标识当前的软件协议版本),父区块哈希编码,默克尔根,时间戳,难度目标,Nonce随机数等数据。其中父区块哈希编码用于和上一个区块产生唯一性链接。默克尔根用于为比特币用户提供简单支付验证(SPV),这一部分内容将在后文中详细介绍。
而区块体中则包含了一组具体的交易记录集合,交易分为两种类型,Coinbase交易和普通交易,每个区块中第一笔交易属于Coinbase交易,是区块链网络给予记账者的奖励。而其它则是用户之间进行转账的普通交易。每个区块中大概包含了4000条左右的交易记录。获得记账权限的节点会将区块头和区块体打包成一个完整的块并广播给整个区块链网络,其它节点验证通过后便会将其作为一个新区块加入区块链。
2.默克尔树(MerkleTree)与交易集合
在区块链结构中默克尔树扮演了极为重要的角色。其一方面用于产生每个区块的唯一数字摘要,另一方面也可以用于在部分节点存储空间有限的情况下进行简单支付验证(SPV)操作。
图二:默克尔树
所谓默克尔树,是一种典型的二叉树数据结构。在每个区块的区块体中都保存了若干条交易记录,这些交易记录被均匀挂载在一个默克尔树结构中。树的每个叶子节点都保存了对应挂载的交易记录哈希值。而每个叶子节点又会两两配对合并为一个新的字符串,进而用新字符串的哈希值构成上一级节点,一直迭代到最终产生一个唯一的根节点HROOT(在交易记录为奇数条的情况下可能会存在余根的情况,因此会将奇数条记录全部拷贝一份,构成平衡树)。这样在根哈希HROOT中就包含了每一条交易的数字摘要,任何一条记录的增删和变更都会由末端传导至根哈希上。
因为默克尔树下挂载的每一笔非相邻交易记录之间都是通过不同的上溯分支连接到根节点,因此默克尔树相比哈希列表可以单独对某个分区内的信息正确性和完整性进行验证而无需重构所有叶子节点下的数据。这一数据结构被广泛应用于分布式网络中的数据校验服务。
图三:异质分区定位算法
除了通过上溯分支验证数据正确性外,默克尔树还可以用于快速定位两个树结构下异质分区的位置。如上图所示。当HROOT-A≠HROOT-B时,只需向其下级节点回溯找到“gsc3”和“gts1”两个异质节点,之后重复这一过程直至追溯到叶子节点,即可定位到两个树结构中的异质分区。
3.简单支付验证(SimplifiedPaymentVerification)
在比特币网络中,每一笔交易都要验证,不仅涉及对帐户余额的验证,还需要对交易的执行结果进行验证。这一过程有时可能需要回溯整个区块链重构账户状态,所需要的算力往往超出一般节点的算力载荷,因此通常情况下是由一些挖矿节点来进行交易验证。
此外还存在另一种场景,那就是支付验证。也就是验证某一笔交易信息是否已经被区块链网络所确认。对此,中本聪提出了一种更为经济的验证方式,那就是简单支付验证(SPV)。SPV是一种基于默克尔树结构的数据存在性校验算法。因为支付验证只需要校验某笔交易是否在区块链中存在,因此并不需要保存整个区块链的信息。
图四:SPV算法如图所示,在区块体中,每笔交易都挂载在默克尔树的一个叶子节点上。如果我要验证交易6是否在某个区块中存在,那么我只需要得到H5,H78,H1234三个节点的信息,然后循着上溯分支计算出默克尔根,验证其与HROOT是否相同即可。因此用户只需要保存每个区块的区块头信息即可完成对某笔交易的支付验证(其本质为验证某笔交易所在的区块是否为共识区块)。
三、拜占庭将军问题(ByzantineFailures)与拜占庭容错算法(ByzantineFaultTolerance)
1.拜占庭将军问题
1982年,计算机科学家莱斯利·兰伯特(LeslieLamport)提出了著名的拜占庭将军问题,该问题基于一个虚构的历史架空场景:
图五:拜占庭将军问题
拜占庭帝国的军队包围了一处敌军的堡垒,但是为了维持包围纵深使得军力不得不分散为几支彼此独立的部队。如果想要攻陷堡垒,那么就需要几支部队共同行动(一起进攻或者一起撤退)。如果只有一部分军队进攻,另一部分军队撤退,那么战局将会陷入无可挽回的失败。已知其中几只部队的将领已经叛变且会向其它部队发送错误的信息,那么采用何种策略才能确保部队之间行动的一致性呢?
这一看似与区块链无关的问题实则触及到了整个区块链网络设计的核心——在成千上万节点共同运作的情况下,如何达成全局数据一致性?
2.拜占庭容错算法
比特币网络属于典型的公链系统,这意味着并不会对网络中的成员设置严苛的准入机制。那么恶意节点和作弊行为就是一个几乎无法规避的问题。如何才能防止恶意节点破坏网络,随意篡改区块链中的数据呢?
莱斯利·兰伯特在提出这一问题的同时也给出了一种在无网络延迟状况下的拜占庭容错算法,这一算法在恶意节点数不超过总结点数1/3的状况下是可解的。首先这一算法将整个分布式网络简化为一个“将军(Commander)——副官(Vice-general)模型”,其中发起某个提议的节点扮演将军,其余节点扮演副官,每支部队之间可以两两互通。
所谓拜占庭容错,指的是在拜占庭问题的场景设定下,要保证如下两点:
当将军是忠诚的时,要同时保证命令的准确性(将军的提议被所有忠诚的副官正确执行)和行动的一致性(将军和忠诚的副官行动保持一致)。
当将军非忠诚时,要保证所有忠诚的副官行动的一致性。
设总结点数为N,恶意节点数为F,首先考虑不可解的情况,即N≤3F时:
图六:N=3时,V2为叛徒的情况
当C和V1是忠诚的,V2是叛徒时。C向V1,V2发出进攻命令。V1从将军处收到进攻命令,但V2告诉V1自己收到撤退命令,V1无法判定C与V2谁是忠诚的,故无法达成一致性。
图七:N=3时,C为叛徒的情况
当V1,V2是忠诚的,C是叛徒时。C向V1发出进攻命令,向V2发出撤退命令。V1从C处收到进攻命令,V2告诉V1自己收到撤退命令,V1仍然无法判定C与V2谁是忠诚的,故无法达成一致性。
之后考虑可解的情况,即N>3F时:
图八:N=4时,V3为叛徒的情况
当C和V1,V2是忠诚的,V3是叛徒时。C向V1,V2,V3发出进攻命令,V2告诉V1自己收到进攻命令,V3告诉V1自己收到撤退命令,此时V1收到的信息集合为{A,A,R},取多数原则,执行进攻命令。其余忠诚副官同理执行进攻命令,实现准确性和全局一致性。
图九:N=4时,C为叛徒的情况
当V1,V2,V3是忠诚的,C为叛徒时。C向V1,V2发出进攻命令,向V3发出撤退命令。V1收到的信息集合为{A,A,R},执行进攻策略。其余忠诚副官同理执行进攻策略,实现全局一致性。
当然在实际的分布式系统中情况远比这要复杂,可能有成百上千节点同时运行,因此当恶意节点的数量增加,这一算法是否还能够实现拜占庭容错呢?我们考虑一种更复杂的情况,令N=7,F=2。
图十:N=7时,V5,V6为叛徒的情况
首先我们定义一个三元函数:
该函数表示“Vz告诉Vx:‘Vy告诉Vz其所收到的命令’”。A表示进攻,R表示撤退,I表示不确定。假设v5和V6是叛徒,C,V1,V2,V3,V4是忠诚的。那么要想在这一情况下实现拜占庭容错,就必须用到递归算法。我们以V1节点为例,当Vx=V1时,作出FVz→V1(Vy→Vz)函数的真值表:
表一:FVz→V1(Vy→Vz)函数真值表
首先我们根据横向多数原则确定每一个忠诚将领从其它将领处收到的信息中的多数真值。然后根据纵向多数原则确定V1的最终策略,根据FVz→V1(Vy→Vz)函数真值表可确定V1的最终策略为攻击。
同理可以计算出其它将领的FVz→Vx(Vy→Vz)函数真值表,结果为所有忠诚将领都会选择攻击策略。当将军为叛徒时推演过程同上。
需要强调的是,莱斯利·兰伯特的这一算法只能应用在无网络延迟(即任意节点间可以瞬时互通)的情形下。当F值增加时,递归算法需要用到一个F维的向量函数真值表,算法复杂度会以指数级上升,因此这一算法在实际的分布式系统中几乎无法应用。在此基础上,后来计算机学者们进一步提出了POW,POS,PBFT,RAFT等实用的拜占庭容错算法,这一部分将在后文中详述。
四、比特币的记账赋权机制与基于工作量证明(ProofofWork)的共识算法
1.比特币的记账赋权机制
比特币网络的本质是一个大型的分布式记账系统,由于该网络不设准入机制,每一个成员节点都可以参与记账。虽然每一笔交易都会被全网广播,但是因为成员节点的网络环境,数据延迟都有可能不同,进而导致每个节点的账本中记录的交易数据也有所不同。更何况还会存在恶意节点的作弊行为。那么对记账者的筛选以及排除恶意节点的影响就成了比特币网络架构设计中所涉的核心问题。
首先比特币网络采用了一套有奖励的记账赋权机制。因为记账行为需要算力和内存开销,而且保存的账本中大部分内容都是与记账节点无关的交易内容。为了保持成员记账的积极性,比特币网络设置了一定的记账奖励。首先参与记账的节点可以获得以比特币形式支付的定额手续费。而获得最终打包权(账本入链)的节点则可以获得高额的打包奖励。打包奖励在第一个四年高达每次50个比特币,而这一数额每四年会减半,最终收敛于2100万个。打包机会与算力正相关,只要全网算力分布均匀,那么打包权也会均匀赋权给所有节点。比特币系统正是通过这种方式完成了货币在全网的扩散分发。
2.工作量证明(POW)
既然每个节点的账本都有可能不一样,那么最终由谁负责记账就成为了一个至关重要的问题。比特币网络采用工作量证明(POW)来实现对记账权限的唯一下发,进而实现账本的全网一致性。
传统的拜占庭容错算法如PBFT算法往往旨在于设计出一种能够对节点间的信息传输进行多重交叉验证的通信机制来达成全局一致性。而POW则采用了另一种更为简单粗暴的设计思路,那就是人为提高恶意节点伪造信息的成本,使得作弊成本远远高于所带来的收益,通过牺牲区块链网络的效率来换取数据安全性。
POW是一种以结果为导向的认证赋权机制,即不关心受验者具体的计算过程,只关心最终的结果。POW要求所有受验者计算一个“数字谜题”,先计算出这个数字谜题的节点将获得当前区块的打包权限。
在每一个记账周期内,每个节点都会接收到全网的多笔交易记录,并保存在本地区块体的交易集合中(其中第一笔交易记录为Coinbase交易,即打包奖励的交易记录,每个节点都会生成自己的Coinbase交易记录)。根据交易集合可以计算出其默克尔根,并和其余信息一起组装成区块头。除默克尔根外,区块头中还保存了当前的协议版本号,父区块哈希值,时间戳,难度目标,Nonce随机数等。其中除了Nonce随机数之外,其它数据都是已经确定的。
POW要求参与记账的节点对自己当前区块的区块头信息进行两次SHA256哈希运算,得到一个256位的数字摘要。哈希运算是一种将不定长字符串数据映射到一个256位定长的二进制散列结构上的加密算法,且用原始数据计算哈希值很容易,但是却几乎无法通过哈希值逆推原始数据。此外哈希算法还具有输入敏感特性,原始数据微小的差异都会使得哈希值大相径庭,几乎不需要考虑哈希碰撞的情况。因而有效规避了记账节点通过伪造符合要求的哈希值和原始数据来窃取记账权利的风险。
图十一:POW解谜流程
首先区块头中保存了一个名为难度目标(target_bits)的字段信息,这一字段用来调节当前POW算法的题设难度。
其中target_bits为目标值,最大为一个固定的十六进制常数target_max。因为哈希值大体上是均匀离散的,因此哈希值每一位是0或者1的概率大体上都是1/2,其取值符合古典概率模型。每一个可能的哈希值都是一个基本事件,总共有有限多个基本事件,这就使得解谜成功率可以通过target_bits参量进行调节。POW的目标难度会随着全网算力涨落而上下浮动,确保每10分钟全网至少能打包一个区块。
POW要求受验节点计算一个哈希值:
且要求:
又因为一个待打包区块的区块头中除Nonce随机数外其余的字段都已经确定,受验节点就只能通过调节Nonce的值来改变H(Nonce)的值。因此解题过程实际上也就是一个通过不断改变Nonce的值来暴力计算符合要求的H(Nonce)的过程,也即俗称的——挖矿。
类似于纸币与主权信用挂钩的主权货币体系抑或是美元与黄金挂钩的布雷顿森林体系。POW是在严格的密码学理论和数学算法限制下用物理资源的强制性开销为比特币的稀缺性和流通性提供信用担保的一种手段,其构成了比特币作为一种货币的信用基石。
也就是说,挖矿本质上是将实体物理资源(如计算机算力与电力开销)转换为虚拟资源(比特币)的过程。
我们假设全网有N台矿机,每台矿机的平均算力为S(次/秒),当前的目标难度为target_bits,要保证十分钟至少打包一个区块,则很容易得出这三者之间的算数关系。
已知H(Nonce)的值域为离散的定长二进制数且符合古典概率模型,故任取一个Nonce1,H(Nonce1)<target_bits的概率为:
每秒全网能进行N*S次计算,则每秒产生的H(Nonce)符合条件的概率为:
要求10分钟至少打包一个块,那么要求十分钟全网算出符合要求的H(Nonce)的概率必须为1,则有:
进而易得:
当某个受验节点第一个得出符合要求的H(Nonce)值时,便会将自己打包的区块和H(Nonce)向全网广播(H(Nonce)会作为本区块哈希编码存入下一个区块的区块头中)。其它节点接收到该信息后会迅速对结果进行验证(验证分为两部分,一方面验证受验区块H(Nonce)是否符合要求,另一方面验证交易集合中的记录是否合法),如果验证通过则将该区块入链并放弃对当前区块的解谜,进入下一个区块的解谜工作。POW记账赋权机制保证了全网只会接受最快算出数字谜题的那个节点所打包的块,进而保证了数据的全局一致性。
就POW作为一种共识算法而言,其优点是显而易见的。去中心化,不设准入的设计有效规避了少数成员对记账权利的垄断。而且强制性的物理资源开销也大大增加了恶意节点的作弊成本,有效避免了恶意节点对全网共识的干扰。
但是另一方面POW的缺点也尤为突出,最明显的便是“数字解谜”的设计大大延缓了网络的记账效率。在10分钟记账周期内,一个区块大约只能存储4000条交易记录,意味着比特币网络每秒大约只能处理7条左右的交易请求。
而且虽然POW基于去中心化的理念设计,但是在后来的实践中不可避免的发生了对初衷的偏移。中本聪最初的设计愿景是全网每一个CPU公平分享记账的权利。但是因为“数字解密”的算数重复性特征,很多专业挖矿团队都采用了更加适合重复运算的GPU集群来挖矿。这使得POW最初的均质赋权体系受到了相当程度的冲击,形成了少数大型矿场垄断算力的局面。针对这种情况,区块链技术在后来的演进中也采用了其它形式的POW算法。如以太坊(Ethash)采用的“内存困难算法”,即将算力开销转为内存开销,使得矿场要想提升挖矿成功率就必须增加内存,而无法借助优化了CPU/GPU架构的专业矿机来实现挖矿效率的指数级提升。
五、比特币网络的身份防伪与交易验证机制
1.公/私钥加密算法与身份防伪
在比特币网络中每个节点随时都会收到来自其它节点的多条交易记录,其中有的交易记录可能是恶意节点伪造的,确保每一笔交易由账户持有者本人发出且合法便成为了比特币交易安全中一个至关重要的问题。对此比特币网络采用了公/私钥加密算法来对每一笔交易进行身份验证。所谓公/私钥加密是一种典型的“非对称加密算法”,“非对称”的意思是信息的加/解密所需要的密钥是不一致的。
用于信息加密的密钥称为“私钥”,当用户注册时会生成一个随机数,并由该随机数生成用户私钥,其由用户本人唯一持有且与比特币账户关联(私钥丢失意味着该账户下所有资产的丢失)。同时比特币网络还会根据私钥产生与之对应的公钥和地址,这两者都是公开的,用于交易时其它节点对交易合法性的验证。
图十二:基于公/私钥算法的身份验证机制
已知私钥由账户所有者唯一持有,而对应公钥可以由任何一个用户持有。当用户A发起一笔转账交易Trade=“A向B转账5BTC”时,首先A会对Trade进行一次SHA256运算得到数字摘要H(Trade)=SHA256(Trade)。之后A会用私钥对H(Trade)加密得到密文C(Trade),然后A会将交易记录Trade,C(Trade),公钥,地址一起打包后向全网广播。
当节点I收到A的广播后,首先会对Trade进行一次SHA256运算得到H(Trade)=SHA256(Trade),之后用收到的公钥解密密文C(Trade),得到D(Trade)=Deciphering(C(Trade))。比对H(Trade)和D(Trade),如果两者一致则证明该条交易记录确实由A发出,若不一致则说明该条记录由恶意节点伪造。
2.超额透支与双重支付
公/私钥加密算法有效排除了恶意节点伪造交易记录的情况,但是即便是正常用户也有可能会存在超额透支自己账户中余额的作弊行为,这就需要引入额外的验证机制。假设用户A的账户中余额为50BTC,但是其却向全网广播了一条“A向B转账100BTC”的交易信息。当其它节点收到该信息后,并不会马上将这条记录写入区块,而是会通过回溯历史区块来重建A的账户信息,并对A的账户状态进行校验。如果其余额低于100BTC,则该条交易信息视为无效交易,并不会被打包进区块中,也就不会出现超额透支的问题。
此外还有另一种更为特殊的情况,假设A的账户中余额为50BTC,但是A同时向全网广播了两条交易信息:“A向B转账50BTC”;“A向C转账50BTC”。当其它节点接收到这两条信息后,都会只接受前一条信息,放弃后一条信息。但是因为网络状况的不同,有可能有的节点保留了前一条信息,而有的节点保留了后一条信息。在这种情况下,永远都是以最终入链的那条交易记录为准,因此发出一条交易记录并不意味着该笔交易会立即生效,只有最终入链的交易记录才会被全网所认可。
3.防篡改机制与最长链原则
图十三:防篡改机制与最长链原则
此外还存在另一种比较极端的情况,因为区块链本身的拓扑结构,每个区块都保存了前一个区块的数字摘要(父区块哈希编码)。如果某个历史区块中的记录发生变动,那么其区块哈希值也会随之发生改变,从而破坏全链的拓扑结构,成为一条废链。如果某个恶意节点想要篡改历史区块中的交易记录,即必须从被篡改的区块开始重新计算一条新链。为了规避恶意节点用被篡改的分支链取代公链,比特币网络引入了“最长链原则”,也就是全网永远以最长的那条区块链作为公链。如果恶意节点想要用分支链B取代公链A,就必须不断向下计算直到分支链B比公链A更长。而又因为POW的限制,记账概率与算力成正比。这就要求恶意用户至少需要占有全网的多数算力才有可能做到这一点(51%算力攻击),而这几乎是一件不可能的事。
在POW和“最长链原则”的双重保障下,比特币网络有效实现了历史数据的防篡改机制。
参考文献
SatoshiNakamoto:Bitcoin:APeer-to-PeerElectronicCashSystem
Castro,Miguel,BarbaraLiskov:PracticalByzantinefaulttolerance.OSDI.Vol.99.1999
Kwon,Jae:Tendermint:Consensuswithoutmining.Draftv.0.6,fall(2014)
全球首烧!保时捷Taycan车库内烧到面目全非一直以特斯拉“宿敌”自居的保时捷电动跑车Taycan,没能逃过起火的宿命.
本文由文驰语联信息技术有限公司翻译近期,比特币愈发呈现出法定货币的可靠替代品的势头,最近发生的许多事件证实了这种说法的正确性.
因怀疑人民币上可能沾染“新冠肺炎病”,近日江苏无锡,一位李阿姨把现金放进微波炉中加热消。还不到一分钟,微波炉就飘出了焦煳味.
三月早春,万物生长。《吕氏春秋》载:“是月也,生气方盛,阳气发泄,生者毕出,萌者尽达。”因此,春耕是这个季节永恒的主题,这个庚子之年更是如此.
来源:新浪美股 北京时间3月3日消息,比特币是一种货币,对不对?好吧,它是的。就像美元和欧元一样,它可以用于购买、出售和定价商品.
今天在知乎上闲逛,看到一个知友问题,是关于最近热门的N号房事件的,不说大家也应该能猜到,比特币又背了一次锅。这位知友的问题是这样的,“N号房事件,加密货币能够成为破案的关键吗”.