Hyperledger Fabric 2.0 官方文档中文版 第3章 关键概念

Hyperledger Fabric 2.0 官方文档中文版 第3章 关键概念


总目录

第1章 引言
第2章 Hyperledger Fabric v2.0的新增功能
第3章 关键概念
第4章 入门
第5章 开发应用程序
第6章 教程(上)
第6章 教程(下)
第7章 部署生产网络
第8章 操作指南
第9章 升级到最新版本


3.关键概念

引言

Hyperledger Fabric是一个分布式账本解决方案的平台,它由一个模块化的体系结构支撑,提供高度的机密性、弹性、灵活性和可扩展性。它旨在支持不同组件的可插拔实现,并适应经济生态系统中存在的复杂性和复杂性。

我们提案首次使用的用户先阅读下面介绍的其余部分,以便熟悉区块链的工作原理以及Hyperledger Fabric的特定功能和组件。

一旦你感到舒服——或者如果你已经熟悉区块链和超级账本结构——那么就开始吧,从那里开始探索演示、技术规范、API等。


什么是区块链?

一个分布式账本

区块链网络的核心是一个分布式账本,它记录网络上发生的所有交易。

区块链账本通常被描述为去中心化,因为它在许多网络参与者之间进行复制,每个参与者在维护过程中相互协作。我们将看到,权力下放和协作是反映企业在现实世界中交换商品和服务的强大属性。

除了分散和协作之外,记录到区块链中的信息仅附加,使用加密技术保证一旦将交易添加到账本中,就不能对其进行修改。这种“不变性”的特性使得确定信息来源变得简单,因为参与者可以确定信息在事后没有被改变。这就是为什么区块链有时被描述为证据系统

智能合约

为了支持信息的一致更新,并启用一整套账本功能(交易、查询等),区块链网络使用智能合约提供对账本的受控访问。

智能合约不仅是在网络上封装信息并保持信息简单的关键机制,还可以编写智能合约,允许参与者自动执行交易的某些方面。

例如,可以编写一个智能合同来规定一个项目的运输成本,其中运费根据项目到达的速度而变化。根据双方同意的条款并写入账本,相应的资金在收到项目时自动转手。

共识
保持账本交易在网络上同步的过程——确保账本只有在交易得到适当参与者的批准时才更新,当账本确实更新时,它们以相同的交易顺序更新——被称为共识

稍后您将了解更多有关账本、智能合约和共识的信息。目前,将区块链视为一个共享、复制的交易系统就足够了,它通过智能合约进行更新,并通过一个叫做共识的协作过程保持一致的同步。

区块链为什么有用?

今天的记录系统

今天的交易性网络只不过是自保留业务记录以来就存在的网络的稍微更新版本。商业网络中的成员彼此进行交易,但他们各自保留各自的交易记录。他们交易的东西——无论是16世纪的佛兰芒挂毯还是今天的证券——每次出售都必须确定出处,以确保销售物品的企业拥有一系列证明其所有权的所有权。

剩下的就是这样一个商业网络:

现代科技已经将这一过程从石板、纸夹到硬盘和云平台,但底层结构是一样的。目前还没有统一的网络参与者身份管理系统,建立出处非常费劲,需要数天时间才能完成证券交易(全球交易量以数万亿美元计),合同必须手工签署和执行,系统中的每个数据库都包含唯一的信息因此代表了一个单一的故障点。

在当今信息和流程共享的支离破碎的方法下,构建一个跨越业务网络的记录系统是不可能的,尽管可见性和信任的需求是明确的。

区块链差异

如果商业网络没有“现代”交易系统所代表的无效率的老鼠窝,而是有在网络上建立身份、执行交易和存储数据的标准方法呢?如果可以通过查看交易清单来确定资产的出处,而这些交易一旦被写入,就不能更改,因此可以信任吗?

商业网络看起来更像这样:

这是一个区块链网络,每个参与者都有自己复制的账本副本。除了账本信息被共享,更新账本的过程也被共享。与今天的系统不同,参与者的私有程序用于更新他们的私有账本,区块链系统有共享程序来更新共享账本。

通过共享账本协调业务网络的能力,区块链网络可以减少与私有信息和处理相关的时间、成本和风险,同时提高信任和可见性。

你现在知道什么是区块链以及它为什么有用。还有很多其他重要的细节,但它们都与信息和流程共享的这些基本思想有关。


什么是Hyperledger Fabric?

Linux基金会于2015年创建了Hyperledger项目,以推进跨行业区块链技术。它不是宣布一个单一的区块链标准,而是鼓励通过一个社区进程,以一种合作的方式开发区块链技术,拥有知识产权,鼓励开放式开发,并随着时间的推移采用关键标准。

Hyperledger Fabric是Hyperledger中的区块链项目之一。与其他区块链技术一样,它有一个账本,使用智能合约,是参与者管理其交易的系统。

Hyperledger Fabric与其他一些区块链系统的不同之处在于它是私有的,是经过许可的。超级账本结构网络的成员通过受信任的成员服务提供商(MSP)注册,而不是允许未知身份参与网络的开放式无许可系统(需要“工作证明”之类的协议来验证交易并保护网络安全)。

Hyperledger Fabric还提供多种可插拔选项。账本数据可以多种格式存储,共识机制可以交换进出,并且支持不同的MSP。

Hyperledger Fabric还提供了创建通道的功能,允许一组参与者创建单独的交易账本。对于某些参与者可能是竞争对手的网络来说,这是一个特别重要的选择,而不是希望他们所做的每一笔交易——例如,他们向某些参与者而不是其他参与者提供的特殊价格——为每个参与者所知。如果两个参与者组成一个通道,那么这些参与者(而不是其他参与者)拥有该通道的账本副本。

共享账本

Hyperledger Fabric有一个由两个组件组成的账本子系统:世界状态交易日志。每个参与者都有一份账本副本到他们所属的每个超级账本架构网络。

世界状态组件描述账本在给定时间点的状态。这是账本的数据库。交易日志组件记录导致世界状态的当前值的所有交易;它是世界状态的更新历史记录。因此,账本是世界状态数据库和交易日志历史记录的组合。

账本有一个可替换的世界状态数据存储。默认情况下,这是一个LevelDB键值存储数据库。交易日志不需要是可插拔的。它只是记录区块链网络使用的账本数据库的前后值。

智能合约

超级账本架构智能合约是用链码编写的,当区块链外部的应用程序需要与账本交互时,该应用程序会调用该合约。在大多数情况下,链码只与账本的数据库组件、世界状态(例如查询它)交互,而不与交易日志交互。

链码可以用几种编程语言实现。目前支持Go和Node。

隐私
根据网络的需要,企业对企业(B2B)网络中的参与者可能对他们共享多少信息非常敏感。对于其他网络,隐私不会成为首要问题。

Hyperledger结构支持隐私(使用通道)是关键运营要求的网络以及相对开放的网络。

共识
交易必须按发生的顺序写入账本,即使它们可能是在网络中不同的参与者之间进行的。要做到这一点,必须确立交易顺序,并制定一种方法,以拒绝错误(或恶意)插入账本的不良交易。

这是计算机科学的一个深入研究的领域,实现它有很多种方法,每种方法都有不同的取舍。例如,PBFT(实用的拜占庭容错)可以提供一种机制,使文件副本彼此通信,以保持每个副本的一致性,即使在损坏的情况下也是如此。或者,在比特币中,排序是通过一个叫做挖掘的过程进行的,在这个过程中,竞争的计算机竞相解决一个密码难题,这个谜题定义了所有进程随后建立的顺序。

Hyperledger Fabric的设计允许网络初学者选择一种最能代表参与者之间存在关系的共识机制。与隐私一样,也有一系列的需求;从关系高度结构化的网络到更为对等的网络。


Hyperledger Fabric模型

本节概述了Hyperledger Fabric中的关键设计功能,这些功能实现了其全面但可定制的企业区块链解决方案的承诺:

  • 资产:资产定义可以在网络上交换几乎任何有货币价值的东西,从全食到古董车再到货币期货。
  • 链码:链码的执行与交易排序分开,限制了跨节点类型所需的信任和验证级别,并优化了网络的可伸缩性和性能。
  • 账本功能:不可变的共享账本对每个通道的整个交易历史进行编码,并包含类似SQL的查询功能,以实现高效的审计和争议解决。
  • 隐私:通道和私人数据收集使私人和保密的多边交易成为可能,这些交易通常是竞争企业和受监管行业在公共网络上交换资产所必需的。
  • 安全和成员服务:许可成员资格提供了一个可信的区块链网络,参与者知道所有交易都可以由授权的监管机构和审计师检测和跟踪。
  • 共识:一种独特的一致性方法可以实现企业所需的灵活性和可伸缩性。

资产

资产可以从有形资产(房地产和硬件)到无形资产(合同和知识产权)。Hyperledger Fabric提供了使用链码交易修改资产的功能。

资产在Hyperledger Fabric中表示为键值对的集合,状态更改记录为通道账本上的交易。资产可以用二进制和/或JSON形式表示。

链码

链码是定义一个或多个资产的软件,以及修改资产的交易指令;换句话说,它是业务逻辑。链码强制执行读取或更改键值对或其他状态数据库信息的规则。链码函数针对账本的当前状态数据库执行,并通过交易提案启动。链码执行会产生一组键值写入(写入集),这些键值写入可以提交到网络并应用于所有对等方的账本。

账本功能

账本是结构中所有状态转换的有序、防篡改的记录。状态转换是由参与方提交的链码调用(“交易”)的结果。每个交易都会产生一组资产键值对,这些资产键值对在创建、更新或删除时提交到账本。

账本由一个区块链(“链”)组成,用于将不可变的、按顺序排列的记录存储在区块中,以及一个状态数据库来维护当前结构状态。每个通道有一个账本。每个对等方为其所属的每个通道保留一份账本副本。

Fabric 账本的一些功能:

  • 使用基于键的查找、范围查询和组合键查询查询和更新账本
  • 使用富查询语言的只读查询(如果使用CouchDB作为状态数据库)
  • 只读历史查询-查询关键字的账本历史记录,启用数据来源方案
  • 交易包括在链码(read set)中读取的键/值的版本和在链码(write set)中写入的键/值的版本
  • 交易包含每个背书对等方的签名,并提交给订购服务
  • 交易按块排序,并从排序服务“传递”到通道上的对等方
  • 对等方根据背书策略验证交易,并执行这些策略
  • 在附加块之前,将执行版本控制检查,以确保自链代码执行时起读取的资产的状态没有更改
  • 一旦交易被验证和提交,就存在不变性
  • 通道的账本包含定义策略、访问控制列表和其他相关信息的配置块
  • 通道包含成员服务提供程序实例,允许从不同的证书颁发机构派生加密材料

有关数据库、存储结构和“查询能力”的深入研究,请参阅账本主题

隐私

Hyperledger Fabric在每个通道的基础上使用一个不可变的账本,以及可以操纵和修改资产当前状态的链码(即更新键值对)。账本存在于一个通道的范围内——它可以在整个网络中共享(假设每个参与者都在一个公共通道上运行)——或者它可以私有化,只包括一组特定的参与者。

在后一种情况下,这些参与者将创建一个单独的通道,从而隔离/分离他们的交易和账本。为了解决希望弥合总体透明性和隐私性之间差距的场景,链码只能安装在需要访问资产状态以执行读写操作的对等方上(换句话说,如果链码没有安装在对等机上,它将无法与账本正确接口)。

当该渠道上的组织子集需要对其交易数据保密时,将使用私有数据收集(collection)将这些数据隔离在一个私有数据库中,该数据库在逻辑上与渠道账本分开,只有授权的组织子集才能访问。

因此,通道将交易从更广泛的网络中保留为私有,而集合则将通道上组织子集之间的数据保持为私有。

为了进一步混淆数据,可以使用常见的加密算法(如AES)对链码中的值进行加密(部分或全部),然后再将交易发送到订购服务并将数据块添加到账本中。只有在密码被加密的情况下,用户才可以使用加密的密钥生成相应的数据。

有关如何在区块链网络上实现隐私的详细信息,请参阅私有数据主题。

安全和成员服务

超级账本结构支撑着一个所有参与者都知道身份的交易网络。公钥基础设施用于生成绑定到组织、网络组件和最终用户或客户端应用程序的加密证书。因此,数据访问控制可以在更广泛的网络和通道级别上进行操作和管理。超级账本结构的这种“许可”概念,再加上通道的存在和功能,有助于解决隐私和保密性是首要问题的场景。

请参阅成员服务提供商(MSP)主题,以更好地理解加密实现,以及在Hyperledger结构中使用的签名、验证和身份验证方法。

共识

在分布式账本技术中,共识最近已成为单一功能内特定算法的同义词。然而,共识不仅仅包括就交易顺序达成一致,而且这种差异在Hyperledger Fabric中体现得淋漓尽致,它在整个交易流程(从提案和背书到订购、验证和承诺)中发挥着重要作用。简言之,一致性被定义为对组成一个块的一组交易的正确性的全循环验证。

当区块交易的顺序和结果符合明确的策略标准检查时,最终达成共识。这些检查和平衡发生在交易的生命周期中,包括使用背书策略来规定哪些特定成员必须背书某个交易类,以及系统链码,以确保这些策略得到执行和维护。在承诺之前,对等方将使用这些系统链码,以确保有足够的背书存在,并且它们来自适当的实体。此外,将进行版本控制检查,在此期间,在将包含交易的任何块附加到账本之前,对账本的当前状态达成一致或同意。此最终检查提供保护,防止双重开销操作和其他可能损害数据完整性的威胁,并允许针对非静态变量执行函数。

除了进行大量的背书、有效性和版本控制检查外,还在交易流的各个方向上进行身份验证。访问控制列表是在网络的层次结构层上实现的(将服务向下排序到通道),当交易提案通过不同的体系结构组件时,有效负载被反复签名、验证和证实。总而言之,协商一致不仅仅局限于一批交易的商定顺序,而是作为一项交易从提议到承诺的过程中进行的持续核查的一个副产品的总体特征。

查看交易流程图以获得共识的可视化表示。


区块链网络

本主题将在概念层面上描述Hyperledger Fabric如何允许组织协作形成区块链网络。如果您是架构师、管理员或开发人员,您可以使用本主题深入了解超级账本结构区块链网络中的主要结构和流程组件。本主题将使用一个可管理的示例,介绍区块链网络中的所有主要组件。

在阅读了本主题并理解了策略的概念之后,您将对组织建立控制已部署的超级账本结构网络的策略所需做出的决策有了坚实的理解。您还将了解组织如何使用声明性策略来管理网络演进,这是Hyperledger Fabric的一个关键特性。简而言之,您将了解Hyperledger Fabric的主要技术组件以及组织需要对其做出的决策。


什么是区块链网络?

区块链网络是为应用程序提供账本和智能合约(链码)服务的技术基础设施。首先,智能合约用于生成交易,然后将这些交易分发到网络中的每个对等节点,在这些节点上,交易不可更改地记录在其账本副本上。应用程序的用户可能是使用客户端应用程序或区块链网络管理员的最终用户。

在大多数情况下,多个组织作为一个联盟组成网络,它们的权限由一组策略决定,这些策略在最初配置网络时由联合体同意。此外,网络策略可以随着时间的推移而改变,这取决于联合体中各组织的协议,正如我们在讨论修改策略的概念时所发现的那样。


样本网络

在开始之前,让我们向您展示我们的目标!下面是一个图,表示我们的示例网络的最终状态。

别担心这看起来很复杂!在我们学习本主题时,我们将逐步构建网络,以便您了解R1、R2、R3和R4组织如何为网络提供基础设施以帮助形成网络。这一基础设施实现了区块链网络,并由组成网络的组织(例如,可以添加新组织)同意的策略进行管理。您将发现应用程序如何使用区块链网络提供的账本和智能合约服务。

四个组织,R1,R2,R3和R4共同决定,并写进一份协议,他们将建立和利用一个超级账本织物网络。R4被指定为网络发起人-它被赋予设置网络初始版本的权力。R4无意在网络上执行业务交易。R1和R2与R2和R3一样,需要在整个网络中进行专用通信。组织R1有一个客户端应用程序,可以在通道C1中执行业务交易。Organization R2有一个客户端应用程序,可以在通道C1和C2中执行类似的工作。Organization R3有一个客户端应用程序,可以在通道C2上执行此操作。对等节点P1维护与C1相关联的账本L1的副本。对等节点P2维护与C1相关联的账本L1的副本和与C2关联的账本L2的副本。对等节点P3维护与C2相关联的账本L2的副本。网络按照网络配置NC4中指定的策略规则进行管理,网络受R1和R4组织的控制。通道C1根据通道配置CC1中指定的策略规则进行管理;通道受组织R1和R2的控制。通道C2根据通道配置CC2中指定的策略规则进行管理;通道受组织R2和R3的控制。有一个订购服务O4,它作为N的网络管理点服务,并使用系统通道。排序服务还支持应用程序通道C1和C2,以便将交易排序到块中进行分发。这四个组织都有一个首选的证书颁发机构。


创建网络

让我们从创建网络基础开始:

当订购者启动时,网络就形成了。在我们的示例网络N中,包含单个节点O4的订购服务是根据网络配置NC4配置的,NC4赋予组织R4管理权限。在网络级别,证书颁发机构CA4用于向R4组织的管理员和网络节点分发身份。

我们可以看到,定义网络N的第一件事是排序服务O4。将订购服务视为网络的初始管理点是很有帮助的。按照事先约定,O4最初由组织R4中的管理员配置和启动,并托管在R4中。配置NC4包含描述网络管理功能起始集的策略。最初,这被设置为只给R4网络权限。这将改变,我们将在后面看到,但目前R4是网络中唯一的成员。

证书颁发机构

您还可以看到证书颁发机构CA4,它用于向管理员和网络节点颁发证书。CA4在我们的网络中扮演着关键的角色,因为它分发了X.509证书,这些证书可以用来识别属于R4组织的组件。CAs签发的证书也可用于签署交易,以表明组织背书交易结果,这是将交易结果记入账本的先决条件。让我们更详细地研究CA的这两个方面。

首先,区块链网络的不同组成部分使用证书相互识别自己来自特定组织。这就是为什么通常有多个CA支持一个区块链网络——不同的组织通常使用不同的CA。我们将在我们的网络中使用四个CA;每个组织一个。事实上,CA是如此重要,以至于Hyperledger Fabric为您提供了一个内置的CA(称为Fabric CA)来帮助您开始工作,不过在实践中,组织会选择使用他们自己的CA。

证书到成员组织的映射是通过一个称为成员服务提供者(MSP)的结构来实现的。网络配置NC4使用一个命名的MSP来标识由CA4分配的证书的属性,CA4将证书持有者与组织R4相关联。然后NC4可以在策略中使用这个MSP名称来授予来自R4的参与者对网络资源的特定权限。此类策略的一个示例是标识R4中可以向网络添加新成员组织的管理员。我们不会在这些图表上显示msp,因为它们会把它们弄乱,但它们非常重要。

其次,我们将在后面看到由CAs颁发的证书是如何成为交易生成和验证过程的核心的。具体地说,X.509证书用于客户端应用程序交易提案和智能合约交易响应,以对交易进行数字签名。随后,承载账本副本的网络节点在接受账本上的交易之前验证交易签名是否有效。

让我们回顾一下示例区块链网络的基本结构。有一个资源,网络N,由证书颁发机构CA4定义的一组用户访问,这些用户对网络N中的资源拥有一组权限,如网络配置NC4中包含的策略所述。当我们配置并启动订购服务节点O4时,所有这些都将成为现实。


添加网络管理员

NC4最初配置为只允许R4用户在网络上管理权限。在下一阶段,我们将允许组织R1用户管理网络。让我们看看网络是如何演变的:

组织R1无法更新网络管理员的配置。在此之后,R1和R4对网络配置拥有同等的权限。

我们看到添加了一个新的组织R1作为管理员-R1和R4现在在网络上拥有平等的权利。我们还可以看到添加了证书颁发机构CA1–它可以用来识别来自R1组织的用户。在这之后,来自R1和R4的用户可以管理网络。

尽管order节点O4运行在R4的基础设施上,R1对它拥有共享的管理权限,只要它可以访问网络。这意味着R1或R4可以更新网络配置NC4,以允许R2组织网络操作的子集。这样,即使R4正在运行订购服务,R1拥有对它的完全管理权限,R2也有创建新联盟的有限权限。

在最简单的形式中,订购服务是网络中的一个节点,这就是您在示例中看到的。订购服务通常是多节点的,可以配置为在不同的组织中具有不同的节点。例如,我们可以在R4中运行O4,并将其连接到组织R1中单独的order节点O2。这样,我们就有了一个多站点、多组织的管理结构。

我们稍后将在本主题后面讨论订购服务,但现在只需将订购服务看作是一个管理点,它提供不同组织对网络的控制访问。


定义联盟

虽然网络现在可以由R1和R4来管理,但是可以做的很少。我们需要做的第一件事就是定义一个联合体。这个词的字面意思是“拥有共同命运的群体”,因此它是区块链网络中一组组织的适当选择。

让我们看看联盟是如何定义的:

网络管理员定义了一个联盟X1,它包含两个成员,组织R1和R2。该联合体定义存储在网络配置NC4中,将在下一个网络开发阶段使用。CA1和CA2分别是这些组织的证书颁发机构。

由于NC4的配置方式,只有R1或R4可以创建新的联盟。这个图显示了一个新的联合体,X1,它将R1和R2定义为其组成组织。我们还可以看到添加了CA2来识别来自R2的用户。请注意,一个联合体可以有任意数量的组织成员-我们刚刚展示了两个,因为这是最简单的配置。

为什么财团很重要?我们可以看到,一个联合体定义了网络中的一组组织,它们共同需要彼此进行交易——在本例中是R1和R2。如果组织有一个共同的目标,那么将它们组织在一起是有意义的,而这正是发生的事情。

这个网络虽然由一个组织发起,但现在由一个更大的组织控制。我们本可以这样开始的,R1,R2和R4共享控制权,但这种建立使它更容易理解。

我们现在将使用consortium X1来创建一个超级账本结构区块链中非常重要的一部分——一个通道


为联盟创建通道

因此,让我们创建结构区块链网络的关键部分——一个通道。通道是一种主要的通信机制,通过它,联盟的成员可以相互通信。一个网络中可以有多个通道,但现在,我们先从一个开始。

让我们看看第一个通道是如何添加到网络中的:

已经使用联盟定义X1为R1和R2创建了通道C1。通道由通道配置CC1控制,完全独立于网络配置。CC1由R1和R2管理,R1和R2对C1拥有同等的权限。R4对CC1没有任何权利。

通道C1为联盟X1提供私有通信机制。我们可以看到通道C1已经连接到订购服务O4,但是没有附加任何其他东西。在网络开发的下一阶段,我们将连接客户端应用程序和对等节点等组件。但在这一点上,一个通道代表了未来连接的潜力

尽管通道C1是网络N的一部分,但它与网络N有很大的区别。还请注意,组织R3和R4不在这个通道中-它用于R1和R2之间的交易处理。在上一步中,我们看到了R4如何授予R1创建新联盟的权限。提到R4也允许R1创建通道,这很有帮助!在这个图中,可能是组织R1或R4创建了通道C1。同样,请注意,一个通道可以有任意数量的组织与之相连,我们已经展示了两个,因为这是最简单的配置。

同样,注意通道C1与网络配置NC4有完全独立的配置CC1。CC1包含控制R1和R2对通道C1的权限的策略,正如我们所看到的,R3和R4在此通道中没有权限。如果R3和R4被R1或R2添加到通道配置CC1中的相应策略中,则R3和R4只能与C1交互。一个例子是定义谁可以向通道添加新组织。特别要注意的是,R4不能将自身添加到通道C1中,它必须并且只能由R1或R2授权。

为什么通道如此重要?通道是有用的,因为它们为联盟成员之间的私有通信和私有数据提供了一种机制。通道提供来自其他通道和网络的隐私。Hyperledger Fabric在这方面很强大,因为它允许组织共享基础设施,同时保持其私有化。这一点并不矛盾——网络中不同的联盟需要不同的信息和流程得到适当的共享,而渠道提供了一种有效的机制来实现这一点。通道提供了基础设施的有效共享,同时维护数据和通信隐私。

我们还可以看到,一旦创建了一个通道,它就在一个非常真实的意义上是“不受网络限制的”。只有在通道配置中明确指定的组织才有权控制它,从现在到将来。同样地,从此时起对网络配置NC4的任何更新都不会对信道配置CC1产生直接影响;例如,如果联合体定义X1被改变,它将不会影响通道C1的成员。因此,通道是有用的,因为它们允许组成通道的组织之间的私人通信。此外,通道中的数据与网络的其他部分完全隔离,包括其他通道。

另外,还有一个为排序服务定义的特殊系统通道。它的行为方式与常规通道完全相同,后者有时称为应用程序通道。我们通常不需要担心这个通道,但我们稍后将在本主题中讨论更多。


节点和账本

现在让我们开始使用该通道将区块链网络和组织组件连接在一起。在下一个网络开发阶段,我们可以看到我们的网络N刚刚获得了两个新组件,即对等节点P1和账本实例L1。

节点P1已加入通道C1。P1实际承载了账本L1的副本。P1和O4可以使用通道C1彼此通信。

节点是承载区块链账本副本的网络组件!最后,我们开始看到一些可识别的区块链组件!P1在网络中的目的纯粹是为了保存一个ledger L1的副本供其他人访问。我们可以认为L1物理上托管在P1上,但逻辑上托管在通道C1上。当我们向通道中添加更多对等点时,我们将更清楚地看到这一点。

P1配置的一个关键部分是由CA1发布的X.509标识,它将P1与组织R1相关联。一旦P1启动,它就可以使用ordero4加入通道C1。当O4接收到这个加入请求时,它使用通道配置CC1来确定P1对这个通道的权限。例如,CC1确定P1是否可以向账本L1读取和/或写入信息。

请注意,对等节点是如何由拥有这些节点的组织连接到通道中的,尽管我们只添加了一个对等节点,但我们将看到在网络中的多个通道上如何存在多个对等节点。稍后我们将看到同行可以扮演的不同角色。


应用程序和智能合约链码

既然通道C1上有一个账本,我们就可以开始连接客户机应用程序来使用账本的主力——节点提供的一些服务!

目前网络的发展为:

智能合约S5已安装到P1上。组织R1中的客户端应用程序A1可以使用S5通过对等节点P1访问账本。A1、P1和O4都连接到信道C1,即它们都可以利用该信道提供的通信设施。

在网络开发的下一阶段,我们可以看到客户端应用程序A1可以使用通道C1连接到特定的网络资源,在这种情况下A1可以同时连接到对等节点P1和订购方节点O4。同样,请看一下通道如何成为网络和组织组件之间通信的中心。与对等方和订购方一样,客户机应用程序将具有与组织关联的标识。在我们的示例中,客户端应用程序A1与组织R1相关联;尽管它位于Fabric区块链网络之外,但它通过通道C1连接到它。

现在看来,A1可以通过P1直接访问账本L1,但实际上,所有访问都是通过一个称为智能合约链码S5的特殊程序来管理的。可以把S5看作是对账本的所有通用访问模式的定义;S5提供了一组定义良好的方法,可以通过这些方法来查询或更新账本L1。简而言之,客户端应用程序A1必须通过智能合约S5才能到达ledger L1!

智能合约可以由每个组织中的应用程序开发人员创建,以实现联合体成员共享的业务流程。智能合约用于帮助生成交易,这些交易可以随后分发到网络中的每个节点。我们稍后再讨论这个想法;网络越大,越容易理解。目前,需要理解的重要一点是,要达到这一点,必须在智能合约上执行两个操作;它必须安装在节点上,然后在通道上定义

超级账本结构用户经常交替使用智能合约链码这两个术语。一般来说,智能合约定义了控制world状态中包含的业务对象生命周期的交易逻辑。然后将其打包成链码,然后部署到区块链网络。可以将智能合约视为管理交易,而链码控制如何打包智能合约以进行部署。

安装链码包

开发智能合约S5后,组织R1中的管理员必须创建链码包并将其安装到节点P1上。这是一个简单的操作;一旦完成,P1就完全了解S5。具体来说,P1可以看到S5的实现逻辑——它用来访问ledgerl1的程序代码。我们将其与S5接口进行对比,后者仅描述S5的输入和输出,而不考虑其实现。

当一个组织在一个通道中有多个对等方时,它可以选择安装智能合约的对等方;它不需要在每个对等方上安装智能合约。

定义链码

尽管链码安装在各个组织的对等端上,但它是在通道范围内进行管理和操作的。每个组织都需要批准一个链码定义,这是一组确定如何在通道上使用链码的参数。组织必须批准链码定义,才能使用已安装的智能合约查询账本和背书交易记录。在我们的示例中,只有一个对等节点P1,组织R1中的管理员必须批准S5的链码定义。

在将链码定义提交给通道并用于与通道账本交互之前,需要有足够数量的组织批准链码定义(默认情况下为大多数组织)。因为通道只有一个成员,R1的管理员可以将S5的链码定义提交给通道C1。一旦定义被提交,S5现在可以被客户端应用程序A1调用

注意,尽管通道上的每个组件现在都可以访问S5,但是它们不能看到它的程序逻辑。这对于安装它的节点是私有的;在我们的示例中,这意味着P1。从概念上来说,这意味着定义并提交给通道的是智能合约接口,而不是安装的智能合约实现。为了强化这一想法,安装智能合约表明我们如何看待它在对等机上的物理承载,而在通道上定义的智能合约则显示了我们如何看待它在逻辑上是由通道托管的。

背书策略

链码定义中提供的最重要的信息是背书策略。它描述了哪些组织必须批准交易才能被其他组织接受到其账本副本上。在我们的示例网络中,只有R1或R2背书交易,才能接受L1账本。

将链码定义提交到通道会将背书策略放置在通道账本上;它使通道的任何成员都可以访问它。您可以在“交易流”主题中阅读有关背书策略的更多信息。

调用智能合约

在对等节点上安装智能合约并在通道上定义后,客户机应用程序就可以调用它。客户端应用程序通过向由智能合约背书策略指定的组织拥有的对等方发送交易提案来实现这一点。交易提案用作智能合约的输入,智能合约使用它生成背书的交易响应,由对等节点返回给客户端应用程序。

正是这些交易响应与交易提案打包在一起,形成一个完全背书的交易,该交易可以分发到整个网络。稍后我们将更详细地研究这一点,了解应用程序如何调用智能合约来生成背书的交易就足够了。

在网络发展的这个阶段,我们可以看到组织R1完全参与了网络。它的应用程序(从A1开始)可以通过智能合约S5访问账本L1,生成将由R1背书的交易,并因此被接受到账本上,因为它们符合背书策略。


完成网络搭建

回想一下,我们的目标是为财团X1——R1和R2组织——创建一个通道。网络开发的下一个阶段是R2组织将其基础设施添加到网络中。

让我们看看网络是如何演变的:

该网络通过增加R2组织的基础设施而发展壮大。具体地说,R2增加了对等节点P2,P2承载了ledger L1的副本,以及链码S5。R2批准与R1相同的链码定义。P2也加入了信道C1,正如应用程序A2一样。A2和P2使用CA2的证书进行标识。所有这些意味着应用程序A1和A2都可以使用对等节点P1或P2调用C1上的S5。

我们可以看到组织R2在通道C1上添加了一个对等节点P2。P2还拥有账本L1和智能合约S5的副本。我们可以看到R2还添加了客户端应用程序A2,它可以通过通道C1连接到网络。为了实现这一点,组织R2中的管理员创建了对等节点P2,并将其连接到通道C1,方法与R1中的管理员相同。管理员还必须批准与R1相同的链码定义。

我们已经建立了我们的第一个运营网络!在网络发展的这个阶段,我们有一个通道,在这个通道中,组织R1和R2可以相互充分地进行交易。具体而言,这意味着应用程序A1和A2可以使用信道C1上的智能合约S5和账本L1来生成交易。

生成和接受交易

与总是托管账本副本的对等节点不同,我们发现有两种不同的对等节点:一种是托管智能合约,另一种是不托管智能合约。在我们的网络中,每个对等节点都承载一个智能合约的副本,但在更大的网络中,会有更多的对等节点不托管智能合约的副本。对等方只能在安装智能合约的情况下运行智能合约,但它可以通过连接到通道了解智能合约的接口。

您不应该认为没有安装智能合约的对等节点在某种程度上是低劣的。更多的情况是,具有智能合约的对等节点有一种特殊的能力——帮助生成交易。请注意,所有对等节点都可以验证并随后接受拒绝其账本L1副本上的交易。然而,只有安装了智能合约的对等节点才能参与交易背书的过程,这是生成有效交易的核心。

在本主题中,我们不必担心交易是如何生成、分发和接受的具体细节,只要了解我们有一个区块链网络,R1和R2组织可以共享信息和流程,作为账本捕获的交易。我们将在其他主题中了解更多有关交易、账本、智能合约的信息。

节点类型

在Hyperledger Fabric中,虽然所有对等方都是相同的,但它们可以根据网络的配置方式承担多个角色。我们现在已经对典型的网络拓扑结构有了足够的了解来描述这些角色。

  • 确认节点。通道中的每个对等节点都是提交对等节点。它接收生成的交易块,然后在将它们作为追加操作提交到对等节点的账本副本之前进行验证。

  • 背书节点。如果安装了智能合约,则每个具有智能合约的对等端都可以是背书对等端。但是,要真正成为背书对等方,客户端应用程序必须使用对等方上的智能合约来生成数字签名的交易响应。背书同侪这个词是对这一事实的明确提及。

智能合约的背书策略标识了组织,其对等方应在生成的交易被接受到提交对等方的账本副本上之前对其进行数字签名。

这是节点的两种主要类型;节点还可以扮演两种其他角色:

  • 领导节点。当一个组织在一个通道中有多个节点时,领导节点是负责将交易从排序节点分发到组织中其他确认节点。节点可以选择参与静态或动态的领导选择。

因此,从领导的角度考虑两组节点是很有帮助的,一组是静态的领导者选择,另一组是动态的领导者选择。对于静态集,可以将零个或多个对等点配置为前导。对于动态集合,一个对等者将被集合选举为领导者。此外,在动态集合中,如果一个领导节点失败,则其余节点将重新选举一个领导者。
这意味着一个组织的节点可以有一个或多个领导者连接到排序服务。这有助于提高处理大量交易的大型网络的弹性和可伸缩性。

  • 锚节点(主节点)。如果节点需要与另一个组织中的对等方通信,那么它可以使用在该组织的通道配置中定义的一个锚节点。一个组织可以定义零个或多个锚节点,锚节点可以帮助处理许多不同的跨组织通信场景。

请注意,节点可以同时是确认节点、背书节点、领导节点和锚节点!只有锚节点是可选的 - 出于所有实际目的,总会有一个领导节点、至少一个背书节点和至少一个确认节点。

将组织和对等方添加到通道

当R2加入通道时,组织必须在对等节点P2上安装智能合约S5。很明显,如果应用程序A1或A2希望在对等节点P2上使用S5来生成交易,那么它必须首先存在;安装是实现这一点的机制。此时,对等节点P2拥有智能合约和账本的物理副本;与P1一样,它既可以生成交易,也可以接受账本L1的副本。

R2必须批准与R1批准的相同链码定义,以便使用智能合约S5。因为组织R1已经将链码定义提交给通道,所以只要组织批准了链码定义并安装了链码包,R2就可以使用链码。提交交易只需发生一次。一个新的组织一旦批准了通道其他成员同意的链码参数,就可以使用链码。由于链码定义的批准发生在组织级别,R2可以批准链码定义一次,并将多个对等方连接到安装了链码包的通道。但是,如果R2要更改链码定义,则R1和R2都需要批准其组织的新定义,然后其中一个组织需要将定义提交给通道。

在我们的网络中,我们可以看到通道C1连接两个客户端应用程序、两个节点和一个排序服务。因为只有一个通道,所以只有一个逻辑账本与这些组件交互。节点P1和P2具有相同的ledger L1副本。智能合约S5的副本通常使用相同的编程语言实现,但如果不是,它们必须在语义上等价。

我们可以看到,在网络中小心地添加节点可以帮助提高吞吐量、稳定性和弹性。例如,网络中更多的节点将允许更多的应用程序连接到它;组织中的多个对等点将在计划内或计划外停机的情况下提供额外的弹性。

这意味着可以配置复杂的拓扑结构来支持各种操作目标,理论上对网络的规模没有限制。此外,单个组织中的节点高效地发现和相互通信的技术机制(gossip协议)将容纳大量节点,以支持此类拓扑。

网络和通道策略的谨慎使用使得即使是大型网络也能得到良好的管理。组织可以自由地向网络添加节点,只要它们符合网络同意的策略。网络和通道策略在自治和控制之间建立了平衡,这是去中心化网络的特征。


简化视觉词汇

我们现在将简化用于表示示例区块链网络的可视化词汇表。随着网络规模的增长,最初用来帮助我们理解通道的线路将变得很麻烦。想象一下,如果我们添加另一个节点或客户端应用程序,或者另一个通道,我们的图表会有多复杂?

这就是我们马上要做的,所以在开始之前,让我们简化视觉词汇。以下是我们迄今为止开发的网络的简化表示:

该图显示了与网络N中的信道C1相关的事实如下:客户端应用程序A1和A2可以使用信道C1与对等方P1和P2以及订购方O4通信。节点P1和P2可以使用信道C1的通信服务。订购服务O4可以利用信道C1的通信服务。信道配置CC1适用于信道C1。

请注意,网络图已通过用连接点替换信道线而简化,连接点显示为包含信道号的蓝色圆圈。没有信息丢失。它消除了交叉线,因为这种表示方式更具伸缩性。这使我们能够更清楚地表示更大的网络。我们通过关注组件和通道之间的连接点,而不是通道本身来实现这种简化。


添加另一个联盟定义

在网络开发的下一个阶段,我们将介绍组织R3。我们将为R2和R3组织提供一个单独的应用程序通道,允许它们彼此进行交易处理。这个应用程序通道将完全独立于先前定义的通道,因此R2和R3交易可以对它们保密。

让我们回到网络级别,为R2和R3定义一个新的联盟X2:

来自组织R1或R4的网络管理员添加了一个新的联盟定义X2,其中包括组织R2和R3。这将用于为X2定义一个新通道。

请注意,网络现在定义了两个联盟:X1表示组织R1和R2,X2表示组织R2和R3。引入了联盟X2,以便能够为R2和R3创建新的通道。

新通道只能由网络配置策略NC4中明确标识为具有相应权限的组织(即R1或R4)创建。这是一个策略的示例,它将可以在网络级别管理资源的组织与能够在通道级别管理资源的组织分开。了解这些策略的工作原理有助于我们理解为什么Hyperledger Fabric具有复杂的分层策略结构。

实际上,联盟定义X2已添加到网络配置NC4中。我们在文档的其他地方讨论了这种操作的确切机制。


添加新通道

现在让我们使用这个新的联合体定义X2来创建一个新的通道C2。为了帮助您更好地理解更简单的通道符号,我们使用了两种视觉样式–通道C1用蓝色圆形端点表示,而通道C2用红色连接线表示:

使用联盟定义X2为R2和R3创建了一个新的通道C2。信道具有信道配置CC2,完全独立于网络配置NC4和通道配置CC1。通道C2由R2和R3管理,R2和R3根据CC2中的策略定义对C2具有同等的权限。R1和R4在CC2中没有任何定义。

通道C2为联盟X2提供了一个私有通信机制。再次,注意组织如何联合在一个联盟是什么形式的渠道。通道配置CC2现在包含了控制通道资源的策略,通过通道C2将管理权限分配给组织R2和R3。它由R2和R3独占管理;R1和R4在通道C2中没有电源。例如,通道配置CC2随后可以更新以添加支持网络增长的组织,但这只能由R2或R3来完成。

注意信道配置CC1和CC2如何保持彼此完全独立,并与网络配置NC4完全分离。我们再次看到了超级账本结构网络的非集中性;一旦创建了通道C2,它就由组织R2和R3独立于其他网络元素进行管理。通道策略始终彼此独立,只能由通道中授权的组织更改。

随着网络和通道的发展,网络和通道配置也将随之发展。有一个过程,通过这个过程可以以一种受控的方式完成——包括捕获对这些配置的更改的配置交易。每次配置更改都会生成一个新的配置块交易,在本主题的后面部分,我们将了解如何验证和接受这些块来分别创建更新的网络和通道配置。

网络和通道配置

在我们的示例网络中,我们看到了网络和通道配置的重要性。这些配置很重要,因为它们封装了网络成员同意的策略,这些策略为控制对网络资源的访问提供了共享的参考。网络和通道配置还包含有关网络和通道组成的事实,例如联盟及其组织的名称。

例如,当首先使用排序服务节点O4形成网络时,其行为由网络配置NC4控制。NC4的初始配置只包含允许组织R4管理网络资源的策略。NC4随后被更新以允许R1管理网络资源。一旦进行了此更改,连接到O4的组织R1或R4的任何管理员都将拥有网络管理权限,因为网络配置NC4中的策略允许这样做。在内部,订购服务中的每个节点记录网络配置中的每个通道,因此在网络级别上创建了每个通道的记录。

这意味着,尽管排序服务节点O4是创建联盟X1和X2以及通道C1和C2的参与者,但是网络的智能包含在O4所遵循的网络配置NC4中。只要O4作为一个好的参与者,并且在处理网络资源时正确地执行NC4中定义的策略,我们的网络将按照所有组织都同意的方式运行。在许多方面,NC4可以被认为比O4更重要,因为它最终控制了网络访问。

同样的原则适用于与节点相关的通道配置。在我们的网络中,P1和P2同样是好行动者。当节点P1和P2与客户端应用程序A1或A2交互时,它们各自使用在通道配置CC1中定义的策略来控制对通道C1资源的访问。

例如,如果A1要访问对等节点P1或P2上的智能合约链码S5,则每个对等节点使用其CC1的副本来确定A1可以执行的操作。例如,根据CC1中定义的策略,A1可以从账本L1读取或写入数据。稍后我们将看到通道中参与者的相同模式及其通道配置CC2。同样,我们可以看到,虽然对等方和应用程序是网络中的关键参与者,但它们在信道中的行为更多地取决于通道配置策略,而不是任何其他因素。

最后,有助于了解网络和通道配置是如何物理实现的。我们可以看到,网络和通道配置在逻辑上是单一的——有一个用于网络,一个用于每个通道。这一点很重要;访问网络或通道的每个组件都必须对授予不同组织的权限有共同的理解。

尽管逻辑上只有一个配置,但实际上它是由构成网络或通道的每个节点复制和保持一致的。例如,在我们的网络中,节点P1和P2都具有通道配置CC1的副本,当网络完全完成时,节点P2和P3都将具有通道配置CC2的副本。类似地,排序服务节点O4具有网络配置的副本,但是在多节点配置中,每个排序服务节点都将具有其自己的网络配置副本。

使用用于用户交易的相同区块链技术(但用于配置交易)保持网络和通道配置的一致性。要更改网络或通道配置,管理员必须提交配置交易以更改网络或通道配置。它必须由适当策略中确定的负责配置更改的组织签署。这项策略被称为国防策略,我们将在稍后讨论

实际上,排序服务节点操作一个小型区块链,通过我们前面提到的系统通道进行连接。使用系统通道排序服务节点分发网络配置交易。这些交易用于协同维护每个排序服务节点的网络配置的一致副本。以类似的方式,应用程序通道中的对等节点可以分发通道配置交易。同样,这些交易用于在每个节点上维护通道配置的一致副本。

通过物理分布,在逻辑上是单一的对象之间的这种平衡是Hyperledger Fabric中的常见模式。例如,逻辑上单一的网络配置之类的对象会在一组订购服务节点之间进行物理复制。我们还可以看到它与渠道配置,账本,以及某种程度上的智能合约,这些合约安装在多个地方,但其接口逻辑上存在于渠道层面。这是一种在Hyperledger Fabric中反复出现的模式,它使Hyperledger Fabric既可以去中心化,又可以同时进行管理。


添加另一个节点

既然组织R3能够完全参与到通道C2中,让我们将其基础设施组件添加到通道中。我们不需要一次只做一个组件,而是一次添加一个对等组件、一个账本副本、一个智能合约和一个客户端应用程序!
让我们看看添加了组织 R3组件的网络:

该图显示了网络N中与通道C1和C2有关的事实如下:客户端应用程序A1和A2可以使用通道C1与节点P1、P2、排序节点O4通信;客户端应用程序A3可以使用通道C2与节点P3和排序节点O4通信。排序节点O4可以利用通道C1和C2的通信服务。通道配置CC1适用于通道C1,CC2适用于通道C2。

首先,请注意,由于节点P3连接到通道C2,它与使用通道C1的节点具有不同的账本L2。账本L2的作用域有效地限定到通道C2。账本L1是完全独立的;它的范围是通道C1。这是有意义的-通道C2的目的是在联盟X2的成员之间提供私有通信,而ledger L2是他们交易的私有存储。

类似地,安装在节点P3上并在通道C2上定义的智能合约S6用于提供对账本L2的受控访问。应用程序A3现在可以使用信道C2来调用智能合约S6提供的服务,以生成可以被网络中每个账本L2副本接受的交易。

在这个时间点上,我们有一个单独的网络,其中定义了两个完全不同的通道。这些通道为组织之间的交易提供独立管理的设施。同样,这是工作中的去中心化;我们在控制和自治之间取得了平衡。这是通过应用于受不同组织控制和影响的通道的策略来实现的。


将节点连接到多个通道

在网络开发的最后阶段,让我们把重点放在R2组织上。我们可以利用R2是X1和X2联盟的成员这一事实,通过将其加入多个通道:

该图显示了网络N中与通道C1和C2有关的事实如下:客户端应用程序A1可以使用通道C1与节点P1和P2以及排序节点O4通信;客户端应用程序A2可以使用通道C1与节点P1、P2以及排序节点O4通信通信,并且可以使用通道C2与节点P2、P3以及排序节点O4通信,客户机应用程序A3可以使用通道C2与节点P3、P2以及排序节点O4通信。排序节点O4可以利用通道C1和C2的通信服务。通道配置CC1适用于通道C1,CC2适用于通道C2。

我们可以看到,R2是网络中的一个特殊组织,因为它是唯一一个同时属于两个应用通道的组织!它可以在通道C1上与组织R1进行交易,同时也可以在不同的通道C2上与组织R3进行交易。

请注意节点P2如何为通道C1安装智能合约S5,为通道C2安装智能合约S6。节点P2通过不同账本的不同智能合约同时成为两个通道的正式成员。

这是一种非常强大的组织和组织之间的分离机制。一直以来,这个基础设施是由一组独立的组织提供和共享的。

同样重要的是要注意到节点P2的行为根据其正在处理的通道而受到非常不同的控制。具体地说,通道配置CC1中包含的策略规定了P2在通道C1中进行交易处理时可用的操作,而通道配置CC2中的策略控制P2在通道C2中的行为。

同样,这是可取的–R2和R1同意通道C1的规则,而R2和R3同意通道C2的规则。这些规则包含在相应的通道策略中—通道中的每个组件都可以而且必须使用这些规则,以按照约定执行正确的行为。

类似地,我们可以看到客户端应用程序A2现在能够在通道C1和C2上进行交易处理。同样,它也将由适当的通道配置中的策略来管理。另外,请注意,客户机应用程序A2和对等节点P2使用的是混合的可视化词汇表-线和连接。你可以看到它们是等价的;它们是视觉同义词。

排序服务

观察者可能会注意到排序节点似乎是一个集中的组件;它最初用于创建网络,并连接到网络中的每个通道。尽管我们将R1和R4添加到控制排序节点的网络配置策略NC4中,但节点运行在R4的基础设施上。在一个非集中化的世界里,这看起来是错误的!

别担心!我们的示例网络展示了最简单的排序配置,以帮助您理解网络管理点的概念。事实上,排序服务本身也可以完全去中心化!我们在前面提到排序服务可以由不同组织拥有的许多单独的节点组成,所以让我们看看在我们的示例网络中是如何实现的。

让我们看看更实际的排序服务节点配置:

多组织排序服务。排序服务包括排序服务节点O1和O4。组织R1提供O1,组织R4提供节点O4。网络配置NC4定义了来自组织R1和R4的参与者的网络资源权限。

我们可以看到,这个排序服务完全去中心化了——它在R1组织中运行,在R4组织中运行。网络配置策略NC4允许R1和R4对网络资源拥有同等的权限。来自组织R1和R4的客户端应用程序和对等节点可以通过连接到节点O1或节点O4来管理网络资源,因为这两个节点的行为方式相同,如网络配置NC4中的策略所定义的那样。在实践中,来自特定组织的参与者倾向于使用其主组织提供的基础设施,但情况并非总是如此。

去中心化交易分布

除了作为网络的管理点之外,排序服务还提供了另一个关键设施——它是交易的分发点。排序服务是一个组件,它从应用程序收集背书的交易,并将它们排序为交易块,然后将这些交易块分发到通道中的每个节点。在每个提交节点,记录交易,不管是有效的还是无效的,并适当更新其本地的账本副本。

请注意,排序服务节点O4对通道C1的作用与对网络N的作用截然不同。在通道级别上,O4的作用是收集交易并在通道C1内分发块。它根据通道配置CC1中定义的策略来执行此操作。相比之下,当在网络级别执行操作时,O4的角色是根据网络配置NC4中定义的策略为网络资源提供管理点。再次注意这些角色是如何由通道和网络配置中的不同策略定义的。这应该会向您强调在Hyperledger Fabric中基于声明性策略的配置的重要性。策略既定义了联盟的每一个成员,也用来控制它们的约定行为。

我们可以看到,排序服务和Hyperledger Fabric中的其他组件一样,是一个完全非集中化的组件。无论是作为网络管理点,还是作为通道中块的分发者,其节点都可以根据需要分布在网络中的多个组织中。

改变策略

在我们对样本网络的研究过程中,我们看到了控制系统中参与者行为的策略的重要性。我们只讨论了一些可用的策略,但是有许多策略可以声明性地定义来控制行为的各个方面。这些单独的策略将在文档的其他地方讨论。

最重要的是,Hyperledger Fabric提供了一个功能独特的强大策略,允许网络和通道管理员自行管理策略更改!其基本理念是,策略变化是一个不变的过程,无论它发生在组织内部还是组织之间,也不管它是由外部监管者强加的。例如,新组织可以加入通道,或者现有组织的权限可能增加或减少。让我们进一步研究如何在Hyperledger Fabric中实现更改策略。

他们的关键理解点是,策略变化是由策略本身内部的策略来管理的。修改策略,简称mod_策略,是管理更改的网络或通道配置中的一级策略。让我们举两个简单的例子来说明我们是如何使用mod_策略来管理网络中的变化的!

第一个例子是最初建立网络的时候。此时,只有组织R4被允许管理网络。实际上,这是通过使R4成为网络配置NC4中定义的唯一具有网络资源权限的组织来实现的。此外,NC4的mod_策略只提到组织R4–只有R4被允许更改此配置。

然后,我们改进了网络N,以允许组织R1管理网络。R4通过将R1添加到通道创建和联盟创建的策略中来做到这一点。由于这个变化,R1能够定义联盟X1和X2,并创建通道C1和C2。R1对网络配置中的通道和联盟策略具有同等的管理权限。

然而,R4可以通过网络配置给R1更多的能量!R4可以将R1添加到mod_策略中,这样R1也可以管理网络策略的更改。

第二种力量比第一种力量强大得多,因为R1现在完全控制了网络配置NC4!这意味着R1原则上可以从网络中删除R4的管理权限。实际上,R4会配置mod_策略,使得R4也需要批准更改,或者mod_策略中的所有组织都必须批准更改。有很多方法使mod_策略灵活化,因为它需要支持任何改变过程所需要的。

这就是mod_的工作策略–它允许从基本配置优雅地演变为复杂的配置。一直以来,这都是在所有相关组织同意的情况下发生的。mod_策略的行为与网络或通道配置中的所有其他策略一样;它定义了一组允许更改mod_策略本身的组织。

在这一小节中,我们只触及了策略和国防策略的力量的表面。在策略主题中会有更详细的讨论,但现在让我们回到我们完成的网络!


网络完全形成

让我们用一致的视觉词汇来回顾一下我们的网络是什么样子。我们使用更紧凑的可视化语法对其进行了再组织,因为它可以更好地适应更大的拓扑:

在该图中,我们看到结构区块链网络由两个应用程序通道和一个排序服务组成。R1和R4负责排序通道,R1和R2负责蓝色应用通道,R2和R3负责红色应用通道。客户端应用程序A1是组织R1的一个元素,CA1是它的证书颁发机构。注意,组织R2的节点P2可以使用蓝色和红色应用通道的通信设施。每个应用程序通道都有自己的通道配置,在本例中是CC1和CC2。系统通道的通道配置是网络配置NC4的一部分。

我们的概念之旅即将结束,我们将构建一个示例超级账本结构区块链网络。我们创建了一个四组织网络,有两个通道和三个对等节点,有两个智能合约和一个排序服务。它由四个证书颁发机构支持。它为三个客户端应用程序提供账本和智能合约服务,这些应用程序可以通过这两个通道与之交互。花点时间浏览图表中网络的详细信息,并随时回顾该主题以巩固您的知识,或者转到更详细的主题。

网络组件摘要

下面是我们讨论过的网络组件的快速摘要:

Hyperledger Fabric 网络摘要

在本主题中,我们了解了不同组织如何共享其基础设施,以提供集成的超级账本结构区块链网络。我们已经看到了如何将集体基础设施组织成提供独立管理的私有通信机制的通道。我们已经了解了客户端应用程序、管理员、节点和排序节点等参与者是如何通过使用来自各自证书颁发机构的证书来标识来自不同组织的。反过来,我们也看到了策略的重要性,定义这些组织参与者对网络和通道资源拥有的一致权限。


身份

什么是身份?

区块链网络中的不同参与者包括节点、排序节点、客户端应用程序、管理员等。这些参与者中的每一个——网络内部或外部的活动元素——都有一个封装在X.509数字证书中的数字标识。这些身份确实很重要,因为它们决定了参与者在区块链网络中对资源和信息的访问权限

此外,数字标识还有一些附加属性,Fabric使用这些属性来确定权限,并且它为标识和相关属性的联合提供了一个特殊的名称-主体。主体与userid或groupid一样,但是更灵活一些,因为它们可以包含参与者身份的广泛属性,例如参与者的组织、组织单元、角色甚至参与者的特定身份。当我们谈论主体时,它们是决定其权限的属性。

要使身份可验证,它必须来自可信的权威机构。成员服务提供者(MSP)是结构中可信任的权威机构。更具体地说,MSP是一个组件,它定义了管理该组织的有效标识的规则。Fabric中的默认MSP实现使用X.509证书作为身份,采用传统的公钥基础设施(PKI)分层模型(稍后将详细介绍PKI)。


一个简单的场景来解释身份的使用

想象一下你去超市买东西。在结账处,你会看到一个标牌,上面写着只接受维萨、万事达和美国运通卡。如果你想用另一张卡付款——我们称之为“Imagine Card”——不管这张卡是不是真的,你的账户里有足够的资金。我们不会接受的。

有一张有效的信用卡是不够的-它还必须被商店接受!PKI和MSP以相同的方式协同工作-PKI提供一个身份列表,MSP说明哪些身份是参与网络的给定组织的成员。

PKI证书颁发机构和msp提供了类似的功能组合。PKI就像一个卡提供商-它分配许多不同类型的可验证身份。另一方面,MSP就像商店接受的卡提供商列表,决定哪些身份是商店支付网络的可信成员(参与者)。MSP将可验证的身份转变为区块链网络的成员。

让我们更详细地研究这些概念。


什么是PKIs?

公钥基础设施(PKI)是一组在网络中提供安全通信的internet技术的集合。是PKI将s放在HTTPS中-如果您在web浏览器上阅读此文档,您可能正在使用PKI来确保它来自经过验证的源。

公钥基础设施(PKI)的要素。PKI由证书颁发机构组成,证书颁发机构向各方(例如服务的用户、服务提供商)颁发数字证书,然后由这些机构在其环境中交换的消息中对自己进行身份验证。CA的证书吊销列表(CRL)构成对不再有效的证书的引用。证书的吊销有多种原因。例如,证书可能会被吊销,因为与证书相关联的加密专用材料已被公开。

虽然区块链网络不仅仅是一个通信网络,但它依赖于PKI标准来确保不同网络参与者之间的安全通信,并确保发布在区块链上的消息被正确地认证。因此,了解PKI的基础知识以及msp为什么如此重要非常重要。

PKI有四个关键要素:

  • 数字证书
  • 公钥和私钥
  • 证书颁发机构
  • 证书吊销列表

让我们快速描述一下这些PKI基础知识,如果你想知道更多细节,维基百科是一个很好的起点。


数字证书

数字证书是一种文档,其中包含一组与证书持有者相关的属性。最常见的证书类型是符合X.509标准的证书,它允许对一方的标识细节在其结构中进行编码。

例如,位于密歇根州底特律的Mitchell Cars制造部门的Mary Morris可能拥有一个SUBJECT属性为C=US,ST=Michigan,L=Detroit,O=Mitchell Cars,OU=Manufacturing,CN=Mary Morris/UID=123456的数字证书。玛丽的证明与她的政府身份证相似,它提供了有关玛丽的信息,她可以用来证明有关她的关键事实。在一个X.509证书中还有许多其他属性,但现在我们只关注这些属性。

描述一个叫玛丽·莫里斯的聚会的数字证书。Mary是证书的SUBJECT,突出显示的SUBJECT文本显示了有关Mary的关键事实。如您所见,证书还包含更多信息。最重要的是,Mary的公钥是在她的证书中分发的,而她的私有签名密钥则不是。此签名密钥必须保密。

重要的是,Mary的所有属性都可以使用一种称为密码学(字面意思是“秘密写入”)的数学技术来记录,这样篡改将使证书失效。密码学允许Mary向其他人展示她的证书以证明她的身份,只要另一方信任证书颁发者,即证书颁发机构(CA)。只要CA安全地保存某些加密信息(也就是说,它自己的私有签名密钥),任何阅读证书的人都可以确保有关Mary的信息没有被篡改-它将始终具有Mary Morris的那些特定属性。把玛丽的X.509证书想象成一张不可能更改的数字身份证。

身份验证、公钥和私钥

身份验证和消息完整性是安全通信中的重要概念。身份验证要求交换消息的各方能够确定创建特定消息的身份。“完整性”意味着信息在传输过程中不能被修改。例如,你可能想确定你是在和真实的玛丽·莫里斯交流,而不是一个模仿者。或者,如果Mary给您发送了一条消息,您可能需要确保它在传输过程中没有被其他人篡改。

传统的身份验证机制依赖于数字签名,顾名思义,数字签名允许一方对其消息进行数字签名。数字签名还可以保证签名消息的完整性。

从技术上讲,数字签名机制要求每一方持有两个加密连接的密钥:一个是广泛可用的用作身份验证锚的公钥,另一个是用于在消息上生成数字签名的私钥。数字签名邮件的收件人可以通过检查附加的签名是否在预期发件人的公钥下有效,从而验证所接收邮件的来源和完整性。

私钥和相应公钥之间的独特关系是使安全通信成为可能的密码魔法。密钥之间唯一的数学关系是,私钥可用于在消息上生成签名,该消息只有相应的公钥才能匹配,并且只能在同一消息上。

在上面的示例中,Mary使用她的私钥对消息进行签名。任何看到签名消息的人都可以使用她的公钥验证签名。


证书颁发机构

如您所见,参与者或节点能够通过系统信任的权威机构为其颁发的数字身份来参与区块链网络。在最常见的情况下,数字身份(或简单的身份)具有加密验证的数字证书的形式,这些证书符合X.509标准,并由证书颁发机构(CA)颁发。

CA是internet安全协议的常见部分,您可能听说过一些更流行的协议:Symantec(最初是Verisign)、GeoTrust、DigiCert、GoDaddy和Comodo等。

证书颁发机构将证书分发给不同的参与者。这些证书由CA进行数字签名,并将参与者与参与者的公钥绑定在一起(还可以选择使用完整的属性列表)。因此,如果信任CA(并知道其公钥),则可以通过验证参与者证书上CA的签名来信任特定参与者绑定到证书中包含的公钥,并拥有包含的属性。

证书可以广泛传播,因为它们既不包括参与者的私钥,也不包括CA的私钥。因此,它们可以用作信任的锚,用于验证来自不同参与者的消息。

CA也有一个证书,并广泛提供。这允许由给定CA颁发的身份的使用者通过检查证书是否只能由相应私钥(CA)的持有者生成来验证身份。

在区块链环境中,每个希望与网络互动的参与者都需要一个身份。在此设置中,您可能会说,可以使用一个或多个CA数字角度定义组织的成员。CA为组织的参与者提供了一个可验证的数字身份的基础。

根CA、中间CA和信任链

CA有两种口味:根CA和中间CA。因为根CA(Symantec、Geotrust等)必须安全地向internet用户分发数以亿计的证书,因此将此过程分散到所谓的中间CA是有意义的。这些中间CA的证书由根CA或其他中间机构颁发,允许为链中任何CA颁发的任何证书建立“信任链”。这种跟踪根CA的能力不仅允许CA的功能扩展,同时仍然提供安全性(允许使用证书的组织有信心地使用中间CA),它还限制了根CA的暴露,如果受到破坏,将危及整个信任链。另一方面,如果一个中间CA被破坏,则会有一个小得多的暴露。

信任链是在根CA和一组中间CA之间建立的,只要这些中间CA的证书的颁发CA是根CA本身,或者具有对根CA的信任链。

在跨多个组织颁发证书时,中间CA提供了巨大的灵活性,这在许可的区块链系统(如Fabric)中非常有用。例如,您将看到不同的组织可能使用不同的根CA,或者同一根CA使用不同的中间CA—这确实取决于网络的需要。

Fabric CA

这是因为CA非常重要,Fabric提供了一个内置的CA组件,允许您在所形成的区块链网络中创建CA。这个称为Fabric CA的组件是一个私有的根CA提供者,能够管理具有X.509证书形式的Fabric参与者的数字身份。因为Fabric CA是一个针对Fabric根CA需求的定制CA,它本质上不能提供SSL证书以供浏览器中的常规/自动使用。但是,由于某些CA必须用于管理标识(即使在测试环境中),所以结构CA可用于提供和管理证书。还可以使用公共/商业根或中间CA来提供标识。

如果您感兴趣,可以在CA文档部分阅读更多关于Fabric CA的内容。


证书吊销列表

证书吊销列表(Certificate Revocation List,CRL)很容易理解,它只是一个引用证书的列表,CA知道这些证书由于某种原因而被吊销。如果你回想一下商店场景,CRL就像是一张被盗信用卡的列表。

当第三方想要验证另一方的身份时,它首先检查签发CA的CRL,以确保证书没有被吊销。验证者不必检查CRL,但如果他们不检查,他们就有接受泄露身份的风险。

使用CRL检查证书是否仍然有效。如果一个模拟者试图将一个被破坏的数字证书传递给一个验证方,可以首先对照签发CA的CRL来检查它,以确保它没有被列为不再有效。

请注意,被吊销的证书与即将过期的证书截然不同。被吊销的证书没有过期-它们是一个完全有效的证书。有关CRL的详细信息,请单击此处

现在,您已经了解了PKI如何通过信任链提供可验证的身份,下一步是了解如何使用这些身份来代表区块链网络的受信任成员。这就是会员服务提供商(MSP)发挥作用的地方——它识别区块链网络中某个组织的成员

要了解更多关于成员资格的信息,请查看MSPs上的概念文档。


成员服务提供商(MSP)

为什么我需要MSP?

因为Fabric是一个许可的网络,区块链参与者需要一种向网络其他成员证明其身份的方法,以便在网络上进行交易。如果你通读过关于身份的文档,你就会看到公钥基础设施(PKI)如何通过信任链提供可验证的身份。区块链网络如何使用信任链?

证书颁发机构通过生成公钥和私钥来颁发身份,公钥和私钥形成可用于证明身份的密钥对。因为私钥永远不能被公开共享,所以需要一种机制来启用MSP的证明。例如,对等方使用其私钥对交易进行数字签名或背书。订购服务上的MSP包含对等方的公钥,然后使用该公钥验证附加到交易的签名是否有效。私钥用于在交易上生成只有对应的公钥(MSP的一部分)才能匹配的签名。因此,MSP是一种机制,它允许网络的其余部分信任和识别该身份,而不必暴露成员的私钥。

回想一下身份主题中的信用卡场景,证书颁发机构就像一个卡提供商—它分配许多不同类型的可验证身份。另一方面,MSP决定商店接受哪些信用卡提供商。通过这种方式,MSP将一个身份(信用卡)转变为一个角色(在商店购买东西的能力)。

这种将可验证身份转换为角色的能力是结构网络功能的基础,因为它允许组织、节点和通道建立msp,确定谁可以在组织、节点和通道级别执行操作。

身份类似于你的信用卡,用来证明你可以支付。MSP类似于已接受的信用卡列表。

考虑一个运营区块链网络的银行联盟。每个银行操作节点和排序节点,节点背书提交给网络的交易。不过,每家银行也会有部门和账户持有人。帐户持有者将属于每个组织,但不会运行网络上的节点。他们只会从他们的移动或网络应用程序与系统交互。那么网络如何识别和区分这些身份呢?CA被用来创建身份,但是和卡片的例子一样,这些身份不能仅仅被发布,它们需要被网络识别。msp用于定义网络成员信任的组织。msp也是在网络中为成员提供一组角色和权限的机制。由于定义这些组织的msp对于网络成员来说是已知的,因此可以使用它们来验证是否允许尝试执行操作的网络实体。

最后,考虑一下,如果你想加入一个现有的网络,你需要一种方法把你的身份转变成网络能识别的东西。MSP是一种使您能够参与许可区块链网络的机制。要在结构网络上进行交易,成员需要:

  1. 拥有由网络信任的CA颁发的标识。
  2. 成为网络成员背书和背书的组织的成员。MSP是身份与组织成员的联系方式。成员资格是通过将成员的公钥(也称为证书、签名证书或signcert)添加到组织的MSP来实现的。
  3. 将MSP添加到网络或通道上的联盟
  4. 确保MSP包含在网络上的策略定义中。

什么是MSP?

尽管名称如此,成员服务提供商实际上并不提供任何服务。相反,MSP需求的实现是一组添加到网络配置中的文件夹,用于定义组织的内部(组织决定其管理员是谁)和外部(允许其他组织验证实体是否有权执行其尝试的操作)。证书颁发机构生成表示身份的证书,而MSP包含一个许可的身份列表。

MSP通过列出根CA和中间CA的成员身份,或通过标识哪些CA被授权为其成员颁发有效标识,来标识哪些根CA和中间CA可以定义信任域的成员。

但MSP的力量不仅仅是简单地列出谁是网络参与者或通道成员。MSP通过标识参与者在节点或通道上拥有的特定权限,将身份转换为角色。请注意,当用户向Fabric CA注册时,admin、peer、client、order或member角色必须与该用户关联。例如,以“peer”角色注册的身份自然应该给peer。类似地,以“admin”角色注册的身份应该授予组织管理员。我们将在后面的主题中深入探讨这些角色的重要性。

我们还讨论了如何在MSP的身份证明文件中添加MSP的身份。


MSP域

MSP出现在区块链网络的两个域中:

  • 在参与者节点上的本地(本地MSP)
  • 信道内配置(信道MSP)

本地msp和channel msp之间的关键区别不在于它们如何工作(都将身份转换为角色),而是它们的作用范围。每个MSP列出特定管理级别的角色和权限。

本地MSPs

为客户机和节点(节点和排序服务)定义了本地msp。本地msp定义节点的权限(例如,谁是可以操作节点的节点管理员)。客户端的本地msp(上述银行场景中的账户持有人)允许用户在其交易中以通道成员身份(例如在链码交易中)或作为系统中特定角色的所有者(例如,在配置交易中)进行身份验证。

每个节点都必须定义一个本地MSP,因为它定义了谁拥有该级别的管理或参与权限(节点管理员不一定是通道管理员,反之亦然)。这允许对通道上下文之外的成员消息进行身份验证,并定义对特定节点的权限(例如,谁能够在节点上安装链码)。请注意,一个组织可以拥有一个或多个节点。MSP定义组织管理员。组织、组织的管理员、节点的管理员以及节点本身都应该具有相同的信任根。

排序节点本地MSP也在节点的文件系统上定义,并且仅适用于该节点。与节点一样,排序节点也属于一个组织,因此只有一个MSP来列出它信任的参与者或节点。

通道MSPs

相比之下,通道MSPs在通道级别定义了管理和参与的权利。应用程序通道上的节点和排序节点共享通道MSPs的相同视图,因此能够正确验证通道参与者。这意味着,如果一个组织希望加入该通道,则需要在通道配置中包含该组织成员的信任链的MSP。否则,来自此组织身份的交易将被拒绝。本地MSPs在文件系统上表示为文件夹结构,而通道MSPs在通道配置中描述。
通道MSP
来自通道的片段 config.json 包含两个组织MSPs的文件。

通道MSPs确定谁拥有通道级别的权限。通道MSPs定义了通道成员(它们本身就是MSP)的标识与通道级策略的实施之间的关系。通道MSP包含通道成员组织的MSP。

参与通道的每个组织都必须为其定义MSP。事实上,提案在组织和MSP之间建立一对一的映射关系。MSP规定了哪些成员有权代表组织行事。这包括MSP本身的配置,以及批准组织具有角色的管理任务,例如向通道添加新成员。如果所有的网络成员都是一个组织或MSP的一部分,数据隐私就会被牺牲。多个组织通过将账本数据仅分离给通道成员来促进隐私。如果一个组织需要更大的粒度,那么可以将组织进一步划分为组织单元(organizationunits,ou),我们将在本主题后面更详细地描述这些单元。

系统通道MSP包括参与排序服务的所有组织的MSPs。排序服务可能包括来自多个组织的排序节点,这些组织共同运行排序服务,最重要的是管理组织联盟和应用程序通道继承的默认策略。

本地MSPs只在应用它们的节点或用户的文件系统上定义。因此,在物理和逻辑上每个节点只有一个本地MSP。但是,由于通道MSPs可用于通道中的所有节点,因此它们在通道配置中逻辑定义一次。然而,通道MSP也被实例化在通道中每个节点的文件系统上,并通过共识保持同步。因此,虽然每个节点的本地文件系统上都有一个通道MSP的副本,但在逻辑上,通道MSP驻留在通道或网络上并由其维护。

下图说明了本地和通道MSPs如何在网络上共存:

普通节点和排序节点的MSPs是本地的,而通道(包括网络配置通道,也称为系统通道)的MSPs是全局的,在该通道的所有参与者之间共享。在此图中,网络系统通道由ORG1管理,但另一个应用程序通道可以由ORG1和ORG2管理。节点是ORG2的成员,由ORG2管理,而ORG1管理图的排序者。ORG1信任来自RCA1的标识,而ORG2信任来自RCA2的标识。需要注意的是,这些是管理标识,反映了谁可以管理这些组件。因此,当ORG1管理网络时,ORG2.MSP确实存在于网络定义中。


组织在MSP中扮演什么角色?

组织是一个逻辑管理的成员组。这可以是大到跨国公司或小到花店。组织(或组织)最重要的是他们在一个MSP下管理他们的成员。MSP允许将身份链接到组织。请注意,这与我们前面提到的X.509证书中定义的组织概念不同。

组织与其MSP之间的独占关系使得以组织命名MSP是明智的,您会发现大多数策略配置都采用了这种约定。例如,组织ORG1可能有一个名为ORG1-MSP的MSP。在某些情况下,一个组织可能需要多个成员组,例如,在组织之间使用通道来执行非常不同的业务功能。在这些情况下,有多个MSP并相应地命名它们是有意义的,例如ORG2-MSP-NATIONALORG2-MSP-GOVERNMENT,这反映了与GOVERNMENT监管通道相比,ORG2NATIONAL销售通道中的不同成员信任根源。

组织单元(OUs)和MSPs

一个组织也可以分为多个组织单元,每个单元都有一组特定的职责,也称为从属关系。将组织单位视为组织内部的一个部门。例如,ORG1组织可能同时具有ORG1.MANUFACTURINGORG1.DISTRIBUTION 组织单元来反映这些独立的业务线。当CA颁发X.509证书时,证书中的OU字段指定标识所属的业务线。像这样使用OU的好处是,这些值可以用于策略定义中以限制访问,或用于基于属性的访问控制的智能合约。否则,需要为每个组织创建单独的MSPs。

指定OUs是可选的。如果不使用OUs,作为MSP一部分的所有标识(由根CA和中间CA文件夹标识)将被视为组织的成员。

节点OU角色和MSPs

此外,还有一种特殊类型的OU,有时称为节点OU,可用于将角色授予身份。这些节点OU角色在$FABRIC_CFG_PATH/msp/config.yaml文件中定义,并包含一个组织单位的列表,这些单位的成员被认为是由该MSP表示的组织的一部分。当您希望将组织的成员限制为持有标识(由MSP指定的ca之一签名)且其中包含特定节点OU角色的成员时,这一点特别有用。例如,使用节点OU,您可以实现更细粒度的背书策略,该策略要求Org1节点背书交易,而不是Org1的任何成员。

为了使用节点OU角色,必须为网络启用“标识分类”功能。当使用基于文件夹的MSP结构时,这是通过在config.yaml驻留在MSP文件夹根目录下的文件:

NodeOUs:
  Enable: true
  ClientOUIdentifier:
    Certificate: cacerts/ca.sampleorg-cert.pem
    OrganizationalUnitIdentifier: client
  PeerOUIdentifier:
    Certificate: cacerts/ca.sampleorg-cert.pem
    OrganizationalUnitIdentifier: peer
  AdminOUIdentifier:
    Certificate: cacerts/ca.sampleorg-cert.pem
    OrganizationalUnitIdentifier: admin
  OrdererOUIdentifier:
    Certificate: cacerts/ca.sampleorg-cert.pem
    OrganizationalUnitIdentifier: orderer

在上面的示例中,MSP有4个可能的节点OU角色:

  • 客户端
  • 节点
  • 管理员
  • 排序

此约定允许您通过X509证书的CommonName属性中的OU来区分MSP角色。上面的例子说明,任何由cacerts/ca.sampleorg-cert.pem颁发的证书中OU=client将被标识为client,OU=peer被标识为peer,等等。从Fabric v1.4.3开始,还有一个OU用于订购者和管理员。新的admins角色意味着您不再需要显式地将证书放在MSP目录的admincerts文件夹中。相反,用户的signcert中的admin角色将身份限定为admin用户。

当使用结构CA或SDK向CA注册用户时,这些角色和OU属性将分配给标识。后续的“注册用户”命令将在用户的/msp文件夹中生成证书。

生成的ROLE和OU属性在位于/signcerts文件夹中的X.509签名证书中可见。角色属性标识为hf.type和指的是参与者在其组织中的角色(例如,指定参与者是节点)。请参阅下面的签名证书片段,其中显示了角色和OU在证书中的表示方式。

注意:对于通道MSPs来说,仅仅因为参与者具有管理员的角色并不意味着他们可以管理特定的资源。给定身份在管理系统方面的实际权力由管理系统资源的策略决定。例如,通道策略可能指定ORG1-MANUFACTURING管理员(即具有admin角色和ORG1-MANUFACTURING节点OU的身份)有权向通道添加新组织,而ORG1-DISTRIBUTION管理员没有此类权限。

最后,OUs可以被联盟中的不同组织用来区分彼此。但是在这种情况下,不同的组织必须使用相同的根CA和中间CA作为其信任链,并分配OU字段来标识每个组织的成员。当每个组织都有相同的CA或信任链时,这会使系统比预期的更集中,因此值得在区块链网络上仔细考虑。

MSP结构

让我们来研究呈现我们目前所描述的功能的MSP元素。

本地MSP文件夹包含以下子文件夹:

上图显示了文件系统上本地MSP中的子文件夹

  • config.yaml:用于通过启用“节点OU”并定义接受的角色来配置结构中的身份分类功能。

  • cacerts:此文件夹包含此MSP所代表的组织信任的根CA的自签名X.509证书的列表。此MSP文件夹中必须至少有一个根CA证书。
    这是最重要的文件夹,因为它标识CA,所有其他证书都必须从中派生,才能被视为相应组织的成员,以形成信任链。

  • intermediatecerts:此文件夹包含此组织信任的中间CA的X.509证书列表。每个证书都必须由MSP中的一个根CA或任何中间CA签名,其颁发CA链最终会返回到受信任的根CA。
    中间CA可以表示组织的不同细分(如ORG1-MANUFACTURINGORG1-DISTRIBUTION do for ORG1),也可以代表组织本身(如果利用商业CA进行组织的身份管理,则可能是这种情况)。在后一种情况下,中间CA可用于表示组织的细分。在这里,您可以找到有关MSP配置的最佳实践的更多信息。请注意,可能有一个没有中间CA的正常工作的网络,在这种情况下,该文件夹将是空的。
    与根CA文件夹一样,此文件夹定义了必须从中颁发证书才能将其视为组织成员的CA。

  • admincerts(Fabric v1.4.3及更高版本中已弃用):此文件夹包含一个标识列表,这些标识定义了具有此组织管理员角色的参与者。通常,此列表中应该有一个或多个X.509证书。
    请注意,在Fabric v1.4.3之前,管理员是通过显式地将证书放在对等机的本地MSP目录的admincerts文件夹中来定义的。对于Fabric v1.4.3或更高版本,不再需要此文件夹中的证书。相反,提案在用户向CA注册时,使用admin角色指定节点管理员。然后,通过signcert中的Node OU role值将标识识别为admin。作为提醒,为了利用管理员角色,必须在config.yaml通过设置“Node OUs”来Enable:true。稍后我们将对此进行更深入的探讨。
    作为提醒,对于通道MSPs来说,仅仅因为参与者具有管理员的角色,并不意味着他们可以管理特定的资源。给定身份在管理系统方面的实际权力由管理系统资源的策略决定。例如,通道策略可能指定ORG1-MANUFACTURING管理员有权向通道添加新组织,而ORG1-DISTRIBUTION管理者没有这样的权限。

  • keystore:(private Key)此文件夹是为普通节点或排序节点(或在客户机的本地MSP中)的本地MSP定义的,并包含节点的私钥。此键用于签署数据-例如,作为背书阶段的一部分,签署交易提案响应。
    此文件夹对于本地MSP是必需的,并且必须正好包含一个私钥。显然,对该文件夹的访问必须仅限于对对等方负有管理责任的用户的身份。
    通道MSP配置不包括此文件夹,因为通道MSP的唯一目的是提供身份验证功能,而不是签名功能。
    注意:如果您使用硬件安全模块(HSM)进行密钥管理,则此文件夹为空,因为私钥由HSM生成并存储在HSM中。

  • signcert:对于普通节点或排序节点(或在客户机的本地MSP中),此文件夹包含节点的签名密钥。此密钥以加密方式与节点标识文件夹中包含的节点身份相匹配,并用于对数据进行签名-例如,作为背书阶段的一部分,对交易提案响应进行签名。
    此文件夹对于本地MSPs是必需的,并且必须正好包含一个公钥。显然,对该文件夹的访问必须仅限于对普通节点负有管理责任的用户的身份。
    通道MSP的配置不包括此文件夹,因为通道MSP的唯一目的是提供身份验证功能,而不是签名功能。

  • tlscacerts:此文件夹包含此组织信任的根CA的自签名X.509证书列表,这些证书用于使用TLS的节点之间的安全通信。TLS通信的一个例子是,对等方需要连接到订购方,以便可以接收账本更新。
    MSP-TLS信息与网络中的节点相关,换句话说,与使用网络的应用程序和管理机构无关。
    此文件夹中必须至少有一个TLS根CA证书。有关TLS的详细信息,请参阅使用传输层安全性(TLS)保护通信

  • tlsIntermediateCerts:此文件夹包含一个列表,该证书由由该MSP表示的组织信任,用于使用TLS的节点之间的安全通信。当商业CA用于组织的TLS证书时,此文件夹特别有用。与成员资格中间CA类似,指定中间TLS CA是可选的。

  • OperationCerts:此文件夹包含与Fabric操作服务API通信所需的证书。

通道MSP包括以下附加文件夹:

  • 吊销证书:如果参与者的身份已被吊销,则有关身份的标识信息(而不是标识本身)将保存在此文件夹中。对于基于X.509的标识,这些标识符是一对字符串,称为Subject Key Identifier(SKI)和Authority Access Identifier(AKI),并且在使用证书时进行检查,以确保证书没有被吊销。
    此列表在概念上与CA的证书吊销列表(CRL)相同,但它也涉及从组织中撤消成员资格。因此,通道MSP的管理员可以通过公布CA的更新的CRL来快速从组织中撤消参与者或节点。此“列表列表”是可选的。它只会在证书被吊销时填充。

如果你读过这篇文章以及我们的关于身份的文档,你现在应该已经很好地理解了身份和msp在Hyperledger Fabric中是如何工作的。您已经了解了如何使用PKI和msp来识别区块链网络中协作的参与者。除了学习msp的物理和逻辑结构之外,您还了解了证书、公钥/私钥和信任根的工作原理。


策略

受众:架构师、应用程序和智能合约开发人员、管理员


什么是策略

在最基本的层面上,策略是一组规则,它们定义了如何做出决策和实现具体结果的结构。为此,策略通常描述什么,例如个人对资产的访问权或权限。我们可以看到,策略在我们的日常生活中被用来保护对我们有价值的资产,包括租车、健康、住房等等。

例如,保险单定义了保险赔付的条件、条款、限额和到期日。本保险单由投保人和保险公司约定,明确双方的权利和责任。

虽然为风险管理制定了保险单,但在Hyperledger Fabric中,保险单是基础设施管理的机制。结构策略表示成员如何就接受或拒绝对网络、通道或智能合约的更改达成一致。策略由联盟成员在最初配置网络时达成一致,但也可以随着网络的发展而修改。例如,它们描述了在通道中添加或删除成员的标准,更改块的形成方式,或指定签署智能合约所需的组织数量。所有这些操作都由一个定义谁可以执行操作的策略来描述。简单地说,您要在结构网络上执行的所有操作都由策略控制。


为什么需要策略

策略是使超级账本结构不同于以太坊或比特币等其他区块链的因素之一。在这些系统中,交易可以由网络中的任何节点生成和验证。控制网络的策略在任何时间点都是固定的,并且只能使用管理代码的同一进程来更改。因为Fabric是一个许可的区块链,其用户由底层基础设施识别,因此这些用户有能力在网络启动之前决定网络的治理,并改变正在运行的网络的治理。

策略允许成员决定哪些组织可以访问或更新结构网络,并提供强制执行这些决策的机制。一个包含给定访问权限的用户或组织的列表。它们还指定了需要多少组织就更新资源(如通道或智能合约)的提案达成一致。一旦编写完成,策略将评估附加到交易和提案的签名集合,并验证签名是否符合网络同意的治理。


在整个结构中如何实施策略

策略在结构网络的不同级别上实现。每个策略域控制网络运行方式的不同方面。

结构策略层次结构的可视化表示。

系统信道配置

每个网络都从一个排序系统通道开始。排序服务必须只有一个排序系统通道,并且它是要创建的第一个通道。系统通道还包含排序服务的成员组织(排序组织)和在网络上进行交易的组织(联盟组织)。

排序系统通道配置块中的策略控制排序服务使用的一致性,并定义如何创建新块。系统通道还控制允许联盟的哪些成员创建新通道。

应用程序通道配置

应用程序通道用于在联合体中的组织之间提供私有通信机制。

应用程序通道中的策略控制在通道中添加或删除成员的能力。应用程序通道还控制在定义链代码并将其提交到使用结构链代码生命周期的通道之前,需要哪些组织批准链代码。在最初创建应用程序通道时,默认情况下,它会从排序者系统通道继承所有排序服务参数。但是,这些参数(以及控制它们的策略)可以在每个通道中自定义。

访问控制列表(ACLs)

网络管理员将对ACLs的结构使用特别感兴趣,ACLs提供了通过将资源与现有策略关联来配置对资源的访问的能力。这些“资源”可以是系统链码上的函数(例如,“qscc”系统链码上的“GetBlockByNumber”)或其他资源(例如,谁可以接收块事件)。ACLs引用在应用程序通道配置中定义的策略,并扩展它们以控制其他资源。默认的结构ACLs集在中可见configtx.yaml文件位于Application:$ApplicationDefaults下,但它们可以并且应该在生产环境中被重写。中命名的资源列表configtx.yaml是当前由Fabric定义的所有内部资源的完整集合。

在该文件中,ACLs使用以下格式表示:

# ACL policy for chaincode to chaincode invocation
peer/ChaincodeToChaincode: /Channel/Application/Readers

其中peer/ChaincodeToChaincode表示被保护的资源,/Channel/Application/Readers是指必须满足的策略,关联交易才能被视为有效。

有关ACL的更深入研究,请参阅《ACL操作指南》中的主题。

智能合约背书策略

链码包中的每个智能合约都有一个背书策略,该策略指定属于不同渠道成员的节点需要根据给定的智能合约执行和验证一个交易,以使该交易被视为有效。因此,背书策略定义了必须“背书”(即批准)提案执行的组织(通过其同行)。

修改策略

最后一种策略对策略在Fabric中的工作方式至关重要,即修改策略。修改策略指定签署(批准)任何配置更新所需的标识组。策略定义了如何更新策略。因此,每个信道配置元素包括对控制其修改的策略的引用。


Fabric策略域

虽然Fabric策略是灵活的,并且可以配置为满足网络的需要,但是策略结构自然会导致由排序服务组织或联盟成员管理的域之间的划分。在下图中,您可以看到默认策略如何实现对以下Fabric策略域的控制。

更详细地查看由排序组织和联盟组织管理的策略域。

一个功能齐全的Fabric网络可以包含许多具有不同职责的组织。通过允许排序服务的创建者建立联盟的初始规则和成员资格,域提供了向不同Fabric扩展不同特权和角色的能力。它们还允许加入联盟的组织创建专用应用程序通道,管理自己的业务逻辑,并限制对网络上的数据的访问。

系统通道配置和每个应用程序通道配置的一部分为排序组织提供了控制哪些组织是联盟成员、如何将块传递到通道以及排序服务节点使用的共识机制。

提供联盟成员创建通道配置的能力。应用程序通道和ACLs是联盟组织用来在通道中添加或删除成员以及限制对通道上数据和智能合约的访问的机制。

如何在Fabric中编写策略

如果要更改Fabric中的任何内容,则与资源关联的策略将描述需要批准它的用户,可以是个人的显式签核,也可以是组的隐式签核。在保险领域,一个明确的签核可以是房屋所有人保险代理组的一个成员。而一个隐含的签署将类似于需要获得大多数业主保险集团管理层成员的批准。这特别有用,因为该组的成员可以随时间变化而不需要更新策略。在Hyperledger Fabric中,策略中的显式签出使用Signature语法表示,隐式签出使用ImplicitMeta语法。

签名策略

签名策略定义了必须签名才能满足策略的特定类型的用户,例如Org1.Peer OR Org2.Peer。这些策略被认为是最通用的,因为它们允许构建非常具体的规则,例如:“OrganA的一个管理员和其他2个管理员,或者6个组织管理员中的5个”。语法支持AND、OR和NOutOf的任意组合。例如,可以使用AND(Org1,Org2)轻松地表示策略,这意味着至少需要来自Org1中一个成员和Org2中一个成员的签名才能满足策略。

隐含元策略

ImplicitMeta仅在基于配置树中策略的分层层次结构的通道配置上下文中有效。ImplicitMeta策略将配置树中最终由签名策略定义的策略的结果聚合在一起。它们是Implicit,因为它们是基于通道配置中的当前组织隐式构造的,它们是Meta元的,因为它们的评估不是针对特定的MSP主体,而是针对配置树中它们下面的其他子策略。

下图说明了应用程序通道的分层策略结构,并显示了名为/channel/adminsImplicitMeta通道配置管理员策略是如何实现的,在满足配置层次结构中其下名为Admins的子策略时解析,其中每个复选标记表示子策略的条件已满足。

如上图所示,ImplicitMeta策略,Type=3,使用不同的语法,“<ANY | ALL | mostive><SubPolicyName>”,例如:

`MAJORITY sub policy: Admins`

图中显示了一个子策略Admins,它引用了配置树中它下面的所有Admins策略。您可以创建自己的子策略,并根据需要命名它们,然后在每个组织中定义它们。

像你提到的一个新的通道管理策略一样,你不必像上面提到的那样更新一个新的策略。因此,随着联盟成员的变化,ImplicitMeta策略被认为更加灵活。排序节点的联盟可以随着新成员的添加或现有成员的离开而更改,但不需要更新策略。回想一下ImplicitMeta策略最终在配置树中解析它们下面的签名子策略,如图所示。

您还可以定义一个应用程序级别的隐式策略,以跨组织(例如在一个通道中)操作,并要求满足其中任何一个、所有满足或大多数满足。这种格式有助于更好、更自然的默认设置,因此每个组织都可以决定有效背书的含义。

如果在组织定义中包含NodeOUs,则可以实现进一步的粒度和控制。组织单元(OU)在Fabric CA客户机配置文件中定义,并且可以在创建时与标识关联。在Fabric中,NodeOUs提供了一种在数字证书层次结构中对身份进行分类的方法。例如,启用了特定节点的组织可能需要“对等”签名才能成为有效的背书,而没有对等签名的组织可能只要求任何成员都可以签名。


例如:通道配置策略

了解策略首先要检查configtx.yaml定义通道策略的位置。我们可以使用configtx.yaml文件,以查看这两种策略语法类型的示例。我们要检查configtx.yaml Fabric-samples/test-network示例使用的文件。

文件的第一部分定义了网络的组织结构。每个组织定义中都有该组织的默认策略、读卡器编写器管理员和·背书·,尽管您可以根据需要为策略命名任何名称。每个策略都有一个描述策略如何表示的类型(签名隐式元数据)和一个规则

下面的测试网络示例显示了系统通道中的Org1组织定义,其中策略类型Signature,背书策略规则定义为“OR('Org1MSP.peer')". 此策略指定作为Org1MSP成员的对等方需要签名。正是这些签名策略成为隐式meta策略所指向的子策略。

使用签名策略定义的组织的示例

- &Org1
        # DefaultOrg defines the organization which is used in the sampleconfig
        # of the fabric.git development environment
        Name: Org1MSP

        # ID to load the MSP definition as
        ID: Org1MSP

        MSPDir: crypto-config/peerOrganizations/org1.example.com/msp

        # Policies defines the set of policies at this level of the config tree
        # For organization policies, their canonical path is usually
        #   /Channel/<Application|Orderer>/<OrgName>/<PolicyName>
        Policies:
            Readers:
                Type: Signature
                Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')"
            Writers:
                Type: Signature
                Rule: "OR('Org1MSP.admin', 'Org1MSP.client')"
            Admins:
                Type: Signature
                Rule: "OR('Org1MSP.admin')"
            Endorsement:
                Type: Signature
                Rule: "OR('Org1MSP.peer')"

下一个ImplicitMeta示例显示在configtx.yaml中. 这些策略集位于/Channel/Application/path上。如果使用默认的Fabric ACLs,这些策略将定义应用程序通道的许多重要功能的行为,例如谁可以查询通道账本、调用链码或更新通道配置。这些策略指向为每个组织定义的子策略。上面一节中定义的Org1包含ReaderWriterAdmin子策略,这些子策略由Application部分中的ReaderWriterAdmin ImplicitMeta策略评估。因为测试网络是用默认策略构建的,所以您可以使用示例Org1来查询通道账本、调用链码,并批准所创建的任何测试网络通道的通道更新。

################################################################################
#
#   SECTION: Application
#
#   - This section defines the values to encode into a config transaction or
#   genesis block for application related parameters
#
################################################################################
Application: &ApplicationDefaults

    # Organizations is the list of orgs which are defined as participants on
    # the application side of the network
    Organizations:

    # Policies defines the set of policies at this level of the config tree
    # For Application policies, their canonical path is
    #   /Channel/Application/<PolicyName>
    Policies:
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"
        LifecycleEndorsement:
            Type: ImplicitMeta
            Rule: "MAJORITY Endorsement"
        Endorsement:
            Type: ImplicitMeta
            Rule: "MAJORITY Endorsement"

Fabric链码生命周期

在Fabric 2.0版本中,引入了一个新的链码生命周期过程,从而使用更民主的过程来管理网络上的链码。新的流程允许多个组织在一个通道上使用链码之前对其操作方式进行投票。这一点很重要,因为正是这个新的生命周期过程和在此过程中指定的策略的组合,决定了整个网络的安全性。有关流的更多详细信息,请参阅Fabric链码生命周期概念主题,但出于本主题的目的,您应该了解如何在此流中使用策略。新流程包括两个步骤,其中指定策略:链码由组织成员批准时,以及链代码提交给通道时。

Application部分configtx.yaml文件包含默认的链码生命周期背书策略。在生产环境中,您可以为自己的用例定制这个定义。

  • 生命周期背书策略控制需要批准链代码定义的用户。
  • 背书策略是链码的默认背书策略。更多信息请参见下文。

链码背书策略

当使用Fabric链码生命周期(即,一个背书策略涵盖与链码关联的所有状态)批准并提交给通道时,为链码指定背书策略。可以通过引用在通道配置中定义的背书策略来指定背书策略,也可以通过显式指定签名策略来指定。

如果在批准步骤中未明确指定背书策略,使用默认背书策略“多数背书”,这意味着属于不同通道成员(组织)的大多数节点需要根据链码执行和验证交易,以便将交易视为有效。此默认策略允许加入通道的组织自动添加到链码背书策略中。如果不希望使用默认的背书策略,请使用签名策略格式指定更复杂的背书策略(例如要求链码由一个组织背书,然后由通道上的其他组织之一背书)。

签名策略还允许包含主体,这些主体只是将身份与角色匹配的一种方式。主体就像用户id或组id,但是它们更通用,因为它们可以包含参与者身份的广泛属性,例如参与者的组织、组织单元、角色甚至参与者的特定身份。当我们谈论主体时,它们是决定其权限的属性。主体被描述为’MSP.ROLE’,其中MSP表示所需的MSP ID(组织),ROLE表示四个可接受的角色之一:Member、Admin、Client和Peer。当用户向CA注册时,角色与标识相关联。您可以自定义结构CA上可用的角色列表。

有效主体的一些示例如下:

  • “Org0.Admin”:Org0 MSP的管理员
  • “Org1.Member”:Org1 MSP的成员
  • “Org1.Client”:Org1 MSP的客户端
  • “Org1.Peer”:Org1 MSP的节点
  • “OrdererOrg.Orderer”:OrderOrg MSP中的排序节点

在某些情况下,某个特定的状态(换句话说,一个特定的键值对)可能需要有一个不同的背书策略。这种基于状态的背书允许默认的链码级背书策略被指定密钥的不同策略覆盖。

如需更深入地了解如何编写背书策略,请参阅《运营指南》中有关背书策略的主题。

注意:策略的工作方式因使用的Fabric版本而异:

  • 在2.0之前的Fabric版本中,可以在链码实例化期间或通过使用链码生命周期命令来更新链码背书策略。如果在实例化时未指定,则背书策略默认为“通道中组织的任何成员”。例如,带有“Org1”和“Org2”的通道将具有默认的背书策略“OR(‘Org1.member’,‘Org2.member’)”。
  • 从Fabric 2.0开始,Fabric引入了一个新的链码生命周期过程,允许多个组织在链码可用于通道之前就如何操作达成一致。新流程要求组织同意定义链码的参数,例如名称、版本和链码背书策略。

重写策略定义

Hyperledger Fabric包含默认策略,这些策略对于开始、开发和测试区块链非常有用,但它们是在生产环境中定制的。您应该知道configtx.yaml文件。通道配置策略可以使用任意动词扩展,而不是configtx.yaml中的默认Readers, Writers, Admins。 当您通过编辑configtx.yaml排序系统通道或configtx.yaml对于特定的通道。

有关详细信息,请参阅有关更新通道配置的主题。


节点

区块链网络主要由一组节点组成。节点是网络的基本元素,因为它们拥有账本和智能合约。在以后的智能账本中,所有不可变的交易都包含在智能账本中。智能合约和账本分别用于将共享过程和共享信息封装在网络中。节点的这些方面使它们成为了解Fabric网络的良好起点。

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

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

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


关于术语的一个词

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


账本和链码

让我们更详细地看一个节点。我们可以看到,它同时承载着账本和链码。更准确地说,节点实际上托管了账本实例和链码实例。请注意,这在Fabric网络中提供了一个有意的冗余-它避免了单点故障。我们将在本节后面了解更多关于区块链网络的分布式和分散性质。

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

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

多账本

一个节点可以托管多个账本,这很有帮助,因为它允许灵活的系统设计。最简单的配置是由一个节点管理一个账本,但在需要时,它绝对适合一个节点托管两个或多个账本。

托管多个账本的节点。节点拥有一个或多个账本,每个账本都有零个或多个适用于它们的链码。在这个例子中,我们可以看到节点P1托管ledger L1和L2。使用链码S1访问账本L1。另一方面,可以使用链码S1和S2访问Ledger L2。

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

多链码

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

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

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

应用程序和节点

我们现在将展示应用程序如何与节点交互以访问账本。账本查询交互涉及应用程序和节点之间的简单三步对话;账本更新交互涉及的内容稍微多一些,需要额外的两个步骤。我们对这些步骤进行了一些简化,以帮助您开始使用Fabric,但不要担心-最重要的是要了解与账本更新交易样式相比,用于账本查询的应用程序与节点交互的差异。

当应用程序需要访问帐本和链码时,它们总是连接到节点。Fabric Software Development Kit(SDK)为程序员提供了方便—其API使应用程序能够连接到节点,调用链码来生成交易,向网络提交交易,这些交易将被排序、验证并提交到分布式账本,并在该过程完成时接收事件。

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

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

节点可以立即将查询结果返回给应用程序,因为满足查询要求的所有信息都在节点的本地账本副本中。节点从不与其他节点协商以响应来自应用程序的查询。然而,应用程序可以连接到一个或多个节点来发出查询;例如,在多个节点之间确认一个结果,或者在怀疑信息可能过期的情况下从另一个节点检索更为更新的结果。在图中,您可以看到账本查询是一个简单的三步过程。

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

在本节的后面部分,您将进一步了解这个排序过程的详细性质,要了解这个过程的详细信息,请参阅交易流主题。


节点和通道

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

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

通道允许一组特定的节点和应用程序在区块链网络中彼此通信。在本例中,应用程序A可以使用通道C直接与节点P1和P2通信。您可以将通道视为特定应用程序和节点之间通信的路径。(为简单起见,此图中未显示排序节点,但必须存在于正常工作的网络中。)

我们发现,通道的存在方式与节点不同,更恰当的做法是将通道视为一个由物理节点集合构成的逻辑结构。理解这一点是至关重要的-节点提供了对通道的访问和管理的控制点。


节点和组织

现在,您了解了节点及账本、链码和通道的关系,您将能够看到多个组织如何聚集在一起形成区块链网络。

区块链网络由多个组织而不是单个组织管理。节点是构建这种分布式网络的核心,因为它们属于这些组织,并且是这些组织的网络连接点。

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

你能看到区块链网络的形成过程中发生了什么,这一点非常重要。该网络由多个组织组成和管理,这些组织向网络提供资源。同行是我们在本主题中讨论的资源,但组织提供的资源不仅仅是同行。这里有一个原则——没有组织向集体网络贡献个人资源,网络就不存在。此外,网络随着这些协作组织提供的资源而增长和收缩。

您可以看到(除了排序服务)没有集中的资源-在上面的示例中,如果组织没有贡献其节点,网络N就不存在。这反映了这样一个事实,即除非并直到组织贡献了构成网络的资源,否则网络就不存在任何有意义的意义。此外,这个网络并不依赖于任何一个组织,只要一个组织存在,它就会继续存在,而不管其他组织有没有来去。这是网络去中心化的核心。

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

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

节点和身份

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

节点通过来自特定证书颁发机构的数字证书向其分配身份。在本指南的其他地方,您可以阅读更多关于X.509数字证书如何工作的信息,但是现在,请将数字证书看作是一张身份证,它提供了关于节点的大量可验证信息。网络中的每个节点都由其所属组织的管理员分配一个数字证书。

当节点连接到通道时,其数字证书通过通道MSP标识其所属组织。在本例中,P1和P2具有由CA1发出的标识。通道C根据其通道配置中的策略确定来自CA1的标识应使用Org1.MSP与Org1关联。类似地,P3和P4被ORG2.MSP标识为ORG2的一部分。

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

暂时离题一下,节点以及与区块链网络交互的所有事物都从他们的数字证书和MSP中获得组织身份。节点、应用程序、最终用户、管理员和排序节点如果要与区块链网络交互,必须具有身份和关联的MSP。我们给每个使用身份(主体)与区块链网络交互的实体命名。您可以在本指南的其他地方了解更多有关主要角色和组织的信息,但现在您知道的足够多了,可以继续了解节点!

最后,请注意节点实际位于何处并不重要—它可以位于云中,或者位于某个组织拥有的数据中心中,或者位于本地计算机上—与之相关的数字证书将其标识为属于某个特定组织。在上面的例子中,P3可以托管在Org1的数据中心,但只要与之相关的数字证书是由CA2颁发的,那么它就归Org2所有。

普通节点和排序节点

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

更新交易与查询交易大不相同,因为单个节点不能单独更新账本-更新需要网络中其他节点的同意。节点需要网络中的其他节点批准账本更新,然后才能将其应用于节点的本地账本。这个过程称为共识,它比简单的查询花费更长的时间来完成。但是,当所有需要批准该交易的节点都这样做了,并且该交易被提交到账本中时,节点将通知其连接的应用程序该账本已被更新。在本节中,我们将向您展示有关普通节点和排序节点如何管理共识过程的更多详细信息。

具体来说,想要更新账本的应用程序需要分为三个阶段,这确保区块链网络中的所有节点保持各自账本的一致性。

  • 在第一阶段中,应用程序与背书节点的子集一起工作,每个节点都向应用程序提供对提案的账本更新的背书,但不将提案的更新应用于其账本副本。
  • 在第二阶段,这些单独的背书作为交易收集在一起并打包成块。
  • 在第三个也是最后一个阶段,这些数据块被分发回每个节点,在每个节点的账本副本提交之前,每个交易都经过验证。

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

第一阶段:提案

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

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

交易提案由返回背书提案响应的节点独立执行。在本例中,应用程序A1生成交易T1提案P,并将其发送到通道C上的节点P1和节点P2。P1使用交易T1提案P执行S1,生成交易T1响应R1,交易T1响应R1与E1一起背书。P2独立地使用交易T1提案P执行S1,生成交易T1响应R2,并与E2一起背书。应用程序A1接收交易T1的两个背书响应,即E1和E2。

最初,应用程序选择一组节点来生成一组提案的账本更新。应用程序选择哪些节点?好吧,这取决于背书策略(为链码定义),它定义了一组组织,这些组织需要在提案的账本更改被网络接受之前对其进行背书。这实际上就是达成共识的意思——每个重要的组织都必须在提案的账本更改被接受到任何节点的账本之前对其进行背书。

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

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

在第1阶段结束时,如果应用程序愿意,可以随意丢弃不一致的交易响应,从而有效地提前终止交易工作流。稍后我们将看到,如果应用程序试图使用一组不一致的交易响应来更新账本,它将被拒绝。

第二阶段:排序并将交易打包成块

交易工作流的第二个阶段是打包阶段。排序节点是这个过程的关键——它从许多应用程序接收包含背书的交易提案响应的交易,并将交易排序成块。有关排序和包装阶段的更多详细信息,请查看我们关于排序阶段的概念性信息

阶段3:验证和提交

在第2阶段的末尾,我们看到排序节点负责收集提案的交易更新、对它们进行排序、将它们打包成块、准备分发给节点的简单而重要的过程。

交易工作流的最后一个阶段涉及从排序节点到普通节点的数据块的分发和后续验证,在那里它们可以提交到账本。具体地说,在每个节点,一个区块内的每一笔交易都经过验证,以确保它在提交到账本之前得到所有相关组织的一致背书。失败的交易记录将保留以供审核,但不会提交到账本中。

排序节点的第二个作用是将块分发给节点。在本例中,排序节点O1将块B2分发到节点P1和节点P2。节点P1处理块B2,导致一个新块被添加到P1上的账本L1。并行地,节点P2处理块B2,导致一个新块被添加到P2上的账本L1。一旦这个过程完成,账本L1在节点P1和P2上被一致地更新,并且每一个都可以通知连接的应用程序交易已经被处理。

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

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

如果交易已正确背书,节点将尝试将其应用于账本。为此,节点必须执行账本一致性检查,以验证该账本的当前状态是否与生成提案的更新时的账本状态兼容。即使交易已完全背书,这也并非总是可能的。例如,另一个交易可能更新了账本中的同一资产,因此交易更新不再有效,因此无法再应用。通过这种方式,账本在通道中的每个节点之间保持一致,因为它们都遵循相同的验证规则。

在节点成功验证每个单独的交易后,它更新账本。失败的交易不会应用于账本,但它们会被保留以供审计之用,成功的交易也是如此。这意味着节点块与从排序者接收的块几乎完全相同,除了块中每个交易上的有效或无效指示符。

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

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

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


排序节点与共识

整个交易工作流过程被称为共识,因为在一个由排序节点调解的过程中,所有普通节点都已就交易的顺序和内容达成一致。共识是一个多步骤的过程,只有当过程完成时,应用程序才会收到账本更新的通知-这可能发生在不同普通节点上的时间稍有不同。

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

就这样!我们现在已经完成了我们的普通节点和其他组件,他们在Fabric。我们已经看到,普通节点在许多方面都是最基本的元素——它们构成网络,承载链码和账本,处理交易提案和响应,并通过不断地对账本应用交易更新来保持账本的最新状态。


账本

受众:架构师、应用程序和智能合约开发人员、管理员

账本是Hyperledger Fabric中的一个关键概念;它存储有关业务对象的重要事实信息;对象属性的当前值以及导致这些当前值的交易的历史记录。


什么是账本?

账本将企业的当前状态作为交易日记帐。最早的欧洲和中国的账本可以追溯到1000年前,苏美尔人在4000年前就有了石质账本——但是让我们从一个更为更新的例子开始吧!

你可能习惯了看你的银行账户。对你来说最重要的是可用的余额——它是你在当前时刻能够花掉的。如果你想知道你的余额是如何产生的,那么你可以查看决定它的交易贷记和借记。这是账本的一个真实例子——一个状态(你的银行余额)和一组确定它的有序交易(贷记和借记)。Hyperledger Fabric的动机是这两个相同的关注点:呈现一组账本状态的当前值,以及捕获决定这些状态的交易的历史记录。


账本、事实和状态

账本并不真正存储业务对象,而是存储有关这些对象的事实。当我们说“我们在账本中存储业务对象”时,我们真正的意思是我们记录了对象当前状态的事实,以及导致当前状态的交易历史的事实。在一个日益数字化的世界里,我们会感觉到我们在看一个物体,而不是一个物体的事实。在数字对象的情况下,它很可能存在于外部数据存储中;我们存储在账本中的事实允许我们识别它的位置以及有关它的其他关键信息。

虽然有关业务对象当前状态的事实可能会发生变化,但有关它的事实的历史是不变的,可以添加到,但不能追溯更改。我们将看到,将区块链视为关于业务对象的不可改变的事实的历史,是理解它的一种简单而有力的方法。

现在让我们更仔细地看一下超级账本的结构!


账本

在Hyperledger Fabric中,账本由两个不同但又相关的部分组成——世界状态和区块链。每一个都代表一组业务对象的事实。

首先,有一个世界状态-一个数据库,保存一组账本状态的当前值。世界状态使程序可以很容易地直接访问状态的当前值,而不必通过遍历整个交易日志来计算它。默认情况下,账本状态表示为键值对,稍后我们将看到Hyperledger Fabric如何在这方面提供灵活性。世界状态可以频繁更改,因为可以创建、更新和删除状态。

其次,还有一个区块链——是记录导致当前世界状态的所有变化的交易日志。交易被收集在区块中,这些区块被附加到区块链中,使您能够了解导致当前世界状态的变化历史。区块链数据结构与世界状态非常不同,因为一旦写入,就无法修改;它是不可变的。

账本L包括区块链B和世界状态W,其中区块链B决定世界状态W。我们也可以说世界状态W来自区块链B。

设想在一个Hyperledger Fabric网络中有一个逻辑账本是很有帮助的。事实上,网络维护一个账本的多个副本,这些副本通过一个称为共识的过程与其他副本保持一致。术语分布式账本技术DLT通常与此类账本相关,这种账本在逻辑上是单一的,但在整个网络中有许多一致的副本。

现在让我们更详细地研究一下世界状态和区块链数据结构。


世界状态

世界状态将业务对象属性的当前值保存为唯一的账本状态。这很有用,因为程序通常需要一个对象的当前值;遍历整个区块链来计算对象的当前值是很麻烦的-您只需直接从世界状态中获取。

包含两个状态的账本世界状态。第一个状态是:key=CAR1,value=Audi。第二个状态有一个更复杂的值:key=CAR2和value={车型:宝马,color=red,owner=Jane}。两个状态都是版本0。

账本状态记录有关特定业务对象的一组事实。我们的示例显示了两辆车的账本状态,CAR1和CAR2,每辆车都有一个键和一个值。应用程序可以调用智能合约,该合约使用简单的账本API来获取、放置和删除状态。注意状态值可以是简单的(Audi…)或复合的(车型:宝马…). 世界状态经常被查询以检索具有特定属性的对象,例如查找所有红色宝马。

世界状态被实现为一个数据库。这很有意义,因为数据库为状态的有效存储和检索提供了一组丰富的运算符。稍后我们将看到,可以将Hyperledger Fabric配置为使用不同的世界状态数据库,以满足应用程序所需的不同类型的状态值和访问模式的需要,例如在复杂的查询中。

应用程序提交捕捉世界状态变化的交易,这些交易最终被提交到账本区块链。Hyperledger Fabric SDK将应用程序与这种共识机制的细节隔离开来;它们只是调用智能合约,并在交易被包括在区块链中时(无论是有效还是无效)收到通知。设计的关键点是,只有由所需的一组背书组织签署的交易才会导致对世界状态的更新。如果一项交易没有足够的背书人签署,它不会导致世界状态的改变。您可以阅读有关应用程序如何使用智能合约以及如何开发应用程序的更多信息。

您还将注意到一个状态有一个版本号,在上图中,状态CAR1和CAR2位于它们的起始版本0。版本号供Hyperledger Fabric内部使用,每次状态更改时都会递增。每当更新状态时都会检查版本,以确保当前状态与签署时的版本匹配。这可以确保世界状态按预期发生变化;确保没有并发更新。

最后,当第一次创建账本时,世界状态为空。因为任何代表世界状态有效变化的交易都记录在区块链上,这意味着世界状态可以随时从区块链中重新生成。这可能非常方便——例如,创建普通节点时,会自动生成世界状态。此外,如果普通节点异常失败,则在接受交易之前,可以在节点重新启动时重新生成世界状态。


区块链

现在让我们把注意力从世界状态转向区块链。世界状态包含一组与一组业务对象的当前状态相关的事实,而区块链则是这些对象如何达到其当前状态的历史记录。区块链已经记录了每个账本状态的所有以前版本及其更改方式。

区块链结构为互连区块的顺序日志,其中每个区块包含一系列交易,每个交易代表对世界状态的查询或更新。对交易进行排序的确切机制在其他地方讨论过;重要的是块排序以及块内的交易排序是在块首次由称为排序服务的Hyperledger Fabric组件创建时建立的。

每个块的头包括块交易的哈希,以及前一个块头的哈希。这样,账本上的所有交易都按顺序排列并以密码方式链接在一起。这种哈希和链接使账本数据非常安全。即使托管账本的一个节点被篡改,它也无法说服所有其他节点它拥有“正确的”区块链,因为账本分布在一个独立节点的网络中。

区块链总是以文件的形式实现,与使用数据库的世界状态不同。这是一个明智的设计选择,因为区块链数据结构严重偏向于非常小的一组简单操作。附加到区块链的末尾是主要的操作,而查询目前是一个相对较少的操作。

让我们更详细地看看区块链的结构。

包含块B0、B1、B2、B3的区块链B。B0是区块链中的第一个区块,创世区块。

在上图中,我们可以看到B2有一个块数据D2,它包含它的所有交易:T5、T6、T7。

最重要的是,B2有一个块头H2,它包含D2中所有交易的加密哈希以及H1的哈希。通过这种方式,区块之间是不可分割和不可改变的联系在一起的,区块链这一术语如此巧妙地抓住了这一点!

最后,如图所示,区块链中的第一个区块被称为创世区块。它是账本的起点,尽管它不包含任何用户交易。相反,它包含一个配置交易,其中包含网络通道的初始状态(未显示)。当我们在文档中讨论区块链网络和通道时,我们将更详细地讨论创世区块。


区块

让我们仔细看看一个块的结构。它由三部分组成

  • 块头
    本节包含三个字段,在创建块时写入。
    区块编号:从0开始的整数(创世区块),每增加一个区块链,就增加1。
    当前块哈希:当前块中包含的所有交易的哈希。
    上一个块头哈希:上一个块头的哈希。
    这些字段是通过加密散列块数据在内部派生的。它们确保每个区块都与相邻区块有着千丝万缕的联系,从而形成一个不可变的账本。

块头详细信息。块B2的块头H2由块号2、当前块数据D2的哈希CH2和前一块报头H1的哈希组成。

  • 区块数据
    本节包含按顺序排列的交易列表。它是在排序服务创建块时写入的。这些交易有一个丰富而直接的结构,我们将在本主题的后面描述这些结构。

  • 区块元数据
    本节包含区块创建者的证书和签名,用于被网络节点验证区块,区块确认节点将每个交易的有效/无效指示符添加到位图中,该位图也位于区块元数据中,以及直到并包括该块的累积状态更新的哈希,以便检测状态分叉。与区块头和区块数据不同,此部分不是区块哈希计算的输入。

交易

正如我们所看到的,交易捕捉世界状态的变化。让我们看看包含块中交易的详细区块数据结构。

交易明细。块B1的区块数据 D1中的交易T4由交易头H4、交易签名S4、交易提案P4、交易响应R4和背书列表E4组成。
在上面的示例中,我们可以看到以下字段:

  • 交易头部
    这一部分以H4为例,捕获了有关交易的一些基本元数据,例如,相关链码的名称及其版本。
  • 签名
    此部分由S4说明,包含由客户端应用程序创建的加密签名。此字段用于检查交易详细信息是否未被篡改,因为它需要应用程序的私钥来生成它。
  • 提案
    该字段由P4说明,它对应用程序提供的输入参数进行编码,智能合约创建提案的账本更新。当智能合约运行时,此提案提供一组输入参数,这些参数与当前世界状态相结合,确定新的世界状态。
  • 响应
    这一部分,以R4为例,将世界状态的前后值作为读写集(RW set)来捕获。它是智能合约的输出,如果交易成功验证,它将应用于账本以更新世界状态。
  • 背书
    如E4所示,这是来自每个必需组织的签名交易响应的列表,这些响应足以满足背书策略。您会注意到,虽然交易中只包含一个交易响应,但是有多个背书。这是因为每个背书都有效地编码了其组织的特定交易响应,这意味着不需要包括任何与充分背书不匹配的交易响应,因为它将被视为无效而被拒绝,并且不会更新世界状态。

这就结束了交易的主要字段-还有其他字段,但这些是您需要了解的基本字段,以便对账本数据结构有一个坚实的理解。


世界状态数据库选项

世界状态在物理上被实现为一个数据库,以提供简单高效的账本状态存储和检索。正如我们所看到的,账本状态可以有简单值或复合值,为了适应这种情况,世界状态数据库的实现可以有所不同,从而可以有效地实现这些值。世界状态数据库的选项目前包括LevelDB和CouchDB。

LevelDB是默认值,当账本状态是简单的键值对时尤其适用。Level DB数据库与普通节点位于同一位置-它嵌入在同一操作系统进程中。

当账本状态被结构化为JSON文档时,CouchDB是一个特别合适的选择,因为CouchDB支持业务交易中经常出现的丰富查询和更丰富数据类型的更新。在实现方面,CouchDB运行在单独的操作系统进程中,但是普通节点和CouchDB实例之间仍然存在1:1的关系。所有这些对于智能合约来说是看不见的。有关CouchDB的更多信息,请参阅CouchDB作为状态数据库

在LevelDB和CouchDB中,我们看到了Hyperledger Fabric的一个重要方面——它是可插拔的。世界状态数据库可以是关系数据存储、图形存储或时态数据库。这在可以有效访问的账本状态类型中提供了极大的灵活性,允许Hyperledger Fabric解决许多不同类型的问题。


账本示例:fabcar

当我们在账本上结束这个主题时,让我们看看一个示例账本。如果您运行了fabcar示例应用程序,那么您已经创建了这个账本。

fabcar示例应用程序创建了一组10辆车,每辆车都有一个独特的身份;不同的颜色、品牌、型号和车主。以下是前四辆车被制造出来后的账本。

账本L由一个世界状态W和一个区块链组成,B.W包含四个带关键字的状态:CAR0、CAR1、CAR2和CAR3。B包含两个块,0和1。块1包含四个交易:T1、T2、T3、T4。

我们可以看到,世界状态包含对应于CAR0、CAR1、CAR2和CAR3的状态。CAR0有一个值表明它是一辆蓝色的丰田普锐斯,目前为Tomoko所有,我们可以看到其他车的类似状态和价值。此外,我们可以看到,所有的汽车状态都是版本号0,这表明这是他们的起始版本号-它们自创建以来就没有更新过。

我们还可以看到,区块链包含两个区块。Block 0是genesis块,尽管它不包含任何与汽车相关的交易。然而,块1包含交易T1、T2、T3、T4,这些交易对应于在世界状态下为CAR0到CAR3创建初始状态的交易。我们可以看到块1链接到块0。

我们没有显示块或交易中的其他字段,特别是块头和哈希。如果你对这些主题的细节感兴趣的话,可以在其他地方找到。它为您提供了一个完整工作的示例,其中包含详细的交易处理,但目前,您已经对Hyperledger Fabric账本有了坚实的概念性理解。做得好!


名称空间

尽管我们把账本当作一个单一的世界状态和一个区块链,但这有点过于简单化了。实际上,每个链码都有自己的世界状态,它与所有其他链码分开。世界状态在一个命名空间中,因此只有同一链码中的智能合约才能访问给定的命名空间。

区块链没有名称空间。它包含来自许多不同智能合约命名空间的交易。您可以在本主题中阅读有关链码命名空间的更多信息。

现在让我们看看命名空间的概念是如何在Hyperledger Fabric通道中应用的。


通道

在Hyperledger Fabric中,每个通道都有一个完全独立的账本。这意味着一个完全独立的区块链,以及完全独立的世界状态,包括名称空间。应用程序和智能合约可以在通道之间进行通信,以便可以在它们之间访问账本信息。

您可以在本主题中阅读有关账本如何与通道一起工作的更多信息。


更多信息

有关交易流、并发控制和世界状态数据库的深入研究,请参阅世界状态主题中的交易流读写集语义CouchDB


排序服务

受众:架构师、排序服务管理员、通道创建者

本主题从概念上介绍了排序的概念、排序节点如何与普通交互、它们在交易流中所扮演的角色,以及当前可用的排序服务实现的概述,特别侧重于推荐的Raft排序服务实现。

什么是排序?

许多分布式区块链,如以太坊和比特币,都是不允许的,这意味着任何节点都可以参与共识过程,在协商过程中,交易被排序并捆绑成块。由于这一事实,这些系统依赖于概率共识算法,这些算法最终在很大程度上保证了账本的一致性,但仍然容易受到不同账本(也称为账本“分叉”)的影响,网络中不同的参与者对接受的交易顺序有不同的看法。

Hyperledger Fabric的工作原理不同。它的特点是一个名为排序的节点(也称为“ordering node”),它执行此交易排序,与其他排序节点一起形成一个排序服务。因为Fabric的设计依赖于确定性的共识算法,所以任何由普通节点验证的块都是最终的和正确的。账本无法在其他许多分布式和无权限区块链网络中分道扬镳。

除了提高最终性之外,将链码执行(发生在普通节点上)的背书与排序分离,使Fabric在性能和可伸缩性方面具有优势,消除了在执行和排序由同一节点执行时可能出现的瓶颈。


排序节点和通道配置

除了排序角色外,排序节点还维护允许创建通道的组织的列表。这个组织的列表称为“联盟”,列表本身保存在“排序节点系统通道”(也称为“排序系统通道”)的配置中。默认情况下,此列表及其所在的通道只能由排序节点管理员编辑。请注意,排序服务有可能保存这些列表中的几个,这使得联盟成为Fabric多租户的载体。

排序节点可以对基本通道进行配置,谁也可以控制他们的读权限。请记住,谁有权修改通道中的配置元素,必须遵守相关管理员在创建联盟或通道时设置的策略。配置交易由排序节点处理,因为它需要知道当前的一组策略来执行其基本的访问控制形式。在这种情况下,排序节点处理配置更新,以确保请求者具有适当的管理权限。如果是这样的话,排序程序将根据现有配置验证更新请求,生成一个新的配置交易,并将其打包到一个块中,该块将转发给通道上的所有普通节点。普通节点随后处理配置交易,以验证由排序节点批准的修改确实满足在通道中定义的策略。


排序节点和身份

与区块链网络交互的所有事物,包括节点、应用程序、管理员和排序节点,都从其数字证书和成员服务提供商(MSP)定义中获取其组织身份。

有关身份和MSPs的更多信息,请查看我们关于身份成员资格的文档。

与普通节点一样,排序节点属于一个组织。与普通节点类似,每个组织都应该使用单独的证书颁发机构(CA)。此CA是否将作为根CA运行,或者您是否选择部署根CA,然后部署与该根CA关联的中间CA,这取决于您。


排序节点和交易流

第一阶段:交易流

我们从节点的话题中看到,它们构成了区块链网络的基础,托管账本,应用程序可以通过智能合约查询和更新账本。

具体来说,想要更新账本的应用程序涉及一个分为三个阶段的过程,以确保区块链网络中的所有普通节点保持各自账本的一致性。

在第一阶段,普通节点应用程序向普通节点的子集发送一个交易提案,这些普通节点将调用智能合约来生成提案的账本更新,然后对结果进行背书。背书人目前不将提议的更新应用于他们的账本副本。相反,背书节点会向节点应用程序返回一个提案响应。在第二阶段,被背书的交易提案最终将被排序成块,然后在第三阶段分发给所有普通节点进行最终验证和提交。

要深入了解第一阶段,请参阅“节点”主题。

第二阶段:对交易进行排序并打包成块

在交易的第一阶段完成后,客户端应用程序已从一组节点接收到一个背书的交易提案响应。现在是交易第二阶段的时候了。

在这个阶段,应用程序客户端向排序服务节点提交包含背书的交易提案响应的交易。排序服务创建交易块,这些交易块最终将分发到通道上的所有节点,以便在第三阶段进行最终验证和提交。

排序服务节点同时从多个不同的应用程序客户端接收交易。这些排序服务节点共同组成排序服务。它的工作是将一批批提交的交易排列成一个定义良好的序列,并将它们打包成块。这些区块将成为区块链的区块!

块中的交易数取决于与块所需大小和最大持续时间相关的通道配置参数(确切地说,BatchSizeBatchTimeout参数)。然后,这些块被保存到排序节点的账本中,并分发给加入通道的所有节点。如果一个节点此时恰好停机,或稍后加入信道,它将在重新连接到排序服务节点后,或通过与另一个普通节点gossiping来接收块。我们将在第三阶段看到节点如何处理这个块。

排序节点的第一个角色是打包提案的账本更新。在本例中,应用程序A1向排序节点O1发送由E1和E2背书的交易T1。同时,应用程序A2向排序节点O1发送由E1背书的交易T2。O1将来自应用A1的交易T1和来自应用A2的交易T2与来自网络中其他应用的其他交易打包到块B2中。我们可以看到,在B2中,交易顺序是T1、T2、T3、T4、T6、T5,这可能不是这些交易到达排序节点的顺序!(此示例显示了一个非常简化的排序服务配置,其中只有一个排序节点。)

值得注意的是,一个块中交易的排序不一定与排序服务接收的顺序相同,因为可能有多个排序服务节点几乎同时接收交易。重要的是,排序服务将交易按严格的顺序排列,普通节点在验证和提交交易时将使用此顺序。

这种对区块内交易的严格排序使得Hyperledger Fabric与其他区块链稍有不同,在其他区块链中,相同的交易可以打包成多个不同的区块,竞争形成一个链。在Hyperledger Fabric中,由排序服务生成的块是最终的。一旦一笔交易被写入一个区块,它在账本中的位置就不会改变。如前所述,Hyperledger Fabric的最终性意味着没有账本分叉——验证的交易永远不会被恢复或删除。

我们还可以看到,虽然普通节点执行智能合约和处理交易,但排序节点绝不会。到达排序节点的每个授权交易都被机械地打包在一个块中—排序节点对交易的内容没有任何判断(通道配置交易除外,如前所述)。

在第二阶段结束时,我们看到排序节点负责收集提案的交易更新、对它们进行排序并将它们打包成块以备分发的简单而重要的过程。

第三阶段:验证和提交

交易工作流的第三个阶段涉及从排序节点到普通节点的数据块的分发和后续验证,在这些数据块可以提交到账本中。

第3阶段从排序节点将块分发到所有连接到它的普通节点开始。同样值得注意的是,并不是每一个普通节点都需要连接到一个排序节点—普通节点可以使用gossip协议将块级联到其他对等点。

每个普通节点将独立地验证分布式块,但以确定的方式,确保账本保持一致。具体地说,通道中的每个普通节点将验证块中的每个交易,以确保它已被所需组织的节点背书,这就是背书匹配,并且它不会被其他最近提交的交易失效,这些交易可能在交易最初被背书时正在运行。无效的交易仍保留在由排序者创建的不可变块中,但它们被普通节点标记为无效,并且不会更新账本的状态。

排序节点的第二个作用是将块分发给普通节点。在本例中,排序节点O1将块B2分发到普通节点P1和普通节点P2。普通节点P1处理块B2,导致一个新块被添加到P1上的账本L1。并行地,普通节点P2处理块B2,导致一个新块被添加到P2上的账本L1。一旦这个过程完成,账本L1在普通节点P1和P2上被一致地更新,并且每一个都可以通知连接的应用程序交易已经被处理。

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

如需更深入地了解第3阶段,请参阅“节点”主题。

排序服务实现

尽管目前可用的每个订购服务都以相同的方式处理交易和配置更新,但是在订购服务节点之间的交易的严格排序上,仍然存在几种不同的实现方式。

有关如何建立一个ordering节点的信息(不管该节点将用于什么实现),请查看我们关于建立ordering节点的文档。

  • Raft(推荐)
    Raft是v1.4.1的新版本,它是一种基于Raft协议etcd中实现的故障容错(CFT)排序服务。Raft遵循一个“leader-and-follower”模型,其中一个leader节点被选出来(每个通道),它的决策被跟随者复制。Raft排序服务应该比基于Kafka的排序服务更容易设置和管理,并且它们的设计允许不同的组织向分布式排序服务贡献节点。
  • kafka(在v2.0中已弃用)
    与基于Raft的排序类似,Apache kafka是一个CFT实现,它使用“leader and follower”节点配置。kafka利用一个ZooKeeper组合来进行管理。基于Kafka的排序服务从Fabric v1.0开始就可以使用了,但是许多用户可能会发现管理Kafka集群的额外管理开销令人望而生畏或不受欢迎。
  • Solo(在v2.0中已弃用)
    排序服务的单独实现仅用于测试,并且仅由单个排序节点组成。它已被弃用,可能会在将来的版本中完全删除。Solo现有用户应转移到单节点筏网中,以实现等效功能。

Raft

有关如何配置Raf排序服务的信息,请参阅我们关于配置Raft排序服务的文档。

在生产网络的排序服务选择中,所建立的Raft协议的结构实现使用了一个“leader-and-follower”模型,其中在通道中的排序节点中动态地选择一个领导者(这个节点集合被称为“consencer set”),这个领导者将消息复制到跟随者节点。因为系统可以承受节点(包括主节点)的丢失,只要还有大部分的排序节点(即所谓的“仲裁”)剩余,Raft被称为“crash fault-tolerance”(CFT)。换句话说,如果一个通道中有三个节点,那么它可以承受一个节点的损失(剩下两个节点)。如果通道中有五个节点,则可能会丢失两个节点(剩下三个节点)。

从他们提供给网络或通道的服务的角度来看,Raft和现有的基于Kafka的排序服务(我们将在后面讨论)是相似的。它们都是CFT排序服务,使用的是leader和follower设计。如果您是应用程序开发人员、智能合约开发人员或节点管理员,您不会注意到基于Raft的排序服务与基于Kafka的排序服务之间的功能差异。但是,有几个主要差异值得考虑,特别是如果您打算管理排序服务:

  • Raft容易搭设。尽管kafka有很多崇拜者,但即使是那些崇拜者也会(通常)承认,部署一个kafka集群及其ZooKeeper组合可能会很棘手,需要在kafka基础设施和设置方面拥有高水平的专业知识。此外,与Raft相比,使用Kafka要管理的组件要多得多,这意味着有更多的地方会出错。kafka也有自己的版本,必须与排序节点协调。有了Raft,所有的东西都嵌入到您的排序节点中
  • kafka和Zookeeper并不是为了在大型网络上运行而设计的。虽然Kafka是CFT,但它应该在一个紧密的主机组中运行。这意味着实际上,您需要一个组织运行Kafka集群。考虑到这一点,在使用Kafka(Fabric支持的)时,让不同的组织运行排序节点并不能给您带来太多的去中心化,因为这些节点都将进入同一个Kafka集群,该集群由一个组织控制。通过Raft,每个组织都可以有自己的排序节点,参与排序服务,从而形成一个更加去中心化的系统。
  • Raft是本地支持的,这意味着用户需要获得所需的镜像,并学习如何使用Kafka和ZooKeeper。同样,对Kafka相关问题的支持是通过Apache处理的,Apache是Kafka的开源开发人员,而不是Hyperledger Fabric。另一方面,Fabric Raft实现已经开发,并将在Fabric开发人员社区及其支持设备中得到支持。
  • Kafka使用一个服务器池(称为“Kafka brokers”),排序节点组织的管理员指定他们希望在特定通道上使用多少节点,Raft允许用户指定将哪些排序节点部署到哪个通道。通过这种方式,普通节点组织可以确保,如果他们也拥有一个排序节点,那么这个节点将成为该通道的排序服务的一部分,而不是信任和依赖一个中央管理员来管理Kafka节点。
  • Raft是Fabric开发拜占庭容错(BFT)排序服务的第一步。正如我们将看到的,在Raft开发中的一些决策就是由这个驱动的。如果你对BFT感兴趣的话,学习如何使用Raft应该能让你轻松过渡。

由于所有这些原因,Fabric v2.0中不推荐使用基于Kafka的排序服务的支持。

注:与Solo和Kafka类似,Raft排序服务在向客户发送回执后可能会丢失交易。例如,如果领导者在跟随者提供接收确认的同时崩溃。因此,应用程序客户机应该在普通节点上监听交易提交事件(检查交易有效性),但是应该格外小心,以确保客户机也能正常地容忍在配置的时间范围内交易没有被提交的超时。根据应用程序的不同,可能需要在超时后重新提交交易或收集新的背书集。

Raft概念

虽然Raft提供了许多与Kafka相同的特性(尽管是在一个更简单、更易于使用的包中),但它在功能上与Kafka有着本质上的不同,并在Fabric中引入了许多新概念或对现有概念的扭曲。

日志条目。Raft排序服务的主要工作单位是“日志条目”,这种条目的完整序列称为“日志”。如果大多数成员(换句话说,是法定人数)就条目及其顺序达成一致,从而使各个排序节点上的日志被复制,那么我们认为日志是一致的。

参与者集。主动参与给定通道的一致性机制并接收该通道的复制日志的排序节点。这可以是所有可用的节点(单个集群中或多个集群中对系统通道有贡献)或这些节点的子集。

有限状态机(FSM)。Raft中的每个排序节点都有一个FSM,它们共同用于确保不同排序节点中的日志序列是确定的(以相同的顺序写入)。

一致性。描述了需要确认一个提案以便可以排序交易的最小同意者数量。对于每个同意者集,这是大多数节点。在有五个节点的群集中,必须有三个节点可用才能构成一致性。如果某个节点的一致性由于任何原因不可用,则排序服务群集对通道上的读和写操作都不可用,并且不能提交新的日志。

领导者。这不是一个新概念——正如我们所说的,kafka也使用了领导者——但关键是要理解,在任何给定的时间,一个通道的同意者集选择一个节点作为领导者(我们将在Raft中描述这是如何发生的)。领导者负责接收新的日志条目,将它们复制到跟随者排序节点,并管理何时将条目视为已提交。这不是一种特殊类型的排序节点。它只是排序节点在某些时候可能具有的一个角色,而不是其他时间的角色,具体视情况而定。

跟随者。同样,这不是一个新的概念,但要了解关注者的关键是,追随者从领导者那里接收日志,并确定地复制它们,确保日志保持一致。正如我们将在我们的领导人选举部分看到的,追随者也会收到来自领导人的“心跳”信息。如果领导者在一段可配置的时间内停止发送这些消息,追随者将发起领导人选举,其中一个将被选为新的领导人。

交易流中的Raft

每个通道都运行在Raft协议的一个单独实例上,这允许每个实例选择不同的leader。这种配置还允许在集群由不同组织控制的排序节点组成的用例中进一步去中心化服务。虽然所有的Raft节点必须是系统通道的一部分,但它们不一定必须是所有应用通道的一部分。通道创建者(和通道管理员)能够选择可用排序节点的子集,并根据需要添加或删除排序节点(只要一次只添加或删除一个节点)。

虽然这种配置以冗余心跳消息和goroutine的形式创建了更多的开销,但它为BFT奠定了必要的基础。

在Raft中,交易(以提案或配置更新的形式)由接收交易的排序节点自动路由到该通道的当前主管。这意味着普通节点和应用程序在任何特定时间都不需要知道谁是领导节点。只有排序节点需要知道。

当排序节点验证检查完成后,交易被排序、打包成块、同意并分发,如我们的交易流的第二阶段所述。

领导者选举如何在Raft里运作

领导者选举如何在raft中运行尽管选举领导者的过程发生在订购者的内部流程中,但值得注意的是,该流程是如何工作的。

Raft节点总是处于以下三种状态之一:跟随者、候选者或领导者。所有节点最初都是作为跟随者开始的。在这种状态下,他们可以接受领导人的日志条目(若有人当选),或者投票给领导人。如果在设定的时间内(例如,5秒),没有收到任何日志条目或心跳信号,则节点会自行升级到候选状态。在候选状态下,节点向其他节点请求投票。如果一个候选人获得了法定人数的选票,那么他将被提升为领导人。领导者必须接受新的日志条目并将其复制到追随者。

要了解领导人选举过程是如何工作的,请查看数据的秘密生命

快照

如果一个排序节点宕机,它如何获得重新启动时丢失的日志?

虽然可以无限期地保留所有日志,但为了节省磁盘空间,Raft使用了一个称为“快照”的过程,在这个过程中,用户可以定义日志中将保留多少字节的数据。此数据量将符合一定数量的块(这取决于块中的数据量)。请注意,快照中只存储完整块)。

例如,假设滞后副本R1刚刚重新连接到网络。它最新的区块是100号。区块头L在块196处,并且被配置成以在本例中表示20个块的数据量进行快照。因此,R1将从L接收块180,然后对块101180发出传送请求。然后,块180196将通过正常的Raft协议复制到R1。

kafka(在v2.0中已弃用).

Fabric支持的另一个崩溃容错排序服务是Kafka分布式流媒体平台的一种改进,可以用作排序节点的集群。您可以在Apache-Kafka网站上阅读更多关于Kafka的信息,但是在较高的层次上,Kafka使用了Raft所使用的概念上的“leader和follower”配置,其中交易(Kafka称之为“消息”)从leader节点复制到follower节点。在leader节点发生故障的情况下,其中一个follower成为leader,并且可以继续排序,确保容错性,就像Raft一样。

Kafka集群的管理,包括任务的协调、集群成员资格、访问控制和控制器选择等,都由ZooKeeper集成及其相关API处理。

众所周知,Kafka集群和ZooKeeper集群的设置非常复杂,因此我们的文档假设了Kafka和ZooKeeper的工作知识。如果您决定在不具备此专业知识的情况下使用Kafka,则在试用基于Kafka的排序服务之前,至少应完成《Kafka快速入门指南》的前六个步骤。您也可以参考这个示例配置文件,以获得对Kafka和ZooKeeper的合理默认设置的简要说明。

要了解如何启动基于Kafka的排序服务,请查看我们关于Kafka的文档


智能合约和链码

受众:架构师、应用程序和智能合约开发人员、管理员

从应用程序开发人员的角度来看,智能合约账本一起构成了Hyperledger Fabric区块链系统的核心。账本保存了一组业务对象的当前和历史状态的事实,而智能合约定义了生成添加到账本中的新事实的可执行逻辑。链码通常由管理员用于将相关智能合约分组以进行部署,但也可以用于Fabric的低级系统编程。在本主题中,我们将重点讨论为什么智能合约链码都存在,以及如何和何时使用它们。


智能合约

在企业之间进行交易之前,它们必须定义一组通用的合同,包括通用术语、数据、规则、概念定义和流程。总而言之,这些合同规定了管理交易方之间所有交互的业务模型。

智能合约在可执行代码中定义不同组织之间的规则。应用程序调用智能合约来生成记录在账本上的交易。

利用区块链网络,我们可以将这些合同转化为可执行程序——在行业内被称为智能合约——以开辟各种新的可能性。这是因为智能合约可以为任何类型的业务对象实现治理规则,因此在执行智能合约时可以自动执行这些规则。例如,智能合约可以确保在指定的时间范围内交付新车,或者根据预先安排的条款释放资金,从而分别改善货物或资本的流动。然而,最重要的是,智能合约的执行比人工的业务流程要高效得多。

上图中,我们可以看到两个组织,ORG1ORG2如何定义了一个car智能合约来查询传输更新car。来自这些组织的应用程序调用此智能合约来执行业务流程中商定的步骤,例如将特定汽车的所有权从ORG1转移到ORG2


术语

Hyperledger Fabric用户经常交替使用智能合约链码这两个术语。一般来说,智能合约定义了控制世界状态中包含的业务对象生命周期的交易逻辑。然后将其打包成链码,然后部署到区块链网络。可以将智能合约视为管理交易,而链码控制如何打包智能合约以进行部署。

智能合约在链码中定义。可以在同一个链码内定义多个智能合约。当部署链码时,其中的所有智能合约都可供应用程序使用。

在图中,我们可以看到一个包含三个智能合约的车辆链码:汽车船只卡车。我们还可以看到一个包含四个智能合约的保险链码:保单负债团和证券化。在这两种情况下,这些合同涵盖了与车辆和保险有关的业务流程的关键方面。在本主题中,我们将以汽车合同为例。我们可以看到,智能合约是与特定业务流程相关的领域特定程序,而链码是一组相关智能合约的技术容器。


账本

在最简单的层面上,区块链不变地记录更新账本状态的交易。智能合约以编程方式访问账本的两个不同部分——区块链,它不可变地记录所有交易的历史,另一个世界状态保存着这些状态的当前值的缓存,因为通常需要的是对象的当前值。

智能合约主要是在世界状态下putgetdelete状态,还可以查询交易的不可变区块链记录。

  • get通常表示检索有关业务对象当前状态的信息的查询。
  • put通常在账本世界状态下创建一个新的业务对象或修改现有的业务对象。
  • delete通常表示从账本的当前状态中删除业务对象,而不是从其历史记录中删除。

智能合约有许多可用的APIs。关键的是,在所有情况下,无论交易在世界状态下创建、读取、更新或删除业务对象,区块链都包含这些变化的不变记录


开发

智能合约是应用程序开发的重点,正如我们所见,一个或多个智能合约可以在一个链码中定义。将链码部署到网络中可以使该网络中的组织使用其所有智能合约。这意味着只有管理员才需要担心链码;其他人都可以从智能合约的角度来思考。

智能合约的核心是一组交易定义。例如,看看fabcar.js这里,您可以看到创建新车的智能合约交易:

async createCar(ctx, carNumber, make, model, color, owner) {
    
    

    const car = {
    
    
        color,
        docType: 'car',
        make,
        model,
        owner,
    };

    await ctx.stub.putState(carNumber, Buffer.from(JSON.stringify(car)));
}

您可以在编写第一个应用程序教程中了解有关Fabcar智能合约的更多信息。

智能合约可以描述与多组织决策中数据的不变性相关的几乎无限多的业务用例。智能合约开发人员的工作是获取可能控制财务价格或交付条件的现有业务流程,并用JavaScript、GoLand或Java等编程语言将其表示为智能合约。将几百年的法律语言转换成程序语言所需的法律和技术技能越来越多地被智能合约审计员所实践。您可以在“开发应用程序”主题中了解如何设计和开发智能合约


背书

与每个链码关联的是一个适用于其中定义的所有智能合约的背书策略。背书策略非常重要;它指示区块链网络中的哪些组织必须签署由给定智能合约生成的交易,才能宣布该交易有效

每一份保险单都有一份保险单。此背书策略确定哪些组织必须批准智能合约生成的交易,然后才能将这些交易标识为有效。

例如,背书策略可能会规定,参与区块链网络的四个组织中有三个必须在交易被视为有效之前签署交易。所有的交易,不管是有效的还是无效的,都会被添加到分布式账本中,但是只有有效的交易才会更新世界状态。

如果背书策略指定必须有多个组织签署一个交易,则智能合约必须由足够多的组织执行,才能生成有效的交易。在上面的例子中,一个用于转让汽车的智能合约交易需要由ORG1ORG2执行并签名,它才有效。

背书策略使Hyperledger Fabric与其他区块链(如以太坊或比特币)不同。在这些系统中,网络中的任何节点都可以生成有效的交易。Hyperledger Fabric更真实地模拟现实世界;交易必须由网络中受信任的组织验证。例如,政府机构必须签署有效的issueIdentity交易,或者汽车的买方卖方都必须签署汽车转让交易。Hyperledger Fabric的设计是为了更好地模拟真实世界的策略。

最后,背书策略只是Hyperledger Fabric中策略的一个例子。可以定义其他策略来确定谁可以查询或更新账本,或从网络中添加或删除参与者。一般来说,策略应该事先由区块链网络中的组织联盟商定,尽管它们不是一成不变的。实际上,策略本身可以定义规则,通过这些规则可以更改策略。尽管这是一个高级主题,但在Fabric提供的规则之上定义自定义背书策略规则也是可能的。


验证交易

当智能合约执行时,它在区块链网络中组织拥有的节点上运行。合约接受一组称为交易提案的输入参数,并将它们与程序逻辑结合使用来读写账本。对世界状态的更改被捕获为交易提案响应(或仅交易响应),其中包含一个读写集,其中包含已读取的状态和交易有效时要写入的新状态。请注意,执行智能合约时,世界状态不会更新

所有交易都有一个标识符、一个提案和一个由一组组织签名的响应。所有交易记录在区块链上,无论有效还是无效,但只有有效的交易才有世界状态。

检查汽车转让交易。您可以看到ORG1ORG2之间的汽车转移交易t3。查看交易如何具有输入{CAR1,ORG1,ORG2}和输出{CAR1.owner=ORG1,CAR1.owner=ORG2},表示所有者从ORG1ORG2的变化。请注意,输入是如何由应用程序的组织ORG1签名的,而输出是由背书策略ORG1ORG2标识的两个组织签名的。这些签名是通过使用每个参与者的私钥生成的,这意味着网络中的任何人都可以验证网络中的所有参与者都同意交易细节。

分发到网络中所有节点的交易由每个节点分两个阶段进行验证。首先,根据背书策略,检查交易以确保有足够的组织签署了交易。其次,它被检查以确保当前的世界状态值与被背书的节点签名时交易的读取集相匹配;没有中间更新。如果一个交易同时通过了这两个测试,则将其标记为有效。所有交易都会被添加到区块链历史记录中,无论有效还是无效,但只有有效的交易才会导致世界状态的更新。

在我们的示例中,t3是一个有效的交易,因此CAR1的所有者已更新为ORG2。但是,t4(未显示)是一个无效的交易,因此虽然它记录在账本中,但世界状态没有更新,CAR2仍然由ORG2拥有。

最后,要了解如何在世界状态中使用智能合约或链码,请阅读链码命名空间主题


通道

Hyperledger Fabric允许组织通过通道同时参与多个独立的区块链网络。通过加入多个通道,组织可以参与所谓的网络的网络。通道提供了基础设施的有效共享,同时维护数据和通信隐私。它们的独立性足以帮助组织将其与不同交易对手的工作流量分开,但也足以使它们在必要时协调独立的活动。

通道在一组组织之间提供了完全独立的通信机制。当一个链码定义被提交到一个通道时,链码中的所有智能合约都可用于该通道上的应用程序。

当智能合约代码安装在组织节点的链码包中时,通道成员只能在通道上定义链码后执行智能合约。链码定义是一个结构,它包含控制链码操作方式的参数。这些参数包括链码名称、版本和背书策略。每个通道成员通过批准其组织的链码定义来同意链码的参数。当足够多的组织(默认情况下大多数)已批准同一链码定义时,可以将定义提交给通道。然后,通道成员可以根据链码定义中指定的背书策略执行链码内的智能合约。背书策略同样适用于同一链码内定义的所有智能合约。

上面的例子中,汽车合同在车辆通道上定义,保险合同在保险通道上定义。car的链码定义指定了一个背书策略,该策略要求ORG1ORG2在交易被视为有效之前对其进行签名。保险合同的链码定义指定只需要ORG3来背书一个交易。ORG1参与两个网络,车辆通道和保险网络,并且可以在这两个网络上与ORG2ORG3协调活动。

链码定义提供了一种方法,使通道成员在开始使用智能合约在通道上进行交易之前就链码的治理达成一致。在上面的例子基础上,ORG1ORG2都希望背书调用car合约的交易。因为默认策略要求大多数组织批准链码定义,所以两个组织都需要批准AND{ORG1,ORG2}的背书策略。否则,ORG1ORG2将批准不同的链码定义,因此无法将链码定义提交到通道。此流程保证来自car智能合约的交易需要得到两个组织的批准。


相互沟通

智能合约可以调用同一通道内和不同通道的其他智能合约。通过这种方式,它们可以读取和写入由于智能合约命名空间而无法访问的世界状态数据。

在这个链码的名称空间中,有一个完整的描述了这个名字空间之间的通信限制。


系统链码

链码中定义的智能合约对一组区块链组织之间商定的业务流程的领域相关规则进行编码。然而,链码还可以定义与域无关的系统交互相对应的低级程序代码,与这些业务流程的智能合约无关。

以下是不同类型的系统链码及其相关缩写:

  • ·_lifecycle·在所有节点中运行,并管理在节点上安装链代码、批准组织的链代码定义以及将链代码定义提交到通道。您可以阅读更多关于 _lifecycle如何实现Fabric chaincode生命周期过程的信息。
  • 生命周期系统链码(LSCC)管理Fabric 1.x版本的链码生命周期。此版本的生命周期要求在通道上实例化或升级链代码。如果通道应用程序功能设置为V1_4_x或更低,您仍然可以使用LSCC来管理链代码。
  • 配置系统链码(CSCC)在所有节点中运行,以处理对通道配置的更改,例如策略更新。您可以在下面的链码主题中阅读有关此过程的更多信息。
  • 查询系统链码(QSCC)运行在所有节点中,以提供账本API,包括块查询、交易查询等。您可以在交易上下文主题中了解有关这些账本API的更多信息。
  • 背书系统链码(ESCC)运行在背书节点中,以加密方式签署交易响应。您可以阅读更多关于ESCC如何实现这个过程的信息。
  • 验证系统链码(VSCC)验证交易,包括检查背书策略和读写集版本控制。你可以阅读更多关于LSCC实现这个过程的信息。

低级Fabric开发人员和管理员可以修改这些系统链码以供自己使用。然而,系统链码的开发和管理是一项专门的活动,与智能合约的开发完全不同,通常不需要。对系统链码的更改必须极其小心,因为它们是超级账本结构网络正确运行的基础。例如,如果系统链码未正确开发,则一个节点可能会以与另一个节点不同的方式更新其世界状态或区块链副本。这种缺乏共识是账本分叉的一种形式,是一种非常不受欢迎的情况。


Fabric链码生命周期

什么是链码?

链码是一个程序,用Go编写,Node.js或Java实现指定接口。链码在安全的Docker容器中运行,该容器与背书节点进程隔离。链码通过应用程序提交的交易初始化和管理账本状态。

链码通常处理网络成员同意的业务逻辑,因此可以将其视为“智能合约”。由链码创建的账本更新仅限于该链码,不能由其他链码直接访问。但是,在同一个网络中,给定适当的权限,链码可以调用另一个链码来访问其状态。

在这个概念主题中,我们将从区块链网络运营商而不是应用程序开发人员的角度来探讨链码。链码操作员可以使用此主题作为如何使用Fabric链码生命周期在其网络上部署和管理链码的指南。


部署链码

结构链码生命周期是一个过程,它允许多个组织在一个通道上使用链码之前就如何操作链码达成一致。网络运营商将使用结构生命周期来执行以下任务:

  • 安装并定义链码
  • 升级链码
  • 部署方案
  • 迁移到新的Fabric生命周期

您可以通过创建新通道并将通道功能设置为V2_0来使用Fabric chaincode生命周期。您将无法使用旧的生命周期来安装、实例化或更新启用了V2_0功能的通道上的链码。但是,在启用V2_0功能后,仍然可以调用使用以前的生命周期模型安装的链码。如果您正在从v1.4.x网络升级,并且需要编辑通道配置以启用新的生命周期,请查看启用新的链码生命周期。


安装并定义链码

Fabric链码生命周期要求组织同意定义链码的参数,例如名称、版本和链码背书策略。通道成员通过以下四个步骤达成一致。不是每个通道上的组织都需要完成每一步。

  • 打包链码:此步骤可以由一个组织完成,也可以由每个组织完成。
  • 在节点上安装链码:每个将使用链码签署交易或查询账本的组织都需要完成此步骤。
  • 批准组织的链码定义:将使用链码的每个组织都需要完成此步骤。在可以在通道上启动链码之前,链码定义需要经过足够数量的组织的批准,以满足通道的生命周期环保策略(默认情况下,大多数组织)。
  • 将链码定义提交到通道:一旦通道上所需数量的组织获得批准,提交交易需要由一个组织提交。提交者首先从已经批准的组织的足够多的节点收集背书,然后提交交易以提交链码定义。

本主题详细概述了Fabric链码生命周期的操作,而不是特定的命令。要了解有关如何使用节点CLI使用Fabric生命周期的更多信息,请参阅Deploying a smart contract To a channel教程或Peer lifecycle命令参考。

第一步:打包智能合约

链码需要打包在tar文件中,然后才能安装到您的节点上。您可以使用Fabric节点二进制文件、Node Fabric SDK或GUN tar等第三方工具来打包链码。当您创建一个链码包时,您需要提供一个链码包标签来创建一个简洁易懂的包描述。

如果使用第三方工具打包链码,则生成的文件需要采用以下格式。Fabric节点二进制文件和Fabric sdk将自动创建此格式的文件。

  • 链码需要打包在tar文件中,以.tar.gz文件扩展名。
  • tar文件需要包含两个文件(没有目录):一个元数据文件“Chaincode-Package-Metadata.json”和另一个包含链码的tar文件。
  • “Chaincode-Package-Metadata.json”包含指定链码语言、代码路径和包标签的JSON。您可以在下面看到元数据文件的示例:
{
    
    "Path":"fabric-samples/chaincode/fabcar/go","Type":"golang","Label":"fabcarv1"}

链码由Org1和Org2单独打包。两个组织都使用MYCC_1作为其包标签,以便使用名称和版本标识包。组织没有必要使用相同的包装标签。

第二步:把链码安装到节点上

您需要在每个将执行和背书交易的节点上安装链码包。无论使用CLI还是SDK,都需要使用节点管理员完成此步骤。您的节点将在安装链码后生成链码,如果链码有问题,则返回生成错误。提案组织只打包一次链码,然后在属于其组织的每个节点上安装相同的包。如果一个通道想要确保每个组织都在运行相同的链码,那么一个组织可以打包一个链码并将其发送到其他通道成员。

成功的安装命令将返回一个链码包标识符,它是包标签与包的哈希相结合。此包标识符用于将节点上安装的链码包与组织批准的链码定义相关联。为下一步保存标识符。您还可以通过使用节点CLI查询安装在节点上的包来查找包标识符。
链码安装
Org1和Org2的节点管理员在加入通道的节点上安装链码包MYCC_1。安装链码包将生成链码并创建MYCC_1:hash的包标识符。

第三步:批准组织的链码定义

链码由链码定义控制。当通道成员批准一个链码定义时,该批准相当于组织对其接受的链码参数进行投票。这些经批准的组织定义允许通道成员在链码可用于通道之前就其达成一致。链码定义包括以下参数,这些参数需要在组织之间保持一致:

  • 名称:应用程序在调用链码时将使用的名称。
  • 版本:与给定链码包关联的版本号或值。如果升级链码二进制文件,则还需要更改链码版本。
  • 序列:定义链码的序列。此值是一个整数,用于跟踪链码升级。例如,第一次安装并批准链码定义时,序列号将为1。下次升级链码时,序列号将递增到2。
  • 背书策略:哪些组织需要执行和验证交易输出。背书策略可以表示为传递给CLI的字符串,也可以引用通道配置中的策略。默认情况下,背书策略设置为Channel/Application/Endorsement,默认要求通道中的大多数组织背书交易。
  • 收集配置:与链码关联的私有数据收集定义文件的路径。有关私有数据收集的更多信息,请参阅私有数据体系结构参考
  • 初始化:所有的链码都需要包含用于初始化链码的Init函数。默认情况下,此函数从不执行。但是,您可以使用链码定义来请求Init函数是可调用的。如果请求执行Init,fabric将确保Init在任何其他函数之前被调用,并且只被调用一次。
  • ESCC/VSCC插件:此链码使用的自定义背书或验证插件的名称。

链码定义还包括包标识符。这是希望使用链码的每个组织的必需参数。对于所有组织,包ID不需要相同。组织可以批准链码定义,而无需安装链码包或在定义中包含标识符。

希望使用链码的每个通道成员都需要为其组织批准链码定义。此批准需要提交给排序服务,然后将其分发给所有节点。此批准需要由组织管理员提交。审批交易成功提交后,已批准的定义将存储在组织的所有节点都可用的集合中。因此,您只需为您的组织批准一次链码,即使您有多个节点。
批准组织的链码定义
来自Org1和Org2的组织管理员批准其组织的MYCC的链码定义。链码定义包括链码名称、版本和背书策略等字段。由于两个组织都将使用链码来背书交易,因此两个组织的已批准定义都需要包括packageID。

第四步:向通道提交链码定义

一旦有足够数量的通道成员批准了链码定义,一个组织就可以将该定义提交给通道。您可以使用checkcommitreadence命令检查在使用节点CLI将定义提交到通道之前,是否应根据哪些通道成员批准了定义来成功提交链代码定义。提交交易提案首先发送给通道成员的节点,后者查询为其组织批准的链码定义,如果其组织已批准,则对该定义进行背书。然后将交易提交给排序服务,然后由排序服务将链码定义提交给通道。提交定义交易需要作为组织管理员提交。

在将定义成功提交到通道之前,需要批准该定义的组织数由Channel/Application/LifecycleEndorsement策略控制。默认情况下,此策略要求通道中的大多数组织背书该交易。LifecycleEndorsement策略独立于链码背书策略。例如,即使链码背书策略只需要来自一个或两个组织的签名,大多数通道成员仍然需要根据默认策略批准链码定义。提交通道定义时,需要针对通道中足够多的节点组织,以满足生命周期策略。您可以在“策略概念”主题中了解有关Fabric链码生命周期策略的更多信息。

还可以将Channel/Application/LifecycleEndorsement策略设置为签名策略,并显式指定通道上可以批准链码定义的组织集。这允许您创建一个通道,在这个通道中,选定数量的组织充当链码管理员,并控制通道使用的业务逻辑。如果您的通道有大量的Idemix组织,这些组织无法批准链码定义或背书链码,并且可能会阻止通道获得多数用户,则也可以使用签名策略。

Org1或Org2的一个组织管理员将链码定义提交给通道。通道上的定义不包括packageID。

组织可以在不安装链码包的情况下批准链码定义。如果组织不需要使用链码,他们可以批准不带包标识符的链码定义,以确保满足生命周期背书策略。

在将链码定义提交给通道之后,链码容器将在安装了链码的所有节点上启动,从而允许通道成员开始使用链码。链码容器可能需要几分钟才能启动。您可以使用链码定义来要求调用Init函数来初始化链码。如果请求调用Init函数,那么第一次调用链码必须是对Init函数的调用。Init函数的调用受链背书策略的约束。

一旦在通道上定义了MYCC,Org1和Org2就可以开始使用链码了。对每个节点的链码的第一次调用将启动该节点上的链码容器。


更新链码

您可以使用与安装和启动链码相同的Fabric生命周期过程升级链码。可以升级链码二进制文件,也可以只更新链码策略。按照以下步骤升级链码:

  1. 重新打包链码:只有在升级链码二进制文件时,才需要完成此步骤。

Org1和Org2升级链码二进制文件并重新打包链码。两个组织使用不同的包标签。

  1. 在您的节点上安装新的链码包:同样,您只需要在升级链码二进制文件时完成此步骤。安装新的链码包将生成一个包ID,您需要将其传递给新的链码定义。您还需要更改链码版本,生命周期过程使用该版本来跟踪链代码二进制文件是否已升级。

Org1和Org2在其节点上安装新包。安装将创建一个新的packageID。

  1. 批准新的链码定义:如果要升级链码二进制文件,则需要更新链码版本和链码定义中的包ID。也可以更新链码背书策略,而不必重新打包链码二进制文件。通道成员只需批准新策略的定义即可。新定义需要将定义中的序列变量增加1。

Org1和Org2的组织管理员批准各自组织的新链码定义。新定义引用新的packageID并更改链码版本。因为这是链码的第一次更新,所以序列从1递增到2。

  1. 将定义提交到通道:当有足够数量的通道成员批准了新的链码定义时,一个组织可以提交新定义以将链码定义升级到通道。生命周期过程中没有单独的升级命令。

Org1或Org2的组织管理员将新的链码定义提交给通道。

提交链码定义后,将启动一个新的链码容器,其中包含升级后的链码二进制文件中的代码。如果请求执行链代码定义中的Init函数,则需要在成功提交新定义后再次调用Init函数来初始化升级后的链码。如果您更新了链码定义而不更改链码版本,那么链码容器将保持不变,并且不需要调用·Init·函数。

一旦将新定义提交给通道,每个节点将自动启动新的链码容器。

Fabric链码生命周期使用链码定义中的序列来跟踪升级。所有通道成员都需要将序列号递增1,并批准新定义以升级链码。version参数用于跟踪链码二进制文件,只有在升级链码二进制文件时才需要更改。


部署方案

以下示例说明如何使用Fabric链码生命周期来管理通道和链码。

加入通道

新组织可以加入已定义链码的通道,并在安装链码包并批准已提交给通道的链码定义后开始使用链码。

Org3加入通道并批准先前由Org1和Org2提交给通道的相同链码定义。

批准链码定义后,新组织可以在其节点上安装包后开始使用链码。不需要再次提交定义。如果背书策略设置为需要大多数通道成员背书的默认策略,则背书策略将自动更新以包括新组织。

链码容器将在Org3节点上第一次调用链码之后启动。

更新背书策略

您可以使用链码定义来更新背书策略,而无需重新打包或重新安装链码。通道成员可以使用新的背书策略批准链码定义并将其提交给通道。

Org1、Org2和Org3批准一个新的背书策略,要求所有三个组织都背书一个交易。它们将定义序列从一个增加到两个,但不需要更新链码版本。

新的背书策略将在新定义提交给通道后生效。通道成员不必通过调用链码或执行Init函数来重新启动链码容器来更新背书策略。

一个组织将新的链码定义提交到通道以更新背书策略。

在不安装链码的情况下批准定义

您可以在不安装链码包的情况下批准链码定义。这允许您在将链码定义提交到通道之前对其进行背书,即使您不希望使用链码来背书交易或查询账本。您需要批准与通道的其他成员相同的参数,但不需要将packageID作为链码定义的一部分。

Org3不安装链码包。因此,它们不需要在链码定义中提供packageID。然而,Org3仍然可以背书MYCC的定义,这一定义已经承诺给通道。

一个组织不同意链码的定义

不批准已提交给通道的链码定义的组织不能使用链码。未批准链码定义或批准其他链码定义的组织将无法在其节点上执行链码。

Org3使用不同于Org1和Org2的背书策略批准链码定义。因此,Org3不能在通道上使用MYCC链码。但是,Org1或Org2仍然可以获得足够的背书,以便将定义提交给通道并使用链码。来自链码的交易仍将添加到账本并存储在Org3节点上。然而,Org3将不能签署交易。

组织可以批准具有任何序列号或版本的新链码定义。这允许您批准已提交给通道的定义并开始使用链码。也可以批准新的链码定义,以更正在批准或打包链码过程中所犯的任何错误。

通道不同意链码定义

如果通道上的组织不同意链码定义,则无法将定义提交给通道。所有通道成员都不能使用链码。

Org1、Org2和Org3都批准不同的链码定义。因此,通道的任何成员都无法获得足够的背书来向通道提交链码定义。没有通道成员可以使用链码。

组织安装不同的链码包

每个组织在批准链码定义时可以使用不同的packageID。这允许通道成员安装不同的链码二进制文件,这些二进制文件使用相同的背书策略并读写同一个链码命名空间中的数据。

组织可以使用此功能安装包含特定于其组织的业务逻辑的智能合约。每个组织的智能合约可以包含组织在其节点背书交易之前需要的附加验证。每个组织还可以编写代码,帮助将智能合约与现有系统中的数据集成。

Org1和Org2各自安装MYCC链码的版本,其中包含特定于其组织的业务逻辑。

使用一个包创建多个链码

通过批准和提交多个链码定义,可以使用一个链码包在通道上创建多个链码实例。每个定义都需要指定不同的链码名称。这允许您在一个通道上运行智能合约的多个实例,但要使合约受制于不同的背书策略。

Org1和Org2使用MYCC_1 链码包来批准和提交两个不同的链码定义。因此,两个节点都有两个链码容器在其节点上运行。MYCC1的背书策略为1/2,而MYCC2的背书策略为2/2。


迁移到新的Fabric生命周期

有关迁移到新生命周期的信息,请查看获取v2.0的注意事项

如果需要更新通道配置以启用新生命周期,请查看启用新链码生命周期


私有数据

什么是私有数据

如果一个通道上的一组组织需要对该通道上的其他组织保密数据,他们可以选择创建一个新的通道,该通道只包含需要访问该数据的组织。但是,在每种情况下创建单独的通道都会产生额外的管理开销(维护链码版本、策略、msp等),并且不允许在希望所有通道参与者看到交易的情况下同时保留部分数据的私有性。

这就是为什么Fabric提供了创建私有数据集合的能力,这使得在通道上定义的组织子集能够背书、提交或查询私有数据,而不必创建单独的通道。


什么是私有数据收集?

集合是两个元素的组合:

  • 实际的私有数据通过gossip协议点对对发送给只有授权查看它的组织。这些数据存储在授权组织节点上的私有状态数据库中,可以从这些授权节点上的链码访问该数据库。这里不涉及排序服务,也看不到私有数据。请注意,由于gossip在授权组织间点对点分发私有数据,因此需要在通道上设置锚节点,并在每个节点上配置CORE_peer_gossip_EXTERNALENDPOINT,以引导跨组织通信。
  • 该数据的哈希值,被背书、排序并写入通道上每个节点的账本中。哈希用作交易的证据,用于状态验证,并可用于审计目的。

下图说明了一个被授权拥有私有数据和一个没有私有数据的节点的账本内容。

如果采集成员遇到争议或希望将资产转让给第三方,则可以决定与其他方共享私有数据。然后,第三方可以计算私有数据的哈希值,并查看它是否与通道账本上的状态匹配,从而证明在某个时间点集合成员之间存在该状态。

在某些情况下,您可能决定使用一组集合,每个集合由一个组织组成。例如,一个组织可以在自己的集合中记录私有数据,这些数据稍后可以与其他通道成员共享,并在链码交易中引用。我们将在下面的共享私有数据主题中看到这方面的示例。

何时使用通道内的集合与单独通道中的集合

  • 当整个交易(和账本)必须在属于通道成员的一组组织内保密时,使用通道
  • 当交易(和账本)必须在一组组织之间共享,但只有这些组织的子集可以访问交易中的部分(或全部)数据时,请使用集合。此外,由于私有数据是点对点分发的,而不是通过块来分发的,当必须对排序服务节点的交易数据保密时,请使用私有数据收集。

解释集合的用例

假设一个通道上有五个组织从事农产品贸易:

  • 在国外出售货物的农民
  • 把货物运到国外的分销商
  • 在当事人之间运送货物的托运人
  • 向分销商购买商品的批发商
  • 向托运人和批发商购买商品的零售商

分销商可能希望与农民托运人进行私人交易,以便对批发商零售商保密交易条款(以免暴露他们收取的加价)。

分销商也可能希望与批发商建立单独的私人数据关系,因为向批发商收取的价格低于零售商的价格。

批发商还可能希望与零售商托运人建立私有数据关系。

与其为这些关系中的每一个定义许多小通道,不如定义多个私有数据集合(PDC),以便在以下对象之间共享私有数据:

  1. PDC1:分销商农民托运人
  2. PDC2:分销商批发商
  3. PDC3:批发商零售商托运人

使用此示例,分销商拥有的节点将在其账本中拥有多个私有数据库,其中包括来自分销商农民托运人关系以及分销商批发商关系的私有数据。

k,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2JlYW5fYnVzaW5lc3M=,size_16,color_FFFFFF,t_70)


私有数据的交易流

当在链码中引用私有数据集合时,为了保护私有数据的机密性,交易处理流程略有不同,因为交易被提议、背书并提交到账本中。

有关不使用私有数据的交易流的详细信息,请参阅我们关于交易流的文档。

  • 客户端应用程序提交一个提案请求,以调用链码函数(读取或写入私有数据)来背书属于集合授权组织一部分的节点。私有数据,或用于生成链码中的私有数据的数据,在方案的一个瞬态字段中发送。
  • 背书节点模拟交易,并将私有数据存储在临时数据存储(节点本地的临时存储)中。他们根据收集策略,通过gossip将私有数据分发给授权的节点。
  • 背书节点将提案响应发送回客户端。提案响应包括背书的读/写集,其中包括公共数据,以及任何私有数据密钥和值的哈希。不会将私有数据发送回客户端。有关背书如何处理私人数据的更多信息,请单击此处
  • 客户机应用程序向排序服务提交交易(包括带有私有数据哈希的提案响应)。具有私有数据哈希的交易通常包含在块中。带有私有数据散列的块被分发到所有节点。通过这种方式,通道上的所有节点可以一致地使用私有数据的散列来验证交易,而不必知道实际的私有数据。
  • 在块提交时,授权的节点使用收集策略来确定他们是否被授权访问私有数据。如果他们这样做,他们将首先检查他们的本地瞬态数据存储,以确定他们是否已经在链码背书时收到了私有数据。如果没有,他们将尝试从另一个授权节点获取私有数据。然后他们将根据公共块中的哈希值验证私有数据,并提交交易和块。在验证/提交时,私有数据被移动到私有状态数据库和私有写集存储的副本中。然后从瞬态数据存储中删除私有数据。

共享私人数据

在许多情况下,一个集合中的私有数据键/值可能需要与其他通道成员或其他专用数据集合共享,例如,当您需要与未包含在原始专用数据集合中的通道成员或通道成员组处理私有数据时。作为交易的一部分,接收方通常希望根据链上哈希验证私有数据。

私有数据收集有几个方面可以共享和验证私有数据:

  • 首先,只要满足背书策略,就不必是集合的成员才能写入集合中的密钥。可以在链码级别、密钥级别(使用基于状态的背书)或集合级别(从Fabric v2.0开始)定义背书策略。
  • 其次,从v1.4.2开始,有一个链码 API GetPrivateDataHash(),它允许非成员节点上的链码读取私钥的哈希值。这是一个重要的特性,您将在后面看到,因为它允许链码根据在以前交易中从私有数据创建的链上散列来验证私有数据。

在设计应用程序和相关的私有数据集合时,应该考虑这种共享和验证私有数据的能力。当然,您可以创建一组多边私有数据集合,以便在不同的通道成员组合之间共享数据,但是这种方法可能会导致需要定义大量的集合。或者,考虑使用较少数量的私有数据集合(例如,每个组织一个集合,或者每对组织一对集合),然后与其他通道成员共享私有数据,或者根据需要与其他集合共享。从Fabric v2.0开始,任何链码都可以使用隐式特定于组织的集合,因此在部署链码时甚至不必定义这些每个组织的集合。

私有数据共享模式

当为每个组织的私有数据集合建模时,可以使用多种模式来共享或传输私有数据,而无需定义多个多边集合的开销。以下是一些可以在链码应用程序中使用的共享模式:

  • 使用相应的公钥跟踪公共状态-您可以选择使用匹配的公钥来跟踪公共状态(例如,资产属性、当前所有权)。等等),对于每个应该有权访问资产对应私有数据的组织,您可以在每个组织的私有数据集合中创建一个私钥/值。
  • 链码访问控制-您可以在链码中实现访问控制,以指定哪些客户端可以查询集合中的私有数据。例如,存储私有数据收集密钥或密钥范围的访问控制列表,然后在链码中获取客户端提交者的凭据(使用GetCreator()链码API或CID library API GetID()或GetMSPID()),并在返回私有数据之前验证他们是否具有访问权限。类似地,您可以要求客户机将密码短语传递到链码中,链码必须与存储在密钥级别的密码相匹配,以便访问私有数据。注意,此模式还可以用于限制客户端对公共状态数据的访问。
  • 带外共享私有数据-作为一个链外选项,您可以在带外与其他组织共享私有数据,他们可以使用GetPrivateDataHash()chaincode API散列键/值,以验证它是否与链上哈希匹配。例如,希望从您处购买资产的组织可能希望在同意购买之前通过检查链上哈希来验证资产的属性以及您是否是合法所有者。
  • 与其他集合共享私有数据-可以使用链码“共享”链上的私有数据,该链代码在其他组织的私有数据集合中创建匹配的键/值。您可以通过transient字段将私有数据键/值传递给链码,链码可以使用GetPrivateDataHash()确认传递的私有数据的哈希与集合中的链上哈希匹配,然后将私有数据写入另一个组织的私有数据集合。
  • 将私有数据传输到其他集合-您可以使用链码“传输”私有数据,该链码将删除集合中的私有数据密钥,并在其他组织的集合中创建它。同样,在调用链代码时使用transient字段传递私有数据,并在链代码中使用GetPrivateDataHash()确认数据存在于私有数据集合中,然后从集合中删除密钥并在另一个组织的集合中创建密钥。为了确保交易始终从一个集合中删除并添加到另一个集合中,您可能需要其他各方(如监管机构或审计师)的背书。
  • 使用私有数据进行交易审批-如果您想在交易完成前获得交易对手的批准(例如,他们同意以特定价格购买资产的链上记录),链码可以要求他们“预先批准”交易,通过向它们的私有数据集合或您的集合写入一个私钥,然后链码将使用GetPrivateDataHash()进行检查。实际上,这正是内置生命周期系统链码用于确保组织在将链码定义提交给通道之前同意其定义的机制。从Fabric v2.0开始,此模式通过集合级别的背书策略变得更加强大,以确保在集合所有者自己的受信任节点上执行和背书链码。或者,可以使用具有密钥级别背书策略的双方同意的密钥,然后使用预批准条款更新该密钥,并在来自所需组织的节点上进行背书。
  • 保持交易处理程序的私有化—先前模式的变体还可以消除给定交易的交易处理程序泄漏。例如,买方表示同意购买他们自己的集合,然后在随后的交易中,卖方在自己的私有数据集合中引用买方的私有数据。带有散列引用的交易证明记录在chain上,只有买方和卖方知道他们是交易人,但是如果需要知道,他们可以显示预映像,例如在随后与另一方进行的交易中,谁可以验证散列。

结合上述模式,值得注意的是,具有私有数据的交易可以绑定到与常规通道状态数据相同的条件下,具体地说:

  • 密钥级交易访问控制-您可以在私有数据值中包含所有权凭证,以便后续交易可以验证提交者是否具有共享或传输数据的所有权特权。在这种情况下,链码将获取提交者的凭证(例如,使用GetCreator()链码API或CID库API GetID()或GetMSPID()),将其与传递给链码的其他私有数据组合,对其进行哈希处理,并使用GetPrivateDataHash()在继续处理交易之前验证它是否与链上哈希匹配。
  • 密钥级别背书策略-与普通通道状态数据一样,您可以使用基于状态的背书来指定哪些组织必须背书共享或传输私有数据的交易,例如使用SetPrivateDataValidationParameter()链码API指定仅所有者的组织节点,托管人的组织节点或其他第三方必须对此类交易进行背书。

示例场景:使用私有数据收集的资产转移

上面提到的私有数据共享模式可以组合起来,以支持功能强大的基于链码的应用程序。例如,考虑如何使用每个组织的私有数据集合来实现资产转移场景:

  • 资产可以由处于公共链码状态的UUID密钥跟踪。只记录资产的所有权,不知道资产的其他信息。
  • 链码将要求任何传输请求必须来自拥有的客户端,并且密钥受基于状态的背书的约束,要求来自所有者组织和监管机构组织的节点必须对任何转移请求进行背书。
  • 资产所有者的私有数据集合包含资产的私有详细信息,由UUID的散列键控。其他组织和排序服务将只看到资产详细信息的哈希值。
  • 让我们假设调节器也是每个集合的成员,因此持久化私有数据,尽管这不一定是这样。

交易资产的交易将展开如下:

  1. 链下,所有者和潜在买家达成交易,以一定的价格交易资产。
  2. 卖方提供其所有权的证明,要么将私有详细信息传递到带外,要么向买方提供凭证,以查询其节点或监管机构节点上的私有数据。
  3. 买方验证私有细节的哈希与链上公共哈希匹配。
  4. 买方调用链码在自己的私有数据收集中记录他们的投标详细信息。链码在买方的节点上被调用,如果托收背书策略有要求,可能在监管者的节点上调用。
  5. 当前所有者(卖方)调用链码来出售和转让资产,传递私有细节和出价信息。链码在卖方、买方和监管机构的节点上调用,以满足公钥的背书策略以及买方和卖方私有数据收集的背书策略。
  6. 链码验证提交客户端是否为所有者,根据卖方集合中的哈希值验证私有详细信息,并根据买方集合中的哈希值验证投标详细信息。然后,链码写入公钥的提案更新(将所有权设置为买方,将背书策略设置为购买组织和监管机构),将私有详细信息写入买方的私有数据集合,并可能从卖方集合中删除私有细节。在最终背书之前,背书人确保将私人数据传播给卖方和监管机构的任何其他授权节点。
  7. 卖方提交带有公共数据和私有数据哈希的交易进行排序,并将其分发到一个块中的所有通道节点。
  8. 每个对等方的块验证逻辑将一致地验证是否满足背书策略(买方、卖方、监管机构均已背书),并验证在链码中读取的公共和私有状态自链码执行以来未被任何其他交易修改。
  9. 由于交易通过了验证检查,所有节点都将交易提交为有效。买方节点和监管方节点从其他授权节点检索私有数据,如果它们在背书时未收到私有数据,则将私有数据保存在其私有数据状态数据库中(假设私有数据与交易的哈希值匹配)。
    10.交易完成后,资产已被转移,对资产感兴趣的其他通道成员可以查询公钥的历史记录以了解其出处,但除非所有者在“需要知道”的基础上共享它,否则将无法访问任何私人详细信息。

基本资产转移场景可以扩展为其他考虑因素,例如,转移链码可以验证支付记录是否可用,以满足支付对交付的要求,或者验证银行在执行转移链代码之前提交了信用证。而不是直接托管节点的交易方,它们可以通过运行节点的托管组织进行交易。


清除私有数据

对于非常敏感的数据,即使是共享私有数据的各方也可能希望——或者政府法规要求——定期“清除”其节点的数据,留下区块链上的数据哈希,作为私有数据的不可变证据。

在某些情况下,私有数据只需要存在于节点的私有数据库中,直到可以复制到节点区块链外部的数据库中。数据也可能只需要存在于节点上,直到完成链码业务流程(交易结算、合同履行等)。

为了支持这些用例,如果私有数据没有针对可配置的块进行修改,可以清除它。无法从链码查询清除的私有数据,其他请求节点也无法使用清除的私有数据。


如何定义私有数据收集

有关集合定义的更多详细信息,以及有关私有数据和集合的其他低级信息,请参阅私有数据参考主题


通道功能

受众:通道管理员、节点管理员

注意:这是一个高级Fabric概念,新用户或应用程序开发人员不必了解它。然而,随着通道和网络的成熟,理解和管理功能变得至关重要。此外,重要的是要认识到更新功能与升级节点是一个不同的过程,尽管通常是相关的。我们将在本主题中对此进行详细描述。

因为Fabric是一个通常涉及多个组织的分布式系统,所以不同版本的Fabric代码可能(并且典型地)存在于网络中的不同节点以及该网络中的通道上。Fabric允许这样做-不需要每个节点和排序节点都处于同一版本级别。事实上,支持不同的版本级别是实现Fabric节点滚动升级的原因。

重要的是,网络和通道以相同的方式处理事物,为诸如通道配置更新和链码调用之类的事情创建确定的结果。如果没有确定的结果,通道上的一个节点可能会使交易无效,而另一个节点可能会验证它。

为此,Fabric定义了所谓“能力”的级别。这些能力在每个通道的配置中定义,通过定义行为产生一致结果的级别来确保确定性。如您所见,这些功能的版本与节点二进制版本密切相关。这些功能使运行在不同版本级别的节点能够在给定特定块高度的通道配置下以兼容和一致的方式运行。您还将看到,在配置树的许多部分中都存在功能,这些功能是按照特定任务的管理路线定义的。

正如您将看到的,有时需要将通道更新到新的功能级别以启用新功能。


节点版本和功能版本

如果您熟悉HyperledgerFabric,您会发现它遵循典型的语义版本控制模式:v1.1、v1.2.1、v2.0等。这些版本指的是发行版及其相关的二进制版本。

功能遵循相同的语义版本控制约定。有v1.1功能、v1.2功能和2.0功能等等。但注意一些区别是很重要的。

  • 每个版本不一定都有一个新的功能级别。建立新功能的需要是根据具体情况而定的,主要依赖于新特性和旧二进制版本的向后兼容性。例如,在v1.4.1中添加Raft排序服务并没有改变交易或排序服务功能的处理方式,因此不需要建立任何新的功能。另一方面,私有数据在v1.2之前不能被节点处理,需要建立v1.2的能力级别。因为不是每个版本都包含一个改变交易处理方式的新特性(或错误修复),所以某些版本不需要任何新功能(例如,v1.4),而其他版本只在特定级别(如v1.2和v1.3)上具有新功能。稍后我们将讨论功能的“级别”及其在配置树中的位置。
  • 节点必须至少处于通道中特定功能的级别。当节点加入一个通道时,它按顺序读取账本中的所有块,从通道的创世区块开始,继续通过交易块和任何后续的配置块。如果一个节点(例如节点)试图读取包含对其不理解的功能的更新的块(例如,v1.4.x节点尝试读取包含v2.0应用程序功能的块),则节点将崩溃。这种崩溃行为是有意的,因为v1.4.x节点不应尝试验证或提交任何超过此点的交易。在加入通道之前,请确保该节点至少是与节点相关的通道配置中指定的功能的结构版本(二进制)级别。稍后我们将讨论哪些功能与哪些节点相关。但是,由于没有用户希望其节点崩溃,因此强烈提案在尝试更新功能之前将所有节点更新到所需级别(最好是更新到最新版本)。这符合默认的Fabric提案,即始终处于最新的二进制和功能级别。

如果用户无法升级他们的二进制文件,那么功能必须保留在较低的级别。较低级别的二进制文件和功能仍将按预期协同工作。但是,请记住,即使用户选择不更新其功能,也始终更新到新的二进制文件是最佳做法。因为功能本身也包括错误修复,所以提案在网络二进制文件支持它们之后更新功能。


功能配置分组

正如我们前面所讨论的,没有一个单一的能力级别包含整个通道。相反,有三种能力,每种能力代表一个管理领域。

  • 排序节点:这些功能控制排序服务独有的任务和处理。因为这些功能不涉及影响交易或节点的流程,因此更新它们完全由排序服务管理员负责(节点不需要了解排序节点功能,因此无论排序节点功能更新到什么程度,都不会崩溃)。请注意,这些功能在v1.1和v1.4.2之间没有变化。然而,正如我们在通道一节中看到的,这并不意味着v1.1排序节点将在能力级别低于v1.4.2的所有通道上工作。
  • 应用程序:这些功能控制任务和处理,这些任务和处理是对等的。由于排序服务管理员在决定节点组织之间交易的性质方面没有任何作用,因此更改此功能级别只属于节点组织。例如,只能在启用v1.2(或更高版本)应用程序组功能的通道上启用私有数据。在私有数据的情况下,这是唯一必须启用的功能,因为关于私有数据的工作方式,没有任何要求更改通道管理或排序服务处理交易的方式。
  • 通道:这个分组包含由节点组织和排序服务共同管理的任务。例如,这是一种定义通道配置更新处理级别的功能,这些更新由节点组织启动,并由排序服务编排。在实际级别上,该分组定义了通道中所有二进制文件的最低级别,因为排序节点和普通节点都必须至少处于与此功能对应的二进制级别,才能处理该功能

默认情况下,通道的排序节点通道功能从排序系统通道继承,在排序系统通道中,对它们的修改是排序服务管理员的专有权限。因此,同级组织应该在将同级组织加入到某个通道之前检查该通道的“创世”模块。尽管通道功能是由排序节点系统通道中的排血节点管理的(就像联盟成员资格一样),但排序管理员通常会与联盟管理员协调,以确保只有当联盟准备好时,通道功能才得到升级。

由于排序系统通道未定义应用程序功能,因此在为通道创建创世区块时,必须在通道配置文件中指定该功能。
指定或修改应用程序功能时要小心。由于排序服务不验证功能级别是否存在,因此它允许创建(或修改)通道以包含例如v1.8应用程序功能,即使不存在此类功能。任何试图读取具有此功能的配置块的节点都会崩溃,即使可以再次将通道修改为有效的功能级别,也无所谓,因为没有节点能够通过v1.8无效功能的块。

要全面了解当前有效的排序节点、应用程序和通道功能,请查看一个示例configtx.yaml文件,其中在“功能”部分列出了它们。

有关功能及其在通道配置中的位置的详细信息,请查看定义功能需求



参考自Hyperledger Fabric官方文档
如有侵权,请联系作者删除,谢谢!
If there is infringement, please contact the author to delete, thank you!

猜你喜欢

转载自blog.csdn.net/bean_business/article/details/108746889