hyperledger fabric是区块链中联盟链的优秀实现,主要代码由IBM、Intel、各大银行等贡献,目前v1.1版的kafka共识方式可达到1000/s次的吞吐量。本文中咱们依次讨论:区块链的共通特性、fabric核心概念、fabric的交易执行流程。本文来源于笔者欲对公司部分业务上链而进行培训的PPT,故图多文字少,不要怕太长。mysql
一、区块链解决方案的特性
1.1 分布式账本
区块链核心概念是分布式账本,就像下面的图1所示,一样的账本(全量的交易数据,详见下节)在任意一台节点(不包括客户端)上都有。因此,其优势是数据很难造假,造假后也能够经过追溯记录来追究法律责任。而缺点就是极大的浪费,传统服务每份数据都尽可能少存几份,即便存了三份拷贝都已经考虑到诸多异常,并使服务可用性达到N个9了。而区块链这种特性,同时形成的另外一个问题是账本不能太大,至少不能超过区块链网络中最小结点的存储以及处理能力。因此,这制约了总交易数据(下文为方便概念介绍,统称为账本ledger)的条数,进而也影响了能写入区块链的单条交易数据的大小。git
图1 区块链分布式账本示意图算法
什么是区块链呢?我很喜欢《区块链技术进阶与实战》一书中对它的定义:区块链是一种按照时间顺序将数据区块以顺序相连的方式组合成的一种链式数据结构。若是以为有点抽象,那么咱们再来看看下面的图2。sql
图2-区块链数据结构示意数据库
图2中就是帐本,它由多个区块构成了一个有时序的链表,而每一个区块里含有多条交易trasaction(缩写为tx)构成的链表。图2下方有一个WorldState世界状态,这实际上是为了提高性能用的。好比,key1共交易了10000次,为了获取它的当前状态值,须要正向执行这10000次交易,这就得不偿失了。若是这1万次交易里,每次新交易执行完,都同步更新一个数据库(在fabric里用的是levelDB),这样查询当前状态时,只须要查询该数据库便可,如图3所示。编程
图3-fabric levelDB状态数据库安全
图3中,区块链账本是在FileSystem文件系统中保存的,而Level DB存放世界状态。服务器
1.2 智能合约smart contract
区块链的发展过程当中,通常1.0时代就是数字货币时代,表明是比特币,而2.0时代就是智能合约(如今是3.0时代,各类联盟链即为表明)。网络
智能合约是运行在区块链上的模块化、可重用的自动执行脚本,有了它咱们就能够完成复杂的业务逻辑,例如同一个区块链上有多份合约,而每份合约能够约定不一样的参与者(企业或者相关方)。也能够指定每份合约里每一个子命令作一批特定的事,你们能够把它想象成关系数据库里的事务。如图4所示,咱们能够在合约里指定容许哪些企业的节点能够参与到交易流程中来(在fabric里这叫共识策略)。
图4-智能合约图示
在fabric中,智能合约叫作chaincode,它有6个状态,以下所示:
- Install → Instantiate → invocable → Upgrade → Deinstantiate → Uninstall.
实际上智能合约就是一段代码,fabric官方承认的是GO语言。首先咱们须要把合约代码上传到区块链上,这一步的状态就叫Install。
接着,须要作初始化操做。好比,如今的数据是存放在mysql中的,那么上线时须要用Instantiate把数据迁移至链上,这也算初始化。初始化后,chaincode就进入invocable可调用状态了。
通用咱们能够经过CLI命令行或者程序里用SDK调用合约(v1.1前还有RestApi调用,现已放弃)。
联盟链因为跨多家企业、多个地区甚至国家,很难使得合约保持一致的版本,所以,每一个合约都有版本号。而版本升级时,就是Upgrade状态。
最后两个状态对应着合约下链。
智能合约能够在供应链等较复杂的业务场景下起到很大的做用,以下面的图5所示:
图5-智能合约技术的应用示意
1.3 数据一致性(共识算法)
既然区块链是一个去中心化的分布式系统,那么天然只能经过投票来决定一致性了:少数服从多数。固然,多少算多数呢?不一样的共识算法下,结果并不相同。好比paxos算法(参见笔者的《paxos算法如何容错的–讲述五虎将的实践》)就是超过一半,而PBFT则须要三分之二以上。
这里有一个拜占庭将军问题须要注意,如何理解该问题能够参见这份翻译过的The_Part-Time_Parliament(Paxos算法中文翻译)文档。简言之,就是投票的拜占庭将军(服务器)们有2种不可靠的形式。第一是迟钝(数据包延迟)、失忆(数据包丢失以及数据包重发)、失踪(服务器宕机)等不含背叛的行为,第二则是有将军是间谍(服务器被攻破)。如paxos这样的算法属于第一种,Fault-tolerance,它不能容忍服务器上有恶意代码;而如PBFT(Practical Byzantine Fault Tolerance)这样的算法是第二类,Byzantine-Fault-tolerance,它可以容忍必定数量的拜占庭将军节点存在,如PBFT、SBFT、RBFT算法等。
第二类Byzantine-Fault-tolerance共识算法虽然看上去很美,但并不成熟,特别是性能低下,好比PBFT是一个多项式复杂度的算法O(N^2),节点过多时(大于100)性能急骤降低。第一类一般是O(N)复杂度,在某些场景下使用效果还不错,好比fabric v1.1的kafka共识机制就是这样的算法,下文咱们会详述。
像比特币、以太坊等采用的共识算法又有所不一样,例如比特币的POW工做量证实算法,它定义一小时内(经过调整运算难度实现,好比调整近似程度)有一个lucky node节点,该节点是经过证实自身的努力(hash值逆解)而幸运选出,选出后它就能够为这段时间的交易作决定(彷佛挺像总统选举^_^)。详情参见我这篇文章:《区块链技术学习笔记》
1.4 非对称加密
区块链经过非对称加密技术实现身份验证与数据加密。其实就是咱们平常在用的SSL技术。
为了方便理解,咱们须要先介绍PKI(Public Key Infrastructure),它是一种遵循标准的利用公钥加密技术为电子商务的开展提供一套安全基础平台的技术和规范。有一个CA(Certificate Authority)权威机构负责向用户(包括服务提供者与使用者)提供数字证书,包括公钥与私钥,同时CA机构还须要提供一个CRL(Certificate Revocation List)证书吊销列表,以下面的图6所示。
图6-CA机构颁发数字证书以及提供CAL
这样,区块链能够经过PKI体系实现安全认证。PKI有三个关键点,咱们下面详述。
1.4.1 数字证书 Digital Certificate
好比Mary Morris符合X.509规范的数字证书里,其Subject属性里就含有她的信息,包括国家C=US、所属的州或者省份ST=Michigan、所在城市L=Detroit、所属单位O=Mitchesll Cars、其余信息OU=Manufacturing、公用信息CN=Mary Morris/UID=123456等,也含有其余信息,以下面的图7所示。
图7-PKI数字证书
1.4.2 公钥与私钥
CA颁发了两个证书:公钥与私钥,其中,私钥仅服务提供者保存,而公钥则可被全部人(服务使用者)保存。
所谓非对称加密,就是公钥加密的消息仅私钥能够解密;同理,私钥加密的消息,仅公钥能够解密。对应于前者,能够实现客户端访问服务器时加密消息,例如访问安全级别高的页面时提交的表单信息都须要用公钥加密,确保只有服务器才能解密网络报文。对应于后者,则可实现签名功能,以下面的图8所示。
图8-PKI中私钥签名后用公钥验签名
图8中Mary Morris用私钥对一段信息的内容(若内容过大则可先HASH后得到小点的字符串)加密后,生成签名附加在消息中。接收者可从CA机构获取到公钥,用公钥解密签名后,再与内容比对,以肯定消息是否来自MaryMorris及内容是否被篡改。对于文件来讲也是同样,小文件直接加密,大文件先生成hash再对hash加密,以下面的图9所示。
图9-对文件的签名
1.4.3 证书信任链
CA证书分为两类:RCA(Root CA)根证书以及ICA(Intermediate CA)中间证书。这些证书由RCA开始构成一个证书信任链,以下面的图10所示。
图10-CA证书信任链条
有许多CA证书权威机构,各自有其RCA。若是RCA得不到信任,那么其下的ICA也没法认证经过。
固然,本身的服务器也能够生成RCA。
在Fabric里,容许不一样的企业使用不一样的RCA,也可使用相同的RCA和不一样的ICA。这与下文中的MSP密切相关。
1.5 小结
咱们来总结下区块链,它主要是为了解决社会上的信任问题而存在的,为此,它付出了沉重的性能、可用性代价。它怎么作到的呢?经过4点实现:一、数据处处存放;二、操做记录不可更改;三、传输数据可信;四、业务脚本约束。
那么,这个信任问题的解决,带来了2个非功能性的约束:数据一致性和可用性。其中可用性包括两点:一、交易在可接受的时间内达成。好比比特币的分叉就会形成严重问题。二、吞吐量达标。而比特币每秒只能有7次交易,这显然过低了。
二、fabric核心概念
hyperledger fabric符合上面说过的区块链的全部特性。咱们必须先了解它的一些概念,才能进一步理解其架构设计。因为英文资料居多,因此这些概念我都以英文描述为准:
- chaincode:智能合约,上文已提到。每一个chaincode可提供多个不一样的调用命令。
- transaction:交易,每条指令都是一次交易。
- world state:对同一个key的屡次交易造成的最终value,就是世界状态。
- endorse:背书。金融上的意义为:指持票人为将票据权利转让给他人或者将必定的票据权利授予他人行使,而在票据背面或者粘单上记载有关事项并签章的行为。一般咱们引伸为对某个事情负责。在咱们的共识机制的投票环节里,背书意味着参与投票。
- endorsement policy:背书策略。由智能合约chaincode选择哪些peer节点参与到背书环节来。
- peer:存放区块链数据的结点,同时还有endorse和commit功能。
- channel:私有的子网络,事实上是为了隔离不一样的应用,一个channel可含有一批chaincode。
- PKI:Public Key Infrastructure,一种遵循标准的利用公钥加密技术为电子商务的开展提供一套安全基础平台的技术和规范。
- MSP:Membership Service Provider,联盟链成员的证书管理,它定义了哪些RCA以及ICA在链里是可信任的,包括定义了channel上的合做者。
- org:orginazation,管理一系列合做企业的组织。
2.1 开发概念
fabric联盟链的开发人员主要分为三类:底层是系统运维,负责系统的部署与维护;其次是组织管理人员,负责证书、MSP权限管理、共识机制等;最后是业务开发人员,他们负责编写chaincode、建立维护channel、执行transaction交易等,以下面的图11所示。
图11-fabric技术人员的分层
fabric大体分为底层的网络层、权限管理模块、区块链应用模块,经过SDK和CLI对应用开发者提供服务,以下面的图12所示。
图12-fabric开发模块图
咱们的开发流程主要包括写智能合约,以及经过SDK调用智能合约,及订阅各种事件,如图13所示。
图13-开发环节
2.2 MSP
每一个管理协做企业的ORG组织均可以拥有本身的MSP。以下图14所示,组织ORG1拥有的MSP叫ORG1.MSP,而组织ORG2业务复杂,因此维护了3个MSP。
图14-ORG可管理本身的MSP
MSP出如今两个地方:在channel上有一个全局的MSP,而每一个peer、orderer、client等角色上都维护有本地的局部MSP,如图15所示。
图15-在channel上的Global MSP以及在参与角色上的Local MSP
本地MSP只保存有Global MSP上的子集,内容保存在本地文件系统上,而全局MSP可在逻辑上认为是配置在系统上的,它实际也在每一个参与者上保存一份拷贝,但会维持一致性。
MSP也分级,如图16中所示,底层的network MSP负责网络层的准入,其MSP由ORG1拥有,而上面的某个channel的MSP则由ORG1和ORG2共同管理。
图16-MSP是分级的
一个MSP下含有如下结构,如图17所示。
图17-MSP结构
可见,MSP结构包括:
- RCA根证书
- ICA中间证书
- OU组织单位
- 管理员证书
- RCL吊销证书列表
- 结点上的具体证书
- 存储私钥的keystore
- TLS的根证书与中间证书
三、fabric交易提交流程
3.1 peer结点的部署
peer结点上保存有帐本ledger以及智能合约,以下图所示:
channel是一个逻辑概念,能够经过MSP隔离全网不一样组织的参与者,以下图所示:
当有多方参与者时,例如4个org组织、8个peer结点时,其中channel链接了P一、P三、P五、P七、P8这五个节点,其余3个节点加入了其余channel,其部署图以下所示:
加入MSP来管理身份时,如P1和P2由ORG1.MSP管理,而P3和P4的证书则由ORG2.MSP管理,他们共同使用一个channel,则以下图所示:
3.2 交易的执行流程
去中心化的设计,必然须要经过投票(多数大于少数)来维持数据一致性,而任何投票都必须经历如下三个过程:
- 有一方先提出议案proposal,该议案有对应的一批投票者须要对该结果背书,这些投票者依据各自的习惯投票,并将结果反馈;
- 统计投票结果,若得到多数赞成,才能进行下一步;
- 将得到多数赞成的议案记录下来,且公之于众。
而这三步fabric固然也少不了,固然它的称法就有所不一样,其对应的三步以下:
- 由client上的CLI或者SDK进行proposal议案的提出。client会依据智能合约chaincode根据背书策略endorse policy决定把proposal发往哪些背书的peer节点,而peer节点进行投票,client汇总各背书节点的结果;
- client将得到多数赞成的议案连同各peer的背书(包括其投票结果以及背书签名)交给orderring service,而orderer会汇总各client递交过来的trasaction交易,排序、打包。
- orderer将交易打包成区块block,而后通知全部commit peer,各peer各自验证结果,最后将区块block记录到本身的ledger帐本中。
咱们看一个具体的例子,若channel上有三个peer背书者,client提交流程以下图所示:
详细解释下上图的流程:
- 首先,client发起一个transaction交易,含有<clientID, chaincodeID, txPayLoad, timestamp, clientSig>等信息,指明了3W要素:消息是谁who在什么时间when发送了什么what。该消息根据chaincode中的背书策略,发向EP一、EP二、EP3这三个peer节点。
- 这三个peer节点模拟执行智能合约,并将结果及其各自的CA证书签名发还client。client收集到足够数量的结果后再进行下一步。
- client将含背书结果的tx交易发向ordering service。
- ordering service将打包好的block交给committing peer CP1以及EP一、EP二、EP3这三个背书者,背书者此时会校验结果并写入世界状态以及帐本中。同时,client因为订阅了消息,也会收到通知。
若是咱们从编程的角度来看,则流程会更清楚:
参见上图,A是咱们的应用程序,其步骤以下:
- A首先链接到peer。
- A调用chaincode发起proposal;与此同时,P1收到后先模拟执行,再产生结果返回给A。
- A收到各peer返回的结果。
- A向O1发起交易;与此同时,O1产生区块后会通知peer,而peer会更新其帐本。
- 最后经过订阅事件A收到告终果。
最后再细看下这三个阶段。
3.2.1 proposal提案阶段
能够看到,A1发出的<T1, P>,收到了<T1, R1, E1>和<T1, R2, E2>两个结果。
3.2.2 package打包阶段
O1在一个channel上会收到许多T交易,它会将T排序,在达到block的最大大小(通常应配1M如下,不然性能降低严重,kafka擅长处理小点的消息)或者达到超时时间后,打成区块P2。
3.2.3 验证阶段
O1将含有多条交易T打成区块的B2发往各peer节点,而P1和P2将B2加入各自的L帐本中。
四、小结
本文偏重于概念的解释,因为篇幅所限,未涉及fabric的系统搭建(请参考笔者的这篇文章《区块链开源实现fabric快速部署及CLI体验》),也未描述共识算法在异常状况下如何维持一致性,这留待下一篇文章解决。fabric的许多思想是值得咱们进一步研究的,其优秀的实现能够帮助咱们经过fabric得到区块链在信任创新上的思路。