超级账本架构参考

喜你入骨 提交于 2020-08-13 04:17:54

架构参考

一、超级账本CA的用户指南

二、超级账本sdk

三、交易流程

​ 本文概述了在资产交换期间发生的事务机制。该场景包括两个客户,A和B,他们在买卖萝卜。他们每个人在网络上都有一个对等点,通过这个对等点,他们发送交易并与超级账本进行交互。

假定:

此交互假设已设置并运行了一个通道。应用程序用户已经向组织的证书颁发机构(CA)注册和登记,并收到了必要的加密处理,用于对网络进行身份验证。

链码(包含一组表示萝卜市场初始状态的键值对)安装在对等节点上并部署到通道上。链码包含了定义一组交易指令和萝卜的商定价格的逻辑。此链码还设置了背书政策,规定peerA和peerB必须为任何交易背书。

1、客户端A初始化启动一个事务

​ 发生什么事情了?客户A正在发送购买萝卜的请求。此请求的目标是peerA和peerB,它们分别代表客户A和客户B。背书策略规定两个对等端必须背书任何事务,因此请求转到peerA和peerB。

接下来,构造事务建议。利用受支持的SDK (Node、Java、Python)的应用程序利用可用的API之一来生成事务建议。这个建议是一个请求,用特定的输入参数调用链码函数,目的是读取和/或更新账本。

SDK充当一个中间体,将事务建议打包成适当的架构格式(gRPC上的协议缓冲区),并使用用户的加密凭证为该事务建议生成唯一的签名。

2、背书节点验证签名并执行交易

支持背书节点验证:

(1)事务的建议是完整的,

(2)尚未提交已经过去(再现攻击保护),

(3)签名是有效的(使用(MSP),和

(4)提交者(客户端,在这个例子中)是正确授权执行该操作,通道(也就是说,每个人都支持对等确保提交者满足频道的作家政策)。

支持的对等点将事务建议输入作为被调用的链码函数的参数。然后对当前状态数据库执行链码,以产生包括响应值、读集和写集(即表示要创建或更新的资产的键/值对)的事务结果。此时没有对分类账进行更新。这些值的集合以及认可的对等方的签名作为“建议响应”传回给SDK, SDK解析应用程序使用的有效负载。

提示:

MSP是一个对等组件,它允许对等验证来自客户端的事务请求并签署事务结果(背书)。写入策略在通道创建时定义,并确定哪些用户有权向该通道提交事务。有关会员资格的更多信息,请查看我们的会员服务提供商(MSP)文档。

3、 对建议书的回应进行检查

应用程序验证认可的对等签名,并比较提案响应,以确定提案响应是否相同。如果链码只查询分类账,应用程序将只检查查询响应,通常不会将交易提交给订购服务。如果客户应用程序打算向订购服务提交交易以更新分类账,则应用程序将确定在提交前是否已完成指定的背书策略(即peerA和peerB都背书了)。该体系结构是这样的,即使应用程序选择不检查响应或以其他方式转发一个未被认可的事务,认可策略仍将被同行强制执行,并在提交验证阶段得到支持。

4、 客户将背书组合成交易

应用程序在“事务消息”中“广播”事务建议和响应到订购服务。事务将包含读/写集,支持同事签名和通道ID。订购服务不需要检查一个事务的整个内容为了执行其操作,它只接收事务从网络中的所有渠道,命令他们按时间顺序由通道,每个通道并创建的事务。

5、验证并提交事务

事务块被“交付”到通道上的所有对等点。对块内的事务进行验证,以确保实现背书策略,并确保自事务执行生成读集以来,读集变量的分类账状态没有变化。块中的事务被标记为有效或无效。

6、 账本更新

每个对等点将块追加到通道的链中,对于每个有效事务,写集都提交到当前状态数据库中。每个对等点发出一个事件,通知客户端应用程序事务(调用)已被固定地附加到链中,以及通知事务是否被验证或无效。

注意:

应用程序应该在提交事务后侦听事务事件,例如通过使用submitTransaction API,它会自动侦听事务事件。如果不侦听事务事件,您将不知道您的事务是否已实际被订购、验证和提交到分类账。

四、服务发现

为什么需要服务发现?

​ 为了在对等点上执行链码,向订货者提交事务,并更新事务的状态,应用程序连接到一个由SDK公开的API。

​ 但是,SDK需要大量的信息来允许应用程序连接到相关的网络节点。除了CA和TLS证书订货人和同行的通道——以及他们的IP地址和端口号——它必须知道同行的相关支持政策以及安装了chaincode(应用程序知道同行送chaincode建议)。

在v1.2之前,此信息是静态编码的。但是,此实现不会动态响应网络更改(例如添加安装了相关链码的对等点,或临时脱机的对等点)。静态配置也不允许应用程序对背书策略本身的更改做出反应(当一个新的组织加入一个通道时可能会发生这种情况)。

此外,客户机应用程序无法知道哪些对等方更新了账簿,哪些没有。因此,应用程序可能会向其账簿数据与网络的其他部分不同步的同行提交建议,从而导致事务在提交时失效并浪费资源。

发现服务通过让对等点动态计算所需的信息并以可消费的方式将其呈现给SDK来改进这个过程。

服务发现如何在Fabric中工作

应用程序在启动时知道一组对等点,应用程序开发人员/管理员信任这些对等点,以便为发现查询提供可信的响应。客户机应用程序使用的一个好的候选对等点是位于同一组织中的对等点。注意,为了让发现服务知道对等点,它们必须定义一个EXTERNAL_ENDPOINT。要了解如何做到这一点,请查看我们的服务发现CLI文档。

应用程序向发现服务发出配置查询,并获得与网络的其他节点通信所需的所有静态信息。通过向对等点的发现服务发送后续查询,可以在任何时候刷新该信息。

该服务在对等点上运行——而不是在应用程序上——并使用八卦通信层维护的网络元数据信息来查找哪些对等点在线。它还从同行的状态数据库中获取信息,例如任何相关的背书策略。

使用服务发现,应用程序不再需要指定它们需要来自哪些对等点的背书。SDK只需向发现服务发送一个查询,询问在给定通道和链码ID的情况下需要哪些对等点。然后,发现服务会计算一个由两个对象组成的描述符:

1、布局:对等点组的列表,以及应选择的每组对等点的相应数量。

2、组到对等映射:从布局中的组到通道的对等。在实践中,每个组很可能是代表单个组织的对等体,但是由于服务API是通用的,并且不了解组织,所以这只是一个“组”。

下面是评价和(Org1, Org2)策略的描述符示例,其中每个组织中有两个对等点。

QuantitiesByGroup: {
       “Org1”: 1,
       “Org2”: 1,
     }
],
EndorsersByGroups: {
  “Org1”: [peer0.org1, peer1.org1],
  “Org2”: [peer0.org2, peer1.org2]
}

换句话说,背书策略需要来自一个Org1中的对等者和一个Org2中的对等者的签名。它还提供了那些可以背书的组织中可用的对等点的名称(在Org1和Org2中都是peer0和peer1)。

然后SDK从列表中选择一个随机布局。在上面的示例中,背书策略是Org1和Org2。如果它是OR策略,SDK将随机选择Org1或Org2,因为来自任一Org的对等方的签名都满足策略。

在SDK选择了一个布局之后,它会根据客户端指定的标准从布局中的对等节点中进行选择(SDK可以这样做是因为它可以访问元数据,比如ledger height)。例如,它可以根据布局中每个组中的对等点的数量,选择具有更高分类高度的对等点——或者排除应用程序发现脱机的对等点。如果根据标准没有一个节点更好,SDK将从最符合标准的节点中随机选择。

发现服务的功能

发现服务可以响应以下查询:

  • 配置查询:返回通道中所有组织的MSPConfig以及通道的订货程序端点。

  • 对等成员关系查询:返回已加入通道的对等成员。

  • 背书查询:返回通道中给定链码的背书描述符。

  • 本地同伴关系查询:返回响应查询的同伴的本地同伴关系信息。默认情况下,客户端需要是管理员,以便对等方响应此查询。

特殊要求

当对等端启用TLS运行时,客户端在连接到对等端时必须提供一个TLS证书。如果对等点没有配置来验证客户端证书(clientAuthRequired为false),那么这个TLS证书可以自签名。

定义功能需求

正如在通道功能中所讨论的,通道配置中为每个通道定义了能力需求(在通道最近的配置块中找到)。通道配置包含三个位置,每个位置定义了不同类型的功能。

Capability Type Canonical Path JSON Path
Channel /Channel/Capabilities .channel_group.values.Capabilities
Orderer /Channel/Orderer/Capabilities .channel_group.groups.Orderer.values.Capabilities
Application /Channel/Application/Capabilities .channel_group.groups.Application.values. Capabilities

设置功能

能力被设置为通道配置的一部分(或者作为初始配置的一部分—稍后我们将讨论—或者作为重新配置的一部分)。

因为新通道默认复制订购系统通道的配置,所以新通道将自动配置为使用订购系统通道的订购者和通道功能以及通道创建事务指定的应用程序功能。

初始配置中的功能

configtx。在发布构件的配置目录中,有一个功能部分,它列举了每种功能类型(通道、订购程序和应用程序)的可能功能。

注意,在根级别(用于通道功能)和订购者级别(用于订购者功能)定义了一个功能部分。

当定义orderer系统通道时,没有应用程序部分,因为这些功能是在创建应用程序通道期间定义的。

五、通道

Hyperledger Fabric channel是一个私人的“子网”,用于两个或更多特定网络成员之间的通信,目的是进行私人和保密的交易。通道由成员(组织)、每个成员的锚点、共享账本、链码应用程序和订购服务节点定义。网络上的每个事务都在一个通道上执行,其中各方必须经过身份验证和授权才能在该通道上进行事务处理。加入通道的每个对等点都有自己的身份,由成员服务提供者(MSP)提供,后者将每个对等点身份验证到其通道对等点和服务。

要创建一个新通道,客户端SDK调用配置系统链码和引用属性,比如锚节点和成员(组织)。这个请求为通道分类账创建一个创世块,它存储有关通道策略、成员和锚对等点的配置信息。当向现有通道添加新成员时,这个genesis块(或者如果适用的话,一个最近的reconfiguration块)将与新成员共享。

为通道上的每个成员选择一个领先的对等点决定了哪个对等点代表该成员与订购服务通信。如果没有识别出leader,可以用算法来识别leader。consensus服务订购事务并将它们以块的形式交付给每个领先的对等点,然后使用gossip协议跨通道将该块分发给它的成员对等点。

尽管任何一个锚点可以属于多个通道,因此维护多个分类账,但是没有分类账数据可以从一个通道传递到另一个通道。这种分类账的分离,通过通道,是定义和实现配置链码,身份会员服务和八卦数据传播协议。数据的传播,包括交易信息、账本状态和通道成员资格,被限制在通道上具有可验证成员资格的对等方。这种隔离的同行和分类帐数据,通过通道,允许网络成员需要私人和机密的交易与商业竞争对手和其他受限制的成员在同一个区块链网络上共存。

六、CouchDB作为状态数据库

数据状态选项

对等状态数据库的当前选项是LevelDB和CouchDB。LevelDB是嵌入在对等进程中的默认键-值状态数据库。CouchDB是另一种外部状态数据库。与LevelDB键值存储类似,CouchDB可以存储链码建模的任何二进制数据(CouchDB附件在内部用于非json数据)。作为文档对象存储,CouchDB允许以JSON格式存储数据,对数据发出丰富的查询,并使用索引支持查询。

LevelDB和CouchDB都支持核心链码操作,比如获取和设置密钥(资产),以及基于密钥的查询。键可以按范围查询,组合键可以建模以支持针对多个参数的等价查询。例如,所有者的组合键asset_id可用于查询某个实体拥有的所有资产。这些基于密钥的查询可以用于对分类账的只读查询,也可以用于更新分类账的事务。

在JSON中建模数据允许对数据的值进行丰富的查询,而不仅仅是查询键。这使您的应用程序和链码更容易读取存储在区块链分类账上的数据。使用CouchDB可以帮助您满足许多未被LevelDB支持的用例的审计和报告需求。如果使用CouchDB并以JSON形式建模数据,还可以使用链码部署索引。使用索引使查询更加灵活和高效,并使您能够查询来自链码的大型数据集。

CouchDB作为独立的数据库进程与对等进程一起运行,因此在设置、管理和操作方面还需要考虑其他因素。您可以考虑从默认的嵌入式LevelDB开始,如果需要额外的复杂的富查询,则转移到CouchDB。将资产数据建模为JSON是一种很好的实践,这样在将来需要时,您就可以选择执行复杂的丰富查询。

提示:

CouchDB JSON文档的键只能包含有效的UTF-8字符串,不能以下划线(" _ ")开头。无论你是使用CouchDB还是LevelDB,你应该避免在键中使用U+0000 (nil字节)。

CouchDB中的JSON文档不能使用以下值作为顶级字段名。这些值保留供内部使用。

任何以下划线"_"开头的字段

七、基于对等通道的事件服务

总体概述

在Fabric的早期版本中,对等事件服务被称为事件中心。无论该块所属的通道是什么,只要新块被添加到对等体的分类器中,该服务就会发送事件,并且它只能被运行事件对等体的组织成员访问(即,为事件连接的那个)。

从v1.1开始,出现了提供事件的新服务。这些服务使用完全不同的设计以每个通道为基础提供事件。这意味着事件的注册发生在通道级别而不是对等点,从而允许对对等点数据的访问进行细粒度控制。接收事件的请求来自对等方组织之外的身份(由通道配置定义)。这还提供了更大的可靠性,并提供了接收可能丢失的事件的方法(无论是由于连接问题还是由于对等方正在加入已经运行的网络)。

可用的服务

交付

该服务将发送已提交到分类账的整个块。如果链代码设置了任何事件,则可以在块的chaincodeaction有效负载中找到这些事件。

DeliverWithPrivateData

此服务发送与交付服务相同的数据,另外还包括来自授权客户组织访问的集合的任何私有数据。

DeliverFiltered

该服务发送“过滤”块,即已提交到分类账的块的最小信息集。它用于对等点的所有者希望外部客户端主要接收有关其事务和那些事务状态的信息的网络中。如果链码设置了任何事件,则可以在过滤块的FilteredChaincodeAction中找到这些事件。

如何注册事件

事件的注册是通过向包含所需的开始和停止位置的对等方发送一个包含传递查找信息消息的信封来完成的。有两个辅助变量SeekOldest和seeklatest可以用来指示分类器上最老的(即第一个)块或最新的(即最后一个)块。为了让服务无限期地发送事件,SeekInfo消息应该包含MAXINT64的停止位置。

默认情况下,事件服务使用通道读取器策略来确定是否为请求客户机授权事件。

交付响应消息的概述

事件服务返回DeliverResponse消息。

每条消息包含以下内容之一:

  • status - HTTP状态代码。如果出现任何故障,每个服务将返回适当的故障代码;否则,它将返回200 -成功,一旦服务完成发送所有的信息要求的SeekInfo消息。

  • 块-仅由交付服务返回。

  • 块和私有数据——仅由DeliverWithPrivateData服务返回。

  • 过滤块-仅由DeliverFiltered服务返回。

一个过滤块包含:

  • 通道ID。

  • 号码(即块号)。

  • 过滤的事务数组。

  • 事务ID。

​ 类型(例如,ENDORSER_TRANSACTION, CONFIG)。

​ 事务验证代码。

  • 过滤后的交易行为。

​ 已过滤的链码操作的数组。

​ 事务的链码事件(有效负载用nilled表示)。

八、私人数据

假定: 本主题假设您理解私有数据文档中的概念材料。

私有数据收集定义

一个集合定义包含一个或多个集合,每个集合都有一个策略定义,其中列出了集合中的组织,以及用于控制背书时私有数据传播的属性,以及是否将清除数据(可选地)。

从Fabric v2.0引入的Fabric链代码生命周期开始,集合定义是链代码定义的一部分。集合由通道成员批准,然后在将链码定义提交到通道时部署。对于所有通道成员,收集文件需要相同。如果您使用对等CLI来批准和提交链码定义,请使用——collections-config标志来指定集合定义文件的路径。如果您对Node使用Fabric SDK。js,访问如何安装和启动您的链码。若要使用前面的生命周期过程部署私有数据收集,请在实例化链代码时使用——collections-config标志。

集合定义由以下属性组成:

  • 名称:集合的名称。

  • 策略:私有数据收集分发策略定义允许哪些组织的对等方持久化使用签名策略语法表示的收集数据,每个成员都包含在一个或签名策略列表中。为了支持读/写事务,私有数据分发策略必须比链码背书策略定义更广泛的组织集合,因为对等点必须拥有私有数据才能背书提议的事务。例如,在有10个组织的通道中,一个私有数据收集分发策略可能包括5个组织,但是背书策略可能要求任何3个组织都背书。

  • requiredPeerCount:每个认可的对等点在签署认可并将提案响应返回给客户端之前必须成功地向其传播私有数据的最小数目(跨授权组织)。将传播作为背书的条件,将确保即使背书的对等方不可用,私人数据也能在网络中可用。当requiredPeerCount为0时,意味着不需要分发,但是如果maxPeerCount大于0,则可能存在一些分发。通常不建议将requiredPeerCount设置为0,因为如果认可对等点变得不可用,它可能会导致网络中的私有数据丢失。通常,您需要在批准时至少对私有数据进行一些分发,以确保网络中多个对等点上的私有数据的冗余。

  • maxPeerCount:为了实现数据冗余,每个认可的对等点试图将私有数据分发给的其他对等点(跨授权组织)的最大数量。如果背书的对等点在背书时间和提交时间之间变得不可用,那么其他在背书时还没有收到私有数据的集合成员将能够从已传播到的对等点提取私有数据。如果将此值设置为0,则在背书时不传播私有数据,从而迫使私有数据在提交时在所有授权的对等点上对背书的对等点进行拉取。

  • blockToLive:表示数据在私有数据库中的生存时间,以块为单位。数据将在私有数据库中存在指定数量的块,之后它将被清除,使该数据从网络中过时,这样它就不能被链码查询,也不能被请求对等方使用。要无限期地保存私有数据,也就是永远不清除私有数据,请将blockToLive属性设置为0。

  • memberOnlyRead:值为true表示对等点自动强制只允许属于集合成员组织之一的客户机对私有数据进行读访问。如果来自非成员组织的客户机试图执行执行私有数据密钥读取的链码函数,则链码调用将以错误结束。如果您想在单个链码函数中编码更细粒度的访问控制,请使用false值。

  • memberOnlyWrite:值为true表示对等点自动强制只允许属于集合成员组织之一的客户端从链码写入私有数据。如果来自非成员组织的客户机试图执行对私有数据密钥执行写操作的链码函数,则链码调用将以错误结束。如果您想在单个链码函数中编码更细粒度的访问控制,请使用false值,例如,您可能希望来自非成员组织的某些客户端能够在某个集合中创建私有数据。

  • endorsementPolicy:可选的背书策略,用于覆盖链码级背书策略的集合。集合级背书策略可以以signaturePolicy的形式指定,也可以是对通道配置中现有策略的channelConfigPolicy引用。endorsementPolicy可能与集合分发策略相同,或者可能需要更少或更多的组织对等点。

这里是一个示例集合定义JSON文件,包含两个集合定义的数组:

[
 {
    "name": "collectionMarbles",
    "policy": "OR('Org1MSP.member', 'Org2MSP.member')",
    "requiredPeerCount": 0,
    "maxPeerCount": 3,
    "blockToLive":1000000,
    "memberOnlyRead": true,
    "memberOnlyWrite": true
 },
 {
    "name": "collectionMarblePrivateDetails",
    "policy": "OR('Org1MSP.member')",
    "requiredPeerCount": 0,
    "maxPeerCount": 3,
    "blockToLive":3,
    "memberOnlyRead": true,
    "memberOnlyWrite":true,
    "endorsementPolicy": {
      "signaturePolicy": "OR('Org1MSP.member')"
    }
 }
]

这个示例使用来自Fabric测试网络的组织Org1和Org2。collectionMarbles定义中的策略授权这两个组织使用私有数据。这是链码数据需要在订购服务节点中保持私有时的典型配置。但是,collectionMarblePrivateDetails定义中的策略限制了对通道中组织子集(在本例中为Org1)的访问。此外,写入此集合需要来自Org1对等点的背书,即使链码级背书策略可能需要来自Org1或Org2的背书。由于“memberOnlyWrite”为真,只有来自Org1的客户端可以调用写入私有数据集合的链码。通过这种方式,您可以控制委托哪些组织写入特定的私有数据收集。

私有数据传播

由于私有数据不包括在提交给订购服务的事务中,因此也不包括在分发给通道中所有对等点的块中,认可的对等点在将私有数据分发给其他被授权组织的对等点中扮演着重要的角色。这确保了通道收集中的私有数据的可用性,即使在对等点被背书后变得不可用。为了帮助传播,集合定义中的maxPeerCount和requiredPeerCount属性控制背书时传播的程度。

如果认可的对等方不能成功地将私有数据传递给至少需要的对等方,它将向客户端返回一个错误。认可的同行将尝试向不同组织的同行传播私人数据,以确保每个被授权的组织都有一份私人数据的副本。由于事务在链码执行时没有提交,因此背书对等点和接收对等点将私有数据的副本存储在本地暂态存储中与它们的区块链一起,直到事务提交为止。

当授权同行没有私人数据的一个副本在提交时瞬态数据存储(因为他们没有一个支持对等或因为他们不接受私人数据通过传播在背书时),他们将试图把私有数据从另一个授权同行,为一个可配置的基于对等的时间属性peer.gossip.pvtData。对等配置核心中的pullRetryThreshold。yaml文件。

使用pullRetryThreshold时注意事项:

如果请求的对等方能够在pullRetryThreshold中检索私有数据,它将把事务提交到它的分类器(包括私有数据散列),并将私有数据存储在它的状态数据库中,从逻辑上与其他通道状态数据分离。

如果请求的对等方不能在pullRetryThreshold内检索私有数据,它将在没有私有数据的情况下将事务提交给它的区块链(包括私有数据散列)。

如果同行有权私有数据,但它丢失,那么同伴将无法支持未来交易参考失踪的私人数据——chaincode查询将发现钥匙不见了(基于关键的散列的存在状态数据库),和chaincode将得到一个错误。

因此,必须将requiredPeerCount和maxPeerCount属性设置得足够大,以确保通道中私有数据的可用性。例如,如果每个背书对等点在事务提交前变得不可用,那么requiredPeerCount和maxPeerCount属性将确保私有数据在其他对等点上可用。

九、读写组语义

十、发布协议

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!