国家互联网金融安全技术专家委员会:很多区块链项目都是炒作、滥竽充数
近年来,随着比特币等虚拟货币的火热,其底层技术区块链在国内外引起了广泛关注。目前区块链正在向金融和其他领域扩展应用,问题较为突出,具体如下:
一、区块链应用中存在的问题
1、金融领域应用
(1)虚拟数字货币方面,目前区块链技术的成熟应用主要体现在虚拟数字货币方面,在虚拟货币市场中存在恶意炒作、价格剧烈波动等系列问题,且为洗钱、恐怖融资等活动提供了便利。
(2)区块链融资方面,部分区块链应用在通过ICO的形式融资,在ICO项目中占比90%以上。其融资规模大,参与用户多,但项目失败率高。同时,存在通过ICO进行传销、诈骗等活动,容易导致金融风险和社会问题。
2、其他领域应用
(1)伪链盛行。目前很多区块链应用项目属于借区块链名义炒作概念、滥竽充数的“伪链”。其对区块链进行随意裁剪,并不能发挥区块链的技术特性,实质上不具备数据防篡改、去中心等核心特点。
(2)过于理想化。目前很多区块链应用项目忽视多方参与的积极性和关联设施改造的难度,其项目实施的难度大,失败可能性很高。
3、共性问题
在具体的应用中,尤其是金融、质量控制、社会管理等关键领域,区块链应用系统设计和实现的安全性至关重要。目前的区块链系统在安全性方面考虑不足,已发生多起数字资产被盗、智能合约漏洞被黑客利用事件。
二、区块链应用的关键因素
现阶段,除虚拟货币外,区块链在其他领域的具体应用仍存在困难。为保障区块链应用充分发挥区块链的技术特性,建议考虑如下关键因素:
1.参与多方性。区块链需要互不信任的多方参与,以实现共同监督。同时应区分不特定多方和特定多方参与的要求。
2.参与积极性。项目的应用要为参与者带来相应价值,否则无法保证区块链运行的持续性。
3.参与真实性。在多方参与的情况下,区块链可以有效保障链上数据的难篡改,但无法解决链外数据上链的真实性。
4.参与可行性。考虑与关联设施对接与改造的难度及成本,充分评估实施可行性。
三、区块链认识的误区
现在部分应用借助区块链名义宣传数据真实和不可篡改等,为避免新技术概念不合理应用,应认清以下事实:
1.物理上的多方不等于参与的多方
2.区块链不直接等于不可篡改
3.区块链不直接等于数据真实
总体来看,区块链是多项技术融合产生的创新,具有独特的技术特性和潜力。但目前无论是虚拟货币还是其他领域,鱼龙混杂,具有较高的金融风险和技术风险。需要进一步理清对区块链应用的认识,避免新技术概念滥用和误用
********************************************************************
(主要应用场景)
区块链应用软件开发顶级案例分析
区块链是一种可生成和共享交易活动数字账簿的数据结构,主要有四个特征:去中心化、去信任、集体维护、可靠数据库,其核心设计思想是系统中的每个网络节点都参与全网公开账簿记账,经多次确认进入历史的区块链记录信息将永久记录,无法进行任何修改。这种分布式总账结构保证了所记录信息的不可篡改和可追溯特性,创造出一条“去中心化”的、牢不可破的网络“信任链”。区块链的应用前景充满想象空间,近日,全球知名信用评级机构穆迪发布了一份报告,详细记录了目前各个公司正在探索的120个区块链项目,并列出了25个顶级的区块链应用案例。
-
金融应用:
1.国际支付:当前的国际支付包括汇款和外汇交易,过程缓慢且费用昂贵,应用区块链技术的数字货币能够解决一些这样的问题。
2.金融资本市场:区块链技术可以应用于各类证券(例如,股票、债券、金融衍生品、回购、贷款和资产担保证券)和商品的整个生命周期:1)发行、持有和交易;2)交易会清算;3)保管和证券付息。该技术采用同步共享的区块链,各类账户不再需要协调,工作流程得以改进,整个链条资产和过程的所有情况得以清晰显示,同时智能合同技术也省掉了一些手动过程。然而,由于不同证券目前的流程尽不相同,为了确保该技术带来的好处优于现有技术、合理进行必要投资,区块链技术在各类证券中的应用应该分别评估。
3.贸易金融:区块链技术能够自动通过智能合约进行贸易金融过程中的信用文件转换。这样能够降低成本,提高效率,减少欺诈风险和人为错误。
4.法规执行审计:区块链技术可以通过区块链交易数据库来简化银行之间的实时对账,审计以及和监管机构的数据共享的报告流程,一旦发现违反内部合规性和外部监管要求的行为,智能合约就会发送警告。另外,区块链技术要求机构间的标准会计模板,这将有助于机构间金融数据的比较和汇总。
5.反洗钱和客户维护:基于区块链技术,银行之间共享信息可以减少之前的客户重复审核的次数,并且能够确保数据的安全性。
6.保险:基于区块链的保险政策能够在满足第三方公证的条件下利用智能合约自动支付索赔,如果有可能获得及时的决定而不需要人为理解,欺诈和索赔的处理成本也会下降。
7.P2P交易:区块链支持P2P平台的高效运转,智能合约可以在满足一定条件的时候确保价值传输,在缺少银行服务但手机普及率高的地区,对于小额信贷和小额保险特别有用。
企业应用:
8.供应链管理:区块链技术可以追踪供应链的每一个环节,突出实时过程中的所有权以及运用智能合约自动处理一些步骤。
9.医疗:应用区块链技术记录医疗数据可以提升数据的安全性和隐私性,可以让患者更放心地提供医生个人的完整的个人病历。另外,基于区块链的治疗可以有利于医疗费用的支付。
10.房地产:区块链技术可以保存房产交易过程的整个历史,消除在所有权方面的欺诈和错误,提高整个房产交易过程的速度和安全性。
11.媒体:数字版权在区块链基础上能更有效地管理并允许付费使用,并且智能合约能够提供自动分布式支付。
12.能源:区块链技术支持电网上匿名匹配生产者的供应和消费者之间的需求,并记录任何电力的传输过程。
政府应用:
13.记录管理:应用区块链技术可以提供实时的访问数据,并且可以保障这些数据在不同的政府机构之间进行安全共享,同时保证信息的隐私性,这些记录包括所有权记录、业务记录和个人信息记录。
14.身份管理:区块链可以让用户用一个通过验证的数字身份在一个安全的环境中登陆。
15.投票选举:基于区块链技术的投票可以提供一个具有签名和时间的投票历史记录,减少重复操作或删除行为,并允许简单的审计和重复计算。
16.税收:利用区块链技术可以自动进行税收征管,并且降低了相关的逃税漏税比例以及相应的税收负担。
17.政府和非盈利组织透明度监督:区块链可以追踪并监督政府和非盈利组织的资金使用状况,有利于减少贪污腐败。
18.立法和监管:一些法律合同可以被智能合约取代。当一些公司没有收到特定的监管要求时,会收到网络中自动发送过来的具有实时数据的警告,通过这种更加安全的监管方式提升了监管效率。
跨行业应用:
19.财务管理与会计:区块链技术可以让跨国公司更方便地向全球办事处转移金融资产,并且这一行为全部会自动进行会计审计,有利于减少相关错误。
20.股东表决:区块链技术可以提高表决的透明度,减少暗箱操作,并允许在线投票。
21.记录管理:区块链能够提供具有最终登陆时间和身份状态的用户登陆信息,并且可以在保障用户隐私安全的情况下在机构间进行信息共享。
22.网络安全:区块链技术可以减少中心故障的风险,另外,区块链还可以监督非法路由行为和非法软件篡改。
23.大数据:区块链技术可以提高数据的质量和安全性,减少因中心节点出问题所带来的风险,且便于数据分析。
24.数据存储:区块链技术可以让任意网络节点分享它们电脑上的存储空间且通过加密来保证数据的安全性。
25.物联网:区块链技术可以追踪收集智能设备的整个历史交换数据,并利用收集来的数据对设备进行优化。
作为支撑比特币发展的基础技术,区块链被普遍推崇为下一代全球信用认证和价值互联网的基础协议之一。它的出现预示着互联网的用途可能从传统信息传递逐步转变成为价值传递,从而对传统产业特别是金融行业带来了前所未有的革命和挑战。因此,区块链自然受到众多创业者和投资者的追逐,截至2016年7月15日,全球大约有149家比特币和区块链创业公司获得了总计超过12亿美元的VC投资。另外,随着全球纯区块链公司的增多,以及现存的一些加密货币公司逐渐转型为区块链解决方案的提供商,据穆迪统计,在2016年第一季度,区块链公司和混合公司(加密货币公司和区块链公司合称)获得的VC投资额达84%,单纯加密货币公司获得的投资仅占16%。区块链公司正在受到越来越多资本的青睐。
此外,该报告也认同目前区块链开发的四项基本方法:投资区块链初创公司、与区块链初创公司合作、区块链咨询和技术公司支持的国际项目、各个企业之间或政企之间的产业合作。
********************************************************
(主要开发方向及细节)
区域链开发技术综述
作者:孟岩,IBM大中华区高级经理,曾负责IBM智慧地球、智慧城市、认知计算等重大技术战略在中国的推广和落地。一年前开始关注区块链技术及其行业应用前景,对比特币、以太坊、超级总账和BigchainDB四个主要区块链技术流派都进行过考察和研究,形成了在中国应用区块链技术的观点和思路。
如果你关注区块链技术长达几个月,可能也会跟我一样,对没完没了的原理介绍、前景描绘、行业探讨和链圈新闻产生了审美疲劳。没错,区块链必须与行业紧密结合,它也有颠覆人类协作方式之洪荒巨力,但是说到底它还是一个技术活,是要写代码的,在咖啡厅里整天坐而论道是造不出金链子来的。技术人员的逻辑简单直接,这个事情有没有前(钱)途?有,那怎么干?
本文试图对区块链有关技术流派和主流平台进行一个概览,作为学习区块链技术体系的导览,意在抛砖引玉,促进区块链开发社区的讨论与共识。
区块链技术的流派
未战先谋局,你想投入区块链开发这个领域,至少先要搞清楚现在有哪些玩家,各自的主张和实力如何。
划分区块链技术流派并无一定之规,据我所见,或可有以下四种方式:
第一是按照节点准入规则,划分为公有链、私有链和联盟链。公有链的代表自然是比特币和以太坊,私有链则以R3 Corda声名最盛,联盟链的代表作品是Hyperledger名下的Fabric。公有链注重匿名性与去中心化,而私有链及联盟链注重高效率,而且还往往设置了准入门槛。公有链、私有链与联盟链之间的这些不同都在技术中有所体现,比如私有链和联盟链假设节点数目不大,可以采用PBFT算法来形成共识。而公有链假设有大量且不断动态变化的节点网络,用PBFT效率太低,只能采用类似抽彩票的算法来确定意见领袖。这就意味着,私有链与联盟链很难变成公有链,而用公有链来作联盟链或私有链虽然容易,却也并非即插即用。此种差异,学者不可不察。
第二是按照共享目标,划分为共享账本和共享状态机两派。比特币是典型的共享账本,而Chain和BigchainDB也应属此类,这几个区块链系统在各个节点之间共享一本总账,因此对接金融应用比较方便。另一大类区块链系统中,各个节点所共享的是可完成图灵完备计算的状态机,如以太坊、Fabric,它们都通过执行智能合约而改变共享状态机状态,进而达成种种复杂功能。
第三是按照梅兰妮 · 斯旺所描述的代际演进,将区块链系统分为1.0、2.0和3.0三代。其中1.0支撑去中心化交易和支付系统,2.0通过智能合约支撑行业应用,3.0支撑去中心化的社会体系。比特币和Chain应属于区块链1.0系统,而以太坊和Fabric是区块链2.0系统,目前尚无成功的区块链3.0系统出现,不成功的尝试倒是有那么一个,就是著名的The DAO。
第四是按照核心数据结构,分为区块链和分布式总账两派。区块链这一派在系统中真的实现了一个区块的链作为核心数据结构,而分布式总账这一派,只是吸取了区块链的精神,并没有真用一条区块链作为核心数据结构,或者虽然暂时用了,但声明说吾项庄舞区块链,意在分布式总账耳,若假以时日,因缘际会,未尝不可取而代之也。
主流区块链技术平台
了解流派划分,仍是只能用来指点江山,吹牛论道,要动手,总要有个切入点。区块链货币据说已经有上千个了,但值得关注的技术平台大概只有数十个,而如果要进入区块链开发领域,打下一个好基础,练出一身好功夫,捞到几个好offer,则值得深入研究学习的平台,屈指可数。
首先当然是比特币。比特币作为区块链的第一个也是目前为止最成功、最重要的样板工程,已经上线运行了八年多,本身没有发生任何严重的安全和运维事故,其稳定与强悍堪称当代软件系统典范。比特币Bitcoin Core是一个代码质量高、文档良好的开源软件,从学习区块链原理、掌握核心技术的角度来说,Bitcoin Core是最佳切入点,能够学到原汁原味的区块链技术。当然,Bitcoin Core是用C++写的,而且用了一些C++11和Boost库的机制,对学习者的C++水平提出了较高的要求。
学习比特币平台开发还有一个优势,就是可以对接繁荣的比特币技术社区。目前围绕比特币进行改进和提升的人很多,人多力量就大,诸如隔离验证、闪电网络、侧链等比较新的想法和技术,都率先在比特币社区里落地。比如侧链技术的主要领导者Blockstream是由密码学货币元老Adam Back领衔的,而Blockstream是Bitcoin Core最大的贡献者之一,所以一些有关侧链的技术在比特币社区里讨论最充分。
但比特币作为一个典型的区块链1.0系统,是不是支撑其他类型区块链应用的最佳技术平台,存在很大的争议。另外,也不是所有人都有能力和必要精通区块链底层技术。所以对那些急于冲到区块链领域里做(quān)事(qián)的人来说,可能更直截了当的学习目标是以太坊和Hyperledger Fabric。
在以太坊上面用Solidity进行的智能合约开发是切入区块链开发最简单的方式,没有之一。以太坊的理想非常宏大,由于配备了强大的图灵完备的智能合约虚拟机,因此可以成为一切区块链项目的母平台,是驮住整个区块链世界的大乌龟。在以太坊上开发一个类似比特币的加密货币,是一个不折不扣的小目标。一般有经验的开发者在文档指导下,半天到一天即可入门。问题在于,入门以后又如何?靠写Solidity是否就可以包打天下?这是大大存疑的。我们也可以反过来说,如果以太坊+Solidity是区块链的终极解决方案,那么怎么还会出现那么多区块链技术门派呢?特别是,以太坊似乎并没有给现实世界中巨型的中心化组织们留下一条活路,这种彻底不妥协的革命态度有可能也成为以太坊推广的障碍。
当前以太坊项目的开发进展并不顺利。一个比较突出的问题是项目过多,力量分散,导致项目质量参差不齐。但尽管如此,跟其他区块链2.0平台相比,以太坊提供的开发环境是最简单最完善的。初学区块链的人绝对有必要学习以太坊,从而对区块链和智能合约建立起一个最“正宗”的认识。
主流区块链技术平台的第三支就是Fabric,它是Hyperledger的第一个也是最知名的孵化项目。 Fabric最早来自IBM的Open Blockchain项目,到2015年11月,IBM将当时已经开发完成的44,000行Go语言代码交给Linux基金会,并入Hyperledger项目之中。在2016年3月一次黑客马拉松中,Blockstream和DAH两家公司将各自的代码并入Open Blockchain,随后改名为Fabric。到目前为止,Fabric与Intel提供的Sawtooth Lake并列为Hyperledger的一级孵化项目,但前者得到的关注远超后者。
从技术角度来说,Fabric思路不错,重点是满足企业商用的需求,比如解决交易量问题。众所周知,比特币最大的短板是它每秒钟7个交易的上限,完全无法满足现实需要。而Fabric目标是实现每秒钟10万交易,这个量接近刚刚过去的双十一交易量瞬时峰值,完全可以满足正常条件下的行业级应用。Fabric用Go语言开发,也提供多种语言的API。特别值得一提的是,Fabric比较充分地运用了容器技术,比如其智能合约就运行在容器当中。这也是Go语言带给Fabric的一项福利,因为Go语言静态编译部署的特征很适合开发容器中的程序。
Fabric还有一些特点,比如其membership服务可以设置节点准入审查,这是典型的联盟链特征。再比如其共识算法是可定制的。Fabric自带PBFT共识算法实现,但是PBFT的算法效率是O(n²),其中n是节点数量。因此PBFT用在节点数量受限的联盟链里是没有问题的,但用在公有链里效率过低。
Fabric的短板是体系较为复杂,虽有文档,但缺少经验的开发者学习起来障碍比较大。然而由于其定位清楚,迎合了不少企业的心态,所以已经有多家机构在基于Fabric秘密研发行业内的联盟链项目。
小众门派
上述区块链开发的三大主流平台,从活跃度、受关注和参与人数来说,远远超过其他平台。但俗话说莫欺少年穷,一些眼下还默默无闻的平台也不容忽视。
Hyperledger的另一个一级孵化项目Sawtooth Lake是Intel开发的区块链平台,是一个很少被关注的项目,大概是因为被同在Hyperledger旗下的Fabric给掩盖了,再加上名字拗口,所以很少看到有人讨论它,项目活跃度也不高。但其实Sawtooth Lake是一个挺有想法的区块链项目,设计十分精心。它以数字金融资产管理为目标,整体架构清晰,模块化程度高,因此可定制能力也强。概念上独创了“交易族(transaction family)”概念,而且还支持PoET和Quorum两种共识机制。当节点数量很多(公有链环境)时,使用第6代Intel Core CPU所提供的SGX扩展功能提供一种称为时间流逝证明(PoET)的机制来形成共识,这种机制与比特币所采用的PoW同属“抽彩票”式的共识算法,但杜绝了通过ASIC专用硬件“作弊”的可能性,排除了比特币出现的算力过于集中的隐患,可靠性由Intel CPU硬件来保障,是公有链系统里很有价值的一个共识机制。另一方面,当节点数量少且受控时,Sawtooth Lake可以采用Quorum共识机制,这是由Ripple提出并验证的共识机制,非常适合于联盟链场景,这样Sawtooth Lake就摇身一变成为很好用的联盟链了。
Sawtooth Lake采用Python开发,并提供了Java SDK。由于这两种语言的流行度,实际上它应该有很大的潜在开发者人群。事实上,R3 CEV曾经测试过Sawtooth Lake并进行了成功的证券交易实验。当前它主要的问题是受关注度不足,不知Intel是否有足够的耐心和毅力坚持到底。如果Intel战略更明确一些,支持力度更大一些,我建议大家可以对它投以更多的关注。
R3 Corda是一个备受关注的分布式账本项目。 R3是由数十家银行和金融机构支持的区块链企业,融资上亿美元,号称汇集了一票高手,潜心研究符合金融行业需求的分布式账本系统。Corda是R3分布式账本系统中的核心,在千呼万唤之后,于11月30日正式开源。
Corda采用JetBrain原创的小众语言Kotlin开发,对Java世界敞开大门,这是令人点赞的。此外,Corda更重要的特色是其与现有世界里大银行、大型中心机构的全面妥协、全面合作的姿态,这与以太坊革命无罪、造反有理的形象形成鲜明对比。Corda在设计中有多项独特考虑,就是为了对接现有的业务规则。比如在其他几乎所有区块链平台里,每一个交易对于各节点来说都是可见的,可见才能验证,能验证才谈得上共识,所以交易的全网可见性是顺理成章的。但是现实世界里金融机构之间的交易,只有交易相关方才能看到交易详情,工行与建行的一笔交易,绝无必要让招行看到。为了对接这个现实,Corda设计了与众不同的机制,牺牲了交易验证的全局可见性,确保只有交易相关方才能看到和验证交易本身。可是另一方面,银行业务是被重度监管的业务,不能因为你用了区块链系统,就把洋洋洒洒的巴塞尔协议晾在一边,监管机构的职能如何体现?这是其他区块链系统里考虑不多的。而Corda设计了独特的Notary和Oracle节点,为监管体系进入留下了空间。仔细品味,这些都是给现实世界当中的大机构预留的美差。这些设计上的考虑,无疑大大增强了Corda被现有大型金融机构采纳的机会。不过这一切看上去很美好,但目前Corda的实现基本上是个花架子,设想的种种,不少处于TODO状态。
另外两个值得点名的区块链门派分别是Chain和BigchainDB。前者跟Visa有合作,后者是一个基于RethinkDB开发的分布式账本,两者各有各的思路和特色,也拿到了为数可观的投资,不排除未来能有大的发展。限于篇幅,在这里不展开介绍了。
区块链开发所需具备的技术基础
可以预见,未来从事区块链开发的主要有三类开发者,一类是开发基于区块链的Web或移动App,这种开发者所需要的技能与今天的Web和移动开发者并无二致,这里就不赘述了。
第二类开发者是开发智能合约的。这类开发者使用类似Solidity这样的智能合约语言,或者直接用Go、Java、Python等语言开发。开发智能合约所要求的语言和算法技术水平不高,什么并发、多线程之类的东西一般用不到,普通开发者均可胜任。但是智能合约的难点在于业务与安全。本质上智能合约就是以代码写成的商业合同,必须对于业务有非常清晰的认识,对于安全有着深刻的理解,才能够写出正确的智能合约。因此,我认为未来智能合约的开发者,可能反而是具体应用领域的行业专家出身居多,因为让他们掌握Python语言,远比让程序员去理解进出口贸易规则或者商业票据业务要容易得多。
第三类开发者,就是区块链核心应用系统和核心平台的开发者。这部分人当然必须是技术高手,按现在通俗的说法,得是后端专家。从语言上讲,C++、Java、Python、Go、JavaScript都有可能要触及。从基础知识来说,要求对密码学、分布式系统、网络编程、系统架构和部署都有相当程度的理解和实践经验。这种开发者显然将是区块链技术浪潮当中的弄潮儿,也将是最大的受益者之一。
特别要点一下密码学。密码学是大多数开发人员的短板,但若要在区块链核心技术领域搞出能够碾压竞品的创新点,密码学是最有可能出成果的地方。不用说搞出什么密码学突破,就是将密码学现有成果充分运用在区块链里,都可能会搞出一些逆天的创新来。比如用零知识证明协议(zero-knowledge proof)构造高度匿名化的区块链系统,比如用私有计算外包(private computing outsourcing)技术让别的节点既能够验证交易,又对交易本身的内容一无所知,这都是能够激发大量商业模式创新的技术,等待密码学黑客们发掘和实现。因此,我相信密码学成为显学的时代即将到来。
区块链是一项前景无限、极具颠覆性和想象空间的技术,它有潜力带来一个完全不同的商业时代,塑造新一代的互联网,也有可能被传统势力合谋异化。无论如何,区块链为创业者和程序员提供了又一次弄潮的机会,在这片蓝海上将演出一场怎样的大戏,我们且拭目以待。
*************************************************************************************
(然后, 你居然看到了这里,好吧,我承认 你的确是对区域链很感兴趣,下面的基本就这样了; 所有的与比特币有关的东西,甚至资料都要捐赠, 下面这本 pdf 正在转制,转制完了,发回复里 )
区块链是由包含交易信息的区块从后向前有序链接起来的数据结构。它可以被存储为flat file(一种包含没有相对关系记录的文件),或是存储在一个简单数据库中。比特币核心客户端使用Google的LevelDB数据库存储区块链元数据。区块被从后向前有序地链接在这个链条里,每个区块都指向前一个区块。区块链经常被视为一个垂直的栈,第一个区块作为栈底的首区块,随后每个区块都被放置在其他区块之上。用栈来形象化表示区块依次堆叠这一概念后,我们便可以使用一些术语,例如:“高度”来表示区块与首区块之间的距离;以及“顶部”或“顶端”来表示最新添加的区块。
对每个区块头进行SHA256加密哈希,可生成一个哈希值。通过这个哈希值,可以识别出区块链中的对应区块。同时,每一个区块都可以通过其区块头的“父区块哈希值”字段引用前一区块(父区块)。也就是说,每个区块头都包含它的父区块哈希值。这样把每个区块链接到各自父区块的哈希值序列就创建了一条一直可以追溯到第一个区块(创世区块)的链条。
虽然每个区块只有一个父区块,但可以暂时拥有多个子区块。每个子区块都将同一区块作为其父区块,并且在“父区块哈希值”字段中具有相同的(父区块)哈希值。一个区块出现多个子区块的情况被称为“区块链分叉”。区块链分叉只是暂时状态,只有当多个不同区块几乎同时被不同的矿工发现时才会发生(参见“8.10.1 区块链分叉”)。最终,只有一个子区块会成为区块链的一部分,同时解决了“区块链分叉”的问题。尽管一个区块可能会有不止一个子区块,但每一区块只有一个父区块,这是因为一个区块只有一个“父区块哈希值”字段可以指向它的唯一父区块。
由于区块头里面包含“父区块哈希值”字段,所以当前区块的哈希值因此也受到该字段的影响。如果父区块的身份标识发生变化,子区块的身份标识也会跟着变化。当父区块有任何改动时,父区块的哈希值也发生变化。父区块的哈希值发生改变将迫使子区块的“父区块哈希值”字段发生改变,从而又将导致子区块的哈希值发生改变。而子区块的哈希值发生改变又将迫使孙区块的“父区块哈希值”字段发生改变,又因此改变了孙区块哈希值,等等以此类推。一旦一个区块有很多代以后,这种瀑布效应将保证该区块不会被改变,除非强制重新计算该区块所有后续的区块。正是因为这样的重新计算需要耗费巨大的计算量,所以一个长区块链的存在可以让区块链的历史不可改变,这也是比特币安全性的一个关键特征。
你可以把区块链想象成地质构造中的地质层或者是冰川岩芯样品。表层可能会随着季节而变化,甚至在沉积之前就被风吹走了。但是越往深处,地质层就变得越稳定。到了几百英尺深的地方,你看到的将是保存了数百万年但依然保持历史原状的岩层。在区块链里,最近的几个区块可能会由于区块链分叉所引发的重新计算而被修改。最新的六个区块就像几英寸深的表土层。但是,超过这六块后,区块在区块链中的位置越深,被改变的可能性就越小。在100个区块以后,区块链已经足够稳定,这时Coinbase交易(包含新挖出的比特币的交易)可以被支付。几千个区块(一个月)后的区块链将变成确定的历史,永远不会改变。
7.2 区块结构
区块是一种被包含在公开账簿(区块链)里的聚合了交易信息的容器数据结构。它由一个包含元数据的区块头和紧跟其后的构成区块主体的一长串交易组成。区块头是80字节,而平均每个交易至少是250字节,而且平均每个区块至少包含超过500个交易。因此,一个包含所有交易的完整区块比区块头的1000倍还要大。表7-1描述了一个区块结构。
表7-1 区块结构
大小 |
字段 |
描述 |
4字节 |
区块大小 |
用字节表示的该字段之后的区块大小 |
80字节 |
区块头 |
组成区块头的几个字段 |
1-9 (可变整数) |
交易计数器 |
交易的数量 |
可变的 |
交易 |
记录在区块里的交易信息 |
7.3 区块头
区块头由三组区块元数据组成。首先是一组引用父区块哈希值的数据,这组元数据用于将该区块与区块链中前一区块相连接。第二组元数据,即难度、时间戳和nonce,与挖矿竞争相关,详见第8章。第三组元数据是merkle树根(一种用来有效地总结区块中所有交易的数据结构)。表7-2描述了区块头的数据结构。
表7-2 区块头结构
大小 |
字段 |
描述 |
4字节 |
版本 |
版本号,用于跟踪软件/协议的更新 |
32字节 |
父区块哈希值 |
引用区块链中父区块的哈希值 |
32字节 |
Merkle根 |
该区块中交易的merkle树根的哈希值 |
4字节 |
时间戳 |
该区块产生的近似时间(精确到秒的Unix时间戳) |
4字节 |
难度目标 |
该区块工作量证明算法的难度目标 |
4字节 |
Nonce |
用于工作量证明算法的计数器 |
Nonce、难度目标和时间戳会用于挖矿过程,更多细节将在第8章讨论。
7.4 区块标识符:区块头哈希值和区块高度
区块主标识符是它的加密哈希值,一个通过SHA256算法对区块头进行二次哈希计算而得到的数字指纹。产生的32字节哈希值被称为区块哈希值,但是更准确的名称是:区块头哈希值,因为只有区块头被用于计算。例如:000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f是第一个比特币区块的区块哈希值。区块哈希值可以唯一、明确地标识一个区块,并且任何节点通过简单地对区块头进行哈希计算都可以独立地获取该区块哈希值。
请注意,区块哈希值实际上并不包含在区块的数据结构里,不管是该区块在网络上传输时,抑或是它作为区块链的一部分被存储在某节点的永久性存储设备上时。相反,区块哈希值是当该区块从网络被接收时由每个节点计算出来的。区块的哈希值可能会作为区块元数据的一部分被存储在一个独立的数据库表中,以便于索引和更快地从磁盘检索区块。
第二种识别区块的方式是通过该区块在区块链中的位置,即“区块高度(block height)”。第一个区块,其区块高度为0,和之前哈希值000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f所引用的区块为同一个区块。因此,区块可以通过两种方式被识别:区块哈希值或者区块高度。每一个随后被存储在第一个区块之上的区块在区块链中都比前一区块“高”出一个位置,就像箱子一个接一个堆叠在其他箱子之上。2014年1月1日的区块高度大约是278,000,说明已经有278,000个区块被堆叠在2009年1月创建的第一个区块之上。
和区块哈希值不同的是,区块高度并不是唯一的标识符。虽然一个单一的区块总是会有一个明确的、固定的区块高度,但反过来却并不成立,一个区块高度并不总是识别一个单一的区块。两个或两个以上的区块可能有相同的区块高度,在区块链里争夺同一位置。这种情况在“8.10.1 区块链分叉”一节中有详细讨论。区块高度也不是区块数据结构的一部分,它并不被存储在区块里。当节点接收来自比特币网络的区块时,会动态地识别该区块在区块链里的位置(区块高度)。区块高度也可作为元数据存储在一个索引数据库表中以便快速检索。
一个区块的区块哈希值总是能唯一地识别出一个特定区块。一个区块也总是有特定的区块高度。但是,一个特定的区块高度并不一定总是能唯一地识别出一个特定区块。更确切地说,两个或者更多数量的区块也许会为了区块链中的一个位置而竞争。
7.5 创世区块
区块链里的第一个区块创建于2009年,被称为创世区块。它是区块链里面所有区块的共同祖先,这意味着你从任一区块,循链向后回溯,最终都将到达创世区块。
因为创世区块被编入到比特币客户端软件里,所以每一个节点都始于至少包含一个区块的区块链,这能确保创世区块不会被改变。每一个节点都“知道”创世区块的哈希值、结构、被创建的时间和里面的一个交易。因此,每个节点都把该区块作为区块链的首区块,从而构建了一个安全的、可信的区块链的根。
在chainparams.cpp里可以看到创世区块被编入到比特币核心客户端里。
创世区块的哈希值为:
0000000000
19d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
你可以在任何区块浏览网站搜索这个区块哈希值,如blockchain.info,你会发现一个用包含这个哈希值的链接来描述这一区块内容的页面:
https://blockchain.info/block/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
https://blockexplorer.com/block/%20000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
在命令行使用比特币核心客户端:
$ bitcoind getblock 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
{
"hash":"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
"confirmations":308321,
"size":285,
"height":0,
"version":1,
"merkleroot":"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
"tx":["4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"],
"time":1231006505,
"nonce":2083236893,
"bits":"1d00ffff",
"difficulty":1.00000000,
"nextblockhash":"00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"
}
创世区块包含一个隐藏的信息。在其Coinbase交易的输入中包含这样一句话“The Times 03/Jan/2009 Chancellor on brink of second bailout forbanks.”这句话是泰晤士报当天的头版文章标题,引用这句话,既是对该区块产生时间的说明,也可视为半开玩笑地提醒人们一个独立的货币制度的重要性,同时告诉人们随着比特币的发展,一场前所未有的世界性货币革命将要发生。该消息是由比特币的创立者中本聪嵌入创世区块中。
7.6 区块的连接
比特币的完整节点保存了区块链从创世区块起的一个本地副本。随着新的区块的产生,该区块链的本地副本会不断地更新用于扩展这个链条。当一个节点从网络接收传入的区块时,它会验证这些区块,然后链接到现有的区块链上。为建立一个连接,一个节点将检查传入的区块头并寻找该区块的“父区块哈希值”。
让我们假设,例如,一个节点在区块链的本地副本中有277,314个区块。该节点知道最后一个区块为第277,314个区块,这个区块的区块头哈希值为: 00000000000000027e7ba6fe7bad39faf3b5a83daed765f05f7d1b71a1632249。
然后该比特币节点从网络上接收到一个新的区块,该区块描述如下:
{
"size":43560,
"version":2,
"previousblockhash":"00000000000000027e7ba6fe7bad39faf3b5a83daed765f05f7d1b71a1632249",
"merkleroot":"5e049f4030e0ab2debb92378f53c0a6e09548aea083f3ab25e1d94ea1155e29d",
"time":1388185038,
"difficulty":1180923195.25802612,
"nonce":4215469401,
"tx":["257e7497fb8bc68421eb2c7b699dbab234831600e7352f0d9e6522c7cf3f6c77",
#[...many more transactions omitted...]
"05cfd38f6ae6aa83674cc99e4d75a1458c165b7ab84725eda41d018a09176634"
]
}
对于这一新的区块,节点会在“父区块哈希值”字段里找出包含它的父区块的哈希值。这是节点已知的哈希值,也就是第277314块区块的哈希值。故这个区块是这个链条里的最后一个区块的子区块,因此现有的区块链得以扩展。节点将新的区块添加至链条的尾端,使区块链变长到一个新的高度277,315。图7-1显示了通过“父区块哈希值”字段进行连接三个区块的链。
图7-1 区块通过引用父区块的区块头哈希值的方式,以链条的形式进行相连
7.7 Merkle 树
区块链中的每个区块都包含了产生于该区块的所有交易,且以Merkle树表示。
Merkle树是一种哈希二叉树,它是一种用作快速归纳和校验大规模数据完整性的数据结构。这种二叉树包含加密哈希值。术语“树”在计算机学科中常被用来描述一种具有分支的数据结构,但是树常常被倒置显示,“根”在图的上部同时“叶子”在图的下部,你会在后续章节中看到相应的例子。
在比特币网络中,Merkle树被用来归纳一个区块中的所有交易,同时生成整个交易集合的数字指纹,且提供了一种校验区块是否存在某交易的高效途径。生成一棵完整的Merkle树需要递归地对哈希节点对进行哈希,并将新生成的哈希节点插入到Merkle树中,直到只剩一个哈希节点,该节点就是Merkle树的根。在比特币的Merkle树中两次使用到了SHA256算法,因此其加密哈希算法也被称为double-SHA256。
当N个数据元素经过加密后插入Merkle树时,你至多计算2*log2(N)次就能检查出任意某数据元素是否在该树中,这使得该数据结构非常高效。
Merkle树是自底向上构建的。在如下的例子中,我们从A、B、C、D四个构成Merkle树树叶的交易开始,如图7-2。起始时所有的交易都还未存储在Merkle树中,而是先将数据哈希化,然后将哈希值存储至相应的叶子节点。这些叶子节点分别是HA、HB、HC和HD:
H~A~ = SHA256(SHA256(交易A))
通过串联相邻叶子节点的哈希值然后哈希之,这对叶子节点随后被归纳为父节点。 例如,为了创建父节点HAB,子节点A和子节点B的两个32字节的哈希值将被串联成64字节的字符串。随后将字符串进行两次哈希来产生父节点的哈希值:
H~AB~=SHA256(SHA256(H~A~ + H~B~))
继续类似的操作直到只剩下顶部的一个节点,即Merkle根。产生的32字节哈希值存储在区块头,同时归纳了四个交易的所有数据。
图7-2 在Merkle树中计算节点
因为Merkle树是二叉树,所以它需要偶数个叶子节点。如果仅有奇数个交易需要归纳,那最后的交易就会被复制一份以构成偶数个叶子节点,这种偶数个叶子节点的树也被称为平衡树。如图7-3所示,C节点被复制了一份。
图7-3 复制一份数据节点,使整个树中数据节点个数是偶数
由四个交易构造Merkle树的方法同样适用于从任意交易数量构造Merkle树。在比特币中,在单个区块中有成百上千的交易是非常普遍的,这些交易都会采用同样的方法归纳起来,产生一个仅仅32字节的数据作为Merkle根。在图7-4中,你会看见一个从16个交易形成的树。需要注意的是,尽管图中的根看起来比所有叶子节点都大,但实际上它们都是32字节的相同大小。无论区块中有一个交易或者有十万个交易,Merkle根总会把所有交易归纳为32字节。
图7-4 一颗囊括了许多数据元素的Merkle树
为了证明区块中存在某个特定的交易,一个节点只需要计算log2(N)个32字节的哈希值,形成一条从特定交易到树根的认证路径或者Merkle路径即可。随着交易数量的急剧增加,这样的计算量就显得异常重要,因为相对于交易数量的增长,以基底为2的交易数量的对数的增长会缓慢许多。这使得比特币节点能够高效地产生一条10或者12个哈希值(320-384字节)的路径,来证明了在一个巨量字节大小的区块中上千交易中的某笔交易的存在。
在图7-5中,一个节点能够通过生成一条仅有4个32字节哈希值长度(总128字节)的Merkle路径,来证明区块中存在一笔交易K。该路径有4个哈希值(在图7-5中由蓝色标注)HL、HIJ、HMNOP和HABCDEFGH。由这4个哈希值产生的认证路径,再通过计算另外四对哈希值HKL、HIJKL、HIJKLMNOP和Merkle树根(在图中由虚线标注),任何节点都能证明HK(在图中由绿色标注)包含在Merkle根中。
图7-5 一条为了证明树中包含某个数据元素而使用的Merkle路径
例7-1中的代码借用libbitcoin库中的一些辅助程序,演示了从叶子节点哈希至根创建整个Merkle树的过程。
例7-1 构造Merkle树
#include
bc::hash_digest create_merkle(bc::hash_digest_list& merkle)
{
// Stop if hash list is empty.
if (merkle.empty())
return bc::null_hash;
else if (merkle.size() == 1)
return merkle[0];
// While there is more than 1 hash in the list, keep looping…
while (merkle.size() > 1)
{
// If number of hashes is odd, duplicate last hash in the list.
if (merkle.size() % 2 != 0)
merkle.push_back(merkle.back());
// List size is now even.
assert(merkle.size() % 2 == 0);
// New hash list.
bc::hash_digest_list new_merkle;
// Loop through hashes 2 at a time.
for (auto it = merkle.begin(); it != merkle.end(); it += 2)
{
// Join both current hashes together (concatenate).
bc::data_chunk concat_data(bc::hash_size * 2);
auto concat = bc::make_serializer(concat_data.begin());
concat.write_hash(*it);
concat.write_hash(*(it + 1));
assert(concat.iterator() == concat_data.end());
// Hash both of the hashes.
bc::hash_digest new_root = bc::bitcoin_hash(concat_data);
// Add this to the new list.
new_merkle.push_back(new_root);
}
// This is the new list.
merkle = new_merkle;
// DEBUG output -------------------------------------
std::cout << "Current merkle hash list:" << std::endl;
for (const auto& hash: merkle)
std::cout << " " << bc::encode_hex(hash) << std::endl;
std::cout << std::endl;
// --------------------------------------------------
}
// Finally we end up with a single item.
return merkle[0];
}
int main()
{
// Replace these hashes with ones from a block to reproduce the same merkle root.
bc::hash_digest_list tx_hashes{
{
bc::decode_hash("0000000000000000000000000000000000000000000000000000000000000000"),
bc::decode_hash("0000000000000000000000000000000000000000000000000000000000000011"),
bc::decode_hash("0000000000000000000000000000000000000000000000000000000000000022"),
}
};
const bc::hash_digest merkle_root = create_merkle(tx_hashes);
std::cout << "Result: " << bc::encode_hex(merkle_root) << std::endl;
return 0;
}
例7-2展示了编译以及运行上述代码后的结果。
例7-2 编译以及运行构造Merkle树代码
$ # Compile the merkle.cpp code
$ g++ -o merkle merkle.cpp $(pkg-config --cflags --libs libbitcoin)
$ # Run the merkle executable
$ ./merkle
Current merkle hash list:
32650049a0418e4380db0af81788635d8b65424d397170b8499cdc28c4d27006
30861db96905c8dc8b99398ca1cd5bd5b84ac3264a4e1b3e65afa1bcee7540c4
Current merkle hash list:
d47780c084bad3830bcdaf6eace035e4c6cbf646d103795d22104fb105014ba3
Result: d47780c084bad3830bcdaf6eace035e4c6cbf646d103795d22104fb105014ba3
Merkle树的高效随着交易规模的增加而变得异常明显。表7-3展示了为了证明区块中存在某交易而所需转化为Merkle路径的数据量。
表7-3 Merkle树的效率
交易数量 |
区块的近似大小 |
路径大小(哈希数量) |
路径大小(字节) |
16笔交易 |
4KB |
4个哈希 |
128字节 |
512笔交易 |
128KB |
9个哈希 |
288字节 |
2048笔交易 |
512KB |
11个哈希 |
352字节 |
65,535笔交易 |
16MB |
16个哈希 |
512字节 |
依表可得,当区块大小由16笔交易(4KB)急剧增加至65,535笔交易(16MB)时,为证明交易存在的Merkle路径长度增长极其缓慢,仅仅从128字节到512字节。有了Merkle树,一个节点能够仅下载区块头(80字节/区块),然后通过从一个满节点回溯一条小的Merkle路径就能认证一笔交易的存在,而不需要存储或者传输大量区块链中大多数内容,这些内容可能有几个G的大小。这种不需要维护一条完整的区块链的节点,又被称作简单支付验证(SPV)节点,它不需要下载整个区块而通过Merkle路径去验证交易的存在。
7.8 Merkle树和简单支付验证(SPV)
Merkle树被SPV节点广泛使用。SPV节点不保存所有交易也不会下载整个区块,仅仅保存区块头。它们使用认证路径或者Merkle路径来验证交易存在于区块中,而不必下载区块中所有交易。
例如,一个SPV节点欲知它钱包中某个比特币地址即将到达的支付,该节点会在节点间的通信链接上建立起bloom过滤器,限制只接受含有目标比特币地址的交易。当节点探测到某交易符合bloom过滤器,它将以Merkleblock消息的形式发送该区块。Merkleblock消息包含区块头和一条连接目标交易与Merkle根的Merkle路径。SPV节点能够使用该路径找到与该交易相关的区块,进而验证对应区块中该交易的有无。SPV节点同时也使用区块头去关联区块和区块链中的区域区块。这两种关联,交易与区块、区块和区块链,证明交易存在于区块链。简而言之,SPV节点会收到少于1KB的有关区块头和Merkle路径的数据,其数据量比一个完整的区块(目前大约有1MB)少了一千倍有余。