Peers

区块链网络主要由一组peer节点(或者简单地说成peer)组成。peer是网络的基本元素,因为它们承载着账本和智能合约。回想一下,账本不可更改地记录了由智能合约生成的所有交易(包含在超级账本Fabric的链码中,稍后将详细介绍)。智能合约和账本分别用于封装网络中的共享进程和共享信息。peer的这些方面使它们成为了解Fabric网络的良好起点。

当然,区块链网络的其他元素也很重要:账本和智能合约、排序器、策略、通道、应用程序、组织、身份和成员,您可以在它们各自的专用部分中阅读更多关于它们的信息。本节主要讨论peer及其与Fabric网络中其他元素的关系。

../_images/peers.diagram.1.pngPeer1

区块链网络由peer节点组成,每个节点都可以保存账本副本和智能合约副本。在本例中,网络N由peer P1、P2和P3组成,它们各自维护各自的分布式账本L1实例。P1 P2和P3使用相同的链码S1来访问他们的分布式账本副本。

可以创建、启动、停止、重新配置甚至删除peer。它们公开了一组API,使管理员和应用程序能够与它们提供的服务进行交互。在本节中,我们将更多地了解这些服务。

A word on terminology

Fabric实现了一个称为链码的技术概念的智能合约——它只是访问账本的一段代码,用受支持的编程语言之一编写。在本主题中,我们通常使用术语链码,但是如果您更习惯这个术语,可以将其理解为智能合约。这是一回事! 如果您想了解更多关于链码和智能合约的信息,请查看我们关于智能合约和链码的文档。

Ledgers and Chaincode

让我们更详细地看看peer。我们可以看到,peer承载了账本和链码。更准确地说,peer实际上承载着账本实例和链码实例。注意,这在Fabric网络中提供了故意的冗余——它避免了单点故障。在本节的后面,我们将更多地了解区块链网络的分布式和去中心特性。

../_images/peers.diagram.2.pngPeer2

peer节点承载账本实例和链码实例。在本例中,P1承载一个账本L1实例和一个链码S1实例。在单个peer上可以托管许多账本和链码。

由于peer是账本和链码的宿主,如果应用程序和管理员想访问这些资源,就必须与peer进行交互。这就是为什么peer被认为是构成Fabric网络的最基本的构件。当第一次创建peer时,它既没有账本也没有链码。稍后我们将看到如何在peer节点上创建账本,以及如何安装链码。

Multiple Ledgers

peer能够承载多个账本,这很有帮助,因为它允许灵活的系统设计。最简单的配置是peer管理一个账本,但是当需要时,peer托管两个或多个账本是绝对合适的。

../_images/peers.diagram.3.pngPeer3

托管多个账本的peer。peer托管一个或多个账本,每个账本具有零个或多个适用于它们的链码。在这个例子中,我们可以看到peer P1承载着账本L1和L2。使用链码S1访问账本L1。另一方面,账本L2可以使用链码S1和S2访问。

虽然peer完全有可能在不加载任何访问该账本的链码的情况下托管账本实例,但是很少有peer是以这种方式配置的。绝大多数peer将至少安装一个链码,该链码可以查询或更新peer的账本实例。值得一提的是,无论用户是否安装了链码供外部应用程序使用,peer端也有始终存在的特殊系统链码。本主题不详细讨论这些。

Multiple Chaincodes

一个peer拥有的账本数量和能够访问该账本的链码数量之间没有固定的关系。一个peer可能有许多链码和许多账本可用。

../_images/peers.diagram.4.pngPeer4

一个peer承载多个链码的例子。每个账本可以有许多链码来访问它。在这个示例中,我们可以看到peer P1承载着L1和L2,其中L1由链码S1和S2访问,L2由S1和S3访问。我们可以看到S1可以同时访问L1和L2。

稍后我们将看到为什么Fabric中的通道概念对于在peer节点上托管多个账本或多个链码非常重要。

Applications and Peers

现在我们将展示应用程序如何与peer交互来访问账本。账本查询交互包括应用程序和peer之间的一个简单的三步对话;账本更新交互稍微复杂一些,需要额外的两个步骤。为了帮助您开始使用Fabric,我们稍微简化了这些步骤,但是不要担心——理解账本查询的应用程序peer交互与账本更新交易样式之间的区别是最重要的。

当应用程序需要访问账本和链码时,它们总是连接到peer。Fabric软件开发工具包(SDK)使程序员很容易做到这一点——它的API使应用程序能够连接到peer,调用链码来生成交易,向网络提交交易,这些交易将被排序并提交到分布式账本,并在此过程完成时接收事件。

通过peer连接,应用程序可以执行链码来查询或更新账本。账本查询交易的结果将立即返回,而账本更新涉及应用程序、peer和排序器之间更复杂的交互。让我们更详细地研究一下。

../_images/peers.diagram.6.pngPeer6

peer与排序器一起,确保每个peer的账本都是最新的。在本例中,应用程序A连接到P1并调用链码S1来查询或更新账本L1。P1调用S1生成一个包含查询结果或建议的账本更新的提案响应。应用程序A接收提案响应,对于查询,流程现在已经完成。对于更新,A从所有响应构建一个交易,并将其发送到O1进行排序。O1将网络上的交易收集到块中,并将其分发给所有的peer,包括P1。P1在应用到L1之前验证交易。更新L1之后,P1生成一个事件,由A接收,表示完成。

peer可以立即将查询结果返回给应用程序,因为满足查询所需的所有信息都在peer的本地账本副本中。peer从不与其他peer协商以响应来自应用程序的查询。但是,应用程序可以连接到一个或多个peer来发出查询;例如,在多个peer之间验证结果,或者如果怀疑信息可能过时,则从另一个peer检索最新的结果。在图中,您可以看到账本查询是一个简单的三步过程。

更新交易以与查询交易相同的方式启动,但是有两个额外的步骤。尽管账本更新应用程序也连接到peer以调用链码,但与账本查询应用程序不同,单个peer此时不能执行账本更新,因为其他peer必须首先同意更改——这是一个称为共识的过程。因此,peer向应用程序返回一个提议更新——该peer将在其他peer事先同意的情况下应用该更新。第一个额外步骤(步骤4)要求应用程序向整个peer网络发送一组匹配的提议更新,作为对各自账本的提交的事务。这是通过应用程序来实现的,它使用一个排序器将交易打包成区块,并将它们分发到整个peer网络,在将它们应用到每个peer网络的本地账本副本之前,可以对它们进行验证。由于整个排序处理需要一些时间(几秒钟)才能完成,因此将异步通知应用程序,如步骤5所示。

在本节的稍后部分,您将了解关于此排序流程的详细性质的更多信息——要真正详细了解此流程,请参阅交易流程主题。

Peers and Channels

尽管本节讨论的是peer而不是通道,但是花点时间了解peer如何通过通道相互交互以及如何与应用程序交互是值得的,通道是区块链网络中的一组组件可以私下通信和交易的一种机制。

这些组件通常是peer节点、排序器和应用程序,通过加入一个通道,它们同意协作,共同地共享和管理与该通道关联的相同的账本副本。从概念上讲,您可以将通道看作类似于朋友组(尽管通道的成员当然不需要是朋友!)一个人可能有几组朋友,每组都有他们一起做的活动。这些群体可能是完全独立的(一群工作上的朋友和一群爱好上的朋友相比),或者他们之间可能有交叉。然而,每个组都是自己的实体,具有某种“规则”。

../_images/peers.diagram.5.pngPeer5

通道允许一组特定的peer和应用程序在区块链网络中彼此通信。在本例中,应用程序A可以使用通道C直接与peer P1和P2通信。(为了简单起见,此图中没有显示排序器,但是必须在一个正常运行的网络中显示排序器。)

我们看到通道的存在方式与peer不同——将通道看作由物理peer集合组成的逻辑结构更合适。理解这一点非常重要——peer为通道的访问和管理提供控制点。

Peers and Organizations

现在您已经了解了peer及其与账本、链码和通道的关系,您将能够看到多个组织是如何组合在一起形成区块链网络的。

区块链网络由一组组织管理,而不是由一个组织管理。peer对于这种分布式网络的构建至关重要,因为它们属于这些组织,并且是这些组织与网络的连接点。

../_images/peers.diagram.8.pngPeer8

具有多个组织的区块链网络中的peer。区块链网络是由不同组织拥有和提供的peer构建的。在这个例子中,我们看到四个组织提供八个peer来组成一个网络。通道C连接网络N中的五个peer——P1、P3、P5、P7和P8。这些组织拥有的其他peer尚未连接到此通道,但通常至少连接到另一个通道。由特定组织开发的应用程序将连接到他们自己组织的peer以及不同组织的peer。同样,为了简单起见,此图中没有显示排序器节点。

你能看到区块链网络的形成过程是非常重要的。这个网络是由多个向其提供资源的组织组成和管理的。peer是我们在本主题中讨论的资源,但是组织提供的资源不仅仅是peer。这里有一个原则在起作用——如果没有组织将他们的个人资源贡献给集体网络,网络实际上是不存在的。此外,网络随着这些协作组织提供的资源的增加和减少而增长和收缩。

您可以看到(除了排序服务之外)没有集中的资源——在上面的示例中,如果组织没有提供它们的peer,网络N将不存在。这反映了一个事实,即除非各组织提供构成网络的资源,否则网络在任何意义上都不存在。此外,网络并不依赖于任何一个单独的组织——只要有一个组织存在,它就会继续存在,不管其他哪个组织可能来来去去。这就是网络去中心化的核心。

不同组织中的应用程序(如上例所示)可能相同,也可能不同。这是因为一个组织完全取决于它的应用程序如何处理其peer的账本副本。这意味着应用程序和表示逻辑可能会因组织而异,即使它们各自的peer承载完全相同的账本数据。

应用程序可以连接到其组织中的peer,也可以连接到另一个组织中的peer,这取决于所需的账本交互的性质。对于账本查询交互,应用程序通常连接到它们自己组织的peer。对于账本更新交互,我们将在后面看到为什么应用程序需要连接到代表每个组织的peer,这些组织需要背书账本更新。

Peers and Identity

既然您已经了解了来自不同组织的peer如何聚集在一起形成一个区块链网络,那么有必要花一些时间了解peer是如何被其管理员分配到组织中的。

peer具有通过来自特定证书颁发机构的数字证书分配给它们的身份。在本指南的其他部分,您可以阅读更多关于X.509数字证书如何工作的信息,但是,就目前而言,可以将数字证书看作是一个ID卡,它提供了关于peer的大量可验证信息。网络中的每个peer都由所属组织的管理员分配一个数字证书。

../_images/peers.diagram.9.pngPeer9

当peer连接到通道时,其数字证书通过通道MSP标识其所属组织。在这个例子中,P1和P2的身份由CA1给出。通道C根据其通道配置中的策略确定来自CA1的身份应该使用ORG1.MSP与Org1关联。同样,P3和P4也被ORG2标识。MSP作为Org2的一部分。

当一个peer使用通道连接到区块链网络时,通道配置中的策略使用peer的身份来确定其权限。身份到组织的映射是由一个称为成员服务提供者(MSP)的组件提供的——它决定如何将peer分配给特定组织中的特定角色,并相应地获得对区块链资源的适当访问权。此外,peer只能由单个组织拥有,因此与单个MSP关联。我们将在本节的稍后部分了解更多关于peer访问控制的内容,本指南的其他部分有一整节关于MSPs和访问控制策略。但是现在,可以将MSP看作是在区块链网络中提供个人身份和特定组织角色之间的链接。

暂时离题一下,peer以及所有与区块链网络交互的东西都从它们的数字证书和MSP获得它们的组织身份。如果peer、应用程序、最终用户、管理员和排序器想要与区块链网络进行交互,他们必须具有身份和关联的MSP。我们为使用身份(主体)与区块链网络交互的每个实体提供一个名称。在本指南的其他地方,您可以了解更多关于主体和组织的信息,但是现在您已经了解了足够多的信息,可以继续了解peer了!

最后,请注意,peer的物理位置在哪里不是很重要——它可以驻留在云端,或在数据中心旗下的一个组织,或者在一个本地机器- - -与它关联的身份标识出它属于一个特定的组织。在我们上面的例子中,P3可以托管在Org1的数据中心,但是只要与它相关联的数字证书由CA2颁发,那么它就属于Org2。

Peers and Orderers

们已经看到peer构成了区块链网络的基础,承载着账本和智能契约,可以通过peer连接的应用程序查询和更新这些合约。然而,应用程序和peer相互交互以确保每个peer的账本保持一致的机制是由称为排序器的特殊节点协调的,现在我们将注意力转向这些节点。

更新交易与查询交易有很大的不同,因为单个peer不能单独更新账本——更新需要网络中其他peer的同意。peer要求网络中的其他peer在将账本更新应用到peer的本地账本之前批准该更新。这个过程称为共识,它比一个简单的查询需要更长的时间来完成。但是,当所有需要批准该交易的peer都这样做时,并且该交易已提交到账本,peer将通知其连接的应用程序账本已更新。在本节中,您将看到更多关于peer和排序器如何管理共识过程的详细信息。

具体来说,想要更新账本的应用程序涉及到一个三步的过程,它确保区块链网络中的所有peer保持它们的账本彼此一致。在第一个阶段,应用程序与背书peer的子集一起工作,每个peer都向应用程序提供对提议的账本更新的背书,但是不将提议的更新应用于它们的账本副本。在第二阶段,这些单独的背书作为交易收集在一起并打包成区块。在最后一个阶段,这些区块被分发回每个peer,在将每个交易应用到该peer的账本副本之前,将在每个peer验证每个账本。

正如您将看到的,排序器节点是这个过程的核心,所以让我们更详细地研究应用程序和peer如何使用排序器生成可以一致应用于分布式复制账本的账本更新。

Phase 1: Proposal

交易工作流的第1阶段涉及应用程序和一组peer之间的交互——它不涉及排序器。阶段1只涉及一个应用程序,该应用程序要求不同组织的背书peer同意提议的链码调用的结果。

要开始第1阶段,应用程序生成一个交易提案,并将其发送给每个所需的peer集以进行背书。然后,这些支持peer中的每一个都使用交易提案独立地执行链码,以生成交易提案响应。它不将此更新应用于账本,而只是简单地签名并将其返回给应用程序。一旦应用程序收到足够数量的签名提案响应,交易流程的第一阶段就完成了。让我们更详细地研究这个阶段。

../_images/peers.diagram.10.pngPeer10

交易提案由返回已背书的提案响应的peer独立执行。在本例中,应用程序A1生成交易T1提案P,并将其发送给通道C上的peer P1和peer P2。单独地,P2使用交易T1提案P执行S1,生成交易T1响应R2,并通过E2表示赞同。应用程序A1收到交易T1的两个已背书的响应,即E1和E2。

最初,应用程序选择一组peer来生成一组提议的账本更新。应用程序选择哪些peer?嗯,这取决于背书策略(为链码定义),它定义了一组组织,这些组织需要在账本更改被网络接受之前对其进行背书。这就是达成共识的真正含义——每一个重要的组织都必须背书提议的账本变更,然后才会被任何peer的账本接受。

peer通过添加其数字签名,并使用其私钥对整个有效负载签名,从而背书提案响应。此背书随后可用于证明该组织的peer生成了特定的响应。在我们的示例中,如果peer P1属于组织Org1,则背书E1对应一个数字证明,“账本L1上的交易T1响应R1已由Org1的peer P1提供!”

当应用程序收到足够多的peer签署的提案响应时,阶段1结束。我们注意到,对于相同的交易提案,不同的peer可以向应用程序返回不同的、因此不一致的交易提案。这可能只是因为结果在不同的时间在不同的peer上的不同状态的账本生成,在这种情况下,应用程序可以简单地请求更新的提案响应。虽不太可能但更严重的是,结果可能不同是因为链码是不确定的。非确定性是链码和账本的敌人,如果发生这种情况,则表明提议的交易存在严重问题,因为不一致的结果显然不能适用于账本。单个peer不能知道他们的交易结果是非确定性的——在检测到非确定性之前,必须收集交易响应进行比较。(严格地说,这还不够,但是我们将这个讨论推迟到交易部分,在交易部分将详细讨论非确定性。)

在阶段1的末尾,如果应用程序希望丢弃不一致的交易响应,它可以自由地丢弃这些响应,从而有效地提前终止交易工作流。稍后我们将看到,如果应用程序试图使用一组不一致的交易响应来更新账本,它将被拒绝。

Phase 2: Ordering and packaging transactions into blocks

交易工作流的第二阶段是打包阶段。排序器是这个过程的关键——它接收包含来自许多应用程序的已背书交易提案响应的交易,并将交易排序为区块。有关排序和打包阶段的更多细节,请查看关于排序阶段的概念信息。

Phase 3: Validation and commit

在阶段2的末尾,我们看到排序器负责收集提案的交易更新、对它们排序并将它们打包成区块,以便分发给peer,这些简单但重要的过程。

交易工作流的最后一个阶段涉及到从排序器到peer的区块的分发和随后的验证,这些区块可以应用到账本中。具体来说,在每一个peer,一个区块内的每一笔交易都要经过验证,以确保它在应用到账本之前得到所有相关组织的一致认可。失败的交易保留下来进行审计,但不应用于账本。

../_images/peers.diagram.12.pngPeer12

排序器节点的第二个角色是将区块分发给peer。在本例中,排序器O1将区块B2分配给peer P1和peer P2。peer P1处理区块B2,导致在P1上的账本L1中添加一个新区块。同时,peerP2处理区块B2,从而将一个新区块添加到P2上的账本L1中。一旦这个过程完成,peer P1和P2上的账本L1就会一直更新,并且每个账本L1都可以通知连接的应用程序交易已经被处理。

阶段3从排序器将区块分发给连接到它的所有peer开始。peer连接到通道上的排序器,这样,当生成一个新区块时,连接到排序器的所有peer都将被发送一个新区块的副本。每个peer将独立地处理此区块,但与通道上的其他peer的处理方式完全相同。这样,我们就能使账本保持一致。同样值得注意的是,并不是每个peer都需要连接到一个排序器——peer可以使用gossip协议将区块级联到其他peer,而其他peer也可以独立地处理它们。但是让我们把那个讨论留到下次吧!

当接收到一个区块时,peer将按照它在区块中出现的顺序处理每个交易。对于每一笔交易,每个peer都将根据生成该交易的链码的背书策略,验证该交易是否已被所需组织背书。例如,一些交易可能只需要一个组织的背书,而另一些交易可能需要多个背书才能被认为是有效的。这个验证过程验证所有相关组织是否生成了相同的结果。还要注意,此验证与阶段1中的签注检查不同,在第1阶段中,应用程序接收来自背书peer的响应,并决定发送提案交易。如果应用程序违反了背书策略,发送了错误的交易,那么在第三阶段的验证过程中,peer仍然可以拒绝该交易。

如果一笔交易被正确地背书,peer将试图将其应用于账本。为此,peer必须执行账本一致性检查,以验证账本的当前状态与生成提案更新时账本的状态是否兼容。这可能并不总是可能的,即使交易已得到完全支持。例如,另一个交易可能更新了账本中的相同资产,因此交易更新不再有效,因此不能再应用。通过这种方式,每个peer的账本副本在整个网络中保持一致,因为它们都遵循相同的验证规则。

在peer成功地验证每一笔交易之后,它将更新账本。失败的交易和成功的交易一样,不应用于账本,但为了审计的目的保留它们。这意味着peer区块几乎与从排序器接收到的区块完全相同,除了区块中每个交易上的有效或无效指示符。

我们还注意到,阶段3不需要运行链码——这只在阶段1中完成,这很重要。这意味着链码只能在背书节点上使用,而不能在整个区块链网络中使用。这通常是有帮助的,因为它保持链代码的逻辑机密,以支持组织。这与链码(交易提案响应)的输出形成对比,链码与通道中的每个peer共享,无论它们是否支持该交易。这种支持peer的专门化旨在帮助可伸缩性。

最后,每次将一个区块提交到peer的账本时,该peer都会生成一个适当的事件。区块事件包括完整的区块内容,而区块交易事件只包含摘要信息,例如区块中的每个交易是否已验证或无效。链码执行产生的链码事件也可以在此时发布。应用程序可以注册这些事件类型,以便在发生时通知它们。这些通知结束了交易工作流的第三个也是最后一个阶段。

总之,第3阶段看到的是由排序器生成的区块一致地应用于账本。将事务严格地按区块排序,允许每个peer验证交易更新在整个区块链网络上一致地应用。

Orderers and Consensus

整个交易工作流流程称为共识,因为所有peer都已就交易的顺序和内容达成协议,而这个流程是由排序器协调的。共识是一个多步骤的过程,只有当流程完成时,应用程序才会收到账本更新的通知——在不同的peer上,更新的时间可能略有不同。

我们将在以后的排序器主题中更详细地讨论排序器,但是现在,将排序器看作是收集和分发应用程序中提案的账本更新的节点,以便peer验证和包含在账本中。

就是这样!现在我们已经完成了peer之旅,以及与Fabric相关的其他组件。我们已经看到,peer在很多方面都是最基本的元素——它们组成网络、托管的链码和账本、处理交易提案和响应,并通过一致的应用交易更新来使账本保持最新。