超级账本学习之二:了解Peer

在进一步了解超级账本以前,我觉得有必要了解一些基本概念,这些概念可以在官方文档中找到。其中,特别重要的是关于Peer的一些理解。在这里我尝试去翻译这篇文章,同时加入我自己的一些理解。

关于Peers

区块链网络主要由一系列的Peers节点组成。Peers是整个网络的基础,因为它是账本和智能合约的载体。通过智能合约,账本以不可篡改的方式记录了交易的全过程。在区块链中,智能合约和账本被用来封装整个网络中的共享处理工程和共享信息。从这个角度来说,Peer是了解超级账本的一个很好的入口。当然,超级账本还有很多其他的重要概念,比如,账本、智能合约、排序服务、通道、成员管理等。本文重点关注peers以及它与超级账本网络中其他模块的关系与交互。

超级账本学习之二:了解Peer_第1张图片

一个区块链网络由peer节点组成,每一个peer节点持有一个或多个账本,以及一个或多个智能合约。上图中网络N由三个peer组成P1、P2和P3。每一个Peer都持有了一个账本实例L1;每个peer都通过链码(智能合约)S1去访问各自的账本副本L1。(注意:从这里我们知道,链码是一段可以访问账本的代码,账本是通过链码来访问的!)

通过暴露的一系列接口,可以允许管理员和运用程序来创建、开启、停止、重新配置甚至删除peer。

账本与链码

进一步了解peer,我们可以说peer持有了账本和链码。但是,更准确的说应该是peer持有了账本和链码的实例。实际上,一个peer可以持有多个账本实例和多个码实例。

超级账本学习之二:了解Peer_第2张图片

正是由于peer持有了账本和链码,管理员和运用程序必须通过peer才能访问这些资源。正因如此,peer被称作超级账本区块链网络中最基础的模块。当peer被创建的时候,里面既没有账本也没有链码。后面将描述账本是如何创建的以及链码是如何安装的。

多账本和多链码

一个peer可以持有多个账本,这对于增加系统设计的灵活性至关重要。当然,超级账本也允许一个账本没有链码,但这种情况很少,因为这就意味着这个账本不能被访问和更改。通常情况,我们每个账本至少有一个链码用于查询或者更改账本实例。实际上,不管用户是否已经安装了自己的链码,每一个peer都有一些系统链码(据我所知,channel的建立以及lead节点的确定就是通过系统链码来完成的)。这些不在本章节的讨论之列。

此外,链码数量与账本数量也没有必然关系。如下图,账本L1可以通过链码S1和S2访问;账本L2可以通过S1和S3访问。因此,S1可以同时访问L1和L2(个人认为,这个特性在实际运用中非常重要,这使得跨系统的联盟链成为可能。)超级账本学习之二:了解Peer_第3张图片

实际上,由于一个Peer可能持有多个账本和多个链码,超级账本中通道(channel)就显得尤为重要了。

Application与Peer

接下来我们将介绍应用程序如何通过Peer去访问账本。简单的说,Application与Peer的交互主要包括账本查询与账本更新。账本查询只需要简单的三次会话;而账本更新需要额外的两次会话。Application总是通过Peer去访问账本和链码的。超级账本提供的SDK可以允许application连接peer、调用链码产生交易、提交交易到整个网络并接收处理过程中产生的事件。

通过连接到一个peer,application开执行链码来查询或者更新账本。查询结果可以很快返回;但是更新账本需要更复杂的交互,这些交互涉及到application、peer还有orderer:

超级账本学习之二:了解Peer_第4张图片

Orderer用来确保所有的Peer持有的账本同步更新。在上图中,查询账本的步骤可以做如下的简单描述:

  1. application连接到peer。
  2. application生成提案,并将提案提交给peer。
  3. peer根据提案调用相应的链码执行。
  4. 链码根据提案查询对应的超级账本。
  5. 向application返回提案应答。

至此,账本查询的完成。更新账本还需要接下来完成下面的步骤:

  1. application根据查询的返回结果生成一个交易并发送给排序服务模块(Orderer)。
  2. orderer将交易发给网络内的所有节点(peers)。
  3. peer根据交易调用相关的链码完成账本更新(此处图中可能产生误导,P1不可以直接调用L1,应该先调用S1,再通过S1调用L1)。
  4. 账本更新完成后产生事件通知application更新完成。

对于账本查询操作,peer本地保存了账本的副本,它不需要向网络内的其它peer查询,因此可以很快的返回操作结果。当然,application可以连接到多个peer上,以尽量确保查询的结果来自最新的账本。

对于账本更新操作,虽然本质上来说application仍然是通过连接的peer调用链码来完成操作,但是与账本查询不同,账本更新以前需要与其他peer达成一致,即共识。因此,需要Orderer将交易提案发送给整个网络的所有peer。每个peer收到交易提案后会从自己的角度判断是接受还是拒绝交易提案。由于整个过程比较耗时,application会在整个过程完成后得到一个异步的通知。关于orderer的工作流程交易流程。

Peer与通道(Channel)

通道为网络中的所有模块提供了私有的沟通与交易渠道。这些模块包括peer节点、oderder节点、application。加入通道后,这些模块可以共享或管理通道内的所有账本。一个节点可以加入到多个通道中(即,拥有多个账本),但是每个通道的账本是隔离的。因此,通道是一个逻辑结构,它由物理存在的各种节点组成。需要注意的是,peers提供了访问通道或者管理通道的接口(个人觉得,通道就是一个区块链,一个区块链由一个账本,一个账本可能有一个或者多个链码)。

超级账本学习之二:了解Peer_第5张图片

Peers与组织(Organizations)

在明白了Peer与账本、链码和通道的关系后,需要进一步了解多个组织怎么样组成一个区块链网络。通常情况,一个区块链网络由多个组织组成,而非一个单一的组织(译注:通俗的说,我们的区块链很有可能是跨域(domain)的,很多时候我们需要多个域一起才能构成一个完整的区块链网络。因此,这里的组织可以看成域的概念)。如下图所示:超级账本学习之二:了解Peer_第6张图片

  • 在图中,我们可以看见4个组织提供了8个peers,进而组成了整个区块链网络。而通道C连接了其中的5个peers,其塔的节点并没有连接到当前通道。但是其他peers(P2、P4和P6)加入了至少一个其他的通道(图中未给出)。每个组织的application只会连接到自己所在组织的peers上。另外,图中没有给出Orderer节点。
  • 因此,整个区块链网络应该是由它所包含的组织构成的。因为组织才是区块链网络所需资源的拥有者和提供者。虽然我们这里讨论的是peer,但是实际上组织才是真正的区块链的价值基础。因此,如果没有有价值的组织,那么区块链网络也就失去了存在的意义。区块链网络的规模与其拥有的有价值的组织有直接的正相关关系(个人觉得,这才是超级账本的真正实际意义所在)。
  • 从上图可以看出,没有一个中心化的资源存在。因此,整个区块链网络并不依赖于某个单独的组织。只要还存在有资源价值的组织,整个区块链网络并不会依赖于某一个组织的出现或者消失。这正是去中心化的核心所在。
  • 每个组织都有自己的application。虽然使用的是同样的账本,但是由于每个组织关注的重点不一样,因此他们的application也会有很大的差异。一个application可以连接到自己所在组织的peer,也可以连接到其他组织的账本。这依赖于application与账本的交互方式。比如:对于查询操作,application只需要连接到自己组织的peer即可;但是对于更新操作,需要连接到所有组织的指定peer,因为更新操作需要背书操作。
  • 为了与当前的区块链网络交互,每一个组织都需要一个锚定节点(Anchor Peer)。如图中的P1、P3、P5、P7和P8就是锚定节点。

Peer与身份

通过特定的认证授权,每个Peer都被赋予了一个指定的数字签名。数字签名像一个身份证,包含了当前peer的各种信息。每个Peer都拥有所在组织管理员签发的数字签名。

超级账本学习之二:了解Peer_第7张图片

  • 当一个Peer加入通道的时候,它的数字签名表明了它所在的组织。如图所示,P1和P2的数字签名有CA1签发;而P3和P4的数字签名由CA2签发。通过配置,通道C知道CA1来自组织ORG1;而CA2来自ORG2。ORG1.MSP和ORG2.MSP由通道的MSP统一管理。
  • 通过配置(Channel Configuration),通道知道接入的每个Peer的权限。MSP(Membership Service Provider)模块完成了这个功能。MSP决定了一个Peer的角色,访问区块链资源的权限。由于一个Peer只能属于一个组织,因此它只能被关联到一个MSP上面。
  • 实际上,所有的节点在访问区块链网络的时候都需要进行身份认证。包括Peer节点、application、Orderer节点以及管理员等。
  • 需要注意的是,节点的物理位置并不重要。它可以是位于云端,也可以是组织的中心服务器或者本地的计算机。节点的身份认证决定了它是否可以加入指定的区块链网络,以及加入网络后的角色和权限。

Peer与排序服务(Orderer)

排序服务保证了application和Peers在交互的时候账本的一致性。正如上面看到的,在账本更新的时候,我们需要需要与网络中其它节点达成共识。通常情况,application需要3个步骤来完成账本更新并保障数据的一致性:

  1. application将更新提案发给指定的背书节点,背书节点对提案背书,但不更新本地账本,然后将背书结果返回给application。在这里,背书节点是所有节点的一个子集,即不要求所有节点参与背书。
  2. application将收集所有的背书,然后打包到块中。
  3. TODO

由上可知,排序节点(Orderer Node)是整个处理的核心。下面来详细介绍application和peer是怎样在分布式的环境下确保更新的一致性的。

步骤一:提案

第一步提案阶段排序服务(Orderer),主要由application和一些相关的Peer节点完成。提案阶段是application向不同组织的背书节点提交更新请求。如下图所示:

超级账本学习之二:了解Peer_第8张图片

  • application产生一个交易提案,并将提案发送给所有相关的背书Peer节点。每个背书节点根据交易提案独立的执行链码,并返回提案回执。需要注意的是,这个阶段背书节点并不更新本地账本,只是对提案签名并返回给application。当application收集到了足够的提案回执,提案阶段就完成了。
  • 如图,A1根据交易T1产生提案P,并分发给通道内的所有背书节点P1和P2。P1和P2分别进行背书,P1调用自己的链码S1产生回执R1和背书E1。P2同理。P1和P2背书完成后将回执发回给application。
  • 背书节点的确认依赖于背书策略,背书策略由链码确定,它定义了一个交易在被整个网络接受以前需要哪些组织背书。从业务上来说,当产生一个交易的时候需要哪些组织确认才能让交易生效,那么这些组织就需要为交易背书。
  • 背书节点(Endorser Peer)在回执中添加数字签名,并且使用私钥对整个payload域加密。因此,背书回执可以看作是该组织对该交易的一个有效证明。
  • 需要注意的是,对于相同的提案,不同的背书节点返回的回执结果可能不一样。导致结果不一样的情况可能原因有两种:一是每个背书节点持有的账本状态不一致,导致背书回执是基于不同的账本状态产生的。对于这种情况,我们只需要简单的请求一个最新回执即可;另外一个原因是由于背书节点链码的不确定性导致的。这种情况就会比较严重,因为不确定性是链码和账本的天敌。不确定性出现说明交易提案本身就有问题,而且很明显这种不一致的结果是不能写入到账本的。而且,每个单独的背书节点并不知道他们的回执具有不确定性,因此需要收集所有的回执并加以比较才能知道是否存在不确定性。关于更多的不确定性的讨论参加交易相关的文章。对于application来说,它在发现不一致的时候可以终止交易,实际上回执不一致的交易会在接下来的步骤中被拒绝掉。

步骤二:打包

打包操作由排序节点(Orderer)完成。所有application的交易在提案完成背书后,包含背书结果的回执会被发送到排序节点。因此,排序节点会收到来自所有application的各种背书提案,它会对所有交易进行排序然后打包发给所有的Peers(包括先前参与背书的Peer)。如下图所示:

超级账本学习之二:了解Peer_第9张图片

  • 图中,A1发送的交易T1包含了回执R1和背书E1 E2;A2发送的交易T2包含了回执R2和背书E1。这些交易咋排序节点中进行排序打包处理,形成一个块B2。
  • 排序服务节点会同步收到不同application发送的很多交易,排序节点会对这些交易排序,然后打包成块。实际上,这些块接下来会发给所有Peer,并成为账本中的新块。在第三步中我们会看见这些块是怎么处理的。
  • 需要注意的是,排序后的交易顺序并不和他们到达的顺序一致。排序后的交易顺序就是它们在链码上的执行顺序,交易之间应该是有严格的顺序的。
  • 在其它的区块链中,同样的交易可能被打包到不同的块中。但是在超级账本的区块链中这是不允许的,因为一旦一个交易被写入到块中,它的位置也就不可篡改,交易历史也不能在未来被修改,以防止账本分叉(即,要保证一个交易的所有记录被写入到同一个块中。如果交易未完全结束,则等待它完全结束后再写入。防止不可预知的交易结果导致账本分叉)。
  • 由此可见,Orderer只是对交易进行排序并打包。它本身不对交易进行验证,因此它和Peer节点不一样,它不包含账本和链码。

步骤三:验证

最后,打包后的交易会被分发到所有节点(Peer)。每个Peer节点会对打包的每一个交易进行验证,以确保每个交易都被相关节点背书,且背书回执是一致的。如果发现不一致,交易将会被审查并保留,不会被写入到账本中。如下图所示:

超级账本学习之二:了解Peer_第10张图片

  • Peer节点连接到排序服务,以确保有新的区块产生的时候能获得这个区块的拷贝。每个Peer会单独的处理新的区块。实际上它们的处理方式是一样的,这样确保了账本的一致性。需要注意的是,不是所有的Peer都会连接到Orderer节点。Peer节点可以通过GOSSIP将新的区块散布到网络的其它节点。
  • 每个Peer都需要验证接收到的每个交易已经被正确的背书。不同的交易有不同的背书策略,需要不同的组织参与背书。Peer需要确保所有需要参与背书的Peer都参与了背书,并产生了同样的背书结果。
  • 在验证成功后,Peer还需要确保当前账本的状态与交易产生是的账本状态是一致的。这就确保了更新后的账本与网络内的其它账本是一致的。因为它们都遵循相同的更新规则。
  • 需要注意的是,验证阶段并不需要链码的参与,链码仅在第一步背书的时候用到。这使得参与背书的组织可以对它的背书链码保密。与之对应的是查询链码,它可以对通道内的所有Peer开放。
  • 最后,每次Peer的账本更新后都会产生一个块事件。块事件包含了整个块的内容,包括块内的所有交易是否有效或者无效等;而块交易事件仅仅包含了一些摘要信息;除此之外,链码也可以在这个时候产生链码事件。application可以通过注册这些事件知道交易流程。

排序服务与共识

整个交易流程可以被称之为共识,因为所有的Peer在排序和交易内容上达成了一致。共识是通过多个步骤达成的,而application只是在共识完成后得到通知而已。排序服务本身也是一个很复杂的处理,但是这里我们简单的认为排序只是搜集、分发来自application的交易提案,而Peer负责验证并将交易更新到账本中。

你可能感兴趣的:(超级账本,区块链,Hyperledger,Fabric)