(译)超级账本官方文档 基本概念(三) - 节点(Peer)
如有翻译不当之处烦请指出,我不确定的地方都给出了原文
超级账本是Linux基金会发起的项目,意在提供一套企业级区块链应用框架,便于大家开发基于区块链技术的应用。
Fabric的基本概念
-
Peer
区块链的网络由节点构成,每个对等节点都拥有一份账本(Ledger)和智能合约(Smart Contract)的拷贝。在下图的示例中,网络N由对等节点(Peer)P1,P2,P3构成,每个节点都保存着属于它们自己的分布式分类账本L1的实例,P1,P2,P3都使用码链(ChainCode)S1来访问自己保存的账本。
image.png
Peer可以被创建,启动,停止,重新配置及删除。通过一组公开的API可以允许管理员及应用程序访问Peer的服务。
-
账本(Ledgers)和码链(Chaincode)
image.png
一个节点(P1)可以包含一个账本的实例(L1)和一个码链的实例(S1),也可以包含多个账本实例和多个码链实例。正因为peer上有账本和码链的实例,管理员或者应用程序想访问这些资源的话就必须和peer交互。这也是为什么peer是超级账本中最基本的区块链设施。新启动的peer上即没有账本实例,也没有码链实例的。
-
多账本(Ledgers)
一个节点可以只包含一个账本实例,也可以包含多个账本实例,这样可以增加系统设计时的灵活性。当需要peer存放多个账本时,也是可以做到的。
image.png
当节点(peer)包含多个账本时,每个账本可以对应0个或多个码链(Chaincode)。如上图所示,节点P1包含账本L1和L2,访问L1的数据可以使用S1提供的服务,访问L2的数据,可以使用S1和S2提供的服务。当然,你的账本可以不部署任何码链,这意味着你没有渠道访问账本内容,这样的配置比较少见。大部分的节点都有至少一个码链提供对账本数据的访问及更新。值得一提的是,不管你有没有为了外部可以访问账本数据而部署码链,节点都有一个特殊的系统码链,我们后面再详述这个系统码链。
-
多码链(Chaincode)
节点中码链数量和账本数量的关系并不是绝对一一对应的。如上图所示,P1有账本L1和L2,访问L1的数据可以通过码链S1和S2,访问L2的数据可以通过码链S1和S3。可以看出,S1可以访问L1和L2两个账本的数据。后面我们会详述为什么通道(Channel)的概念在peer拥有多个账本和多个码链时是那么重要。 -
应用(Applications)和节点(Peer)
image.png
现在我们来介绍应用程序是如何连接到节点并访问节点上账本数据的。应用想在节点上查询账本信息的操作通过简单的三个交互步骤完成,账本数据的更新要复杂一点,需要多两步操作。为了更容易理解这些流程,我们简化了一下这些步骤。不用担心简化后的流程会影响你的理解,最重要的是理解应用程序连接到节点进行账本数据查询操作和更新账本操作的区别。
应用程序总是需要连接到节点上来获取账本数据或者使用码链。超级账本的SDK为程序员提供了很简便的方式去访问节点,调用码链生成交易,提交交易到网络并同步到其它分布式账本中,获取交易结果等。
通过连接到节点上,应用程序可以调用码链来查询或者更新账本,查询操作会立即返回,更新账本的操作要复杂一点,涉及到application,peer和orderer,我们来详细看看。
peer和orderers联合起来确保每个节点上的账本是最新的。在上面的例子中,应用程序A连接到P1,然后调用S1对L1进行查询或更新操作。P1调用S1生成一个包含查询结果或者账本更新提议。应用程序A收到响应后,能立即拿到查询结果。对于更新,A根据所有的响应构建一个交易(事务),并把它发送给O1进行排序(A builds a transaction from all of the responses, which it sends it to O1 for ordering)。O1搜集整个网络的交易(事务),将它们放入区块中,并分发给所有节点(peer),包括P1。P1在把这些交易加入到L1前会验证这些交易(事务)。一旦L1被更新了,P1会生成一个事件,通知A操作完成。
peer能立即返回A查询结果是因为满足查询条件的数据都在peer的本地账本中。peer不会联络其它peer以及时响应A的查询。应用程序可以连接到多个Peer上执行查询操作,比如你想验证多个peer上的查询结果是否一致,你就可以连接到多个peer上查询。从图中可以看出,查询操作很简单,三步而已。
更新操作与查询操作相似,但多了两步。尽管需要更新账本的应用程序可以连接到peer上调用Chaincode,但与查询不同的是,单个节点不能执行账本更新操作,因为其它peer必须先同意这次操作才行,这个过程叫共识。因此,peer会返回应用程序建议更新-如果其余peer意见一致,该peer才会执行这个操作(apply subject)。除了查询操作的三步外,第四步,应用程序需要发送一套合适的更新建议给所有的peer,作为一条交易放在他们各自的账本中。这个过程是通过order对交易进行打包并放入区块中,然后分发给网络的所有peer,peer在把区块加入到本地账本前会先验证区块有效性。整个ordering操作需要一段时间才能完成(几秒钟),应用程序会收到异步通知,也就是图中的第五步。 -
节点和通道(Peers and Channels)
peer节点,orderer节点和应用程序通过加入通道(Channel),共同管理,共享和加入的通道相关联的在peer上的独立拷贝的账本。你可以理解成你有多个朋友圈,每个朋友圈相互独立,每个朋友圈有一些全员参与的活动。或者,某个朋友可能处于多个朋友圈中,不管怎样,每个朋友圈是相对独立的。
image.png
通道允许一些特殊的peer和应用程序在一个区块链网络中互相通信。在上图的例子中,应用程序A可以直接在通道C中和P1,P2通信。你可以把通道理解成特殊的一些peer和应用程序通信的渠道。
通道并不像peer那样存在与物理环境中,你可以把通道理解成在peer组成的物理网络中的逻辑结构。另外一个重点是,peer提供了通道的访问和管理控制点。 -
节点和组织(Peers and Organizations)
现在你应该了解了peer和peer与账本(Ledgers),码链(Chaincode)和通道(Channel)之间的关系了。接下来你会了解到区块链网络中多个组织之间的关系。
区块链网络有多个组织,而不是单个组织管理。Peer是分布式网络如何构建的中心,因为组织拥有他们,也是构成组织网络的连接点。
image.png
在网络中的peer有多个组织。区块链网络是由属于不同组织的peer构建而成。上图的示例中我们看到4个组织,为网络提供了8个peer。通道C在区块链网络中连接了P1,P3,P5,P7,P8。其余的在组织中的peer没有加入到通道C中,但加入了至少一个其它的通道。一个被组织部署的应用程序会连接到组织的peer上,其余的组织也是如此。为了简化,orderer节点没有出现。
在这种组织架构下的区块链网络会发生什么情况是你需要了解的重点。这些组织构成了,并管理着区块链网络,也为网络贡献了资源。peer是我们要讨论的资源,当然,组织提供的资源不仅仅是peer。
没有组织提供的独立的资源,这个共享网络将不复存在。网络的扩大或缩小都由这些协作的组织决定。
你会发现,除了orderer外,没有中心化的资源。在上图的示例中,如果没有组织贡献的peer节点,网络就不存在。并且,网络并不被任何独立的组织所影响,只要有一个组织存在,网络就存在,这是去中心化的本质。
不同组织中的应用程序可以相同,也可以不同,这完全取决于组织中的应用程序如何操作对应peer中的账本副本。这意味着不同组织的应用程序及其展现的逻辑可能大不相同,尽管他们对应的peer都操作着相同的账本数据。
应用程序是连接到当前组织的peer还是其它组织的peer取决于应用程序需要以怎样的方式与账本交互。 -
节点和身份(Peers and Identity)
image.png
Peer通过来自特定证书颁发机构的数字证书为其分配身份。您可以阅读更多有关X.509数字证书的内容,但是,现在,将数字证书视为一张ID卡,它提供了许多关于Peer的验证信息。网络中的每个Peer都有一个由对应组织管理员颁发的数字证书。
当一个Peer连接到Channel,通过Channel的MSP,可以验证节点所属的组织。在上图的示例中,P1和P2的身份由CA1颁发。Channel C根据其Channel配置中的策略确定来自CA1的身份应使用ORG1.MSP与Org1相关联。类似地,ORG2.MSP将P3和P4识别为Org2的一部分。
当peer通过Channel连接到区块链网络中时,Channel根据配置的策略通过peer的身份来决定它有什么权限。组件Membership Service Provider (MSP)提供了组织身份的映像,这决定了peer在组织中能获得什么身份以及对应的访问区块链资源的能力。后面我们会介绍MSP,但就目前而言,将MSP视为在区块链网络中提供个人身份与特定组织角色之间联系的桥梁。
Peer或者任何与区块链网络交互时都需要从他们的数字证书和MSP中获取组织身份。如果Peers,应用程序,终端用户,管理员,orderers想访问区块链网络,他们必须拥有身份及相关的MSP。我们用身份-主体(an identity --- a principal)的方式来命名所有与区块链网络交互的实体。后面我们会说到主体(principal)和组织(organizations),但现在,只需要理解Peer。
最后,注意,Peer的物理位置在哪里并不重要,重要的是Peer的身份及属于哪个组织( it's the identity associated with it that identifies it as being owned by a particular organization)。在上面的例子中,P3可以不在Org1的数据中心,但只要它的数字证书是由CA2颁发的,那它就是Org2的Peer。 -
节点(Peers)和Orderers
image.png
应用程序和Peers交互时需要确认账本是一直保持同步的,而处理这个过程的特殊节点叫做Orderers,接下来我们就关注它。
更新一笔交易(事务)与查询一笔交易(事务)的区别很大,仅靠一个Peer是不能更新账本的,更新操作是需要网络中其它Peer同意的。一个Peer要更新账本信息,并同步到其它Peer节点上之前,需要经过统一。这个过程称为共识(consensus),这个过程比查询要花费更多的时间。但当所有Peer都同意一笔交易(事务)可以执行,这个交易(事务)才可以提交到账本中,Peers会通知应用程序账本更新了。接下来我们聊聊更多关于Peers和Orderers如何管理共识。
特别的,应用程序想更新账本需要经过3个阶段,这是为了保证网络中所有节点的账本保持一致。第一阶段,应用程序与背书Peer节点子网协同工作,每个背书Peer提供给应用程序账本更新操作的背书,确认这个操作,但并不会把这个更新操作实实在在的更新到账本上。第二阶段,这些分散的背书(或者叫操作记录吧)汇集到一起,当成一笔交易打包进区块。最后阶段,这些区块被分发给所有Peers,区块中的交易在被验证后,会加入到Peer本地的账本中。接下来我们更详细的说说这三个阶段,你将会了解到Orderers是共识过程中的关键。
过程1
第一阶段,交易(事务)的工作流程只涉及到应用程序和一些Peers的交互,不会牵扯到Orderers。阶段1只关心应用程序请求不同组织的背书Peer认同调用Chaincode的执行结果。在开始阶段1之前,应用程序生成交易(事务)提议,并发送给它需要的对其提议背书的Peer。每个背书Peer根据交易(事务)提议独立地执行Chaincode,以生成交易(事务)提议的响应。这个操作并没有把更新操作应用到账本中,而只是对交易(事务)提议进行签名然后返回给应用程序。一旦应用程序收到足够多的被签名的提议响应,第一阶段的交易流程就完成了。接下来详细看看第一阶段的流程。
交易提议被peer独立执行,并给返回被认可的响应。在上图示例中,应用程序A1生成交易T1及提议P,发送给通道C中的P1和P2。P1将T1P(transaction T1 proposal P)作为输入,执行S1,得到T1R1,被认证后记为E1。P2也独立地执行S1,将T1P作为输入,计算后得到T1R2,被认证后记为E2。应用程序A收到两个成功背书的响应,也就是E1和E2.
最开始,应用程序会选出一组peer来生成账本更新提议。哪些peer会被选出来是依据的背书策略,这个背书策略决定了哪些组织需要在广播账本更新提议前对更新提议进行背书。这会影响到共识方式,任何一个关心更新提议是否背书的组织都会在广播给peer更新提议并被peer接受前确认提议是否有背书。
peer对一个提议响应进行背书,就是把自己的数字签名加入到响应中,并用自己的私钥对整个响应签名。背书内容随后可以被用于证明这个响应是某个组织的peer生成的。在我们的例子中,如果peer P1属于组织1(Org1),那么背书E1就相当于可以证明L1上的交易T1和响应R1是由Org1的peer P1提供的。
当应用程序得到了足够多的签名的提议响应时,第一阶段就结束了。
我们注意到peer可能返回不同的信息,因此同一笔交易可能有不一致的返回信息。这可能由于响应是在不同时间,不同peer,在不同账本状态下生成的,大多数情况下应用程序可以多次请求更新的提议响应。另外更严重,但概率很小的原因是因为链码的不确定性导致的响应不一致。不确定性是链码和账本的大敌,如果这种情况发生了,对提议交易来说是很严重的,不一致的提议响应肯定不能提交到账本中。一个独立的节点是不可能知道交易结果是非确定性的交易,在检测到非确定性交易前,必须将交易汇总比较(严格地说,即使这还不够,但我们将此讨论推迟到交易部分,其中详细讨论了非确定性)。
在第一阶段结束时,如果应用程序希望如此的话,可以放心丢弃不一致的响应以提前结束交易流程。后面我们会看到如果应用程序使用不一致的响应提交到账本时,会被拒绝。
过程2 打包
第二个交易流程是打包。Orderer节点这个过程关键的点,它接收来自很多应用传来的背书过的提议交易响应。Orderer对交易进行排序,并将大量的交易打包进区块,并准备将区块分发到所有连接到Orderer的peer,包括背书peer。
orderer的第一个角色就是打包账本更新提议。在上图的例子中,应用A1发送给Orderer O1一个被E1和E2背书的交易T1。同时,应用A2发送给Orderer O1一个被E1背书的交易T2。O1将A1传来的交易和A2传来的交易以及其它交易共同打包进区块B2。我们可以看到区块B2里的交易排序是T1,T2,T3,T4,T6,T5,并不一定是按照到达orderer节点的顺序(这个例子展示了一个非常简单的orderer配置)。
Orderer节点会同时收到网络Channel中不同应用程序发送的账本更新提议。Orderer节点的任务就是按照事先定义好的顺序整理这些更新提议,并把它们打包进区块,为下一步的分发做准备。这些区块将构成区块链。一旦Orderer节点生成了期望大小的区块,或者超过最大等待时间,Orderer会向连接到它特定Channel的Peer发送区块。第三个过程会详述这个流程。
区块中的交易排列顺序和交易到达Orderer节点的顺序没有直接关系。交易在区块中可以是任意的排列顺序,这个次序就是交易执行的顺序。重点是有一个严格的交易排序,但具体是怎样的排序并不重要。
区块中的严格交易顺序排列使得Fabric与公链中一笔交易可以被打包进多个不同区块的情况不同。在Fabric中,这不可能发生,由多个Orderer生成的区块就是最终的区块,因为交易被写入区块后,交易的位置顺序就确定了。这意味着Fabric不会存在分叉。一旦交易被写入区块,以后就不能再重写了。
我们可以看到,peer是存储账本和链码的,orderer完全不会存储这些。每一笔交易到达orderer时,orderer只是机械的将交易打包进区块,而不会理会交易的价值,额度等。这是Fabric的一个重要特性,所有交易都会按照一个严格的顺序进行整理,没有交易会被抛弃掉。
到第二阶段结束时,我们可以了解到orderer的责任就是进行必要的,简单的收集交易更新提议,将他们排序,打包进区块,准备分发出去。
过程3 认证
最后一个交易工作流程是分发和验证从orderer到peer的区块,如果验证成功,将会被提交到账本中。
特别的,在每个peer中,在区块中的每一笔交易在更新到账本之前都是验证过的,以保证所有交易都是由相关的组织背书过的。失败的交易会保留,作为日后审查用,并不会更新到账本中。
Orderer除了在过程2中的打包角色外,在过程3中还负责分发区块到peer节点。在这个例子中,O1分发区块到P1和P2。P1处理区块2,然后将区块2添加到P1的账本L1中。同时,P2处理区块2,然后将区块2添加到P2的账本L1中。一旦操作完成,账本L1在P1和P2中都被更新了,每个Peer都可以向连接到他们的应用程序发送处理结果。
Orderer向连接到他的Peer分发区块是过程3的开始。连接到orderer节点的某个渠道的peer,会收到orderer生成的新区块的一份拷贝。每个peer节点都会独立的处理收到的区块,但所有peer处理区块的方式都是相同的。采用这种方式,不同peer中的账本可以达成共识。并不是所有的peer都必须连接到orderer节点,peer和peer之间可以通过gossip协议来传递区块,这样peer也可以独立的处理相同区块。
收到一个区块后,peer会按照交易在区块中出现的顺序依次处理。对于每一笔交易,peer会按照生成这笔交易的链码背书策略检查交易是否被与之相关组织的背书。例如,某些交易可能只需要一个组织背书,而另一些交易需要多个组织同时背书才有效。这个验证过程验证了所有相关组织产生的结果或者输出是否一致。同时请注意,第三阶段的验证和第一阶段不同,阶段一只是应用程序收到背书节点的响应,判断是否需要发送交易提议。如果应用程序发送错误的交易,违反了背书策略,在第三阶段的验证过程中peer还是可以拒绝本次交易。
如果交易背书正确,peer将尝试把交易提交到账本中。为了能写账本,peer必须进行账本一致性检查,保证当前账本的状态与账本更新后的状态一致。这个状态并不总会是一致的,即使交易拥有完整的背书。举个栗子,另外一笔交易可能已经更新了账本中的同一个资产,以至于我们正要更新的交易将永远不会被写入账本。这样的话,每个节点中的账本必须通过网络保持共识,每个节点的验证方式是一样的。
在peer验证完每笔独立交易后,将更新账本。失败的交易会保存下来作为审查资料。这意味着peer中的区块和从orderer中收到的区块一致,除了区块中指示交易成功或失败的标志。
我们也要注意到,第三阶段并没有执行链码,这一步只会在第一阶段完成,这很重要。这意味着链码只在背书节点可用,而不是整个网络中都可用,这保证了链码在背书组织中的安全及私密。这和收到链码的执行结果不同,执行结果会分享到所有在Channel里的peer,不论他是否能背书交易。背书节点的这种设计方式是为了方便扩展。
最后,每次区块被提交到peer的账本中时,这个peer会生成对应的事件。区块事件包含区块的所有内容,而区块交易事件只包含简要信息,比如每笔区块中的交易是否有效。由链码的执行而产生的链码事件也可以在这个时候发布。应用程序可以注册这些事件,当这些事件发生时,可以收到通知。这些通知在交易工作流程的第三阶段和最后阶段完成。
总的来说,我们可以知道第三阶段由orderer产生的区块被不断地同步到账本中。区块中交易的严格排序能让每个peer在区块链网络中始终如一地验证交易并提交到账本中。
Orderer和共识
整个交易工作流程被称为共识,因为所有peer都认同交易的排序和内容,在执行过程中由orderer节点来协调。共识是多步骤的过程,应用程序只会在共识过程结束时收到通知,但通知的时间在不同的peer上可能不同。
我们将会在后面更多的探讨orderer,现在,把orderer仅仅当做从应用程序收集、分发账本更新提议到peer,由peer进行验证及更新账本的过程。