Hyperledger composer
简介
Hyperledger Composer是一个广泛的开放式开发工具集和框架,可简化开发区块链应用程序的过程。我们的主要目标是缩短实现价值的时间,并使您的区块链应用程序与现有业务系统的集成更加容易。您可以使用Composer快速开发用例,并在数周而不是数月内部署区块链解决方案。Composer允许您对业务网络进行建模,并将现有系统和数据与区块链应用程序集成。
Hyperledger Composer支持现有的Hyperledger Fabric区块链基础架构和运行时,它支持可插拔的区块链共识协议,以确保指定的业务网络参与者根据策略对交易进行验证。
日常应用程序可以使用业务网络中的数据,从而为最终用户提供简单且受控的访问点。
您可以使用Hyperledger Composer快速建模您当前的业务网络,其中包含您的现有资产以及与之相关的交易。资产是有形或无形的商品,服务或财产。作为业务网络模型的一部分,您定义可以与资产交互的交易。商业网络还包括与他们互动的参与者,每个参与者都可以跨多个商业网络与唯一身份相关联。
Hyperledger Composer在实践中如何工作?
例如,一个正在运行的业务网络;房地产经纪人可以快速建立自己的业务网络模型,例如:
- 资产:房屋和房屋清单
- 参加者:买家和房主
- 交易:买卖房屋,创建和关闭清单
参与者可以根据其作为买方,卖方或经纪人的角色来限制交易的访问权限。然后,房地产经纪人可以创建一个应用程序,向买方和卖方提供一个简单的用户界面,以查看公开清单和报价。该业务网络还可以与现有库存系统集成,添加新房屋作为资产并删除已售出的财产。可以将其他相关方注册为参与者,例如,土地注册处可能与买方互动以转让土地所有权。
安装
安装准备
环境:ubuntu18.04
下载脚本
curl -O https://hyperledger.github.io/composer/latest/prereqs-ubuntu.sh
赋予权限
chmod u+x prereqs-ubuntu.sh
运行脚本
./prereqs-ubuntu.sh
安装组件
步骤1:安装CLI工具
有一些对Composer开发人员有用的CLI工具。最重要的是composer-cli
,它包含所有基本操作,因此我们将首先安装它。接下来,我们还会拿起generator-hyperledger-composer
,composer-rest-server
和Yeoman
。后三部分不是开发环境的核心部分,但是如果您正在关注教程或开发与业务网络交互的应用程序,它们将非常有用,因此我们现在就安装它们。
请注意,不应将su
或sudo
用于以下npm命令。
-
基本的CLI工具:
npm install -g composer-cli@0.20
-
用于在计算机上运行REST服务器以将业务网络公开为RESTful API的实用程序:
npm install -g composer-rest-server@0.20
-
用于生成应用程序资产的有用实用程序:
npm install -g generator-hyperledger-composer@0.20
-
Yeoman是生成应用程序的工具,它利用
generator-hyperledger-composer
:npm install -g yo
步骤2:安装composer
如果您已经在线尝试过Composer,则将看到浏览器应用程序“ Playground”。您也可以在开发计算机上本地运行它,从而为您提供一个用于查看和演示业务网络的UI。
-
浏览器应用程序,用于简单地编辑和测试业务网络:
npm install -g composer-playground@0.20
步骤3:设定您的IDE
尽管可以使用浏览器应用程序处理您的业务网络代码,但大多数用户将更喜欢在IDE中工作。我们最喜欢的是VSCode
,因为可以使用Composer扩展程序。
-
从以下URL安装VSCode
-
打开VSCode,转到“扩展”,然后
Hyperledger Composer
从市场中搜索并安装扩展。
步骤4:安装Hyperledger Fabric
此步骤为您提供了本地Hyperledger Fabric运行时,以将您的业务网络部署到该运行时。
-
在您选择的目录中(我们假设
~/fabric-dev-servers
),获取.tar.gz
包含用于安装Hyperledger Fabric的工具的文件:mkdir ~/fabric-dev-servers && cd ~/fabric-dev-servers curl -O https://raw.githubusercontent.com/hyperledger/composer-tools/master/packages/fabric-dev-servers/fabric-dev-servers.tar.gz tar -xvf fabric-dev-servers.tar.gz
一个
zip
只需更换:如果你喜欢也可以.tar.gz
使用文件fabric-dev-servers.zip
和tar -xvf
使用命令unzip
在前面的代码片段的命令。 -
使用刚刚下载并解压缩的脚本来下载本地Hyperledger Fabric v1.2运行时:
cd ~/fabric-dev-servers export FABRIC_VERSION=hlfv12 ./downloadFabric.sh
恭喜,您现在已经安装了典型开发人员环境所需的所有内容。继续阅读以了解您将在此环境下进行的一些最常见的事情,以开发和测试您的区块链业务网络。
控制您的开发环境
启动和停止Hyperledger Fabric
~/fabric-dev-servers
如果遵循建议的默认值,则可以使用一组脚本来控制运行时。
首次启动新的运行时时,需要运行启动脚本,然后生成PeerAdmin卡:
cd ~/fabric-dev-servers export FABRIC_VERSION=hlfv12 ./startFabric.sh ./createPeerAdminCard.sh
您可以使用启动和停止运行时~/fabric-dev-servers/stopFabric.sh
,然后使用重新启动~/fabric-dev-servers/startFabric.sh
。
在开发会话结束时,运行~/fabric-dev-servers/stopFabric.sh
,然后运行~/fabric-dev-servers/teardownFabric.sh
。请注意,如果您运行了拆解脚本,则下次启动运行时时,将需要创建新的PeerAdmin卡,就像第一次启动时一样。
本地运行时旨在频繁启动,停止和拆除,以供开发使用。如果您正在寻找具有更持久状态的运行时,则需要在开发环境之外运行一个,并在其中部署业务网络。例如,可以通过Kubernetes或在IBM Cloud等托管平台上运行它。
启动网络应用(“游乐场”)
要启动Web应用程序,请运行:
composer-playground
它通常会自动在以下地址打开浏览器:http:// localhost:8080/login
您应该在Web应用程序的“我的业务网络”屏幕上看到PeerAdmin@hlfv1
使用createPeerAdminCard
脚本创建的Card :如果没有看到此消息,则可能是您没有正确启动运行时!
恭喜,您已经运行了所有组件,并且您还知道在完成开发会话后如何停止和拆除它们。
教程
游乐场教程
在本分步教程中,我们将逐步建立业务网络,定义我们的资产,参与者和交易,并通过创建一些参与者和资产并提交交易以将资产的所有权从一个变为另一个来测试我们的网络。另一个。本教程旨在用作使用在线游乐场环境的Hyperledger Composer概念的简介。
第一步:打开Hyperledger Composer游乐场
打开Composer Playground(请注意,此链接会将您带到Web Composer Playground-如果您已经安装了开发环境,则也可以使用本地版本)。
您应该看到“ 我的业务网络”屏幕。在我的商业网络,您可以使用页面显示您的业务网络可以连接到的摘要,以及身份连接到它们。暂时不要担心太多,因为我们将创建自己的网络。
第二步:建立新的业务网络
接下来,我们要从头开始创建新的业务网络。一个业务网络具有几个定义属性。名称和可选说明。您也可以选择在现有模板上建立新的业务网络,或导入自己的模板。
-
单击“ Web浏览器”标题下的“ 部署新业务网络 ”以开始使用。
-
新的业务网络需要一个名称,我们称它为
tutorial-network
。 -
(可选)您可以输入业务网络的描述。
-
接下来,我们必须选择一个业务网络作为基础,因为我们要从头开始构建网络,请单击empty-business-network。
-
现在已经定义了我们的网络,点击Deploy。
注意:如果您在本地使用游乐场并连接到真实的 Fabric,请参考教程底部的其他说明。
第三步:连接到业务网络
现在我们已经创建并部署了业务网络,您应该在钱包中看到一个名为admin的新业务网络卡,用于我们的业务网络教程网络。钱包可以包含用于连接到多个已部署业务网络的业务网卡。
连接到外部区块链时,商务网卡代表了连接到商务网络所需的一切。它们包括连接详细信息,身份验证材料和元数据。
要连接到我们的业务网络,请单击我们的业务网络卡下方的立即连接。
第四步:添加模型文件
如您所见,我们现在位于“ 定义”选项卡中,在此选项卡中可以创建和编辑组成业务网络定义的文件,然后再部署这些文件并使用“ 测试”选项卡对其进行测试。
当我们选择一个空的业务网络模板时,我们需要修改提供的模板文件。第一步是更新模型文件。模型文件定义了我们业务网络中的资产,参与者,交易和事件。
有关我们的建模语言的更多信息,请查阅我们的文档。
-
单击模型文件进行查看。
-
删除模型文件中的代码行,并将其替换为:
/** * My commodity trading network */ namespace org.example.mynetwork asset Commodity identified by tradingSymbol { o String tradingSymbol o String description o String mainExchange o Double quantity --> Trader owner } participant Trader identified by tradeId { o String tradeId o String firstName o String lastName } transaction Trade { --> Commodity commodity --> Trader newOwner }
该域模型定义用于修改商品所有者的单一资产类型
Commodity
,单一参与者类型Trader
和单一交易类型Trade
。
第五步:添加事务处理器脚本文件
现在已经定义了域模型,我们可以定义业务网络的事务逻辑。Composer使用JavaScript函数表达业务网络的逻辑。当提交交易进行处理时,这些功能会自动执行。
有关编写事务处理器功能的更多信息,请参阅我们的文档。
-
单击添加文件按钮。
-
单击脚本文件,然后单击添加。
-
删除脚本文件中的代码行,并将其替换为以下代码:
/** * Track the trade of a commodity from one trader to another * @param {org.example.mynetwork.Trade} trade - the trade to be processed * @transaction */ async function tradeCommodity(trade) { trade.commodity.owner = trade.newOwner; let assetRegistry = await getAssetRegistry('org.example.mynetwork.Commodity'); await assetRegistry.update(trade.commodity); }
此功能仅
owner
根据newOwner
传入Trade
交易的属性更改商品的属性。然后,它将修改Commodity
后的内容持久化回资产注册表中,用于存储Commodity
实例。
第六步:访问控制
访问控制文件定义业务网络的访问控制规则。我们的网络很简单,因此不需要编辑默认的访问控制文件。基本文件使当前参与者可以networkAdmin
完全访问业务网络和系统级操作。
虽然可以有多个模型或脚本文件,但在任何业务网络中只能有一个访问控制文件。
有关访问控制文件的更多信息,请参阅我们的文档。
第七步:部署更新的业务网络
现在我们有了模型,脚本和访问控制文件,我们需要部署和测试我们的业务网络。
单击部署更改以升级业务网络。
注意:如果您在本地使用游乐场并连接到真实的 Fabric,请参考教程底部的其他说明。
第八步:测试业务网络定义
接下来,我们需要通过创建一些参与者(在本例中为Traders),创建资产(商品),然后使用我们的贸易交易来更改商品所有权来测试我们的业务网络。
单击测试选项卡以开始。
第九步:创建参与者
我们应该添加到业务网络中的第一件事是两个参与者。
-
确保在左侧选择了交易者选项卡,然后单击右上方的创建新参与者。
-
您将看到交易者参与者的数据结构。我们需要一些易于识别的数据,因此请删除其中的代码并粘贴以下内容:
{ "$class": "org.example.mynetwork.Trader", "tradeId": "TRADER1", "firstName": "Jenny", "lastName": "Jones" }
-
单击“ 新建”以创建参与者。
-
您应该能够看到您创建的新交易者参与者。我们需要另一个交易来测试我们的贸易交易虽然如此,创建另一个交易,但是这一次,使用下面的数据:
{ "$class": "org.example.mynetwork.Trader", "tradeId": "TRADER2", "firstName": "Amy", "lastName": "Williams" }
在继续之前,请确保两个参与者都存在于操盘手视图中!
第十步:创建资产
现在我们有两个交易者参与者,我们需要一些东西让他们交易。创建资产与创建参与者非常相似。该商品我们创建将有一个老板,表明它属于财产交易与tradeId的TRADER1
。
-
单击资产下的商品标签,然后单击创建新资产。
-
删除资产数据并将其替换为以下内容:
{ "$class": "org.example.mynetwork.Commodity", "tradingSymbol": "ABC", "description": "Test commodity", "mainExchange": "Euronext", "quantity": 72.297, "owner": "resource:org.example.mynetwork.Trader#TRADER1" }
-
创建此资产后,您应该能够在“ 商品”选项卡中看到它。
步骤十一:在参与者之间转移商品
现在,我们有两个交易商和商品对他们之间的贸易,我们可以测试我们的贸易事务。
事务是Hyperledger Composer业务网络中所有更改的基础,如果您想在本教程之后尝试自己的业务,请尝试从“ 我的业务网络”屏幕并使用更高级的业务网络模板创建另一个业务网络。
要测试贸易交易:
-
单击左侧的“ 提交事务”按钮。
-
确保交易类型为Trade。
-
用以下内容替换事务数据,或仅更改详细信息:
{ "$class": "org.example.mynetwork.Trade", "commodity": "resource:org.example.mynetwork.Commodity#ABC", "newOwner": "resource:org.example.mynetwork.Trader#TRADER2" }
-
点击提交。
-
检查我们的资产已经改变所有权从
TRADER1
到TRADER2
,通过扩大资产数据部分。您应该看到所有者列为resource:org.example.mynetwork.Trader#TRADER2
。 -
要查看我们业务网络的完整交易记录,请单击左侧的“ 所有交易 ”。这是提交的每笔交易的列表。您可以看到,即使未在我们的业务网络模型中将交易定义为交易,我们使用UI进行的某些操作(例如创建交易者参与者和商品资产)也被记录为交易。这些事务称为“系统事务”,是所有业务网络通用的,并在Hyperledger Composer运行时中定义。
注销业务网络
现在,事务已成功运行,我们应该注销业务网络,并在开始的“ 我的业务网络”屏幕上结束。
- 在屏幕的右上角是一个标记为admin的按钮。这将列出您当前的身份,要注销,请单击admin打开下拉菜单,然后单击我的业务网络。
将业务网络部署到真实结构。
在本地使用Playground,您可以使用与在浏览器本地存储中工作的“ Web浏览器”的连接,也可以在通常称为“ hlfv1”的组中使用与真实 Fabric的连接。
如果您要连接到真实的 Fabric,则可能已经为具有PeerAdmin和ChannelAdmin角色的身份创建了Card(通常称为PeerAdmin)。这是用于通过Composer部署和更新网络的卡。
将网络部署到真实 Fabric时,需要单击“ 部署”按钮,还需要完成其他字段-您需要提供网络管理员的详细信息。
滚动到“部署”屏幕的底部,找到用于网络管理员的凭据。对于简单的Development Fabric和许多测试网络,您可以提供ID和密码。注册ID-管理员注册机密-adminpw
指定ID和密码后,您可以单击“ 部署”按钮,然后在第三步继续教程。
如果使用的是自定义或生产结构,请与结构管理员联系以获取网络管理员的详细信息。
连接到真实结构时更新业务网络
当您使用真实的 Fabric并单击Deploy Changes时,您将看到一个附加弹出对话框,要求您从下拉列表中指定安装卡和升级卡。通常,您指定与用于部署初始网络相同的PeerAdmin卡。如果不确定,请与结构管理员联系。
选择卡,然后单击升级按钮。请注意,在实际的Fabric上,这可能需要几分钟才能完成。
在第八步继续教程。
开发人员教程
本教程将引导您从头开始构建Hyperledger Composer区块链解决方案。在几个小时的时间内,您将能够从颠覆性的区块链创新的构想,到针对真正的Hyperledger Fabric区块链网络执行交易,以及生成/运行与区块链网络交互的示例Angular 2应用程序。
本教程概述了可用于您自己的用例的技术和资源。
注意:本教程是针对在运行Hyperledger Fabric v1.2的Ubuntu Linux上构建的最新Hyperledger Composer编写的,下面对此进行了引用,并且还针对Mac环境进行了测试。
先决条件
在开始本教程之前:
- 设置您的开发环境
- 安装编辑器,例如VSCode或Atom
第一步:创建业务网络结构
Hyperledger Composer的关键概念是业务网络定义(BND)。它为您的区块链解决方案定义了数据模型,交易逻辑和访问控制规则。要创建BND,我们需要在磁盘上创建合适的项目结构。
最简单的入门方法是使用Yeoman生成器来创建骨架业务网络。这将创建一个目录,其中包含业务网络的所有组件。
-
使用Yeoman创建骨架业务网络。该命令将需要一个商业网络名称,描述,作者名称,作者电子邮件地址,许可证选择和名称空间。
yo hyperledger-composer:businessnetwork
-
输入
tutorial-network
网络名称,以及用于描述,作者名称和作者电子邮件的所需信息。 -
选择
Apache-2.0
作为许可证。 -
选择
org.example.mynetwork
作为名称空间。 -
选择
No
当询问是否生成一个空网络。
第二步:定义业务网络
商业网络由资产,参与者,交易,访问控制规则以及可选的事件和查询组成。在前面的步骤中创建的基本业务网络中,有一个model(.cto
)文件,其中将包含业务网络中所有资产,参与者和交易的类定义。骨架业务网络还包含permissions.acl
具有基本访问控制规则的访问控制()文档,logic.js
包含事务处理器功能的脚本()文件以及package.json
包含业务网络元数据的文件。
建模资产,参与者和交易
要更新的第一个文档是模型(.cto
)文件。该文件是使用Hyperledger Composer建模语言编写的。模型文件包含资产,交易,参与者和事件的每个类别的定义。它隐式扩展了建模语言文档中描述的Hyperledger Composer系统模型。
-
打开
org.example.mynetwork.cto
模型文件。 -
用以下内容替换内容:
/** * My commodity trading network */ namespace org.example.mynetwork asset Commodity identified by tradingSymbol { o String tradingSymbol o String description o String mainExchange o Double quantity --> Trader owner } participant Trader identified by tradeId { o String tradeId o String firstName o String lastName } transaction Trade { --> Commodity commodity --> Trader newOwner }
-
将更改保存到
org.example.mynetwork.cto
。
添加JavaScript事务逻辑
在模型文件中,Trade
定义了交易,指定了与资产和参与者的关系。事务处理器功能文件包含执行模型文件中定义的事务的JavaScript逻辑。
该Trade
交易旨在仅接受Commodity
要交易的资产的标识符,以及Trader
要设置为新所有者的参与者的标识符。
-
打开
logic.js
脚本文件。 -
用以下内容替换内容:
/** * Track the trade of a commodity from one trader to another * @param {org.example.mynetwork.Trade} trade - the trade to be processed * @transaction */ async function tradeCommodity(trade) { trade.commodity.owner = trade.newOwner; let assetRegistry = await getAssetRegistry('org.example.mynetwork.Commodity'); await assetRegistry.update(trade.commodity); }
-
将更改保存到
logic.js
。
添加访问控制
-
替换文件中的以下访问控制规则
permissions.acl
:/** * Access control rules for tutorial-network */ rule Default { description: "Allow all participants access to all resources" participant: "ANY" operation: ALL resource: "org.example.mynetwork.*" action: ALLOW } rule SystemACL { description: "System ACL to permit all access" participant: "ANY" operation: ALL resource: "org.hyperledger.composer.system.**" action: ALLOW }
-
将更改保存到
permissions.acl
。
第三步:生成业务网络存档
现在已经定义了业务网络,必须将其打包到可部署的业务网络存档(.bna
)文件中。
-
使用命令行浏览到
tutorial-network
目录。 -
在
tutorial-network
目录中,运行以下命令:composer archive create -t dir -n .
运行该命令后,tutorial-network@0.0.1.bna
已在tutorial-network
目录中创建了一个名为的业务网络归档文件。
第四步:部署业务网络
创建.bna
文件后,可以将业务网络部署到Hyperledger Fabric实例。通常,需要来自Fabric管理员的信息来创建PeerAdmin
身份,并具有将链码安装到对等方以及在composerchannel
通道上启动链码的特权。但是,作为开发环境安装的一部分,PeerAdmin
已经创建了一个标识。
安装业务网络后,可以启动网络。为了最佳实践,应在部署后创建一个新的身份来管理业务网络。此身份称为网络管理员。
检索正确的凭证
一个PeerAdmin
有正确的凭据业务网络卡已为开发环境安装的一部分创建的。
部署业务网络
将业务网络部署到Hyperledger Fabric要求将Hyperledger Composer业务网络安装在对等方上,然后可以启动业务网络,并且必须创建新的参与者,身份和关联的卡才能成为网络管理员。最后,必须导入网络管理员业务网卡以供使用,然后可以对网络执行ping操作以检查其是否在响应。
-
要安装业务网络,请从
tutorial-network
目录运行以下命令:composer network install --card PeerAdmin@hlfv1 --archiveFile tutorial-network@0.0.1.bna
该
composer network install
命令要求使用PeerAdmin名片(在这种情况下,是事先创建和导入的),并且其文件路径.bna
定义了名片网络。 -
要启动业务网络,请运行以下命令:
composer network start --networkName tutorial-network --networkVersion 0.0.1 --networkAdmin admin --networkAdminEnrollSecret adminpw --card PeerAdmin@hlfv1 --file networkadmin.card
该
composer network start
命令需要一个商务网卡,以及该商务网的管理员身份名称,该商务网的名称和版本以及要创建的准备导入为商务网卡的文件的名称。 -
要将网络管理员身份导入为可用的商务网卡,请运行以下命令:
composer card import --file networkadmin.card
该
composer card import
命令需要使用中指定的文件名composer network start
来创建卡。 -
要检查业务网络是否已成功部署,请运行以下命令来ping通网络:
composer network ping --card admin@tutorial-network
该composer network ping
命令需要一张商务网卡才能识别要ping的网络。
第五步:生成REST服务器
Hyperledger Composer可以基于业务网络生成定制的REST API。对于开发Web应用程序,REST API提供了一个有用的语言无关的抽象层。
-
要创建REST API,请导航至
tutorial-network
目录并运行以下命令:composer-rest-server
-
输入
admin@tutorial-network
作为卡名。 -
选择 决不当询问是否在生成的API中使用名称空间时,请使用名称空间。
-
选择 没有 当询问是否保护生成的API。
-
选择 是 当询问是否启用事件发布。
-
选择 没有 当询问是否启用TLS安全性时。
生成的API连接到已部署的区块链和业务网络。
第六步:生成骨架Angular应用程序
Hyperledger Composer还可以生成针对REST API运行的Angular 4应用程序。
-
要创建Angular 4应用程序,请导航至
tutorial-network
目录并运行以下命令:yo hyperledger-composer:angular
-
选择 是 当要求连接到正在运行的业务网络时。
-
输入标准
package.json
问题(项目名称,描述,作者姓名,作者电子邮件,许可证) -
输入
admin@tutorial-network
用于商务网卡。 -
选择“ 连接到现有的REST API”
-
输入
http://localhost
REST服务器地址。 -
输入
3000
用于服务器端口。 -
选择不使用命名空间
然后,Angular生成器将为项目创建支架并安装所有依赖项。要运行该应用程序,请导航到您的角度项目目录并运行 npm start
。这将启动针对您的REST API运行的Angular 4应用程序 http://localhost:4200
。
注意:Yo Angular应用程序生成器旨在基于简单和基本的业务网络模型定义(例如trade-network
此处的网络模型)生成框架Web应用程序。在编写Web应用程序中查看更多Angular生成器
使用Composer查询语言和REST API的查询教程
在本教程中,我们将在开发人员教程的基础上进行扩展,以演示查询。本机查询语言可以过滤使用条件返回的结果,并可以在事务中调用以执行操作,例如更新或删除结果集上的资产。
查询是在.qry
业务网络定义的父目录中的查询文件()中定义的。查询包含WHERE子句,该子句定义选择资产或参与者的标准。
本教程使用tutorial-network
在Developer-Tutorial中开发和部署的业务网络。
先决条件
在开始本教程之前:
第一步:更新业务网络
开发人员教程中创建的业务网络必须进行更新。更新后的业务网络包含两个事件和一个附加事务。
更新模型文件
必须更新模型文件以包含事件和新事务。
-
打开的模型(
.cto
)文件tutorial-network
。 -
将以下事件和事务添加到模型:
event TradeNotification { --> Commodity commodity } transaction RemoveHighQuantityCommodities { } event RemoveNotification { --> Commodity commodity }
-
将更改保存到模型。
更新事务逻辑以使用查询和事件
现在已经更新了域模型,我们可以编写在提交事务进行处理时执行的其他业务逻辑。在本教程中,我们将事件和查询添加到下面的业务逻辑中。
-
打开事务处理器功能文件
lib/logic.js
。 -
用以下JavaScript替换事务逻辑:
/** * Track the trade of a commodity from one trader to another * @param {org.example.mynetwork.Trade} trade - the trade to be processed * @transaction */ async function tradeCommodity(trade) { // set the new owner of the commodity trade.commodity.owner = trade.newOwner; let assetRegistry = await getAssetRegistry('org.example.mynetwork.Commodity'); // emit a notification that a trade has occurred let tradeNotification = getFactory().newEvent('org.example.mynetwork', 'TradeNotification'); tradeNotification.commodity = trade.commodity; emit(tradeNotification); // persist the state of the commodity await assetRegistry.update(trade.commodity); } /** * Remove all high volume commodities * @param {org.example.mynetwork.RemoveHighQuantityCommodities} remove - the remove to be processed * @transaction */ async function removeHighQuantityCommodities(remove) { let assetRegistry = await getAssetRegistry('org.example.mynetwork.Commodity'); let results = await query('selectCommoditiesWithHighQuantity'); for (let n = 0; n < results.length; n++) { let trade = results[n]; // emit a notification that a trade was removed let removeNotification = getFactory().newEvent('org.example.mynetwork','RemoveNotification'); removeNotification.commodity = trade; emit(removeNotification); await assetRegistry.remove(trade); } }
-
将更改保存到
logic.js
。
第一个功能tradeCommodity
将在传入的贸易交易中更改商品的所有者属性(具有新的所有者所有者),并发出相应的Notification事件。然后,它将修改后的商品持久化回资产注册表中,该资产注册表用于存储商品实例。
第二个函数调用一个命名查询“ selectCommoditiesWithHighQuantity”(在中定义queries.qry
),它将返回数量大于60的所有商品资产记录;发出事件; 并从AssetRegistry中删除该商品。
第二步:创建查询定义文件
事务处理程序逻辑使用的查询在必须调用的文件中定义queries.qry
。每个查询条目定义执行查询所依据的资源和条件。
-
在
tutorial-network
目录中,创建一个名为的新文件queries.qry
。 -
将以下代码 并粘贴到
queries.qry
:/** Sample queries for Commodity Trading business network */ query selectCommodities { description: "Select all commodities" statement: SELECT org.example.mynetwork.Commodity } query selectCommoditiesByExchange { description: "Select all commodities based on their main exchange" statement: SELECT org.example.mynetwork.Commodity WHERE (mainExchange==_$exchange) } query selectCommoditiesByOwner { description: "Select all commodities based on their owner" statement: SELECT org.example.mynetwork.Commodity WHERE (owner == _$owner) } query selectCommoditiesWithHighQuantity { description: "Select commodities based on quantity" statement: SELECT org.example.mynetwork.Commodity WHERE (quantity > 60) }
-
将更改保存到
queries.qry
。
第三步:重新生成您的业务网络存档
在业务网络中更改文件后,必须将业务网络重新打包为业务网络存档(.bna
),然后重新部署到Hyperledger Fabric实例。升级已部署的网络要求所部署的新版本具有新的版本号。
-
在
tutorial-network
目录中,打开package.json
文件。 -
将version属性从更新
0.0.1
为0.0.2
。 -
使用命令行导航到
tutorial-network
目录。 -
运行以下命令:
composer archive create --sourceType dir --sourceName . -a tutorial-network@0.0.2.bna
第四步:部署更新的业务网络定义
我们需要部署修改后的网络以使其成为区块链上的最新版本!我们正在使用新创建的归档业务网络归档文件来更新现有已部署的业务网络;这是我们在《开发人员指南》中使用的相同的商业网络名称。
-
切换到终端,将目录更改为包含的文件夹
tutorial-network@0.0.2.bna
。 -
运行以下命令以安装更新的业务网络:
composer network install --card PeerAdmin@hlfv1 --archiveFile tutorial-network@0.0.2.bna
-
运行以下命令以将网络升级到新版本:
composer network upgrade -c PeerAdmin@hlfv1 -n tutorial-network -V 0.0.2
-
在使用以下命令继续之前,请检查业务网络的当前版本:
composer network ping -c admin@tutorial-network | grep Business
第五步:为更新的业务网络重新生成REST API
现在,我们将使用添加的查询来集成新近更新的业务网络,并公开该业务网络的REST API。
-
使用命令行导航到
tutorial-network
目录。 -
使用以下命令启动REST服务器:
composer-rest-server
-
输入
admin@tutorial-network
作为卡名。 -
当询问是否在生成的API中使用名称空间时,请选择从不使用名称空间。
-
当询问是否保护生成的API时,选择No。
-
当询问是否启用事件发布时,选择“ 是 ”。
-
当询问是否启用TLS安全性时,选择No。
第六步:测试REST API并创建一些数据
打开网络浏览器并导航到http://本地主机:3000 / explorer。您应该看到LoopBack API Explorer,使您可以检查和测试生成的REST API。
我们应该能够看到已经添加了称为“查询”的REST端点,并在扩展后显示了业务网络中定义的REST Query操作的列表。 tutorial-network
在继续之前,我们需要创建一些数据,以充分展示查询。使用提供的样本JSON数据,使用REST API创建3个交易者(参与者)以及其他一些商品(资产)。
-
首先,在REST Explorer中单击“ Trader”,然后在/ Trader上单击“ POST”方法,然后向下滚动到“ Parameter”部分-依次创建以下Trader实例:
{ "$class": "org.example.mynetwork.Trader", "tradeId": "TRADER1", "firstName": "Jenny", "lastName": "Jones" }
-
点击“试用”以创建参与者。“响应代码”(向下滚动)应为200(成功)
-
通过 以下JSON创建另一个交易者:
{ "$class": "org.example.mynetwork.Trader", "tradeId": "TRADER2", "firstName": "Jack", "lastName": "Sock" }
-
通过处理以下JSON创建第三个交易者:
{ "$class": "org.example.mynetwork.Trader", "tradeId": "TRADER3", "firstName": "Rainer", "lastName": "Valens" }
-
现在滚动到顶部,然后在REST资源管理器中单击“商品”对象。
-
单击POST操作,然后向下滚动至Parameters部分:以与上述相同的方式,为所有者TRADER1和TRADER2创建两个商品资产记录(见下文):
{
"$class": "org.example.mynetwork.Commodity",
"tradingSymbol": "EMA",
"description": "Corn",
"mainExchange": "EURONEXT",
"quantity": 10,
"owner": "resource:org.example.mynetwork.Trader#TRADER1"
}
{
"$class": "org.example.mynetwork.Commodity",
"tradingSymbol": "CC",
"description": "Cocoa",
"mainExchange": "ICE",
"quantity": 80,
"owner": "resource:org.example.mynetwork.Trader#TRADER2"
}
第七步:使用商品交易REST API资源管理器执行查询
现在我们有了一些资产和参与者,我们可以使用生成的查询REST操作测试一些查询。
执行一个简单的REST查询
现在我们有了资产和参与者,我们可以尝试一些查询。
我们可以首先尝试的最简单的REST查询是命名查询selectCommodities
。
展开“查询” REST端点,您将看到我们在模型中定义的命名查询。
这些查询现在作为REST查询公开,并为其生成/ GET操作。请注意,查询的描述(我们在模型定义中定义)显示在右侧。
-
展开
selectCommodities
查询。 -
点击“试用”按钮。
它将退还所有现有商品-应该退还2件资产。
执行过滤的REST查询
让我们通过其交易所选择所有商品-例如“ EURONEXT”主交易所。
-
展开查询端点“ selectCommoditiesByExchange”,然后滚动到“参数”部分。
-
在“ Exchange”参数中输入“ EURONEXT”。
-
点击“试用”。
结果显示,响应主体中仅显示了带有“ EURONEXT”交换的商品
使用命名查询的结果执行事务更新
最后,您还记得我们已经定义了一个简单查询,该查询可以在查询文件中过滤数量大于60的商品。当在事务功能中使用时,查询功能非常强大,例如,使用查询允许事务逻辑设置资产集或参与者集以对其进行更新或创建删除操作。
我们selectCommoditiesWithHighQuantity
在removeHighQuantityCommodities
事务中使用查询。如果在REST资源管理器中执行此/ GET操作,您将看到它仅选择数量大于60的那些资产。
现在,让我们使用查询执行大批量商品的删除。
首先,请检查一下自己有多少种商品(使用“商品” / GET操作),然后应该至少看到两种商品,其中一种(可可)的数量大于60。
让我们检查一下实际查询,方法是单击REST端点/selectCommoditiesWithHighQuantity
,然后单击/ GET,然后向下滚动到“ Try it Out”(试一试)-应该有一个符合条件的商品。
好。现在,让我们执行一个REST事务,该事务使用“高数量”查询定义来确定要删除的商品。
单击RemoveHighQuantityCommodities REST端点以显示/ POST操作。
点击POST,向下滚动到参数部分,并点击“试一试外” -记:你不必须在“数据”部分输入任何数据。
向下滚动,您应该看到一个transactionId,它代表事务处理器功能内部的“删除”调用(本身是区块链事务),并将更新世界状态-响应码应为200
最后,让我们验证我们的商品状态。返回“商品” REST操作,然后再次执行/ GET操作。...“尝试一下”。
结果应表明商品资产“可可”已经消失,即仅剩余数量小于等于60的商品资产,在我们的示例中为资产“玉米”。命名查询提供了交易更新(以删除大量商品),并在业务逻辑中执行。
恭喜你!
做得好,您现在已经完成了本教程,希望您现在对Composer中查询的功能有了更好的了解。您可以开始创建/构建自己的查询(或修改现有查询并向该业务网络添加相关数据-注意:您需要重新部署所有查询更改)才能尝试!
将Hyperledger Composer区块链业务网络部署到单个组织的Hyperledger Fabric
在开发环境中,将为您(fabric-dev-servers
)创建一个仅用于开发的简单Hyperledger Fabric单一组织,单个对等网络,以及部署区块链业务网络所需的所有Hyperledger Composer配置。
本教程将演示管理员为了将区块链业务网络部署到单个组织的Hyperledger Fabric实例而需要采取的步骤,包括如何生成必要的Hyperledger Composer配置。随后的教程将演示如何为多个组织将区块链业务网络部署到Hyperledger Fabric实例。
在本教程中,您可能希望参考Hyperledger Fabric文档。
先决条件
- 在继续之前,请确保已按照安装开发环境中的步骤进行操作。
第一步:启动Hyperledger Fabric网络
为了遵循本教程,您必须启动Hyperledger Fabric网络。您可以使用开发环境中提供的简单Hyperledger Fabric网络,也可以使用通过遵循Hyperledger Fabric文档而构建的自己的Hyperledger Fabric网络。
本教程将假定您使用开发环境中提供的简单Hyperledger Fabric网络。如果您使用自己的Hyperledger Fabric网络,则必须在下面详述的配置和您自己的配置之间进行映射,并且它应该是单个组织网络。
-
通过运行以下命令来启动干净的Hyperledger Fabric:
cd ~/fabric-dev-servers export FABRIC_VERSION=hlfv12 ./stopFabric.sh ./teardownFabric.sh ./downloadFabric.sh ./startFabric.sh
-
删除钱包中可能存在的所有商务网卡。可以忽略所有指出找不到商务网卡的错误,这是很安全的:
composer card delete -c PeerAdmin@fabric-network composer card delete -c admin@tutorial-network
如果这些命令失败,则说明您具有以前版本的网卡,并且必须删除文件系统卡存储。
rm -fr ~/.composer
第二步:探索Hyperledger Fabric网络
此步骤将探索刚刚启动的Hyperledger Fabric网络,以便您可以了解其配置方式以及组成的组件。在后续步骤中,您将使用本节中的所有信息来配置Hyperledger Composer。
配置文件
开发环境中提供的简单Hyperledger Fabric网络已使用Hyperledger Fabric配置工具cryptogen
和进行了配置configtxgen
。
的配置cryptogen
存储在文件中:
~/fabric-dev-servers/fabric-scripts/hlfv12/composer/crypto-config.yaml
的配置configtxgen
存储在文件中:
~/fabric-dev-servers/fabric-scripts/hlfv12/composer/configtx.yaml
通过阅读Hyperledger Fabric文档,您可以找到有关这些配置工具,它们的功能以及如何使用它们的更多信息。
组织机构
简单的Hyperledger Fabric网络由一个名为的单一组织组成Org1
。组织使用域名org1.example.com
。此外,该组织的会员服务提供商(MSP)称为Org1MSP
。在本教程中,您将部署仅组织Org1
可以与之交互的区块链业务网络。
网络组件
Hyperledger Fabric网络由以下几部分组成:
- 的一个对等节点
Org1
,名为peer0.org1.example.com
。- 请求端口是7051。
- 事件集线器端口是7053。
- 的单个证书颁发机构(CA)
Org1
,名为ca.org1.example.com
。- CA端口是7054。
- 一个名为的订购者节点
orderer.example.com
。- 订购者端口为7050。
Hyperledger Fabric网络组件在Docker容器中运行。在Docker容器中运行Hyperledger Composer时,peer0.org1.example.com
可以使用以上名称(例如)与Hyperledger Fabric网络进行交互。
本教程将在Docker主机上而不是在Docker网络内部运行Hyperledger Composer命令。这意味着Hyperledger Composer命令必须使用localhost
主机名和公开的容器端口与Hyperledger Fabric网络进行交互。
用户数
该组织Org1
配置了一个名为的用户Admin@org1.example.com
。该用户是管理员。组织的管理员有权将区块链业务网络的代码安装到其组织的对等方,也可以根据配置来启动区块链业务网络。在本教程中,您将通过充当用户来部署区块链业务网络Admin@org1.example.com
。
用户Admin@org1.example.com
在目录中存储了一组证书和私钥文件:
~/fabric-dev-servers/fabric-scripts/hlfv12/composer/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
稍后,您将使用其中一些文件与Hyperledger Fabric网络进行交互。
除了管理员外,Org1
还使用默认用户配置了CA(证书颁发机构)。该默认用户的注册ID为admin
,注册密码为adminpw
。但是,该用户无权部署区块链业务网络。
渠道
最后,composerchannel
已创建一个名为的通道。对等节点peer0.org1.example.com
已加入此通道。您只能将Hyperledger Composer区块链业务网络部署到现有渠道中,但可以通过遵循Hyperledger Fabric文档来创建其他渠道。
第三步:建立连接配置文件
连接配置文件指定查找和连接到Hyperledger Fabric网络所需的所有信息,例如,所有Hyperledger Fabric网络组件的主机名和端口。在此步骤中,您将为Hyperledger Composer创建一个连接配置文件,以用于连接到Hyperledger Fabric网络。
-
创建一个名为的连接配置文件
connection.json
。 -
给连接配置文件
name
,version
并x-type
通过添加以下三行的顶部性质connection.json
:{ "name": "fabric-network", "x-type": "hlfv1", "version": "1.0.0",
name
连接配置文件中的属性为Hyperledger Fabric网络命名,因此我们以后可以引用它。在刚创建的连接配置文件中,名称为fabric-network
。您可以为Hyperledger Fabric网络使用任何您喜欢的名称。Hyperledger Composer设计为与不同类型的区块链网络兼容。当前,仅支持Hyperledger Fabric v1.x,但是您必须指定要使用的区块链网络的类型。Hyperledger Fabric v1.2的x类型是
hlfv1
。版本号是此连接配置文件格式的版本。目前只有的1个版本
1.0.0
。还有一个可选属性
x-commitTimeout
,也可以使用定义该属性,该属性定义Hyperledger Composer在放弃等待之前应等待多长时间将提交的事务提交给组织的对等方。如果未指定,则默认值为300 seconds
。 -
我们必须指定Hyperledger Fabric网络中所有对等节点的主机名和端口。只有1个同peer,我们给它加了个标签
peer0.org1.example.com
。"peers": { "peer0.org1.example.com": { "url": "grpc://localhost:7051" } },
在这里,我们指定了单个对等节点
peer0.org1.example.com
(使用主机名localhost
),请求端口7051和事件集线器端口7053。该
peers
数组可以包含多个对等节点。如果您有多个对等节点,则应将它们全部添加到peers
对象中。 -
我们必须在Hyperledger Fabric网络中指定要用于注册现有用户和注册新用户的证书颁发机构(CA)的主机名和端口。
"certificateAuthorities": { "ca.org1.example.com": { "url": "http://localhost:7054", "caName": "ca.org1.example.com" } },
在这里,我们指定了单个CA
ca.org1.example.com
(使用hostnamelocalhost
)和CA端口7054,并将此条目标记为ca-org1.example.com
-
我们必须在要连接的Hyperledger Fabric中指定所有订购节点的主机名和端口。
"orderers": { "orderer.example.com": { "url": "grpc://localhost:7050" } },
在这里,我们指定了单个订购者节点
orderer.example.com
(使用hostnamelocalhost
)和订购者端口7050,并将其标记为orderer.example.com
。该
orderers
对象可以包含多个订购者节点。如果您有多个订购者节点,则应将它们全部添加到orderers
对象中。 -
现在,我们必须指定网络中的所有组织。在本教程中,只有1个组织
Org1
。"organizations": { "Org1": { "mspid": "Org1MSP", "peers": [ "peer0.org1.example.com" ], "certificateAuthorities": [ "ca.org1.example.com" ] } },
在这里,我们描述了对等方的所有者以及其证书颁发机构是谁,此外,我们还声明了为此组织定义的MSP ID。在本教程中,它已定义为
Org1MSP
。 -
我们必须指定现有频道的名称。我们将在区块链中部署我们的区块链业务网络
composerchannel
。这是在通道对象中定义的。"channels": { "composerchannel": { "orderers": [ "orderer.example.com" ], "peers": { "peer0.org1.example.com": { "endorsingPeer": true, "chaincodeQuery": true, "eventSource": true } } } },
在这里,我们定义了通道
composerchannel
,还定义了该通道的订购者和同伴。我们还指定对等方将在此通道中执行的角色。在本教程中,我们添加了先前使用其标签引用的单个订购者和单个对等方。对等方将安装业务网络,因此将成为交易认可方,能够处理链码查询并生成事件。区块链业务网络将部署到所有指定的对等节点。部署区块链业务网络后,指定的对等节点将用于查询区块链业务网络,认可交易和订阅事件。 -
所需的最后一部分是客户端部分。客户端应用程序(例如Hyperledger Composer)使用它来了解它在交互时所代表的组织以及一些额外的可选超时。
"client": { "organization": "Org1", "connection": { "timeout": { "peer": { "endorser": "300", "eventHub": "300", "eventReg": "300" }, "orderer": "300" } } } }
在这里,我们指定我们在Org1
。超时用于确定与对等方或订购者进行交互时等待响应的时间,并且以秒为单位指定值。如果您未指定任何内容,则默认值为45 seconds
。
-
将更改保存到
connection.json
。完成的连接配置文件应如下所示:{ "name": "fabric-network", "x-type": "hlfv1", "version": "1.0.0", "peers": { "peer0.org1.example.com": { "url": "grpc://localhost:7051" } }, "certificateAuthorities": { "ca.org1.example.com": { "url": "http://localhost:7054", "caName": "ca.org1.example.com" } }, "orderers": { "orderer.example.com": { "url": "grpc://localhost:7050" } }, "organizations": { "Org1": { "mspid": "Org1MSP", "peers": [ "peer0.org1.example.com" ], "certificateAuthorities": [ "ca.org1.example.com" ] } }, "channels": { "composerchannel": { "orderers": [ "orderer.example.com" ], "peers": { "peer0.org1.example.com": { "endorsingPeer": true, "chaincodeQuery": true, "eventSource": true } } } }, "client": { "organization": "Org1", "connection": { "timeout": { "peer": { "endorser": "300", "eventHub": "300", "eventReg": "300" }, "orderer": "300" } } } }
第四步:查找Hyperledger Fabric管理员的证书和私钥
为了将区块链业务网络部署到此Hyperledger Fabric网络,我们必须将自己标识为具有执行此操作权限的管理员。在此步骤中,您将找到将自己标识为管理员所需的文件。
我们的Hyperledger Fabric网络的管理员是个名为的用户Admin@org1.example.com
。该用户的证书和私钥文件存储在目录中:
~/fabric-dev-servers/fabric-scripts/hlfv12/composer/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
您必须首先找到该用户的证书文件。证书是身份的公共部分。证书文件可以在signcerts
子目录中找到,并且名为Admin@org1.example.com-cert.pem
。如果查看此文件的内容,则将发现类似于以下内容的PEM编码证书:
-----BEGIN CERTIFICATE-----
MIICGjCCAcCgAwIBAgIRANuOnVN+yd/BGyoX7ioEklQwCgYIKoZIzj0EAwIwczEL
MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG
cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2Nh
Lm9yZzEuZXhhbXBsZS5jb20wHhcNMTcwNjI2MTI0OTI2WhcNMjcwNjI0MTI0OTI2
WjBbMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMN
U2FuIEZyYW5jaXNjbzEfMB0GA1UEAwwWQWRtaW5Ab3JnMS5leGFtcGxlLmNvbTBZ
MBMGByqGSM49AgEGCCqGSM49AwEHA0IABGu8KxBQ1GkxSTMVoLv7NXiYKWj5t6Dh
WRTJBHnLkWV7lRUfYaKAKFadSii5M7Z7ZpwD8NS7IsMdPR6Z4EyGgwKjTTBLMA4G
A1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMCsGA1UdIwQkMCKAIBmrZau7BIB9
rRLkwKmqpmSecIaOOr0CF6Mi2J5H4aauMAoGCCqGSM49BAMCA0gAMEUCIQC4sKQ6
CEgqbTYe48az95W9/hnZ+7DI5eSnWUwV9vCd/gIgS5K6omNJydoFoEpaEIwM97uS
XVMHPa0iyC497vdNURA=
-----END CERTIFICATE-----
接下来,您必须找到该用户的私钥文件。私钥用于以此身份签署交易。私钥文件可以在keystore
子目录中找到。私钥文件的名称是一个十六进制长字符串,后缀_sk
为114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457_sk
。每次生成配置时,名称都会更改。如果查看此文件的内容,则将发现类似于以下内容的PEM编码的私钥:
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg00IwLLBKoi/9ikb6
ZOAV0S1XeNGWllvlFDeczRKQn2uhRANCAARrvCsQUNRpMUkzFaC7+zV4mClo+beg
4VkUyQR5y5Fle5UVH2GigChWnUoouTO2e2acA/DUuyLDHT0emeBMhoMC
-----END PRIVATE KEY-----
记住这两个文件的路径,或将它们 到与connection.json
上一步中创建的连接配置文件相同的目录。下一步将需要这些文件。
第五步:为Hyperledger Fabric管理员创建业务网卡
商业网卡包含连接到区块链商业网络和基础Hyperledger Fabric网络所需的所有信息。此信息包括在第三步中创建的连接配置文件,以及在第四步中为管理员提供的证书和私钥。
在此步骤中,您将为管理员创建一个业务网卡,用于将区块链业务网络部署到Hyperledger Fabric网络。
运行composer card create
命令以创建商务网卡。您必须指定在先前步骤中创建或位于的所有三个文件的路径:
composer card create -p connection.json -u PeerAdmin -c Admin@org1.example.com-cert.pem -k 114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457_sk -r PeerAdmin -r ChannelAdmin
名为的商务网卡文件PeerAdmin@fabric-network.card
将被写入当前目录。让我们探索传递给composer card create
命令的选项。
-p connection.json
这是我们在第三步中创建的连接配置文件的路径。
-u PeerAdmin
这是我们用来指代管理员用户的名称。Admin@org1.example.com
我们使用了一个名称,而不是在很长的地方都使用,而是使用了一个名称,PeerAdmin
以便我们可以轻松地引用此用户。
-c Admin@org1.example.com-cert.pem
这是Admin@org1.example.com
我们在第四步中找到的用户的证书文件的路径。
-k 114aab0e76bf0c78308f89efc4b8c9423e31568da0c340ca187a9b17aa9a4457_sk
这是Admin@org1.example.com
我们在第四步中找到的用户的私钥文件的路径。
-r PeerAdmin -r ChannelAdmin
在这里,我们指定用户具有哪些角色。此信息是必需的,以便Hyperledger Composer操场知道哪些用户能够执行哪些操作。该用户Admin@org1.example.com
是Hyperledger Fabric网络的管理员,并具有PeerAdmin
(安装链码的ChannelAdmin
能力)和(实例化链码的能力)的角色。
第六步:为Hyperledger Fabric管理员导入业务网卡
Hyperledger Composer只能使用放置在钱包中的商务网卡。钱包是文件系统上包含商务网卡的目录。在此步骤中,您将在第五步中创建的商务网卡导入到钱包中,以便可以在后续步骤中使用商务网卡。
运行composer card import
命令以将商务网卡导入钱包:
composer card import -f PeerAdmin@fabric-network.card
让我们探索传递给composer card import
命令的选项。
-f PeerAdmin@fabric-network.card
这是我们在第五步中创建的商务网卡文件的路径。
现在,您可以通过指定名称来使用此名片PeerAdmin@fabric-network
。现在,您已经准备好将区块链业务网络部署到Hyperledger Fabric网络。
我们将部署tutorial-network
通过遵循Developer Tutorial创建的区块链业务网络。如果您没有按照开发人员指南创建业务网络档案(.bna)文件,请按照开发人员指南的步骤1、2和3进行操作。
第七步:将Hyperledger Composer业务网络安装到Hyperledger Fabric对等节点上
在此步骤中,您将在所有组织的Hyperledger Fabric对等节点上安装区块链业务网络。用Hyperledger Fabric术语来说,这是一个链码安装操作。
运行composer network install
命令以将Hyperledger Composer运行时安装到在第三步中创建的连接配置文件中指定的Hyperledger Fabric对等节点上:
composer network install -c PeerAdmin@fabric-network -a tutorial-network@0.0.1.bna
让我们探索传递给composer network install
命令的选项。
-c PeerAdmin@fabric-network
这是我们在第六步中导入钱包的商务网卡的名称。
-a tutorial-network@0.0.1.bna
您必须安装业务网络的副本。在这里,我们指定要部署的区块链业务网络的文件名tutorial-network@0.0.1.bna
。
第八步:启动区块链业务网络
在这一步中,您将启动区块链业务网络。用Hyperledger Fabric术语来说,这是一个链码实例化操作。
运行composer network start
命令以启动区块链业务网络:
composer network start --networkName tutorial-network --networkVersion 0.0.1 -A admin -S adminpw -c PeerAdmin@fabric-network
让我们探索传递给composer network start
命令的选项。
-c PeerAdmin@fabric-network
这是我们在第六步中导入钱包的商务网卡的名称。
--networkName tutorial-network
这是称为的区块链业务网络的名称tutorial-network
。
--networkVersion 0.0.1
这是称为的区块链业务网络版本,在业务网络的package.json属性中tutorial-network
定义version
-A admin
部署区块链业务网络时,您必须创建至少一名参与者,他们将成为区块链业务网络管理员。该参与者负责将其他参与者加入到区块链业务网络中。在这里,我们指定我们要创建一个名为的区块链业务网络管理员admin
。
-S adminpw
这指定我们的区块链业务网络管理员admin
将使用的注册机密adminpw
从CA(证书颁发机构)请求证书和私钥。当您指定此选项时,为业务网络管理员指定的名称必须是已向CA注册的用户的现有注册ID。
现在我们的区块链业务网络已经启动,我们可以使用admin@tutorial-network.card
创建的业务网卡文件与其进行交互。
步骤九:为业务网络管理员导入业务网卡
运行composer card import
命令以将商务网卡导入钱包:
composer card import -f admin@tutorial-network.card
现在,您可以通过指定名称来使用此名片admin@tutorial-network
。现在您已经准备好与正在运行的区块链业务网络进行交互!
第十步:测试与区块链业务网络的连接
运行composer network ping
命令以测试与区块链业务网络的连接:
composer network ping -c admin@tutorial-network
检查测试结果是否成功,并且为业务网络列出了一个名为的参与者NetworkAdmin
。
结论
在本教程中,您已经了解了如何使用连接到Hyperledger Fabric网络所需的所有信息来配置Hyperledger Composer,以及如何将区块链业务网络部署到该Hyperledger Fabric网络。
如果您使用了开发环境中提供的简单Hyperledger Fabric网络,为什么不按照Hyperledger Fabric文档尝试构建自己的Hyperledger Fabric网络,看看是否可以成功地为其部署区块链业务网络?
将Hyperledger Composer区块链业务网络部署到Hyperledger Fabric(多个组织)
本教程深入介绍了跨多个组织的配置区块链网络的过程。
它概述了配置基于Hyperledger Fabric的多组织区块链网络所需的步骤。这两个组织的区块链网络基于Hyperledger Fabric提供的示例网络。此外,它描述了生成必要的安全工件并保护两个组织中的网络安全的步骤。
一旦配置了区块链网络,我们将展示如何部署业务网络(例如,来自示例网络的商品交易业务网络),该业务网络在其自己的链码容器中运行,并在两个组织之间共享的分类帐上实例化。然后,我们将与共享分类帐的交互显示为不同的参与者/身份,如每个组织中的身份提供者所生成的。
建议您首先遵循随附的单一组织教程;本教程演示了如何为单个组织将区块链网络部署到Hyperledger Fabric实例,并将更详细地解释一些概念。
本教程中的Hyperledger Fabric区块链网络(针对两个组织)是使用docker容器配置的,两个组织的Fabric网络都在同一台机器上-显然,在现实世界中,它们将位于单独的IP网络或域中,或者安全的云环境。
为了方便起见,本教程具有彩色编码的步骤,以指示“哪个组织”应遵循特定的步骤或顺序-或实际上,如果两个组织都需要执行这些步骤。
第一步是两个组织都要遵循的步骤:
示例步骤:Org1和Org2遵循的步骤
该组织Org1
由Green Conga Block爱丽丝(Alice)代表:
示例步骤:Org1遵循的步骤
该组织Org2
由紫罗兰色Conga方块Bob代表:
示例步骤:Org2遵循的步骤
您可以自己执行这些步骤,或者与朋友或同事配对并一起执行这些步骤。
让我们开始吧!
先决条件
如果您先前已安装Composer开发环境,则需要首先拆除开发环境提供的Hyperledger Fabric容器:
cd ~/fabric-dev-servers
export FABRIC_VERSION=hlfv12
./stopFabric.sh
./teardownFabric.sh
接下来,使用命令行克隆以下GitHub Fabric Samples存储库(重要信息:请勿使用Fabric网站上的示例:因为缺少本教程所需的一些更改)
git clone https://github.com/mahoney1/fabric-samples.git
在本多组织教程中,我们正在使用“ 构建您的第一个网络结构”样本网络。此后,我们将这个Hyperledger Fabric网络称为“ BYFN”(建立第一个网络)网络。如果您选择将组织划分为运行在不同IP网络上的单独的物理机或单独的虚拟机,则不在本教程的范围之内。
第一步:启动Hyperledger Fabric网络
为了遵循本教程,您必须启动新的Hyperledger Fabric网络。本教程将假定您使用Hyperledger Fabric 构建您的第一个网络教程中提供的Hyperledger Fabric 网络。
-
将目录更改为
fabric-samples
cd fabric-samples
-
使用以下命令下载平台二进制文件,包括密码原(bash命令需要三个参数):
curl -sSL http://bit.ly/2ysbOFE | bash -s 1.2.1 1.2.1 0.4.10
确认下载的Docker映像列表没有问题。
(请注意,您可以忽略输出中的初始“错误:pathspec v1.xx不匹配”消息-您甚至可能看不到此消息)
-
我们需要使用之前克隆的Git存储库中的“ multi-org”分支(以使用当前的Fabric级别):
git checkout multi-org
-
将目录更改为
first-network
示例cd first-network
-
接下来,启动BYFN网络-
byfn.sh
由于我们使用CouchDB作为世界状态数据库(与Fabric BYFN页面上指定的数据库不同),因此必须指定其他标志(下面的脚本)-我们也想启动证书颁发机构(CA)每个组织。 -
从
first-network
目录中依次执行以下命令:./byfn.sh -m generate ./byfn.sh -m up -s couchdb -a
如果该命令成功运行,则第一个命令将生成光纤网络/安全工件(请参阅此链接。在第二个命令(以上)之后,BYFN网络已启动,并在继续操作之前验证您是否看到以下输出:
========= All GOOD, BYFN execution completed ===========
_____ _ _ ____
| ____| | \ | | | _ \
| _| | \| | | | | |
| |___ | |\ | | |_| |
|_____| |_| \_| |____/
接下来,从以前的Fabric环境中删除钱包中可能存在的所有“旧”商务网卡。可以忽略所有指出找不到商务网卡的错误,这是很安全的:
composer card delete -c PeerAdmin@byfn-network-org1
composer card delete -c PeerAdmin@byfn-network-org2
composer card delete -c alice@trade-network
composer card delete -c bob@trade-network
composer card delete -c admin@trade-network
composer card delete -c PeerAdmin@fabric-network
但是,任何其他类型的故障都可能表明您的存储卡中有来自较早版本的Hyperledger Composer的存储卡,然后您必须按照以下方式删除HOME目录中的文件系统存储卡:
rm -fr $HOME/.composer
第二步:探索Hyperledger Fabric网络
此步骤将探索BFYN网络配置和组件。需要配置详细信息才能完成后续步骤。
组织机构
BYFN网络由两个组织组成:Org1
和Org2
。组织Org1
使用域名org1.example.com
。的会员服务提供商(MSP)Org1
称为Org1MSP
。组织Org2
使用域名org2.example.com
。的MSP Org2
称为Org2MSP
。在本教程中,您将部署一个blockchain业务网络,无论是组织Org1
,并Org2
能与之交互。
网络组件
Hyperledger Fabric网络由以下几部分组成:
- 有两个对等节点,分别为
Org1
,peer0.org1.example.com
和peer1.org1.example.com
。- 的请求端口
peer0
是7051。 - 的事件集线器端口
peer0
是7053。 - 的请求端口
peer1
是8051。 - 的事件集线器端口
peer1
是8053。
- 的请求端口
- 的单个CA(证书颁发机构)
Org1
,名为ca.org1.example.com
。- CA端口是7054。
- 有两个对等节点,分别为
Org2
,peer0.org2.example.com
和peer1.org2.example.com
。- 的请求端口
peer0
是9051。 - 的事件集线器端口
peer0
是9053。 - 的请求端口
peer1
是10051。 - 的事件集线器端口
peer1
是10053。
- 的请求端口
- 的单个CA(证书颁发机构)
Org2
,名为ca.org2.example.com
。- CA端口是8054。
- 一个名为的订购者节点
orderer.example.com
。- 订购者端口为7050。
这些组件在Docker容器中运行。在Docker容器中运行Hyperledger Composer时,peer0.org1.example.com
可以使用以上名称(例如)与Hyperledger Fabric网络进行交互。
本教程将在Docker主机上而不是在Docker网络内部运行Hyperledger Composer命令。这意味着Hyperledger Composer命令必须使用localhost
主机名和公开的容器端口与Hyperledger Fabric网络进行交互。
所有网络组件都使用TLS进行加密以保护通信。您需要所有网络组件的证书颁发机构(CA)证书才能连接到那些网络组件。可以在包含byfn.sh脚本的目录中找到CA证书。
订购者节点的CA证书:
crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt
CA证书Org1
:
crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
CA证书Org2
:
crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
稍后,您将使用这些文件与Hyperledger Fabric网络进行交互。
用户数
该组织Org1
配置了一个名为的用户Admin@org1.example.com
。该用户是管理员。
用户Admin@org1.example.com
在目录中存储了一组证书和私钥文件:
crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
该组织Org2
配置了一个名为的用户Admin@org2.example.com
。该用户是管理员。
用户Admin@org2.example.com
在目录中存储了一组证书和私钥文件:
crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
稍后,您将使用其中一些文件与Hyperledger Fabric网络进行交互。
除了管理员,中科院(证书颁发机构)的Org1
和Org2
已经配置了默认用户。该默认用户的注册ID为admin
,注册密码为adminpw
。但是,该用户无权部署区块链业务网络。
建议创建一个临时工作目录(和子目录)来管理Composer连接配置文件和密钥/证书文件,我们将在本教程的后面部分中使用它们。
mkdir -p /tmp/composer/org1
mkdir -p /tmp/composer/org2
渠道
名为的频道mychannel
已创建。这四个等节点- ,peer0.org1.example.com
,peer1.org1.example.com
,peer0.org2.example.com
和peer1.org2.example.com
已经加入到这个频道。
连接配置文件
我们需要一个描述该结构网络的基本连接配置文件,然后可以将其提供给该网络alice
并bob
为其组织进行自定义。
{
"name": "byfn-network",
"x-type": "hlfv1",
"version": "1.0.0",
"channels": {
"mychannel": {
"orderers": [
"orderer.example.com"
],
"peers": {
"peer0.org1.example.com": {
"endorsingPeer": true,
"chaincodeQuery": true,
"eventSource": true
},
"peer1.org1.example.com": {
"endorsingPeer": true,
"chaincodeQuery": true,
"eventSource": true
},
"peer0.org2.example.com": {
"endorsingPeer": true,
"chaincodeQuery": true,
"eventSource": true
},
"peer1.org2.example.com": {
"endorsingPeer": true,
"chaincodeQuery": true,
"eventSource": true
}
}
}
},
"organizations": {
"Org1": {
"mspid": "Org1MSP",
"peers": [
"peer0.org1.example.com",
"peer1.org1.example.com"
],
"certificateAuthorities": [
"ca.org1.example.com"
]
},
"Org2": {
"mspid": "Org2MSP",
"peers": [
"peer0.org2.example.com",
"peer1.org2.example.com"
],
"certificateAuthorities": [
"ca.org2.example.com"
]
}
},
"orderers": {
"orderer.example.com": {
"url": "grpcs://localhost:7050",
"grpcOptions": {
"ssl-target-name-override": "orderer.example.com"
},
"tlsCACerts": {
"pem": "INSERT_ORDERER_CA_CERT"
}
}
},
"peers": {
"peer0.org1.example.com": {
"url": "grpcs://localhost:7051",
"grpcOptions": {
"ssl-target-name-override": "peer0.org1.example.com"
},
"tlsCACerts": {
"pem": "INSERT_ORG1_CA_CERT"
}
},
"peer1.org1.example.com": {
"url": "grpcs://localhost:8051",
"grpcOptions": {
"ssl-target-name-override": "peer1.org1.example.com"
},
"tlsCACerts": {
"pem": "INSERT_ORG1_CA_CERT"
}
},
"peer0.org2.example.com": {
"url": "grpcs://localhost:9051",
"grpcOptions": {
"ssl-target-name-override": "peer0.org2.example.com"
},
"tlsCACerts": {
"pem": "INSERT_ORG2_CA_CERT"
}
},
"peer1.org2.example.com": {
"url": "grpcs://localhost:10051",
"grpcOptions": {
"ssl-target-name-override": "peer1.org2.example.com"
},
"tlsCACerts": {
"pem": "INSERT_ORG2_CA_CERT"
}
}
},
"certificateAuthorities": {
"ca.org1.example.com": {
"url": "https://localhost:7054",
"caName": "ca-org1",
"httpOptions": {
"verify": false
}
},
"ca.org2.example.com": {
"url": "https://localhost:8054",
"caName": "ca-org2",
"httpOptions": {
"verify": false
}
}
}
}
将此基本文件(上面) 到新目录 byfn-network.json
下的新文件中/tmp/composer
并保存。
为以下对等节点打开byfn-network.json
并用INSERT_ORG1_CA_CERT
CA证书替换文本的所有实例Org1
:-使用以下命令从.pem文件中获取证书,以便可以将其嵌入到上述连接配置文件中。
awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt > /tmp/composer/org1/ca-org1.txt
文件的内容,/tmp/composer/org1/ca-org1.txt
并替换INSERT_ORG1_CA_CERT
.json文件中的文本。现在看起来应该像这样(在配置文件中必须是一行,如图所示)
"pem": "-----BEGIN CERTIFICATE-----\nMIICNTCCAdygAwIBAgIRAMNvmQpnXi7uM19BLdha3MwwCgYIKoZIzj0EAwIwbDEL\nMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG\ncmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRowGAYDVQQDExF0bHNjYS5l\neGFtcGxlLmNvbTAeFw0xNzA2MjYxMjQ5MjZaFw0yNzA2MjQxMjQ5MjZaMGwxCzAJ\nBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJh\nbmNpc2NvMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEaMBgGA1UEAxMRdGxzY2EuZXhh\nbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASJn3QUVcKCp+s6lSPE\nP5KlWmE9rEG0kpECsAfW28vZQSIg2Ez+Tp1alA9SYN/5BtL1N6lUUoVhG3lz8uvi\n8zhro18wXTAOBgNVHQ8BAf8EBAMCAaYwDwYDVR0lBAgwBgYEVR0lADAPBgNVHRMB\nAf8EBTADAQH/MCkGA1UdDgQiBCB7ULYTq3+BQqnzwae1RsnwQgJv/HQ5+je2xcDr\nka4MHTAKBggqhkjOPQQDAgNHADBEAiB2hLiS8B1g4J5Qbxu15dVWAZTAXX9xPAvm\n4l25e1oS+gIgBiU/aBwSxY0uambwMB6xtQz0ZE/D4lyTZZcW9SODlOE=\n-----END CERTIFICATE-----\n"
在同一个.json文件中-您需要使用INSERT_ORG2_CA_CERT
对等节点的CA证书替换文本的所有实例,以便Org2
:-使用以下命令将.pem文件转换为可以嵌入上述连接配置文件中的文件。
awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt > /tmp/composer/org2/ca-org2.txt
文件的内容/tmp/composer/org2/ca-org2.txt
并替换名为的文本INSERT_ORG2_CA_CERT
。再一次,全部在同一行。
将文本的所有实例替换INSERT_ORDERER_CA_CERT
为订购者节点的CA证书:使用以下命令将.pem文件转换为可以嵌入到上述连接配置文件json文件中的文件。
awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt > /tmp/composer/ca-orderer.txt
文件的内容/tmp/composer/ca-orderer.txt
并替换文本INSERT_ORDERER_CA_CERT
。再一次,全部在同一行。
完成后,将此文件另存为 /tmp/composer/byfn-network.json
。
现在,此连接配置文件描述结构网络的设置,网络中所有对等方,订购者和证书颁发机构,定义了参与网络的所有组织,还定义了该网络上的通道。Hyperledger Composer只能与单个通道进行交互,因此只能定义一个通道。
第三步:自定义Org1的连接配置文件
这只是alice
在client
具有可选超时的部分中指定所属组织的情况下,将以下块添加到上述连接配置文件中/tmp/composer/byfn-network.json
,该version
属性之间以及该属性之前channel
(一旦完成),将其保存为名为的新文件 /tmp/composer/org1/byfn-network-org1.json
。
"client": {
"organization": "Org1",
"connection": {
"timeout": {
"peer": {
"endorser": "300",
"eventHub": "300",
"eventReg": "300"
},
"orderer": "300"
}
}
},
因此配置文件的部分应如下所示
...
"version": "1.0.0",
"client": {
"organization": "Org1",
"connection": {
"timeout": {
"peer": {
"endorser": "300",
"eventHub": "300",
"eventReg": "300"
},
"orderer": "300"
}
}
},
"channel": {
...
第四步:为Org2建立连接配置文件
重复相同的过程bob
-但这次将组织指定为Org2
,然后将文件另存为/tmp/composer/byfn-network-org2.json
-,因此配置文件的部分应如下所示:
...
"version": "1.0.0",
"client": {
"organization": "Org2",
"connection": {
"timeout": {
"peer": {
"endorser": "300",
"eventHub": "300",
"eventReg": "300"
},
"orderer": "300"
}
}
},
"channel": {
...
第五步:找到Org1的Hyperledger Fabric管理员的证书和私钥
Hyperledger Fabric Org1网络的管理员是的用户Admin@org1.example.com
。该用户的证书和私钥文件存储在目录中:
crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
您必须首先找到该用户的证书文件。证书是身份的公共部分。证书文件可以在signcerts
子目录中找到,并且名为Admin@org1.example.com-cert.pem
。
接下来,您必须找到该用户的私钥文件。私钥用于以此身份签署交易。私钥文件可以在keystore
子目录中找到。私钥文件的名称是一个十六进制长字符串,后缀为_sk
,例如:78f2139bfcfc0edc7ada0801650ed785a11cfcdef3f9c36f3c8ca2ebfa00a59c_sk
。每次生成配置时,名称都会更改,因此下面的通配符。
记住这两个文件的路径-或将它们 到与/tmp/composer/org1/byfn-network-org1.json
在“第三步”中创建的连接配置文件相同的目录。在接下来的步骤中,您将需要这些文件。
使用以下命令执行此操作:
export ORG1=crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
cp -p $ORG1/signcerts/A*.pem /tmp/composer/org1
cp -p $ORG1/keystore/*_sk /tmp/composer/org1
第六步:查找Org2的Hyperledger Fabric管理员的证书和私钥
我们的Hyperledger Fabric网络的管理员是个名为的用户Admin@org2.example.com
。该用户的证书和私钥文件存储在目录中:
crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
您必须首先找到该用户的证书文件。证书是身份的公共部分。证书文件可以在signcerts
子目录中找到,并且名为Admin@org2.example.com-cert.pem
。
接下来,您必须找到该用户的私钥文件。私钥用于以此身份签署交易。私钥文件可以在keystore
子目录中找到。私钥文件的名称是一个十六进制长字符串,后缀_sk
为d4889cb2a32e167bf7aeced872a214673ee5976b63a94a6a4e61c135ca2f2dbb_sk
。每次生成配置时,名称都会更改。
记住这两个文件的路径,或将它们 到与/tmp/composer/byfn-network-org2.json
您在第四步中创建的连接配置文件相同的目录。在接下来的步骤中,您将需要这些文件。
使用以下命令执行此操作:
export ORG2=crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
cp -p $ORG2/signcerts/A*.pem /tmp/composer/org2
cp -p $ORG2/keystore/*_sk /tmp/composer/org2
第七步:为Org1的Hyperledger Fabric管理员创建业务网卡
在此步骤中,您将为管理员创建业务网卡,以用于将区块链业务网络部署到Hyperledger Fabric网络。
运行composer card create
命令以使用的连接配置文件创建商务网卡Org1
。您必须指定在先前步骤中创建或位于的所有三个文件的路径:(注意:sk文件将有所不同。)
composer card create -p /tmp/composer/org1/byfn-network-org1.json -u PeerAdmin -c /tmp/composer/org1/Admin@org1.example.com-cert.pem -k /tmp/composer/org1/*_sk -r PeerAdmin -r ChannelAdmin -f PeerAdmin@byfn-network-org1.card
如果该命令成功运行,则名为的商务网卡文件PeerAdmin@byfn-network-org1.card
将被写入当前目录。
第八步:为Org2的Hyperledger Fabric管理员创建业务网卡
在此步骤中,您将为管理员创建业务网卡,以用于将区块链业务网络部署到Hyperledger Fabric网络。
运行composer card create
命令以使用的连接配置文件创建商务网卡Org2
。您必须指定在先前步骤中创建或位于的所有三个文件的路径:
composer card create -p /tmp/composer/org2/byfn-network-org2.json -u PeerAdmin -c /tmp/composer/org2/Admin@org2.example.com-cert.pem -k /tmp/composer/org2/*_sk -r PeerAdmin -r ChannelAdmin -f PeerAdmin@byfn-network-org2.card
如果该命令成功运行,则名为的商务网卡文件PeerAdmin@byfn-network-org2.card
将被写入当前目录。
步骤九:为Org1的Hyperledger Fabric管理员导入业务网卡
运行composer card import
命令以将要使用的业务网卡Org1
导入钱包:
composer card import -f PeerAdmin@byfn-network-org1.card --card PeerAdmin@byfn-network-org1
如果该命令成功运行,PeerAdmin@byfn-network-org1
则将名为的商务网卡导入钱包。
第十步:为Org2的Hyperledger Fabric管理员导入业务网卡
运行composer card import
命令以将要使用的业务网卡Org2
导入钱包:
composer card import -f PeerAdmin@byfn-network-org2.card --card PeerAdmin@byfn-network-org2
如果该命令成功运行,PeerAdmin@byfn-network-org2
则将名为的商务网卡导入钱包。
步骤十一:将业务网络安装到Org1的Hyperledger Fabric对等节点上
运行composer network install
命令以将业务网络安装到Org1
在“步骤三”中创建的连接配置文件中指定的所有Hyperledger Fabric对等节点上:
composer network install --card PeerAdmin@byfn-network-org1 --archiveFile trade-network.bna
从上面可以看到,我们正在使用一个称为Hyperledger Composer的业务网络trade-network
来测试我们的多组织环境。您将需要一个文件trade-network.bna
(业务网络归档,来自我们的示例网络)来进行测试。如果没有,只需转到https://composer-playground.mybluemix.net/并将trade-network
示例部署在在线Playground中,然后以“ admin”身份“连接”到业务网络,将版本号更改为0.1.14
在左下方,将其导出为当前目录trade-network.bna
。商业网络具有在文件中指定的version属性package.json
。使用composer start
步骤十七中的命令启动业务网络时,必须指定该版本。如果您正在使用trade-network
示例网络,版本为0.1.14
。(注意:如果您打算使用其他网络(例如Composer教程网络tutorial-network
作为您的业务网络),则需要在network install
上面的命令中及其后指定该文件作为本教程中的业务网络档案,此业务网络的正确版本号)。
该network install
命令的一个有用功能是它将输出业务网络的名称和刚刚安装的版本号,您可以记下这些内容以供以后在“第十七步”中使用。
第十二步:将业务网络安装到Org2的Hyperledger Fabric对等节点上
运行composer network install
命令以将业务网络安装到Org2
在步骤四中创建的连接配置文件中指定的所有Hyperledger Fabric对等节点上:
composer network install --card PeerAdmin@byfn-network-org2 --archiveFile trade-network.bna
步骤十三:定义业务网络的背书策略
运营中的业务网络具有背书策略,该策略定义了组织在将交易提交到区块链之前必须背书交易的规则。默认情况下,将使用背书策略部署业务网络,该策略规定只有一个组织在将交易提交到区块链之前必须背书交易。
在现实世界的区块链业务网络中,多个组织将希望确保他们在将交易提交到区块链之前就认可了交易,因此默认的认可策略是不合适的。而是可以在启动业务网络时指定自定义认可策略。
你可以找到Hyperledger面料文档的代言策略的详细信息,在签注政策。
请注意,用于业务网络的认可策略必须采用Hyperledger Fabric Node.js SDK使用的JSON格式。这与Hyperledger Fabric CLI使用的简单认可策略格式不同,您可以在Hyperledger Fabric文档中看到该格式。
创建具有/tmp/composer/endorsement-policy.json
以下内容的认可策略文件,并将其保存到磁盘。您将在以后的步骤中使用此文件,因此请记住放置位置!
{
"identities": [
{
"role": {
"name": "member",
"mspId": "Org1MSP"
}
},
{
"role": {
"name": "member",
"mspId": "Org2MSP"
}
}
],
"policy": {
"2-of": [
{
"signed-by": 0
},
{
"signed-by": 1
}
]
}
}
背书政策刚才创建的状态,无论Org1
并且Org2
必须在企业网络中的认可交易,才可以被提交到blockchain。如果同意Org1
或Org2
不同意交易,或不同意交易的结果,则该交易将被业务网络拒绝。
步骤十四:了解和选择业务网络管理员
启动业务网络时,必须为业务网络配置一组初始参与者。这些参与者将负责引导业务网络并将其他参与者加入业务网络。在Hyperledger Composer中,我们将这些最初的参与者称为业务网络管理员。
在我们的业务网络中,组织Org1
和Org2
拥有平等的权利。每个组织将为该业务网络提供一个业务网络管理员,而这些业务网络管理员将加入其组织中的其他参与者。的业务网络管理员Org1
将是Alice,而的业务网络管理员Org2
将是Bob。
启动业务网络时,必须将所有业务网络管理员的证书(身份的公共部分)传递给执行命令以启动业务网络的组织。启动业务网络后,所有业务网络管理员都可以使用其身份与业务网络进行交互。
您可以在部署业务网络中找到有关业务网络管理员的更多信息。
步骤十五:检索Org1的业务网络管理员证书
运行composer identity request
命令以检索证书,供Alice用作以下业务网络管理员Org1
:
composer identity request -c PeerAdmin@byfn-network-org1 -u admin -s adminpw -d alice
此命令的-u admin
和-s adminpw
选项与在Hyperledger Fabric CA(证书颁发机构)中注册的默认用户相对应。
证书将被放置alice
在当前工作目录中的目录中。创建了三个证书文件,但是只有两个很重要。它们是admin-pub.pem
证书(包括公钥)和admin-priv.pem
私钥。仅该admin-pub.pem
文件适合与其他组织共享。该admin-priv.pem
文件必须保密,因为它可以用来代表发行组织签署交易。
步骤十六:检索Org2的业务网络管理员证书
运行composer identity request
命令以检索证书,供Bob用作以下业务网络管理员Org2
:
composer identity request -c PeerAdmin@byfn-network-org2 -u admin -s adminpw -d bob
此命令的-u admin
和-s adminpw
选项与在Hyperledger Fabric CA(证书颁发机构)中注册的默认用户相对应。
证书将被放置bob
在当前工作目录中的目录中。创建了三个证书文件,但是只有两个很重要。它们是admin-pub.pem
证书(包括公钥)和admin-priv.pem
私钥。仅该admin-pub.pem
文件适合与其他组织共享。该admin-priv.pem
文件必须保密,因为它可以用来代表发行组织签署交易。
步骤十七:启动业务网络
运行composer network start
命令以启动业务网络。只Org1
需要执行此操作。该命令使用/tmp/composer/endorsement-policy.json
在步骤十三中创建的文件,以及admin-pub.pem
由爱丽丝和鲍勃在步骤十五和步骤十六中创建的文件,因此,必须确保此命令可访问所有这些文件:
composer network start -c PeerAdmin@byfn-network-org1 -n trade-network -V 0.1.14 -o endorsementPolicyFile=/tmp/composer/endorsement-policy.json -A alice -C alice/admin-pub.pem -A bob -C bob/admin-pub.pem
该命令完成后,将启动业务网络。爱丽丝(Alice)和鲍勃(Bob)都将能够访问业务网络,开始建立业务网络,并加入各自组织的其他参与者。但是,Alice和Bob都必须使用在先前步骤中创建的证书来创建新的商务网卡,以便他们可以访问商务网。
步骤十八:创建一个业务网卡以Org1的身份访问业务网络
运行composer card create
命令以创建一个业务网卡,该业务网管的管理员Alice Org1
可以使用它来访问业务网:
composer card create -p /tmp/composer/org1/byfn-network-org1.json -u alice -n trade-network -c alice/admin-pub.pem -k alice/admin-priv.pem
运行composer card import
命令以导入刚创建的商务网卡:
composer card import -f alice@trade-network.card
运行composer network ping
命令以测试与区块链业务网络的连接:
composer network ping -c alice@trade-network
如果命令成功完成,那么您应该org.hyperledger.composer.system.NetworkAdmin#alice
在命令的输出中看到完全限定的参与者标识符。现在,您可以使用此商务网卡与区块链商务网络以及组织中的其他参与者进行交互。
让我们创建一个参与者,发布一个身份(映射到该参与者),并在区块链网络上创建一个资产作为该身份。
运行以下composer participant add
命令,将其 到命令行以执行:
composer participant add -c alice@trade-network -d '{"$class":"org.example.trading.Trader","tradeId":"trader1-org1", "firstName":"Jo","lastName":"Doe"}'
接下来,trader1-org1
使用以下composer issue identity
命令创建标识:
composer identity issue -c alice@trade-network -f jo.card -u jdoe -a "resource:org.example.trading.Trader#trader1-org1"
导入卡并进行测试
composer card import -f jo.card
composer network ping -c jdoe@trade-network
下一步,我们将创建一个资产-在命令行中,提交交易创造商品资产,因为参与者jdoe
(或者,如果你已经安装了作曲家游乐场,连接为jdoe@trade-network
以trade-network
创建资产“EMA” -的JSON片段是如下所示)。
要使用CLI创建资产- 以下transaction submit
序列-它会为您创建商品资产:
composer transaction submit --card jdoe@trade-network -d '{"$class": "org.hyperledger.composer.system.AddAsset", "targetRegistry" : "resource:org.hyperledger.composer.system.AssetRegistry#org.example.trading.Commodity", "resources": [{"$class": "org.example.trading.Commodity","tradingSymbol":"EMA", "description":"Corn commodity","mainExchange":"EURONEXT", "quantity":"10","owner":"resource:org.example.trading.Trader#trader1-org1"}]}'
或者,要在Playground中创建- 以下内容:
{
"$class": "org.example.trading.Commodity",
"tradingSymbol": "EMA",
"description": "Corn commodity",
"mainExchange": "EURONEXT",
"quantity": 10,
"owner": "resource:org.example.trading.Trader#trader1-org1"
}
最后,执行a composer network list
确认业务网络中生成的工件:
composer network list -c jdoe@trade-network
步骤十九:创建一个业务网卡以Org2的身份访问业务网络
运行composer card create
命令以创建一个商业网卡,商业网络管理员Bob Org2
可以使用它来访问商业网络:
composer card create -p /tmp/composer/org2/byfn-network-org2.json -u bob -n trade-network -c bob/admin-pub.pem -k bob/admin-priv.pem
运行composer card import
命令以导入刚创建的商务网卡:
composer card import -f bob@trade-network.card
运行composer network ping
命令以测试与区块链业务网络的连接:
composer network ping -c bob@trade-network
如果命令成功完成,那么您应该org.hyperledger.composer.system.NetworkAdmin#bob
在命令的输出中看到完全限定的参与者标识符。让我们登上另一个交易者,这次是组织2:
再次创建一个参与者,发布一个身份(映射到该参与者)-由于我们已经在区块链网络上拥有资产,因此我们将使用一笔交易来更改所有权(从Org1交易者到Org2交易者):
运行以下composer participant add
命令,将其 到命令行以执行:
composer participant add -c bob@trade-network -d '{"$class":"org.example.trading.Trader","tradeId":"trader2-org2", "firstName":"Dave","lastName":"Lowe"}'
接下来,trader2-org2
使用以下composer issue identity
命令创建标识:
composer identity issue -c bob@trade-network -f dave.card -u dlowe -a "resource:org.example.trading.Trader#trader2-org2"
导入卡并进行测试
composer card import -f dave.card
composer network ping -c dlowe@trade-network
最后,提交交易以更改先前创建的商品资产的所有权。我们将以资产所有者乔恩·多伊(Jon Doe)的身份提交交易,并将其转移给交易商“戴夫·洛(Dave Lowe)”。然后,当组织2交易者参与者映射到dlowe
身份时,我们将验证所有权更改:执行以下步骤。
composer transaction submit --card jdoe@trade-network -d '{"$class":"org.example.trading.Trade","commodity":"resource:org.example.trading.Commodity#EMA","newOwner":"resource:org.example.trading.Trader#trader2-org2"}'
最后,composer network list
以Org 2交易者身份参与,以确认资产所有权的更改:
composer network list -c dlowe@trade-network
结论
在本教程中,您已经了解了如何在多组织设置中基于Hyperledger Composer配置区块链网络。您还学习了如何使用每个组织中的授权证书颁发的身份将业务网络(例如我们的商品交易网络)部署到该区块链网络,并作为每个组织中的参与者执行一些简单的交易。
与其他业务网络互动
Hyperledger Composer包括业务网络可以使用的功能,以访问记录在另一个业务网络中的资产,参与者或交易。
本教程将演示业务网络开发人员从不同的业务网络调用Hyperledger Composer业务网络所需采取的步骤。作为教程的一部分,您将两次部署相同的业务网络。本教程中的业务网络将在相同的渠道上,但是它们可以在不同的渠道上。本示例中使用的业务网络将是开发人员教程中概述的教程网络。本教程将业务网络称为“ A”和“ B”
先决条件
- 在继续之前,请确保已按照安装开发环境中的步骤进行操作。
第一步:启动Hyperledger Fabric网络
为了遵循本教程,您必须启动Hyperledger Fabric网络。您可以使用开发环境中提供的简单Hyperledger Fabric网络,也可以使用通过遵循Hyperledger Fabric文档而构建的自己的Hyperledger Fabric网络。
本教程将假定您使用开发环境中提供的简单Hyperledger Fabric网络。如果您使用自己的Hyperledger Fabric网络,则必须在下面详述的配置和您自己的配置之间进行映射。
-
通过运行以下命令来启动干净的Hyperledger Fabric:
cd ~/fabric-dev-servers export FABRIC_VERSION=hlfv12 ./stopFabric.sh ./teardownFabric.sh ./downloadFabric.sh ./startFabric.sh
-
删除钱包中可能存在的所有商务网卡。可以忽略所有指出找不到商务网卡的错误,这是很安全的:
composer card delete -c PeerAdmin@hlfv1
如果这些命令失败,则您具有以前版本的商务网卡,并且您将必须删除文件系统卡存储。
rm -fr ~/.composer
-
通过运行以下命令来创建对等管理卡
./createPeerAdminCard.sh
第二步:定义业务网络
-
按照开发人员教程中的步骤一和步骤二进行操作。这将是网络A。
-
再次执行步骤1和2,但创建一个名为的业务网络
other-tutorial-network
。这将是网络B。 -
需要在网络A中更新交易逻辑,并在业务网络B中查询资产,然后在业务网络A中更新资产的数量属性。
替换
logic.js
脚本文件的内容以更新事务处理器功能,如下所述。/** * Track the trade of a commodity from one trader to another * @param {org.example.mynetwork.Trade} trade - the trade to be processed * @transaction */ async function tradeCommodity(trade) { trade.commodity.owner = trade.newOwner; const otherNetworkData = await getNativeAPI().invokeChaincode('other-tutorial-network', ['getResourceInRegistry', 'Asset', 'org.example.mynetwork.Commodity', trade.commodity.tradingSymbol], 'composerchannel'); const stringAsset = new Buffer(otherNetworkData.payload.toArrayBuffer()).toString('utf8'); const asset = getSerializer().fromJSON(JSON.parse(stringAsset)); trade.commodity.quantity = asset.quantity; const assetRegistry = await getAssetRegistry('org.example.mynetwork.Commodity'); await assetRegistry.update(trade.commodity); }
-
遵循开发人员教程中的第三步。
第三步:部署业务网络
-
使用以下命令安装并启动业务网络A
composer network install --card PeerAdmin@hlfv1 --archiveFile tutorial-network@0.0.1.bna composer network start --networkName tutorial-network --networkVersion 0.0.1 --networkAdmin admin --networkAdminEnrollSecret adminpw --card PeerAdmin@hlfv1 --file networkA.card composer card import --file networkA.card --card networkA
-
使用以下命令安装并启动业务网络B
composer network install --card PeerAdmin@hlfv1 --archiveFile other-tutorial-network@0.0.1.bna composer network start --networkName other-tutorial-network --networkVersion 0.0.1 --networkAdmin admin --networkAdminEnrollSecret adminpw --card PeerAdmin@hlfv1 --file networkB.card composer card import --file networkB.card --card networkB
-
要检查业务网络是否已成功部署,请运行以下命令来ping通业务网络
composer network ping --card networkA composer network ping --card networkB
第四步:创建资产
-
在企业网络A中创建一个参与者。运行以下命令。
composer participant add --card networkA -d '{"$class": "org.example.mynetwork.Trader", "tradeId": "bob@example.com", "firstName": "Bob", "lastName": "Jones"}'
-
在业务网络A中创建资产
composer transaction submit --card networkA -d '{"$class": "org.hyperledger.composer.system.AddAsset", "targetRegistry" : "resource:org.hyperledger.composer.system.AssetRegistry#org.example.mynetwork.Commodity", "resources": [{"$class": "org.example.mynetwork.Commodity","tradingSymbol": "Ag","owner": "resource:org.example.mynetwork.Trader#bob@example.com","description": "a lot of gold", "mainExchange": "exchange", "quantity" : 250}]}'
-
在业务网络B中创建一个参与者。运行以下命令。
composer participant add --card networkB -d '{"$class": "org.example.mynetwork.Trader", "tradeId": "fred@example.com", "firstName": "Fred", "lastName": "Bloggs"}'
-
在业务网络B中创建资产。运行以下命令。注意不同的数量属性。
composer transaction submit --card networkB -d '{"$class": "org.hyperledger.composer.system.AddAsset", "targetRegistry" : "resource:org.hyperledger.composer.system.AssetRegistry#org.example.mynetwork.Commodity", "resources": [{"$class": "org.example.mynetwork.Commodity","tradingSymbol": "Ag","owner": "resource:org.example.mynetwork.Trader#fred@example.com","description": "a lot of gold", "mainExchange": "exchange", "quantity" : 500}]}'
第五步:将网络A上的身份绑定到网络B上的参与者
-
导出networkA卡以获取凭据
composer card export -c networkA
-
解压缩卡,您可能需要将networkA.card重命名为networkA.zip。
-
将身份绑定到参与者。运行以下命令。
composer identity bind --card networkB --participantId resource:org.hyperledger.composer.system.NetworkAdmin#admin --certificateFile ./networkA/credentials/certificate
-
创建具有绑定标识的卡。
composer card create -p ~/.composer/cards/networkB/connection.json --businessNetworkName other-tutorial-network -u admin -c ./networkA/credentials/certificate -k ./networkA/credentials/privateKey -f newNetworkB.card
-
导入卡
composer card import --file newNetworkB.card --card newNetworkB
-
ping网络以激活身份
composer network ping --card newNetworkB
第六步:查看资产数据
查看资产以查看数量为250。
composer network list --card networkA -r org.example.mynetwork.Commodity -a Ag
第七步:提交交易
提交事务以查看在其他业务网络上查询资产的效果。请注意,仅查询NetworkB,数量不变。
composer transaction submit --card networkA -d '{"$class": "org.example.mynetwork.Trade", "commodity": "resource:org.example.mynetwork.Commodity#Ag", "newOwner": "resource:org.example.mynetwork.Trader#bobId"}'
第八步:检查更新的资产
查看更新的资产,以检查数量是否已正确更新为500。
composer network list --card networkA -r org.example.mynetwork.Commodity -a Ag
Hyperledger Composer中的访问控制-教程
访问控制和授权是Hyperledger Composer的重要组成部分,也是区块链上成员组织共享的业务网络安全架构的重要组成部分。Hyperledger Composer使管理员可以控制参与者(实际上是参与者角色)在业务网络中有权查看或执行的资源或数据。这些参与者通常将在各自的成员组织内部进行操作或交易,并且每个人对分类帐都有自己的访问控制要求,同时允许对共享数据或所有成员组织可能共享的数据或特定数据进行受控访问。成员在同一业务网络上进行交互。
本教程探讨了这样的业务网络-商品交易网络-在我们的教程和示例网络的其他地方可以看到,并显示了在该示例网络中实际使用的ACL的示例。
访问控制规则(定义ACL的语言)分为两个主要区域:
- 有权访问系统名称空间中的系统,网络或管理资源和操作(管理网络和系统操作);和
- 通过域特定的业务网络ACL 访问资源或在给定的业务网络本身内执行操作(例如创建,读取,更新资产)的权限。
本教程使用在线Playground试用一些简单的有条件的访问规则。这样,您将以各种身份与示例网络进行交互-最终,我们要将访问控制应用于区块链的用户。我们还将看到参与者角色如何用于控制访问,其中多个身份可以映射到指定的参与者角色(例如监管者)。重要的是要注意,在真实的区块链网络中,所有操作(无论是来自Node JS应用程序,CLI还是实际上来自REST的操作)均受管辖业务网络的ACL并受其控制。问责制是在身份级别上看到的。
如果愿意,您还可以针对已部署的现有Hyperledger Composer应用本教程中的规则。您只需要获取并部署“ 开发人员指南”中使用的示例商品贸易业务网络-记住删除前面提到的全局贸易网络ACL规则-即可开始使用该环境了。
先决条件
无-只是一个互联网连接,您现在即可:-)
第一步:访问在线游乐场并选择您的业务网络
我们将使用trade-network
来自Composer示例网络存储库的示例商业网络()。
-
转到在线游乐场,如有必要,请在出现提示时清除本地存储。接受“欢迎”徽标,您就可以开始了。
-
单击
Deploy a new business network
模式/图标。 -
向下滚动并单击
trade-network
示例-向上滚动时,它将为您填充名称,描述和网络管理卡字段。 -
在“部署”按钮处于活动状态(确认名称为
trade-network
)的情况下,单击“ 部署”以部署业务网络。 -
最后,单击“立即连接”以连接到已部署的业务网络(默认ID-右上方显示)。
-
“贸易网络”自述文件应该处于活动状态,您可以在左列中看到商业网络的组件-其中之一是ACL文件
permissions.acl
,它控制对资源的访问。开箱即用的示例业务网络已启用“所有访问”,这最终将最终不同于生产样式环境。
创建交易者参与者
-
点击屏幕顶部附近的“测试”标签。这是我们创建样本交易者参与者的地方。
-
单击
Trader
左侧-创建新参与者(右上方),如下所示-以下示例为“ TRADER1”:
第一条记录:
{
"$class": "org.example.trading.Trader",
"tradeId": "TRADER1",
"firstName": "Jenny",
"lastName": "Jones"
}
- 重复步骤2,并
Trader
使用上面的示例数据创建5个其他参与者(“ TRADER2”至“ TRADER6”)(适当更改名称)。我们在下面提供了“ TRADER2”和“ TRADER3”作为示例。
第二条记录:
{
"$class": "org.example.trading.Trader",
"tradeId": "TRADER2",
"firstName": "Jack",
"lastName": "Sock"
}
第三条记录:
{
"$class": "org.example.trading.Trader",
"tradeId": "TRADER3",
"firstName": "Rainer",
"lastName": "Valens"
}
第四条记录:
{
"$class": "org.example.trading.Trader",
"tradeId": "TRADER4",
"firstName": "Davor",
"lastName": "Dolittle"
}
第五条记录:
{
"$class": "org.example.trading.Trader",
"tradeId": "TRADER5",
"firstName": "Steve",
"lastName": "Alonso"
}
第六条记录:
{
"$class": "org.example.trading.Trader",
"tradeId": "TRADER6",
"firstName": "Lars",
"lastName": "Graf"
}
创建商品资产
- 仍然在“测试”面板中,通过选择左侧的“商品”来创建一些商品记录-所有权(
owner
字段)与本教程中的“交易者”参与者相关。请注意,所有者是一个关系字段。
第一条记录:
{
"$class": "org.example.trading.Commodity",
"tradingSymbol": "EMA",
"description": "Corn",
"mainExchange": "EURONEXT",
"quantity": 10,
"owner": "resource:org.example.trading.Trader#TRADER1"
}
第二条记录:
{
"$class": "org.example.trading.Commodity",
"tradingSymbol": "CC",
"description": "Cocoa",
"mainExchange": "ICE",
"quantity": 80,
"owner": "resource:org.example.trading.Trader#TRADER2"
}
第三条记录:
{
"$class": "org.example.trading.Commodity",
"tradingSymbol": "HO",
"description": "Heating Oil",
"mainExchange": "NYMEX",
"quantity": 40,
"owner": "resource:org.example.trading.Trader#TRADER3"
}
第四条记录:
{
"$class": "org.example.trading.Commodity",
"tradingSymbol": "HG",
"description": "Copper",
"mainExchange": "COMEX",
"quantity": 100,
"owner": "resource:org.example.trading.Trader#TRADER4"
}
第五条记录:
{
"$class": "org.example.trading.Commodity",
"tradingSymbol": "SM",
"description": "Soybean Meal",
"mainExchange": "CBOT",
"quantity": 70,
"owner": "resource:org.example.trading.Trader#TRADER5"
}
第六条记录:
{
"$class": "org.example.trading.Commodity",
"tradingSymbol": "AG",
"description": "Silver",
"mainExchange": "CBOT",
"quantity": 60,
"owner": "resource:org.example.trading.Trader#TRADER6"
}
创建身份以测试ACL
接下来,让我们创建一些交易者身份-我们需要为交易者发布身份(TRADER1-6),以便我们可以测试这些身份的访问权限(每个身份都映射到各自的交易者参与者记录)
- 单击
admin
(右上角),然后从下拉列表中选择“ ID注册表” - 点击右上方的“发布新ID”,它将显示“发布新身份”对话框
- 在ID名称字段中-输入
tid1
将用于TRADER1的身份 - 在“参与者”字段中-输入
TRADER1
以搜索参与者-并选择标准参与者名称 - 点击“新建”继续。
(通过5上述步骤2)重复使用“发出新ID”序列同一性tid2
,tid3
,tid4
,tid5
和tid6
分别映射这些各自TRADER参与者。
现在,我们准备开始创建访问控制规则。
重要提示:如果您要为基于Hyperledger Composer的环境(而不是在线环境)发布新的身份,请确保使用“添加到钱包”选项将每个已发布的身份添加到您的钱包中。
添加商品交易网络访问控制规则
您部署的标准“商品贸易网络”示例网络附带标准的系统和网络ACL规则,该规则管理业务网络的参与者,以使他们能够访问诸如资产注册表之类的注册表,或者能够查看分类账中的历史记录。
但是我们要添加一些特定于交易的访问控制规则-让我们从定义我们首先要实现的目标开始!ACL的黄金法则是,除非明确允许,否则默认情况下对参与者隐式“拒绝”访问业务网络内的资源。
您将通过查看当前ACL来注意到permissions.acl
,在ACL文件中定义了某些“系统”或“管理员”类型规则-这是为了使参与者能够使用Composer系统操作,例如能够写入Composer系统历史学家注册表。
在开始之前,我们将需要permissions.acl
为我们的交易网络删除一个“全局”规则,因为该规则通常用作示例网络,因此现在必须被删除。这是删除的规则(直到-包括-最后一个大括号):
rule Default {
description: "Allow all participants access to all resources"
participant: "ANY"
operation: ALL
resource: "org.example.trading.*"
action: ALLOW
}
将其从permissions.acl
文件中删除(保留“系统”或“管理员”规则)后,单击“ 更新”按钮(左下方)以使更改生效。
就我们的规则目标而言-这些是我们要应用的政策:
日常活动-规则目标:
1a。交易者只能查看和更新自己的个人资料(参与者记录)
1b。允许交易者使用自己的资产(商品)进行所有操作
- 限制“交易者”类型的参与者,使其只能提交
Trade
交易(因为随着时间的推移,在“实时” /运营业务网络中模型中可能定义了几笔交易)
历史记录-规则目标:
- 确保交易者只能看到他们创建的交易历史。
- 允许REG类型的参与者(监管者)有权查看交易者进行的所有历史交易的历史记录(以及使用其自己的参与者资料)-为此,有两个规则子集-4a和4b。
重要的是,此时要注意的是,名称空间org.example.trading
(我们的商品交易业务网络)没有定义业务网络ACLS(只有系统名称),因此默认情况下隐式“拒绝”访问该业务网络中的资源。
规则1a-交易者资料限制规则
首先-限制交易者只能查看和更新自己记录的规则。
- 将身份切换为
tid1
(单击右上角的当前身份并选择ID注册表,为选择“立即使用”tid1
)-然后单击“测试”标签 - 确认您没有看到任何交易者记录。
- 将身份切换为“ admin”用户(右上方,“ ID注册表”),然后转到“定义”选项卡,然后单击
permissions.acl
左侧的“访问控制”()。 - 在注释行之后,将以下规则粘贴到您的编辑会话的顶部,并确保您已粘贴上面现有的3个“系统”和“网络”系统规则:
规则:
rule R1a_TraderSeeUpdateThemselvesOnly {
description: "Trader can see and update their own record only"
participant(t): "org.example.trading.Trader"
operation: READ, UPDATE
resource(v): "org.example.trading.Trader"
condition: (v.getIdentifier() == t.getIdentifier())
action: ALLOW
}
然后单击左下方的“ 更新”按钮以更新业务网络。
该规则将允许current
交易参与者(映射到current
身份,无论是在游乐场(在此处)还是在您的应用程序中)都可以读取和更新自己的目标交易者记录。
- 测试ACL:将用户切换到身份
tid1
(右上方,“ ID注册表”),然后单击“测试”选项卡-检查该身份仅可见TRADER1记录。
规则1b-交易者资产所有权-仅允许所有者更新
默认情况下,交易者无法查看或更新之前创建的任何商品。
我们需要一个规则来使交易者能够访问被指定为“所有者”的商品。
- 将身份切换为
tid1
(单击右上角的当前身份并选择ID注册表,为选择“立即使用”tid1
)-然后单击“测试”标签 - 确认您没有看到任何商品记录。
- 将身份切换回“管理员”用户(右上方,“ ID注册表”),然后转到“定义”选项卡,然后单击
permissions.acl
左侧的“访问控制”()。 - 将以下规则粘贴到您的编辑会话的第1行中,并粘贴到现有规则上方:
规则:
rule R1b_TraderSeeTheirCommodities {
description: "Trader can see/work with their own Commodities"
participant(t): "org.example.trading.Trader"
operation: ALL
resource(c): "org.example.trading.Commodity"
condition: (c.owner.getIdentifier() == t.getIdentifier())
action: ALLOW
}
然后单击左下方的“ 更新”按钮以更新业务网络。
该规则将允许current
交易者参与者对其“拥有”的目标商品资源进行所有操作。
- 测试ACL:将用户切换到身份
tid1
(右上方,“ ID注册表”),然后单击“测试”选项卡-确认TRADER1参与者拥有一种商品,并且对该身份可见/可编辑(图标)。
暗含的是,此交易者TRADER1目前无法查看或更新其他交易者的资产(商品)-我们不需要为此制定规则,但是在现实世界中可能存在一项允许特定的高级交易者“参见“其他商品”,尽管它们不是同一商品的所有者。
规则2-限制性规则:只有“交易者”参与者可以提交Trade
智能合约交易
默认情况下,交易者无法提交Trade
交易(在我们的模型中定义,并且在脚本文件中为其编写了智能合约逻辑的交易)来更新他拥有的商品。
我们需要一个规则,使交易者能够提交Trade
被指定为“所有者”的交易。该Trade
交易使当前所有者可以将商品的所有权更改为另一商人。
- 将身份切换为
tid1
(单击右上角的当前身份并选择ID注册表,为选择“立即使用”tid1
)-然后单击“测试”标签 - 确认您无法提交
Trade
交易(“提交交易”- 并粘贴在下面)以尝试更改商品的所有权-您将收到一条消息,提示您无法CREATE
提交交易。
要 的JSON:
{
"$class": "org.example.trading.Trade",
"commodity": "resource:org.example.trading.Commodity#EMA",
"newOwner": "resource:org.example.trading.Trader#TRADER2"
}
- 将身份切换回“管理员”用户(右上方,“ ID注册表”),然后转到“定义”选项卡,然后单击
permissions.acl
左侧的“访问控制”()。 - 将以下规则粘贴到您的编辑会话的第1行中,并粘贴到现有规则上方:
规则:
rule R2_EnableTradeTxn {
description: "Enable Traders to submit transactions"
participant: "org.example.trading.Trader"
operation: ALL
resource: "org.example.trading.Trade"
action: ALLOW
}
然后单击左下方的“ 更新”按钮以更新业务网络。
而已。我们已经知道,参与者只能使用自己的商品。这将仅允许交易者参与者提交类型的交易Trade
(我们在业务网络中可以有许多不同的参与者类型)。
- 测试ACL:将用户切换为身份
tid1
(右上方,“ ID注册表”)-具有ID的商品的所有者EMA
一种。点击“测试”标签。提交Trade
事务 并粘贴此事务,用以下提供的事务替换当前内容:
要 的JSON:
{
"$class": "org.example.trading.Trade",
"commodity": "resource:org.example.trading.Commodity#EMA",
"newOwner": "resource:org.example.trading.Trader#TRADER2"
}
b。通过转到“所有交易”(在左侧)来确认交易已提交,历史记录中的第一条记录显示TRADE
交易确认了转移。参与者TRADER1不再拥有该商品。相比之下,转换为身份tid2
将显示其具有两个商品记录,因为TRADER2是收件人的所有者。
规则3-启用规则:允许交易者仅查看自己的历史记录
默认情况下,由于系统的ACL(其中一部分是历史学家记录注册表),每个交易(例如及相关tid1
,tid2
等身份)可以看到所有事务的历史记录-一个例子是UpgradeBusinessNetwork
由管理员进行。
我们将锁定对历史学家的访问权限,以使交易者只能看到他们在历史学家中提交的交易。
- 将身份切换为
tid3
(单击右上角的当前身份并选择ID注册表,为选择“立即使用”tid3
)-然后单击“测试”标签 - 确认您可以看到与“系统”活动有关的交易,但也可以看到其他交易者(TRADER1和TRADER2)。
- 将身份切换回“管理员”用户(右上方,“ ID注册表”),然后转到“定义”选项卡,然后单击
permissions.acl
左侧的“访问控制”()。 - 将以下规则粘贴到您的编辑会话的第1行中,并粘贴到现有规则上方:
规则:
rule R3_TradersSeeOwnHistoryOnly {
description: "Traders should be able to see the history of their own transactions only"
participant(t): "org.example.trading.Trader"
operation: READ
resource(v): "org.hyperledger.composer.system.HistorianRecord"
condition: (v.participantInvoking.getIdentifier() != t.getIdentifier())
action: DENY
}
该规则将当前交易者参与者限制为仅查看他/她在区块链上调用的交易。
然后单击左下方的“ 更新”按钮以更新业务网络。
- 测试ACL:
一种。将用户切换到身份tid3
(右上角,“ ID注册表”)-您将仅看到“身份激活”类型条目,而没有看到与TRADER1和TRADER2相关的已提交交易历史。这就是我们所期望的。
b。接下来,切换到身份tid1
-您将看到仅与交易相关的交易记录(包括之前提交的“ TRADE”交易)tid1
,尤其是将商品“ CC”所有权转让给TRADER2的情况(相比之下,身份tid2
,受让人不会请参阅历史记录提交的“ TRADE”交易tid1
-仅是已转让的商品资产)。
规则4a和4b-启用规则:允许监管者查看自己的资料和所有历史活动,包括交易
理所当然的是,监管者希望审查/审核在业务网络中执行的历史交易。他们不一定需要访问“参与者”或“资产”本身(取决于用例或策略),而是与之相关的活动。
我们的“商品交易”业务网络模型中还没有“监管者”,因此我们将其添加为单独的参与者类型,然后继续定义规则,以允许拥有监管者“角色”的人访问历史记录记录。请记住,可以将一个或多个身份映射到参与者实例,“ Regulator”就是一个很好的例子。
- 将身份切换为(
admin
如果尚未这样做)-然后单击“定义”(顶部) - 单击模型文件,然后添加新的参与者类型(将其添加到
Trader
参与者下方),如下所示:
模型:
participant Regulator identified by regId {
o String regId
o String firstName
o String lastName
}
-
确保单击“ 更新”按钮以更新网络。
-
切换到“测试”选项卡(仍为“管理员”)并按如下方式创建参与者调节器:
创建记录:
{
"$class": "org.example.trading.Regulator",
"regId": "Reg101",
"firstName": "Jon",
"lastName": "Doe"
}
- 在ID注册表中为具有ID的身份创建一个Identity,
101
并将其映射到上面创建的参与者管理者“ Reg101”。
此时,由于之前定义的系统ACL规则,调节器现在可以在Composer的Historian中查看系统事务的历史记录。但是在这一点上,他看不到自己的参与者资料。
- 添加以下规则:
规则:
rule R4a_RegulatorSeeThemselves {
description: "Regulators can see and update their own record"
participant: "org.example.trading.Regulator"
operation: READ, UPDATE
resource: "org.example.trading.Regulator"
action: ALLOW
}
该规则仅允许监管机构参与者更新其个人档案记录(如果他们希望对其进行更新,则可以根据需要进行测试;我们之前做过类似的操作)。
然后,单击左下方的UPDATE按钮以使用新规则更新业务网络。
-
接下来,将身份(在Id注册表中)切换到监管者身份
101
,然后点击“立即使用” -
检查您是否确实可以查看历史记录(显示了我们以前的交易-然后单击“查看记录”以查看任何系统类型的交易活动,例如
AddAsset
或AddParticipant
-作为监管者,您应该可以看到此活动。 -
接下来,点击“查看记录”进行贸易交易-出现了问题-没有任何反应。您(监管机构)当前没有权限(通过ACL)能够查看交易记录
-
将身份切换回“管理员”,作为更改规则的良好做法。
-
添加以下监管者授权规则(将规则插入
permissions.acl
顶部的文件中):
规则:
rule R4b_RegTransView {
description: "Grant Regulator full access to Trade Transactions"
participant: "org.example.trading.Regulator"
operation: ALL
resource: "org.example.trading.Trade"
action: ALLOW
}
然后单击左下方的“ 更新”按钮以更新业务网络。
该规则使监管者可以访问贸易交易资源,从而可以从Historian的“查看记录”中查看贸易交易。
此规则也适用于映射到监管者角色和监管者参与者注册表中的任何后续身份。
- 测试ACL-现在再次进行贸易交易并检查您是否确实可以查看记录
在本教程中,您尝试了增量创建ACL规则的尝试,仅允许该示例商品贸易业务网络的参与者应获得必要的访问控制。我们已经看到了ACL规则如何为应用于参与者(或实际上是参与者角色)的资源提供授权和访问控制。ACL控制着对资源和事务的访问控制,无论是创建,删除或更新资源还是执行事务。在定义以下条件或标准时,我们还具有访问控制语言和规则的功能:“谁”有能力对分类账进行“什么”。
将Google OAUTH2.0与REST服务器一起使用
本教程提供了有关配置OAUTH2.0身份验证策略(例如,针对Google,Facebook,Twitter身份验证提供者等)的见解,以授权对已配置的REST Server实例中的资源的访问-并允许区块链网络的最终用户与部署的智能合约/业务网络。下面显示了概述图,而在更下方显示了显示身份验证流程的更详细的图。您将在多用户模式下运行REST服务器并测试与示例贸易网络作为不同区块链身份进行的交互,并通过REST API访问资源。为此,您将需要设置自己的Google帐户/授权方案(请参阅步骤的附录-不需要很长时间),或者至少使用本教程中提供的ID /元数据。可以说,它使用Hyperledger Composer作为底层的区块链网络。
注意:我们已经按照此处所述的第3步“设置您的IDE”中的说明设置了标准的“ Development Fabric”网络。
有很多Passport策略可供选择。从企业组织的角度来看,诸如SAML,JSON Web令牌(JWT)或LDAP之类的企业策略显然更合适-例如组织Active Directory服务器。我们使用/启用Google+ API作为本教程的身份验证提供程序,因为任何人都可以轻松设置Google帐户(请参阅附录以了解如何实现此功能)并配置服务/执行本教程,而不必担心要安装中间件的先决条件。
OAUTH2.0实际上是一个“授权协议”,但可以用作“授权身份验证方案”-身份验证通常意味着通过用户自己的凭据来识别用户,而此处使用的OAUTH2.0身份验证则用作“委托”身份验证方案。这里有许多“角色”可以通过背景进行扩展。Composer REST服务器的作用是提供对业务网络资源的访问,这些资源受Google+ API OAuth2.0方案保护。资源所有者是我们建立的Google+ API用户帐户(在附录中进行了描述),其作用是向客户端应用程序授予同意(或其他方式)。Google+授权服务器请求资源所有者的同意,并向REST客户端(例如Web客户端应用)颁发访问令牌,以使他们能够访问受保护的资源。较小的API提供程序可以将Google+中的相同应用程序和URL空间用于授权服务器和资源服务器。这个想法是,当一个Web应用程序用户(使用REST API来访问业务网络)出现时,他/她不需要预先注册任何东西。凭借已配置的客户端应用程序(尽管这确实取决于OAUTH2.0流程设置),该应用程序用户被授予了同意。在我们的教程中,我们使用浏览器来使用REST API,并查看身份验证流程的实际工作方式。较小的API提供程序可以将Google+中的相同应用程序和URL空间用于授权服务器和资源服务器。这个想法是,当一个Web应用程序用户(使用REST API来访问业务网络)出现时,他/她不需要预先注册任何东西。凭借已配置的客户端应用程序(尽管这确实取决于OAUTH2.0流程设置),该应用程序用户被授予了同意。在我们的教程中,我们使用浏览器来使用REST API,并查看身份验证流程的实际工作方式。较小的API提供程序可以将Google+中的相同应用程序和URL空间用于授权服务器和资源服务器。这个想法是,当一个Web应用程序用户(使用REST API来访问业务网络)出现时,他/她不需要预先注册任何东西。凭借已配置的客户端应用程序(尽管这确实取决于OAUTH2.0流程设置),该应用程序用户被授予了同意。在我们的教程中,我们使用浏览器来使用REST API,并查看身份验证流程的实际工作方式。凭借已配置的客户端应用程序(尽管这确实取决于OAUTH2.0流程设置),该应用程序用户被授予了同意。在我们的教程中,我们使用浏览器来使用REST API,并查看身份验证流程的实际工作方式。凭借已配置的客户端应用程序(尽管这确实取决于OAUTH2.0流程设置),该应用程序用户被授予了同意。在我们的教程中,我们使用浏览器来使用REST API,并查看身份验证流程的实际工作方式。
同意后授予访问密钥; 令牌允许客户端访问受OAuth2.0保护的API。在OAuth 2.0中,这些访问令牌称为“承载者令牌”,可以单独使用而无需签名或加密来访问信息。此外,访问令牌存储在用户Web浏览器本地存储区中的cookie中。当用户发出后续请求时,将从cookie中检索访问令牌,并验证访问令牌,而不是重新认证用户。
REST Server本身被配置为使用MongoDB存储持久保存商务网卡(连接到网络所需)。通常,组织将运行下面描述的REST服务器Docker映像的多个实例,并配置持久性数据存储的高可用性实例,例如MongoDB副本集。通过配置组件以实现高可用性,管理员可以停止,重新启动或删除REST服务器实例,而应用程序用户不会失去通过REST对已部署业务网络的访问权限。
您应该以非特权用户身份执行本教程(不需要sudo或提升的特权)。
步骤1:使用MongoDB设置持久性数据库凭证数据存储
如前所述,一旦将适当的商务网卡导入REST电子钱包,我们便会将凭据存储在持久性数据存储中。
启动MongoDB实例
- 打开一个终端窗口,然后输入以下命令:
docker run -d --name mongo --network composer_default -p 27017:27017 mongo
它应该输出已经下载了docker映像并提供SHA256消息。MongoDB docker容器的实例已启动。使用--network composer_default
此处很重要,以实现与REST服务器的简单网络连接。
步骤2:使用OAUTH2.0模块构建REST Server Docker映像
- 在$ HOME目录中,创建一个名为
dockertmp
cd 的临时目录:
cd $HOME ; mkdir dockertmp
cd dockertmp
- 在临时目录中,创建一个
Dockerfile
在编辑器中调用的docker文件,并将其粘贴到以下序列中(包括\
在RUN
和npm
下面的行之后所需的特殊反斜杠字符-即延续字符):
FROM hyperledger/composer-rest-server
RUN npm install --production loopback-connector-mongodb passport-google-oauth2 && \
npm cache clean --force && \
ln -s node_modules .node_modules
该Docker文件将提取位于/ hyperledger / composer-rest-server的Docker映像,并另外安装两个npm模块:
• loopback-connector-mongodb –此模块为LoopBack框架提供MongoDB连接器,并允许我们的REST服务器将MongoDB用作数据源。有关更多信息:https : //www.npmjs.com/package/loopback-connector-mongodb
• Passport-google-oauth2 –此模块使我们可以通过REST服务器使用Google+帐户进行身份验证。有关更多信息:https : //www.npmjs.com/package/passport-google-oauth-2
- 在与
Dockerfile
驻留目录相同的目录中,构建自定义Docker REST Server映像:
docker build -t myorg/composer-rest-server .
给-t标志的参数是您要为此Docker映像指定的名称,这可以由您自己决定-但在本指南中,该映像将称为“ myorg / composer-rest-server”。
您应该看到与以下类似的输出,其中最下面的两行显示“已成功构建”:
docker build -t myorg/composer-rest-server .
Sending build context to Docker daemon 4.203GB
Step 1/2 : FROM hyperledger/composer-rest-server
---> e682b4374837
Step 2/2 : RUN npm install --production loopback-connector-mongodb passport-google-oauth2 && npm cache clean --force && ln -s node_modules .node_modules
---> Running in 7a116240be21
npm WARN saveError ENOENT: no such file or directory, open '/home/composer/package.json'
npm WARN enoent ENOENT: no such file or directory, open '/home/composer/package.json'
npm WARN composer No description
npm WARN composer No repository field.
npm WARN composer No README data
npm WARN composer No license field.
+ passport-google-oauth2@0.1.6
+ loopback-connector-mongodb@3.4.1
added 114 packages in 7.574s
npm WARN using --force I sure hope you know what you are doing.
---> a16cdea42dac
Removing intermediate container 7a116240be21
Successfully built a16cdea42dac
Successfully tagged myorg/composer-rest-server:latest
信息:不必担心看到上面控制台上显示的“ npm warn messages”。这可以忽略。
- 最后,在本节中,返回目录结构的上一级:
cd ..
步骤3:为REST Server实例配置定义环境变量
envvars.txt
在$ HOME目录中创建一个名为的文件,然后粘贴以下配置设置-请注意,您将需要用下面自己的 Google API +客户端信息替换下面显示的客户端ID和clientSecret(如附录所示)
COMPOSER_CARD=restadmin@trade-network
COMPOSER_NAMESPACES=never
COMPOSER_AUTHENTICATION=true
COMPOSER_MULTIUSER=true
COMPOSER_PROVIDERS='{
"google": {
"provider": "google",
"module": "passport-google-oauth2",
"clientID": "312039026929-t6i81ijh35ti35jdinhcodl80e87htni.apps.googleusercontent.com",
"clientSecret": "Q4i_CqpqChCzbE-u3Wsd_tF0",
"authPath": "/auth/google",
"callbackURL": "/auth/google/callback",
"scope": "https://www.googleapis.com/auth/plus.login",
"successRedirect": "/",
"failureRedirect": "/"
}
}'
COMPOSER_DATASOURCES='{
"db": {
"name": "db",
"connector": "mongodb",
"host": "mongo"
}
}'
此处定义的环境变量将表明我们希望使用Google OAuth2和MongoDB作为持久数据源的身份验证的多用户服务器。
第一行表示我们将以其启动网络的商业网卡的名称-针对已定义的商业网络的特定REST Administrator。您还将看到,在此配置中,我们还定义了REST服务器将使用的数据源以及我们正在使用的身份验证提供程序。这些分别可以通过COMPOSER_DATASOURCES和COMPOSER_PROVIDERS变量看到。
步骤4:在当前终端中加载环境变量并启动持久性REST Server实例
- 在与
envvars.txt
您创建的包含环境变量的文件相同的目录中,运行以下命令:
source envvars.txt
INFO命令没有输出?-这是预期的。如果您的文件中确实存在语法错误,envvars.txt
则在运行此命令后,将通过错误指示该错误。
- 现在让我们通过使用“ echo”命令检查几个环境变量来确认确实设置了环境变量,如下所示
echo $COMPOSER_CARD
echo $COMPOSER_PROVIDERS
步骤5:部署样本商品交易业务网络以从REST客户端进行查询
-
如果您尚未这样做
trade-network.bna
,请从https://composer-playground.mybluemix.net/下载贸易网络的。确保记下“关于”页面上方显示的版本号。 -
在Playground中,以身份连接到网络
admin
并导出trade-network.bna并将其 到您的主目录。
- 要部署业务网络,首先需要将业务网络安装到对等方
composer network install --card PeerAdmin@hlfv1 --archiveFile trade-network.bna
记下运行上述命令后输出的版本。这是商业网络的版本,您将提供给用于启动商业网络的下一个命令。
运行以下命令,替换<business_network_version>
为先前安装命令输出的版本号。
composer network start --card PeerAdmin@hlfv1 --networkName trade-network --networkVersion <business_network_version> --networkAdmin admin --networkAdminEnrollSecret adminpw --file networkadmin.card
您应确认商品贸易业务网络已启动,并且已创建“ admin” networkadmin.card文件。
- 接下来,导入商务网卡,并与卡连接以将证书下载到钱包:
composer card import -f networkadmin.card
composer network ping -c admin@trade-network
您应该确认连接已成功测试。现在,我们准备使用已部署的业务网络。
步骤6:为Composer REST服务器实例创建REST服务器管理员
- 创建一个名为的REST Administrator身份
restadmin
以及一个关联的商务网卡(用于稍后启动REST服务器)。
composer participant add -c admin@trade-network -d '{"$class":"org.hyperledger.composer.system.NetworkAdmin", "participantId":"restadmin"}'
composer identity issue -c admin@trade-network -f restadmin.card -u restadmin -a "resource:org.hyperledger.composer.system.NetworkAdmin#restadmin"
- 导入并测试卡:
composer card import -f restadmin.card
composer network ping -c restadmin@trade-network
- 因为我们将REST服务器托管在具有其自身特定网络IP信息的另一个位置,所以我们需要更新connection.json-以便docker主机名(来自持久REST服务器实例内部)可以解析彼此的IP地址。
下面的单行代码将用docker主机名替换“ localhost”地址,并创建一个新的connection.json
-放入我们的REST管理员的卡片中。稍后,在本教程结尾处,我们还将在OAUTH2.0 REST身份验证序列中为“测试”身份验证的用户使用此自定义connection.json文件。要快速更改主机名- 并粘贴,然后在$ HOME目录的命令行中运行此单行代码(如下)。
sed -e 's/localhost:7051/peer0.org1.example.com:7051/' -e 's/localhost:7053/peer0.org1.example.com:7053/' -e 's/localhost:7054/ca.org1.example.com:7054/' -e 's/localhost:7050/orderer.example.com:7050/' < $HOME/.composer/cards/restadmin@trade-network/connection.json > /tmp/connection.json && cp -p /tmp/connection.json $HOME/.composer/cards/restadmin@trade-network/
步骤7:启动持久性REST服务器实例
- 运行以下docker命令以启动REST服务器实例(使用
restadmin
商务网卡)
docker run \
-d \
-e COMPOSER_CARD=${COMPOSER_CARD} \
-e COMPOSER_NAMESPACES=${COMPOSER_NAMESPACES} \
-e COMPOSER_AUTHENTICATION=${COMPOSER_AUTHENTICATION} \
-e COMPOSER_MULTIUSER=${COMPOSER_MULTIUSER} \
-e COMPOSER_PROVIDERS="${COMPOSER_PROVIDERS}" \
-e COMPOSER_DATASOURCES="${COMPOSER_DATASOURCES}" \
-v ~/.composer:/home/composer/.composer \
--name rest \
--network composer_default \
-p 3000:3000 \
myorg/composer-rest-server
这将输出Docker容器的ID,例如。690f2a5f10776c15c11d9def917fc64f2a98160855a1697d53bd46985caf7934
并确认REST服务器确实已经启动。
- 使用我们的容器检查一切正常-您可以使用以下命令查看其运行情况:
docker ps |grep rest
docker logs rest
在日志末尾查找“在http:// localhost:3000 / explorer上浏览您的REST API ”-如果不存在,请追溯步骤(上述)。
步骤8:测试REST API是否受保护并需要授权
- 打开浏览器窗口,并通过转至http:// localhost:3000 / explorer启动REST API资源管理器,以查看和使用可用的API。
INFO管理员身份restadmin
用作初始默认值-REST服务器使用restadmin
身份,直到jdoe
在REST客户端钱包中将特定身份设置为默认身份为止。
- 转到“系统:常规业务网络方法”部分
- 转到“ / system / historian” API,然后单击“尝试一下!” 按钮,如下所示:
您应该会遇到授权错误,这是因为我们已配置Google+护照OAUTH2.0身份验证策略来保护对REST服务器的访问。一旦实现了通过OAUTH2.0身份验证pa的身份验证,浏览器中的REST API便可以与贸易商品业务网络进行交互(即,一旦导入了名片)。
步骤9:创建一些参与者和身份以测试OAUTH2.0身份验证
- 您需要创建一组参与者和身份以进行测试,然后才能与业务网络进行交互。这是因为REST服务器可以在多用户模式下处理多个REST客户端。我们将使用composer CLI命令添加参与者和身份,如下所示-名字是Jo Doe:
composer participant add -c admin@trade-network -d '{"$class":"org.example.trading.Trader","tradeId":"trader1", "firstName":"Jo","lastName":"Doe"}'
composer identity issue -c admin@trade-network -f jdoe.card -u jdoe -a "resource:org.example.trading.Trader#trader1"
composer card import -f jdoe.card
- 再次,因为我们将使用此身份在持久性REST docker容器内进行测试-我们将需要更改主机名以表示docker可解析的主机名-再次运行此一类代码以快速执行这些更改:
sed -e 's/localhost:7051/peer0.org1.example.com:7051/' -e 's/localhost:7053/peer0.org1.example.com:7053/' -e 's/localhost:7054/ca.org1.example.com:7054/' -e 's/localhost:7050/orderer.example.com:7050/' < $HOME/.composer/cards/jdoe@trade-network/connection.json > /tmp/connection.json && cp -p /tmp/connection.json $HOME/.composer/cards/jdoe@trade-network/
- 我们需要将卡导出到文件中以用于导入其他位置(即,将用于导入浏览器客户端中的钱包的卡),因此,在这一点上,我们可以丢弃的初始商务网卡文件
jdoe
。
composer card export -f jdoe_exp.card -c jdoe@trade-network ; rm jdoe.card
- 对参与者Ken Coe(
kcoe
)重复上述步骤-创建一个trader2
参与者并颁发身份kcoe
-命令序列为:
composer participant add -c admin@trade-network -d '{"$class":"org.example.trading.Trader","tradeId":"trader2", "firstName":"Ken","lastName":"Coe"}'
composer identity issue -c admin@trade-network -f kcoe.card -u kcoe -a "resource:org.example.trading.Trader#trader2"
composer card import -f kcoe.card
sed -e 's/localhost:7051/peer0.org1.example.com:7051/' -e 's/localhost:7053/peer0.org1.example.com:7053/' -e 's/localhost:7054/ca.org1.example.com:7054/' -e 's/localhost:7050/orderer.example.com:7050/' < $HOME/.composer/cards/kcoe@trade-network/connection.json > /tmp/connection.json && cp -p /tmp/connection.json $HOME/.composer/cards/kcoe@trade-network/
composer card export -f kcoe_exp.card -c kcoe@trade-network ; rm kcoe.card
现在可以将这些卡导入,然后在下一部分中将其用于REST客户端(即浏览器)中。
步骤10:从REST API资源管理器进行身份验证并使用特定身份进行测试
- 转到http:// localhost:3000 / auth / google-这会将您定向到Google身份验证同意屏幕。
- 使用以下凭据登录:(如下所示的示例-根据建议,您应按照本教程附录部分中的说明进行设置):
- 电子邮件:composeruser01@gmail.com
- 密码:
- 您将通过Google身份验证,然后重定向回REST服务器(http:// localhost:3000 / explorer),该服务器在左上角显示访问令牌消息-单击“显示”以查看令牌。
尽管我们的REST服务器已通过Google+ OAUTH2.0服务的身份验证(由其项目/客户端范围定义,并使用附录中为OAUTH2.0服务设置的客户端凭据),但实际上,在以下方面,我们尚未采取任何措施:区块链身份或使用商业网卡与我们的商品贸易网络互动-我们将使用jdoe
我们之前创建的身份进行下一步。
步骤11:检查默认钱包并导入卡并设置默认身份
-
首先,转到电子钱包下的REST端点,并执行GET操作(和“尝试一下”)以获取电子钱包的内容-检查电子钱包是否包含任何商务网卡-它应显示为空
[ ]
:GET /钱包
-
您需要向REST客户端钱包添加一个身份,然后将该身份设置为用于进行API调用的默认身份。转到/ Wallets下的POST系统操作-它称为
/Wallets/Import
端点 -
选择导入文件
jdoe_exp.card
-并提供卡的名称为jdoe @ trade-network,然后单击“试用”
-
向下滚动-您应该获得HTTP状态代码204(请求成功)
-
接下来,返回
GET /钱包
您应该看到已将jdoe@trade-network
其导入钱包。另请注意,的值default property
是true,这意味着在与“商品交易”业务网络进行交互时(直到您将其更改为使用其他网络时),默认情况下将使用此业务网络卡。
步骤12:测试与业务网络的交互,并将其作为默认ID jdoe
- 转到“系统REST API方法”部分,然后展开“ / GET系统/历史记录”部分
- 单击“试用”-您现在应该可以看到Historian Registry的结果,即区块链标识“ jdoe”和一组交易
- 转到
Trader
方法并展开/ GETTrader
端点,然后单击“试用”
它应该确认我们能够像经过jdoe
身份验证的会话中那样与REST Server进行交互。
现在,您应该能够看到当前创建的所有交易者参与者。如果设置了任何ACL,则可能会对其可见的内容施加限制(它们尚未应用于当前示例网络,但可以在ACL教程 FYI中看到ACL规则的示例)。可以说,访问业务网络的REST API受到访问控制的约束-就像与业务网络的任何其他交互(例如Playground,JS API,CLI等)一样。
- 接下来,返回
POST /wallet/import
操作并导入kcoe_exp.card
卡名称设置为的卡文件,kcoe@trade-network
然后单击'Try it Out
导入它-它应该返回成功的(204)响应。
- 但是,要使用此卡,我们需要在电子钱包中将其设置为默认卡名称-转到
POST /wallet/name/setDefault/
方法,选择kcoe@trade-network
作为默认卡名称,然后单击Try it Out
。现在这是默认卡。
- 返回
Trader
方法并展开/ GETTrader
端点,然后单击“尝试一下”。它应该确认我们现在使用的是不同的卡名,并且在我们仍通过身份验证后仍能够与REST Server交互。
结论
教程部分到此结束-您已经了解了如何配置基于客户端的Google OAUTH2.0身份验证服务,该服务可用于授权客户端应用程序并提供与受保护资源服务器(即REST Server实例)交互的同意,而无需需要对每个请求进行身份验证。此外,REST Server在多用户模式下运行,因此,允许多个区块链标识与来自同一REST客户端会话的已部署商品交易业务网络进行交互,并受令牌到期时间等的限制。
以下附录描述了在本教程之前如何设置本教程中的Google身份验证方案。
附录-Google+身份验证配置和设置
以下附录描述了如何创建用于认证客户端应用程序的OAUTH2.0认证服务。高级别概述中的这些步骤包括:
- 创建Google API +项目
- 创建凭据服务帐户
- 建立OAuth2.0同意书
- 为凭证服务帐户创建OAuth2.0客户端ID凭证
步骤A1:创建Google API +项目
-
登录到您的Google帐户-如果您没有该帐户,请在google.com上创建一个帐户,然后登录Google
您应该在到达时看到以下页面。在搜索栏中搜索“ Google+”,然后在显示时选择Google+ API图标。
-
选定后-单击以启用Google+ API-为此,这一点很重要。
-
由于您还没有“项目”,因此系统会提示您创建一个项目,以启用API。点击“创建项目”
-
系统将提示您给它起一个名字-称其为'GoogleAuth'并记下项目ID(在我们的情况下显示为)
proven-caster-195417
-稍后将使用它。 -
创建项目后,您将再次被重定向到Google+ API页面。现在,您应该看到选择的项目名称和“启用”服务的选项。点击“启用”。
步骤A2:创建凭据服务帐户
-
启用服务后,系统将提示您创建服务帐户凭据,以便您可以使用该服务。点击“创建凭据”。
-
系统将询问您一系列问题,以确定您需要哪种凭证。提供以下屏幕快照中显示的答案。为API,Web服务器(例如Node js,Tomcat)和应用程序数据选择“ Google+ API”,为底部的引擎问题选择“否”。
-
点击
What credentials do I need
并点击继续
-
接下来,设置一个凭据服务帐户-名称为“ GoogleAuthService”-在下拉列表中选择“项目”,然后选择一个角色
Owner
以及JSON类型和 -
点击“获取您的凭证”-它应以JSON格式下载(或提示下载)服务凭证-将其保存到安全位置。
- 使用应用程序凭据保存JSON文件。下载凭据后,该站点会将您带回到凭据主页,您将看到一个新的服务帐户密钥。
步骤A3:创建OAUTH2.0同意
- 转到“ OAuth同意屏幕”标签=您将需要提供“ Google Auth REST OAUTH2服务”之类的“产品名称”-当请求同意批准请求时(即当我们在在主教程中的REST客户端)和电子邮件地址中,点击“保存”。
OAuth同意屏幕是用户(在本教程中)根据Google Auth REST服务进行身份验证时将看到的内容
步骤A4:为凭证服务帐户创建OAuth2.0客户端ID凭证
-
返回“凭据”标签,然后单击“创建凭据”下拉菜单,然后选择“ OAuth客户端ID”。
-
选择“ Web应用程序”,并给它一个简单的名称,例如“ Web Client 1”
-
在“授权的JavaScript起源”部分下,添加带有以下URI的行-这是客户端应用程序(REST服务器):
-
我们将需要在底部添加“授权重定向URI”,这是在获得Google+ OAUTH2.0身份验证服务的同意后,将经过身份验证的会话重定向回的位置。回调将与我们将在Composer REST Server环境变量中配置的变量匹配(特别
COMPOSER_PROVIDERS
是envvars.txt
在执行主教程中的此指令时的变量)。
在“授权重定向URI”下,添加以下URI作为授权URI。注意:最好 /粘贴下面的每个URI,然后在每个行条目之后在浏览器中按ENTER键-因为URI行编辑器有时可以在键入时截断您的条目。例如,如果您在键入URI时暂停。
http://localhost:3000/auth/google
http://localhost:3000/auth/google/callback
然后点击底部的“创建”按钮。
系统将提示您保存客户端ID和客户端密钥- 这两个密码并保存以备后用。
一切就绪-现在您可以返回主教程,使用Google的OAUTH2.0客户端身份验证服务来设置REST Server身份验证。
Google认证OAUTH2.0设置和认证范围一词
当应用程序使用OAuth 2.0进行授权时,它代表用户执行操作,以请求OAuth 2.0访问令牌来访问资源,该令牌由一个或多个作用域字符串标识。当然,通常情况下-要求用户本身批准访问。
当用户(例如管理员)为特定范围授予对应用程序的访问权限时,至少在Google中,会在Google+ API控制台中设置项目级别的同意“品牌”,以挑战初始同意。此后,一旦获得同意,Google就会认为该用户(通过他/她已建立的Google帐户)已授予对API +项目中任何已配置的客户端ID的特定范围的访问权限;授予表示对整个应用程序的信任-对于Google+ API配置中定义的范围。
结果是不会提示应用程序提供者多次批准对同一逻辑客户端应用程序的任何资源的访问。
幸运的是,当评估是否要授权同一项目中的其他项目时,Google授权基础结构可以使用有关在Google+ API控制台中设置的给定项目中的客户ID的用户批准信息。它还要求您设置可以被授予同意的授权URI(例如,成功认证后的应用程序回调URL)。
Google授权模块将观察到调用应用程序和Web客户端ID在同一个项目中,并且在未经用户批准的情况下,将ID令牌返回给应用程序,由Google签名。ID令牌将包含几个数据字段,其中以下几个字段特别相关:
iss: always accounts.google.com
aud: the client ID and secret of the web component of the project
email: the email that identifies the user requesting the token
该ID令牌旨在通过HTTPS传输。在使用它之前,Web组件必须执行以下操作:
验证密码签名。因为令牌采用JSON Web令牌或JWT的形式,并且存在用于验证大多数流行编程语言中可用的JWT的库,所以这是直接且高效的。
确保该aud
字段的值与其自己的客户端ID相同。
一旦完成,REST服务器就可以高度确定-令牌是由Google发行的。
使用游乐场
Hyperledger Composer Playground提供了用于配置,部署和测试业务网络的用户界面。先进的Playground功能允许用户管理业务网络的安全性,邀请参与者加入业务网络并连接到多个区块链业务网络。
如果您不熟悉Playground,我们建议您遵循Playground Tutorial,该指南将指导您完成与业务网卡进行交互之前创建,部署和测试新的区块链业务网络的过程。
请注意:如果两个或多个用户使用Hyperledger Composer Playground连接到Hyperledger Fabric的相同实例,请确保在另一个用户更新了业务网络定义之后,每个用户都刷新了他们的浏览器。刷新浏览器会接受其他用户对业务网络定义所做的更改。如果在不接受其他用户的更改的情况下更改了业务网络,则更改将丢失。
导航游乐场
商业网络页面
“ 业务网络” 页面是默认的Playground登录页面。在这里,您可以查看所有可使用的商务网卡。每个商务网卡都提供连接到区块链商务网络所需的所有信息。只能使用有效的商务网卡访问区块链商务网络。连接到已部署的业务网络后,将转到“ 定义”页面。
在此页面上,您可以:
- 连接到业务网络。如果您已经有一个已部署的业务网络并为其创建了业务网卡,则可以单击立即连接以连接到业务网络。
- 部署新的业务网络。如果这是您第一次使用Playground,或者您希望启动新的网络,则部署自己的网络是一个不错的起点。创建新的业务网络时,可以选择将业务网络定义基于示例网络,也可以从头开始创建自己的网络。
- 与商务网卡进行交互。商业网卡用于连接到已经存在的商业网络,并且是连接配置文件和身份的组合。该卡提供了删除身份/卡,导出卡以及连接到相应业务网络的选项。
- 导入商务网卡。
.card
从计算机导入现有文件是向“业务网络”页面添加业务网卡的最简单方法。 - 使用用户ID和用户密码进行连接。如果网络管理员为您提供了用户ID和用户机密,请单击“ 使用凭据连接”以输入它们并生成商务网卡。
- 运行Playground教程。如果您不知道从哪里开始,那么Playground教程将从头开始创建业务网络,并执行一些基本操作。
商业网络选项
使用商务网卡连接到商务网络后,无论您是在查看“ 定义”选项卡还是“ 测试”选项卡,都有许多可用的选项。
- 左上角是您使用的连接配置文件的名称以及您连接到的业务网络。在上面的示例中,连接配置文件称为Web,而业务网络名称为basic-sample-network。
- 链接到“ 定义”和“ 测试”选项卡。在“ 定义”选项卡中,可以添加,修改和删除业务网络的内容,在“ 测试”选项卡中,可以创建在“ 定义”选项卡中定义的资产和参与者,并测试业务网络的功能。
- 右上方是一个下拉菜单,显示用于连接到业务网络的身份。该下拉列表包含一个指向Identity Registry的链接,以及退出业务网络并返回“ 业务网络”页面的功能。
定义选项卡
“定义”选项卡用于创建,编辑和升级您的业务网络。
在“ 定义”选项卡的左侧,您可以看到当前业务网络定义中所有文件的列表。要检查文件的内容,请单击该文件,它将出现在编辑器视图中。可以使用添加文件按钮将新文件添加到您的企业网络。可以将模型文件,脚本文件,访问控制文件和查询文件添加到您的业务网络。
添加并修改了业务网络定义的文件后,您可以使用“ 部署更改”按钮将更改部署到网络中。单击“ 部署更改”后,您可以在“ 测试”选项卡中尝试进行更改。在导出按钮允许您下载您当前的业务网络作为.bna
文件。
请注意:如果两个或多个用户使用Hyperledger Composer Playground连接到Hyperledger Fabric的相同实例,请确保在另一个用户更新了业务网络定义之后,每个用户都刷新了他们的浏览器。刷新浏览器会接受其他用户对业务网络定义所做的更改。如果在不接受其他用户的更改的情况下更改了业务网络,则更改将丢失。
测试标签
“ 测试”选项卡用于通过使用在“ 定义”选项卡中定义的资产类型,参与者类型和交易来测试已部署的业务网络。
在“ 测试”选项卡的左侧,列出了每种参与者类型和资产类型。单击参与者类型,资产类型或所有事务将显示一个注册表,其中显示该类型的所有活动实例。例如,通过单击SampleParticipant,您可以看到一个注册表,其中显示了已创建的所有SampleParticipant。如果这是您第一次查看“ 测试”标签,那么您的注册表将为空!
在每个注册表中,您可以创建相应的资产,参与者或提交相应的交易。
在“ 所有交易”注册表(也称为“历史记录”)中,您可以查看业务网络中发生的每笔交易的记录,包括由系统事件(例如创建参与者或资产)引起的某些交易。在事务注册表中,您可以提交事务,然后通过检查更改的资源来检查其效果是否已经发生。
游乐场任务
商业网卡
商业网卡
商业网卡提供了连接到区块链商业网络所需的所有信息。只能通过有效的商务网卡访问区块链商务网络。商业网卡包含已部署的商业网络中单个参与者的ID和身份。Hyperledger Composer Playground中使用商务网卡来连接到已部署的商务网。您可以为一个已部署的业务网络拥有多个业务网卡,这些业务网卡属于多个参与者。
商业网卡在“连接配置文件”下进行分组,每张卡都显示可通过“立即连接”选项使用显示的身份访问的商业网络。可以使用名片上的图标删除或导出名片。
这是一个商业网卡,可用于使用“新用户”身份连接到名为“ my-business-network”的商业网络
在游乐场内发布身份信息时,可以创建商务网卡。然后,可以将此商务网卡导出并与他人共享,从而允许他们使用颁发的身份连接到商务网络。如果管理员为用户提供了注册ID和密码(与企业网络中的有效标识相对应),则可以在游乐场中直接创建企业网卡。也可以手动创建商务网卡。
使用Playground创建对等管理员卡
首次将业务网络部署到Hyperledger Fabric实例时,需要在相关Hyperledger Fabric对等方上安装Hyperledger Composer链码,然后在通道上实例化业务网络。此过程需要对等或通道管理员拥有特殊的Hyperledger Fabric特权。
必须创建对等管理员业务网卡,才能将Hyperledger Composer业务网络部署到Hyperledger Fabric实例。要创建对等管理员商务网卡:
-
在“ 我的业务网络”屏幕上,点击创建业务网络卡。
-
选择Hyperledger Fabric v1.2,然后单击Next。
-
输入您的连接配置文件的详细信息。为了更好地了解创建连接配置文件,请参阅部署到Hyperledger Fabric,然后单击下一步。
-
选择证书,然后上传证书和私钥信息以获取对等管理员身份。在部署到Hyperledger面料教程给出在哪里可以找到正确的证书的概述。
-
输入名片的名称。
-
选择“ 管理员卡”,然后选择“ 对等管理员”和“ 频道管理员”。
-
点击下一步
对等管理卡现在应该出现在“ 我的业务网络”屏幕中。现在,您可以使用Playground将业务网络部署到Hyperledger Fabric实例。
使用业务网卡提供对您的业务网络的访问
通过提供商务网卡,授予了另一用户访问您的商务网的权限。一旦创建,就可以将商务网卡导出并提供给创建该网卡的用户。
为了绑定创建商务网卡所需的身份,商务网络中必须存在一个参与者。
在Playground中发布身份后,可以选择保存该身份以在“业务网络”页面中使用。通过选择此选项,将为发布的身份创建一个商务网卡,该身份对于当前商务网络有效。注销当前业务网络后,该业务网络卡将出现在“业务网络”页面上,并且可以从此位置导出该业务网络卡以与其他用户共享。
制作名片
-
在“ 业务网络”页面上,选择用于连接到您的业务网络的身份。单击立即连接。请注意:您必须使用有权创建新身份的身份。
-
如果需要,请创建要为其分配身份的参与者:
- 单击测试选项卡,然后单击创建新参与者。
- 完成参与者定义,然后单击“ 新建”。
-
单击右上角的身份名称,然后单击下拉列表中的“ ID注册表 ”。
-
点击+发布新ID。
-
选择一个ID名称,然后输入一个现有的参加者来关联新的身份。提供了一项预见服务以自动完成已知参与者。
-
点击新建。
-
点击添加到我的钱包。将商务网卡添加到“商务网络”页面后,您可以使用它来连接到商务网络,或将其导出以供其他人使用。
现在,“ 业务网络”页面应显示新的“业务网络卡”。
导出名片
通过与您要导出的商务网卡进行交互,可以从Playground 的“ 商务网”页面中导出商务网卡,这是一个一步的过程。
- 在“ 商务网络”页面上,单击要导出的商务网卡上的“ 导出”图标。商业网卡应下载为
.card
文件。
请注意:如果您导出从未使用过的商业网卡(例如,发送给新参与者),它将包含获取证书和私钥所需的注册ID和注册机密,然后将其用于识别参与者。或者,如果导出以前使用过的商业网卡,则该商业网卡将已经包含证书和私钥。有关参与者和身份的更多信息,请参阅我们的主要文档。
重要提示:导出的身份证应谨慎处理,因为其中包含不受保护的凭据。我们建议您仅发送已加密的身份证。
访问业务网络
导入名片
导入业务网卡使您可以连接到已部署的业务网络。
-
在“ 业务网络”页面上,单击右上角的“ 导入业务网卡 ”。
-
拖放或浏览以选择
.card
要导入的商务网卡()文件。点击导入。
现在,在您的“业务网络”页面上应该可以看到“业务网络卡”;您现在可以连接到已部署的业务网络。
使用凭据连接
可以从“ 商业网络”页面创建商业网卡的两种方法。
可以使用证书来创建商务网卡,这需要以下条件:证书和私钥,由商务网络的管理员提供;商业网卡的名称;凭证有效的商业网络名称;部署目标业务网络的运行时的连接配置文件详细信息。
要使用证书从“ 商务网络”页面创建商务网卡:
-
收到证书和私钥后,单击“ 业务网络”页面右上方的“ 使用凭据连接”按钮。
-
如果您先前已连接到已部署的运行时,请从显示的列表中选择它,然后单击“ 下一步”并继续执行步骤4;否则,请转至步骤4。否则选择单选选项以连接到新的区块链,然后单击下一步。
-
指定提供给您的连接配置文件详细信息,然后单击保存。
-
输入证书,私钥,业务网卡名称和业务网络名称,然后单击“ 创建”。
现在,应该在“ 业务网络”页面中显示“业务网络卡” 。
手动创建商务网卡
商业网卡是.zip
包含多达三个元素的存档()文件:
- 连接配置文件。(
.json
) - 一个元数据文件,其中包含用于身份的数据,以用于连接到业务网络。(
metadata.json
) - 包含证书和私钥的可选凭据目录。
请注意:如果没有凭据目录,则元数据文件必须包含具有属性名称enrollmentSecret的Enrollment Secret属性。如果指定了enrollmentSecret,则在导出商务网卡时,将创建并填充包含证书的凭据目录。
元数据文件应采用以下格式:
{
"name": "PeerAdmin",
"description": "A valid Business Network Card",
"businessNetwork": "basic-sample-network",
"enrollmentId": "UserID",
"enrollmentSecret": "UserSecret",
"roles": [
]
}
该businessNetworkName,图像,enrollmentSecret和角色属性是可选的。可用角色为PeerAdmin
和ChannelAdmin
。
开发商业网络
开发人员使用Hyperledger Composer对业务网络进行数字化。业务网络由网络中的多个参与者访问,其中一些参与者可能负责网络本身的维护(托管),称为网络维护者。
通常,网络的每个维护者都将运行几个对等节点(以实现崩溃容错功能),而Hyperledger Fabric会在对等节点集之间 分布式分类帐。
模型
开发人员与业务分析师一起为业务网络定义域数据模型。数据模型使用Composer建模语言表示,并定义将存储在分类账中或作为事务处理的资源的结构。
域模型到位后,开发人员可以将智能合约捕获为用JavaScript编写的可执行事务处理器功能。
访问控制
并行地,开发人员或技术分析人员可以定义业务网络的访问控制规则,以强制哪些参与者可以访问分类帐上的数据以及在哪些条件下。
部署
开发人员将模型,脚本和访问控制规则打包到可部署的Business Network存档中,并使用命令行工具将存档部署到运行时进行测试。
测试
像所有业务逻辑一样,为业务网络创建单元和系统测试也很重要。开发人员可以使用流行的JavaScript测试框架(例如Mocha和Chai)运行单元测试(针对Node.js嵌入式运行时)或针对Hyperledger Fabric运行系统测试。
整合
一旦对业务网络进行了测试并就位,则需要创建前端应用程序。使用REST服务器自动为业务网络生成REST API,然后使用Yeoman代码生成器框架生成Angular应用程序。
可以将REST服务器配置为对业务网络中的参与者进行身份验证,以确保强制执行凭据和权限。
参考文献
业务网络定义
业务网络定义是Hyperledger Composer编程模型的关键概念。它们被表示BusinessNetworkDefinition
类中,在定义的composer-common
模块和出口双方composer-admin
和composer-client
。
业务网络定义包括:
- 一组模型文件
- 一组JavaScript文件
- 访问控制文件
模型文件定义了业务网络的业务域,而JavaScript文件包含事务处理器功能。交易处理器功能在Hyperledger Fabric上运行,并可以访问存储在Hyperledger Fabric区块链世界状态中的资产注册表。
模型文件通常由业务分析师创建,因为它们定义了模型元素(资产,参与者和交易)之间的结构和关系。
JavaScript文件通常由实现业务分析师提供的业务需求的开发人员创建。
访问控制文件包含一组访问控制规则,这些规则定义了业务网络中不同参与者的权限。
定义后,可以使用composer
命令行界面将业务网络定义打包到存档中。然后,可以使用模块中的AdminConnection
类将这些存档部署或更新到Fabric上composer-admin
。
参考文献
创建业务网络定义
业务网络定义具有以下布局:
models/ (optional)
lib/
permissions.acl (optional)
package.json
README.md (optional)
创建新业务网络定义的最简单方法是git clone
举个例子,或者使用Hyperledger Composer Yeoman生成器创建骨架业务网络。
自述文件
使用Markdown标记语言的业务网络用途描述。
Package.json
业务网络定义具有名称(限于基本ASCII字母数字字符和-
),易于理解的描述和版本号。网络的版本号的格式应为Major.Minor.Micro和 Semantic Versioning原则,以增加版本号。
网络的标识符由其名称,-
字符及其版本号组成。因此,有效标识符(和示例)是mybusinessnetwork-1.0.3
。
从读取业务网络定义的元数据package.json
,这意味着业务网络定义也可能是有效的npm
程序包。
楷模
业务网络定义的域模型集定义了与外部系统(例如,将事务提交到网络的系统)集成时在网络内部和网络外部有效的类型。
域模型可以打包在业务网络定义中(通常存储在models
目录下),也可以声明package.json
为外部依赖项。如果要跨业务网络定义共享模型,则可以通过npm依赖项引用模型。
剧本
商业网络定义的脚本通常存储在lib
目录下,并打包在商业网络定义内。脚本使用ES 5 JavaScript编写,并且引用在业务网络的域模型中定义的类型。
Permissions.acl
表示的业务网络的权限以可选permissions.acl
文件表示。
克隆示例业务网络定义
示例业务网络定义存储在GitHub上的https://github.com/hyperledger/composer-sample-networks
。您可以使用git clone
此存储库下拉所有示例网络。每个样本网络都存储在该packages
目录下。
生成业务网络定义
代
yo hyperledger-composer
? Please select the type of project: (Use arrow keys)
❯ Angular
Business Network
Model
然后选择 Business Netork
- 回答所有问题
Welcome to the Hyperledger Composer project generator
? Please select the type of project: Business Network
You can run this generator using: 'yo hyperledger-composer:businessnetwork'
Welcome to the business network generator
? Business network name: mynetwork
? Description: This is my test network
? Author name: Mr Conga
? Author email: conga@congazone.org
? License: Apache-2
? Namespace: org.conga
create package.json
create permissions.acl
create README.md
create models/org.conga.cto
create .eslintrc.yml
create features/sample.feature
create features/support/index.js
create test/logic.js
create lib/logic.js
这将生成一个具有asset
,participant
和transaction
定义以及mocha
单元测试的基本业务网络。
还包括一个“最佳实践” eslint配置文件,该文件定义了JS代码的样本掉毛规则。
参考文献
部署业务网络
在可以部署业务网络定义之前,必须将其打包到业务网络存档(.bna)文件中。该composer archive create
命令用于从磁盘上的业务网络定义文件夹创建业务网络存档文件。
一旦创建了业务网络存档文件,就可以使用composer network install
命令和命令将其部署到Hyperledger Fabric中composer network start
。
例如:
composer network install --archiveFile tutorial-network@1.0.0.bna --card PeerAdmin@fabric-network
composer network start --networkName tutorial-network --networkVersion 1.0.0 --card PeerAdmin@fabric-network --networkAdmin admin --networkAdminEnrollSecret adminpw
要升级已经部署的业务网络的业务网络定义,请使用composer network upgrade
CLI命令。
将业务网络部署到Hyperledger Fabric v1.2
在Hyperledger Fabric v1.2中,对等方强制执行管理员和成员的概念。管理员有权将新业务网络的Hyperledger Fabric链码安装到对等方。成员没有安装链码的权限。为了将业务网络部署到一组对等方,必须提供对所有这些对等方都具有管理权限的标识。
要使该身份及其证书可用,您必须使用与对等管理员身份相关联的证书和私钥来创建对等管理名片。Hyperledger Composer提供了示例Hyperledger Fabric v1.2网络。该网络的对等管理员称为PeerAdmin
,当您使用示例脚本启动网络时,将自动为您导入身份。请注意,对等管理员可能会为其他Hyperledger Fabric网络使用不同的名称。
重要说明:将业务网络部署到Hyperledger Fabric v1.2时,在Hyperledger Fabric证书颁发机构(CA)配置中定义了一个引导注册器。Hyperledger Composer开发环境包含Hyperledger Fabric的预配置实例,具有引导程序注册商的特定注册ID和注册机密。
企业网络管理员
部署业务网络时,将根据业务网络定义中指定的访问控制规则强制执行访问控制。每个业务网络必须至少有一个参与者,并且该参与者必须具有用于访问业务网络的有效身份。否则,客户端应用程序将无法与业务网络进行交互。
业务网络管理员是负责在部署业务网络之后为其组织配置业务网络的参与者,并负责从其组织中加入其他参与者。由于业务网络包括多个组织,因此对于任何给定的业务网络,应该有多个业务网络管理员。
org.hyperledger.composer.system.NetworkAdmin
Hyperledger Composer提供了代表业务网络管理员的内置参与者类型。该内置参与者类型没有任何特殊权限;它们仍然受制于业务网络定义中指定的访问控制规则。因此,建议您从以下示例访问控制规则开始,这些规则将授予业务网络管理员对业务网络的完全访问权限:
rule NetworkAdminUser {
description: "Grant business network administrators full access to user resources"
participant: "org.hyperledger.composer.system.NetworkAdmin"
operation: ALL
resource: "**"
action: ALLOW
}
rule NetworkAdminSystem {
description: "Grant business network administrators full access to system resources"
participant: "org.hyperledger.composer.system.NetworkAdmin"
operation: ALL
resource: "org.hyperledger.composer.system.**"
action: ALLOW
}
默认情况下,Hyperledger Composer将在部署期间自动创建一个业务网络管理员参与者。用于部署业务网络的身份也将绑定到该业务网络管理员参与者,以便在部署后可以使用该身份与业务网络进行交互。
Hyperledger Fabric对等管理员可能没有使用Hyperledger Fabric证书颁发机构(CA)颁发新身份的权限。这可能会限制业务网络管理员从其组织中招募其他参与者的能力。因此,最好创建一个具有使用Hyperledger Fabric证书颁发机构(CA)颁发新身份的权限的业务网络管理员。
您可以对composer network start
命令使用其他选项,以指定在业务网络部署期间应创建的业务网络管理员。
如果企业网络管理员具有注册ID和注册机密,则可以使用-A
(企业网络管理员)和-S
((企业网络管理员使用注册机密))标志。例如,以下命令将为现有admin
注册ID 创建业务网络管理员:
composer network start --networkName tutorial-network --networkVersion 1.0.0 --c PeerAdmin@fabric-network -A admin -S adminpw
在本地使用Playground部署业务网络
请注意:使用本地Playground实例将业务网络部署到Hyperledger Fabric v1.2时,作为部署过程的一部分,您必须选择如何为初始业务网络参与者提供凭据。最初的参与者将是NetworkAdmin。
使用游乐场部署业务网络时,系统将提示您输入初始参与者的凭据。凭证既可以作为证书提供,也可以作为预定义的注册ID和注册机密提供。如果您使用在Hyperledger Composer开发环境中设置的Hyperledger Fabric实例,则引导注册商的注册ID为admin
,引导注册商的注册密钥为adminpw
。最初的参与者使用Hyperledger Fabric证书颁发机构(CA)中为引导注册器设置的凭据,并且将是NetworkAdmin。
在本地使用Playground部署业务网络时,必须至少具有一个PeerAdmin
角色的业务网卡和至少一个具有ChannelAdmin
角色的业务网卡。这些名片中的每一个都必须包含正确的管理员证书。
参考文献
发射事件
事件可由Hyperledger Composer发出,并由外部应用程序订阅。事件在业务网络定义的模型文件中定义,并由事务处理程序功能文件中的事务JavaScript发出。请注意,尽管发出事件的代码在事务处理器函数内部,但是在运行此代码时不会立即发出事件。相反,一旦提交了事务,便执行事件排放。
在你开始之前
在将事件添加到业务网络之前,您应该对业务网络的建模语言以及组成完整业务网络定义的内容有很好的了解。
程序
-
事件在
.cto
业务网络定义的模型文件()中定义,其方式与资产和参与者相同。事件使用以下格式:event BasicEvent { }
-
为了发布事件,创建事件的事务必须调用三个函数,第一个是
getFactory
函数。该getFactory
允许事件被作为交易的一部分而创建的。接下来,必须使用创建事件factory.newEvent('org.namespace', 'BasicEvent')
。这BasicEvent
将在指定的名称空间中创建一个定义。然后,必须设置事件的必需属性。最后,必须使用发出事件emit(BasicEvent)
。调用此事件的简单事务如下所示:/** * @param {org.namespace.BasicEventTransaction} basicEventTransaction * @transaction */ async function basicEventTransaction(basicEventTransaction) { let factory = getFactory(); let basicEvent = factory.newEvent('org.namespace', 'BasicEvent'); emit(basicEvent); }
该事务创建并发出一个BasicEvent
业务网络的模型文件中定义的事件类型。有关getFactory函数的更多信息,请参见Composer API文档。
测试业务网络
Hyperledger Composer支持三种测试类型:交互式测试,自动单元测试和自动系统测试。这三种服务的目的各不相同,对于确保区块链项目的成功至关重要。
部署业务网络定义之后,运行交互式“烟雾测试”以确保部署成功通常会很有用。该composer
CLI公开运行这样冒烟测试的命令。
在另一方面,您可以使用Docker Compose和Mocha / Chai编写全面的系统测试,这些测试可以启动运行时,部署业务网络定义,然后以编程方式创建资产,提交事务并检查资产注册表的状态。
单元测试的重点是确保在处理交易时对世界状态进行正确的更改。
可以使用CI / CD构建管道(例如Jenkins,Travis CI或Circle CI或替代方案)自动执行单元测试和系统测试。
互动测试
您可以使用Playground交互式测试创建参与者,资产和提交交易。
从命令行进行测试
命令行可用于检查运行时的状态并提交事务。使用composer network list
命令查看资产和参与者注册表的状态。使用composer transaction submit
命令提交事务。
创建单元测试
事务处理器功能中的业务逻辑应具有单元测试,理想情况下应具有100%的代码覆盖率。这将确保您在业务逻辑中没有错别字或逻辑错误。
您可以使用标准的JavaScript测试库(例如Mocha,Chai,Sinn和Istanbul)对事务处理器功能中的逻辑进行单元测试。
在embedded
运行时进行单元测试非常有用,因为它可以让你快速测试业务逻辑在一个模拟的Node.js blockchain环境,而不必站立一个Hyperledger面料。
请参考示例网络以获取单元测试的示例。例如:https : //github.com/hyperledger/composer-sample-networks/blob/master/packages/bond-network/test/Bond.js
参考文献
发布模型或业务网络定义以供应用程序使用
Hyperledger Composer可以选择使用npm
程序包管理器来发布业务网络和模型。通过将业务网络发布到npm
需要引用业务网络的应用程序(例如,对它们进行自省或部署),可以声明对已发布npm
程序包的二进制程序包依赖性。对业务网络使用npm包的语义版本控制还可以使应用程序指定其容忍度,以接受对业务网络的不兼容更改。
该npm
软件包管理器是一个功能强大的(互联网规模)机制来分发任何二进制文件,并在一个表达元数据package.json
文件。
类似地,可以将一组Composer域模型(CTO文件)打包到一个npm
包中以进行发布。发布模型的能力允许模型在多个业务网络中重用(通过声明package.json
依赖性),并确保语义版本控制可用于控制模型本身的演变。
但是,npm
使用Composer不需要发布到。您可以在应用程序内部捆绑业务网络,并使用git等版本控制软件简单地管理其源文件。
发布模型或业务网络定义以供应用程序使用的最简单方法,它是npm
使用npm publish
命令将业务网络定义推送到程序包管理器的。这将允许希望使用业务网络定义(例如,通过API进行部署)的应用程序将业务网络定义作为其package.json
文件中的依赖项进行引用。
参考文献
升级已部署的业务网络
将业务网络成功部署到区块链后,可能需要升级业务网络定义。要升级业务网络定义,请首先将要部署的更新部署到业务网络组件文件的本地副本(模型,脚本,查询,访问控制和事务处理器文件),然后更新本地业务网络的版本文件。更新版本后,将的新版本安装.bna
到您的区块链,然后使用composer network upgrade
命令切换为使用新版本。
在你开始之前
在升级已部署的业务网络定义之前:
- 确保您的业务网络已成功部署。
- 对要部署的业务网络进行所有必需的更新。
第一步:更新企业网络版本
重要的是,该package.json
文件是安装你的企业网络的新版本,以您的blockchain之前更新。
-
package.json
在您的业务网络目录中打开文件。 -
更新版本属性。版本属性必须是一个
.
单独的数字,例如0.0.2
或1.16.4
。确保记下您正在设置的版本号,因为它是以下步骤所必需的。
第二步:打包您的业务网络
更新版本号后,必须将业务网络打包到业务网络归档文件(.bna
)中。然后.bna
可以将其安装在区块链上并启动。该composer archive create
命令可以打包目录或npm模块,在本示例中,我们将使用directory命令。
-
在您的企业网络目录中运行以下
composer archive create
命令:composer archive create -t dir -n .
第三步:安装新的业务网络
打包业务网络后,必须将其安装到区块链中。它的安装过程与原始业务网络的安装过程相同。
-
使用以下命令将业务网络安装到您的区块链:
composer network install -a NETWORK-FILENAME.bna -c peeradmin@hlfv1
命令中使用的商业网卡必须是对等管理卡,才能将商业网络安装到区块链对等体。
第四步:升级到新的业务网络
既然已经将业务网络安装到对等方,则必须启动它。该composer network upgrade
命令将指示对等方停止使用较旧版本的业务网络,并开始使用命令中指定的版本。
-
升级到使用以下命令安装的业务网络:
composer network upgrade -c peeradmin@hlfv1 -n NETWORK-NAME -V NETWORK-VERSION
网络名称和网络版本必须与
package.json
已安装的业务网络中的内容匹配。
您的业务网络现在应该已成功升级。
查询和过滤业务网络数据
查询用于返回有关区块链世界状态的数据;例如,您可以编写查询以返回指定期限内的所有驱动程序,或者返回具有特定名称的所有驱动程序。该composer-rest-server
组件通过生成的REST API公开命名查询。
查询是业务网络定义的可选组件,写在单个查询文件(queries.qry
)中。
注意:使用Hyperledger Fabric v1.2运行时时,必须将Hyperledger Fabric配置为使用CouchDB持久性。
筛选器与查询类似,但是使用LoopBack筛选器语法,并且只能使用Hyperledger Composer REST API发送。当前,仅WHERE
支持LoopBack过滤器。内的支持的运算符WHERE
是:=,和,或,GT,GTE,LT,LTE,NEQ。使用GET
针对资产类型,参与者类型或交易类型的调用来提交过滤器;然后将过滤器作为参数提供。过滤器返回指定类的结果,而不返回扩展指定类的类的结果。
查询类型
Hyperledger Composer支持两种查询类型:命名查询和动态查询。命名查询在业务网络定义中指定,并且由composer-rest-server组件作为GET方法公开。动态查询可以在运行时在事务处理器功能内或从客户端代码动态构建。
编写命名查询
查询必须包含描述和声明。查询描述是描述查询功能的字符串。查询语句包含控制查询行为的运算符和函数。
查询描述可以是任何描述性字符串。查询语句必须包括SELECT
运营商,可以选择包括FROM
,WHERE
,AND
,ORDER BY
,和OR
。
查询应采用以下格式:
query Q1{
description: "Select all drivers older than 65."
statement:
SELECT org.example.Driver
WHERE (age>65)
}
查询参数
查询可以使用_$
语法嵌入参数。请注意,查询参数必须是基本类型(字符串,整数,双精度型,长整型,布尔型,日期时间),关系或枚举。
以下命名查询是根据1个参数定义的:
query Q18 {
description: "Select all drivers aged older than PARAM"
statement:
SELECT org.example.Driver
WHERE (_$ageParam < age)
ORDER BY [lastName DESC, firstName DESC]
}
查询参数通过composer-rest-server通过为命名查询创建的GET方法自动公开。
有关Hyperledger Composer查询语言的详细信息,请参阅查询语言参考文档。
使用API的查询
可以通过调用buildQuery或查询 API 来调用查询。所述BuildQuery对于 API需要指定作为API输入的一部分的整个查询字符串。该查询 API需要你指定要运行查询的名称。
有关查询API的更多信息,请参阅API文档。
查询访问控制
返回查询结果时,您的访问控制规则将应用于结果。当前用户无权查看的任何内容都将从结果中删除。
例如,如果当前用户发送的查询将返回所有资产,如果他们仅有权查看有限的资产选择,则查询将仅返回该有限的资产集。
使用过滤器
只能使用Hyperledger Composer REST API提交过滤器,并且必须使用LoopBack语法。要提交查询,必须针对提供的过滤器作为参数的资产类型,参与者类型或事务类型提交GET REST调用。要过滤的参数支持的数据类型是数字,布尔值,日期时间和字符串。基本过滤器采用以下格式,其中op
表示运算符:
{"where": {"field1": {"op":"value1"}}}
请注意:只有顶级WHERE
运算符可以有两个以上的操作数。
当前,仅WHERE
支持LoopBack过滤器。内的支持的运算符WHERE
是:=,和,或,GT,GTE,LT,LTE,NEQ。过滤器可以组合多个运算符,在以下示例中,and运算符嵌套在or运算符内。
{"where":{"or":[{"and":[{"field1":"foo"},{"field2":"bar"}]},{"field3":"foobar"}]}}
的之间操作者返回给定的范围之间的值。它接受数字,日期时间值和字符串。如果提供了字符串,则between操作符将按字母顺序返回提供的字符串之间的结果。在下面的示例中,过滤器将返回驱动程序属性按字母顺序在a和c之间(包括a和c)的所有资源。
{"where":{"driver":{"between": ["a","c"]}}}
程序访问控制
建议您使用声明性访问控制在业务网络定义中实施访问控制规则。但是,您可以通过检索和测试当前参与者或当前身份来在事务处理器中实现编程访问控制。您可以针对当前参与者的属性或当前身份运行测试,以允许或拒绝执行事务处理器功能。
事务处理器函数可以调用该getCurrentParticipant
函数以获取当前参与者:
let currentParticipant = getCurrentParticipant();
当前参与者是来自业务网络定义的建模参与者的实例,或者是系统类型的实例org.hyperledger.composer.system.NetworkAdmin
。
事务处理器函数可以调用该getCurrentIdentity
函数以获取当前身份:
let currentIdentity = getCurrentIdentity();
当前身份是系统类型的实例org.hyperledger.composer.system.Identity
,它表示已部署的业务网络中的身份。
在你开始之前
在执行这些步骤之前,您必须已经对业务网络定义中的参与者进行了建模并将其部署为业务网络。您必须已经创建了这些参与者的一些实例,并为这些参与者颁发了身份。
以下过程显示了使用以下参与者模型的示例:
namespace net.biz.digitalPropertyNetwork
participant Person identified by personId {
o String personId
o String firstName
o String lastName
}
participant PrivilegedPerson extends Person {
}
程序
- 在事务处理程序功能中,使用以下
getCurrentParticipant
功能验证当前参与者的类型符合要求:
async function onPrivilegedTransaction(privilegedTransaction) {
let currentParticipant = getCurrentParticipant();
if (currentParticipant.getFullyQualifiedType() !== 'net.biz.digitalPropertyNetwork.PrivilegedPerson') {
throw new Error('Transaction can only be submitted by a privileged person');
}
// Current participant must be a privileged person to get here.
}
- 在事务处理程序功能中,使用以下
getCurrentParticipant
功能验证当前参与者的参与者ID :
async function onPrivilegedTransaction(privilegedTransaction) {
let currentParticipant = getCurrentParticipant();
if (currentParticipant.getFullyQualifiedIdentifier() !== 'net.biz.digitalPropertyNetwork.Person#PERSON_1') {
throw new Error('Transaction can only be submitted by person 1');
}
// Current participant must be person 1 to get here.
}
可以将当前参与者的参与者ID与(通过关系)链接到资产的参与者进行比较,以验证当前参与者是否有权访问或修改资产:
async function onPrivilegedTransaction(privilegedTransaction) {
// Get the owner of the asset in the transaction.
let assetOwner = privilegedTransaction.asset.owner;
let currentParticipant = getCurrentParticipant();
if (currentParticipant.getFullyQualifiedIdentifier() !== asset.owner.getFullyQualifiedIdentifier()) {
throw new Error('Transaction can only be submitted by the owner of the asset');
}
// Current participant must be the owner of the asset to get here.
}
- 在事务处理程序功能中,使用以下
getCurrentIdentity
功能验证当前身份的证书是否符合要求:
async function onPrivilegedTransaction(privilegedTransaction) {
let currentIdentity = getCurrentIdentity();
// Get the PEM encoded certificate from the current identity.
let certificate = currentIdentity.certificate;
// Perform testing on the PEM encoded certificate.
if (!certificate.match(/^----BEGIN CERTIFICATE----/)) {
throw new Error('Transaction can only be submitted by a person with a valid certificate');
}
// Current identity must have a valid certificate to get here.
}
Hyperledger作曲家历史学家
Hyperledger Composer Historian是一个专门的注册表,用于记录成功的交易,包括参与者和提交交易的身份。历史学家将事务存储为HistorianRecord
资产,这些资产在Hyperledger Composer系统名称空间中定义。
历史记录器注册表是Hyperledger Composer系统级实体。要将历史学家注册表作为访问控制资源,必须将历史学家引用为:org.hyperledger.composer.system.HistorianRecord
。
请注意:所有参与者都必须具有创建HistorianRecord
资产的权限。如果交易是由没有创建HistorianRecord
资产许可的参与者提交的,则该交易将失败。
历史记录资产
历史记录器注册表将成功的交易存储为HistorianRecord
资产。每当交易成功完成时,HistorianRecord
就会创建资产并将其添加到历史记录注册表中。记录资产在系统名称空间中定义,并具有以下定义:
asset HistorianRecord identified by transactionId {
o String transactionId
o String transactionType
--> Transaction transactionInvoked
--> Participant participantInvoking optional
--> Identity identityUsed optional
o Event[] eventsEmitted optional
o DateTime transactionTimestamp
}
String transactionId
导致HistorianRecord
资产创建的交易的transactionId 。String transactionType
导致HistorianRecord
资产创建的交易类别。Transaction transactionInvoked
与导致HistorianRecord
资产创建的交易的关系。Participant participantInvoking
与提交交易的参与者的关系。Identity identityUsed
与用于提交交易的身份的关系。Event[] eventsEmitted
可选属性,包含事务发出的任何事件。DateTime transactionTimestamp
导致HistorianRecord
创建资产的事务的时间戳。
所有HistorianRecord
资产与创建资产的交易,交易的调用参与者以及提交交易时使用的身份都有关系。希望获得这些属性的应用程序必须解决此关系。
系统交易
Hyperledger Composer运行时进行的若干操作被归类为事务。这些“系统事务”在Hyperledger Composer系统模型中定义。以下内容将添加HistorianRecord
资产:
- 添加,删除和更新资产
- 添加,删除和更新参与者
- 颁发,绑定,激活和撤销身份
- 更新业务网络定义
保护历史数据
作为注册表,可以使用访问控制规则来控制对历史数据的访问。但是,作为系统级实体,historian注册表的资源名称始终为org.hyperledger.composer.system.HistorianRecord
。
以下访问控制规则允许成员仅在参考他们提交的交易时查看历史数据。
rule historianAccess{
description: "Only allow members to read historian records referencing transactions they submitted."
participant(p): "org.example.member"
operation: READ
resource(r): "org.hyperledger.composer.system.HistorianRecord"
condition: (r.participantInvoking.getIdentifier() == p.getIdentifier())
action: ALLOW
}
检索历史数据
可以使用API调用或查询来检索历史注册表中的数据。后面的所有示例都使用async / await功能,并假定代码被封装在具有async
属性的函数中。
将客户端和REST API与Historian一起使用
HistorianRecord
资产可以使用REST API system/historian
和来返回system/historian/{id}
。
使用REST API时,的GET调用system/historian
将返回所有历史数据。该调用应谨慎使用,返回不受限制,并可能导致返回大量数据。
system/historian/{id}
使用REST API的GET调用将返回HistorianRecord
指定的资产。
查询历史学家
可以以与其他注册表相同的方式查询历史学家。例如,返回所有HistorianRecord
资产的典型查询如下:
let historian = await businessNetworkConnection.getHistorian();
let historianRecords = await historian.getAll();
console.log(prettyoutput(historianRecords));
由于这是一个“ getAll”调用,因此可能会返回大量数据。因此,查询功能对于能够选择记录的子集至关重要。一个典型的例子是根据时间选择记录。这使用查询功能来选择事务时间戳超过特定点的记录。返回的记录可以用相同的方式处理。
let now = new Date();
now.setMinutes(10); // set the date to be time you want to query from
let q1 = businessNetworkConnection.buildQuery('SELECT org.hyperledger.composer.system.HistorianRecord ' +
'WHERE (transactionTimestamp > _$justnow)');
await businessNetworkConnection.query(q1,{justnow:now});
可以使用更高级的查询;例如,以下查询选择并返回添加,更新和删除资产系统事务。
// build the special query for historian records
let q1 = businessNetworkConnection.buildQuery(
`SELECT org.hyperledger.composer.system.HistorianRecord
WHERE (transactionType == 'AddAsset' OR transactionType == 'UpdateAsset' OR transactionType == 'RemoveAsset')`
);
await businessNetworkConnection.query(q1);
定制卡存储
默认卡存储是/home/username/.composer
主机上的目录。对于在云环境中运行的应用程序而言,本地钱包可能会出现问题,并且可能需要将卡存储在不同的目录位置。通过使用自定义钱包,用户可以控制存储商务网卡以及用于Hyperledger Fabric身份验证的证书和私钥的位置。
建筑
无论何时制作BusinessNetworkConnection
或AdminConnection
,它都有一个关联CardStore
。可以将每个连接配置为使用特定的CardStore
。在Hyperledger Composer存储库中,有两个针对商店的预配置选项:
composer-wallet-filesystem
composer-wallet-inmemory
可以为任何给定的后端数据库或对象存储编写自定义实现,从而支持CardStore
在非默认文件位置,单独的Docker容器中或托管在基于云的数据存储中的规范。可以使用配置文件或环境变量来完成存储区配置。
可以使用全局npm安装来安装多个云钱包实现。
配置自定义钱包
有两种定义自定义钱包的配置的方法:使用.json
配置文件或定义环境变量。
请注意:任何自定义钱包实现必须composer-wallet
在模块名称中包含前缀。
使用配置文件
对于生产部署,能够在应用程序外部配置卡存储更为有用,Hyperledger Composer使用标准配置模块config
。配置文件是从当前工作目录的子目录中加载的config
。默认配置文件称为default.json
,可以使用NODE_ENV
环境变量更改配置文件名。
例如,这是一个名为“云钱包”的实施配置 composer-wallet-redis
{
"composer": {
"wallet": {
"type": "composer-wallet-redis",
"desc": "Uses a local redis instance,
"options": {
}
}
}
}
type
是此模块的名称desc
是人类的一些文字
请注意:每个连接将具有指定的卡存储的新实例。如果这些解析到同一个后端存储,则可以共享卡。
使用环境变量
通过环境变量在命令行上指定自定义钱包的详细信息,可以通过设置包含与配置文件相同信息的环境变量来实现。
以下环境变量示例使用与前面的配置文件相同的格式和数据。
export NODE_CONFIG={"composer":{"wallet":{"type":"composer-wallet-redis","desc":"Uses a local redis instance,"options":{}}}}
此外壳中的任何应用程序都将使用云钱包。
配置文件系统定制卡存储
通过将a storePath
作为钱包选项之一进行指定,可以使用配置文件来更改文件系统卡存储的位置。
{
"composer": {
"wallet" : {
"type": "composer-wallet-filesystem",
"options" : {
"storePath" : "/my/network/location"
}
}
}
相同的.json
代码段可以作为环境变量导出。
配置基于云的自定义卡存储
以下GitHub存储库分别包含使用Redis和IBM Cloud Object Store的云定制钱包的实现。
- composer-tools / composer-wallet-redis- 使用Redis服务器提供后备存储
- composer-tools / composer-wallet-ibmcos- 使用IBM Cloud Object Store提供后备存储。它具有与S3兼容的API
- composer-tools / composer-wallet-cloudant- 使用IBM Cloudant提供后备存储
可以使用全局npm安装来安装多个云自定义钱包实现。
要迁移到这些自定义钱包解决方案,请参阅相关GitHub存储库的README文件。
一般而言,迁移到云钱包实施需要三个步骤。
- 导出要在云定制钱包中使用的商务网卡。
- 更改配置以指定云定制钱包。
- 将名片导入云定制钱包。
这composer-wallet-filesystem
是默认的卡存储区,并且在磁盘上采用相同的布局,并且默认情况下位于相同的位置。
一些样本和测试用例显示了通过编程方式创建的卡存储。这仍然是可能的,但是在初始创建卡存储方面略有不同。
通过API使用自定义钱包
API CardStore配置
使用默认位置文件系统卡存储仍然是API调用中的默认选项。例如:
adminConnection = new AdminConnection();
clientConnection = new BusinessNetworkConnection();
仅当在同一shell实例中执行时,才会在位置使用文件系统卡存储/home/username/.composer
,或者在指定的导出自定义钱包中使用NODE_CONFIG
。
要在API中指定自定义钱包而不使用全局导出的值,必须将其作为传递给连接的选项包括在内:
const connectionOptions = {
wallet : {
type: 'composer-wallet-filesystem',
options : {
storePath :'/my/network/location'
}
}
};
adminConnection = new AdminConnection(connectionOptions);
clientConnection = new BusinessNetworkConnection(connectionOptions);
在上文中,钱包类型可以是新文件位置或基于云的位置的钱包类型。
API MemoryCardStore配置
以前要在MemoryCardStore中使用,代码应该已经编写
cardStore = new MemoryCardStore();
const adminConnectionOptions = {
cardStore : cardStore
};
adminConnection = new AdminConnection(adminConnectionOptions);
// or more concisely
clientConnection = new BusinessNetworkConnection({cardStore});
现在这已更改,并且必须以其他方式指定卡存储:
const connectionOptions = {
wallet : {
type: 'composer-wallet-inmemory'
}
};
adminConnection = new AdminConnection(connectionOptions);
clientConnection = new BusinessNetworkConnection(connectionOptions);
云钱包和Hyperledger Composer Rest服务器
为了方便起见,最新的Hyperledger Composer Rest Server docker映像将在github存储库上提供所有云钱包,用于将composer-tools预加载到映像中。
开发应用
Hyperledger Composer支持创建Web,移动或本机Node.js应用程序。它包括composer-rest-server
(自动基于LoopBack技术)(用于自动生成用于业务网络的REST API),以及hyperledger-composer
用于Yeoman框架(用于生成框架Angular应用程序)的代码生成插件。
此外,它包括一组丰富的JavaScript API,用于构建本机Node.js应用程序。
编写一个Node.js应用程序
通过开发与Hyperledger Composer配合使用的Node.js应用程序,您可以以编程方式连接到已部署的业务网络,创建,读取,更新和删除资产和参与者,以及提交事务。
编写Web应用程序
需要与已部署的业务网络交互的Web应用程序应调用REST API。创建REST API的最简单方法是使用composer-rest-server
以动态生成从部署的业务网络中的REST API。
订阅事件
Node.js应用程序可以使用API调用从业务网络订阅事件composer-client.BusinessNetworkConnection.on
。事件在业务网络模型文件中定义,并由事务处理器功能文件中的指定事务发出。
参考文献
编写Node.js应用程序
应用程序开发人员使用composer-client
npm模块以编程方式连接到已部署的业务网络,创建,读取,更新和删除资产和参与者,并提交交易。如果应用程序需要能够部署或管理业务网络,则composer-admin
可以使用npm模块。
该示例landregistry.js
文件包含一个表示土地注册处的类,并包含列出土地所有权,添加默认所有权和提交交易的方法。这是使用JavaScript类实现的;但是,您可以随意构建代码。
值得强调的是,API的风格是使用诺言。通常,Hyperledger Composer API将返回一个承诺,该承诺在成功完成操作时或操作的结果(如果适用)时将被解决。
如果您不熟悉基于Promise的开发,那么值得在线阅读一些教程以了解一个想法。除此之外,在节点8中,现在支持异步/等待,这使得开发异步应用程序变得更加容易。此处显示的示例利用await并假定代码包含在具有async
属性的函数中
所需模块
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
对于Hyperledger Composer客户端应用程序,这是唯一需要的npm模块。
连接到Hyperledger Composer运行时
创建一个BusinessNetworkConnection实例,然后将其用于连接到运行时:
this.bizNetworkConnection = new BusinessNetworkConnection();
我们将在此处进行的第一个Hyperledger Composer API调用是connect()API,用于在Hyperledger Fabric上建立与Hyperledger Composer运行时的连接。需要提供适当的cardName进行连接,例如,admin@digitalproperty-network
取决于数字属性网络的部署方式,它可以是有效的卡名。如果成功,此API会将一个Promise返回给businessNetworkDefinition:
let this.businessNetworkDefinition = await this.bizNetworkConnection.connect(cardName);
对于客户端应用程序,这是必需的所有必要设置,从这时起,取决于应用程序要对调用的API进行何种操作。
将资产添加到注册表
Hyperledger Composer运行时将为每种类型的建模资产创建一个默认注册表。因此,在此示例中,将创建一个LandTitle注册表。我们在这里要做的是访问该注册表,然后添加一些资产。该getAssetRegistry()
方法采用CTO模型文件中定义的标准资产名称(即名称空间加上资产类型的名称)。它返回由资产注册表解决的承诺:
this.titlesRegistry = await this.bizNetworkConnection.getAssetRegistry('net.biz.digitalPropertyNetwork.LandTitle');
下一步是创建一些资产(_bootstrapTitles
在代码中查找方法)
工厂样式模式用于创建资产。工厂是从businessNetworkDefinition获得的,用于创建业务网络中定义的所有类型的实例。注意名称空间和资产名称的使用。然后,我们可以设置此资产的属性。此处的标识符(firstName lastName)与模型中定义的属性匹配。
let factory = this.businessNetworkDefinition.getFactory();
owner = factory.newResource('net.biz.digitalPropertyNetwork', 'Person', 'PID:1234567890');
owner.firstName = 'Fred';
owner.lastName = 'Bloggs';
我们现在有一个人!现在我们需要一个地契。注意如何将所有者指定为我们刚刚创建的人。(在实际的示例代码中,我们两次执行此代码以创建landTitle1和landTitle2)。
let landTitle2 = factory.newResource('net.biz.digitalPropertyNetwork', 'LandTitle', 'LID:6789');
landTitle2.owner = owner;
landTitle2.information = 'A small flat in the city';
现在,我们创建了一个地名,该地名需要存储在注册表中。
await this.titlesRegistry.addAll([landTitle1, landTitle2]);
这是使用API来添加多个标题,该标题返回一个承诺,该承诺在添加资产时得到解决。我们需要做的最后一件事是添加Person,Fred Bloggs。由于这是一个“参与者”,因此使用了getParticipantRegistry API。
let personRegistry = await this.bizNetworkConnection.getParticipantRegistry('net.biz.digitalPropertyNetwork.Person');
await personRegistry.add(owner);
列出注册表中的资产
在示例应用程序中,这是以另一种方法处理的list()
。需要与放置资产相同的设置,因此与之前需要获取资产注册表一样,但是此图块我们称为getAll()API。这将返回一个对象数组。
let registry = await this.bizNetworkConnection.getAssetRegistry('net.biz.digitalPropertyNetwork.LandTitle');
let aResources = await registry.getAll();
let table = new Table({
head: ['TitleID', 'OwnerID', 'First Name', 'Surname', 'Description', 'ForSale']
});
let arrayLength = aResources.length;
for (let i = 0; i < arrayLength; i++) {
let tableLine = [];
tableLine.push(aResources[i].titleId);
tableLine.push(aResources[i].owner.personId);
tableLine.push(aResources[i].owner.firstName);
tableLine.push(aResources[i].owner.lastName);
tableLine.push(aResources[i].information);
tableLine.push(aResources[i].forSale ? 'Yes' : 'No');
table.push(tableLine);
}
// Put to stdout - as this is really a command line app
return table;
其中大多数不是Hyperledger Composer API代码-但它显示了如何访问已返回对象的详细信息。在这一点上,值得再次看一下模型。
asset LandTitle identified by titleId {
o String titleId
o Person owner
o String information
o Boolean forSale optional
}
participant Person identified by personId {
o String personId
o String firstName
o String lastName
}
您可以看到如何以非常简单的方式访问所有者和标题信息。
提交交易
我们需要做的最后一件事是提交交易。这是模型文件中事务的定义:
transaction RegisterPropertyForSale identified by transactionId{
o String transactionId
--> LandTitle title
}
交易在此处有两个字段,即trandsactionId和对应提交出售的土地所有权的引用。第一步是访问该地名的注册表,并获取我们要提交出售的特定地名。
let registry = await this.bizNetworkConnection.getAssetRegistry('net.biz.digitalPropertyNetwork.LandTitle');
await registry.get('LID:1148');
现在,getAssetRegistry调用应该看起来有点熟悉,使用get API来获取特定的地名。下一步是创建我们要提交的交易。
let serializer = this.businessNetworkDefinition.getSerializer();
let resource = serializer.fromJSON({
'$class': 'net.biz.digitalPropertyNetwork.RegisterPropertyForSale',
'title': 'LID:1148'
});
await this.bizNetworkConnection.submitTransaction(resource);
我们需要在这里创建一个“序列化器”。这样就可以创建资源-然后将该资源传递给SubmitTransaction API。请注意,事务JSON与模型文件中指定的结构匹配。
参考文献
编写Web应用程序
要与已部署的业务网络交互,Web应用程序应进行REST API调用。要为业务网络创建自定义REST API,请使用composer-rest-server
命令。
要创建可以与REST API交互的框架Angular应用程序,请使用yo hyperledger-composer
命令。
请按照“ 开发者指南”获取有关如何使用composer-rest-server
和Angular生成器的示例。
从业务网络存档(.BNA)生成Angular应用程序
构建Angular应用程序的流程如下:
如果您已经有一个Business Network Archive,并且想要构建一个框架式Angular应用程序(请参阅下面的注释),请使用以下参考说明,如果您想完全理解如何从头开始开发BNA并从那里构建一个应用程序,请请参阅开发人员教程。
注意:
Yo Angular应用程序生成器仅支持简单的基本业务网络模型定义-它是一个简单的应用程序生成器。生成的应用程序(包括它生成的Web表单)将不支持更复杂的类型或字段表达式-例如。概念不起作用,其他更复杂的建模类型或表达式也不起作用-您应在生成时或使用骨架应用程序时检查错误(例如,在Angular应用程序中发布的内部错误),并检查REST中的异常/验证错误启动REST服务器的服务器日志记录。请注意,如果定义了概念(建模语言中的抽象类),则将其忽略(如果存在于模型文件中),以完成骨架应用程序的生成。无论您连接到现有的业务网络,它都适用,或从业务网络档案(BNA)文件生成Angular骨架。复杂的字段定义(以示例为例)或表达式将不会出现在生成的HTML表单中,并且不会出现,除非您选择继续自行定制框架Web应用程序。
先决条件
- 您将需要Hyperledger Composer 开发工具才能运行Angular生成器。
- 您要部署的业务网络存档(.BNA)。
1.启动在本地计算机上运行的Hyperledger Fabric
如果您已经安装了开发工具,则已经安装了Hyperledger Fabric。
转到fabric-dev-servers
目录并启动Hyperledger Fabric。如果您使用了我们的开发工具安装指南,则以下代码为示例:
cd ~/fabric-dev-servers
export FABRIC_VERSION=hlfv12
./startFabric.sh
./createPeerAdminCard.sh
这还将创建一个PeerAdmin
.card文件,该文件是修改在部署对等方上运行的代码所必需的。
您可以通过运行以下命令随时列出已安装的所有卡:
composer card list
2.准备Hyperledger Fabric对等体
为了将业务网络存档安装到Hyperledger Fabric网络上,您需要将业务网络安装到对等节点上。建议您从一个干净的目录开始。将您的BNA移至该目录,并将终端目录更改为该目录。
为此,您将需要拥有Business Network存档,您可以在下面看到一个示例tutorial-network
以及用于部署的“ PeerAdmin”卡。
composer network install --card PeerAdmin@hlfv1 --archiveFile tutorial-network@0.0.1.bna
3.在Hyperledger Fabric上启动您的业务网络
我们将使用composer network start
命令来启动业务网络,我们将需要使用PeerAdmin
卡进行此操作。我们还需要在网络上创建一个用户,我们将使用“管理员”用户名和密码开始。
以下是使用tutorial-network
BNA 的示例。
composer network start --networkName tutorial-network --networkVersion 0.0.1 --networkAdmin admin --networkAdminEnrollSecret adminpw --card PeerAdmin@hlfv1
这将为企业网络创建一个“管理”卡,对于上一个示例,该卡是 admin@tutorial-network.card
请注意:admin
用户名和adminpw
密码是针对在开发人员指南中部署的Hyperledger Fabric实例配置的特定Hyperledger Fabric身份的。如果您从头开始配置Hyperledger Fabric实例,则这些身份详细信息将有所不同。
4.安装“管理员”卡以备使用
接下来,我们将取出刚刚制作的管理卡,并将其导入以与您的企业网络一起使用。
composer card import --file admin@tutorial-network.card
5.启动REST服务器并生成Swagger API文档
导航到您的目录并运行composer-rest-server
命令。
composer-rest-server
- 输入admin @ tutorial-network作为卡名。确保不添加
.card
扩展名。 - 当询问是否在生成的API中使用名称空间时,请选择从不使用名称空间。
- 当询问是否保护生成的API时,选择No。
- 当询问是否启用事件发布时,选择“是”。
- 当询问是否启用TLS安全性时,选择No。
然后将生成其余服务器,并可在http:// localhost:3000 / explorer上使用
6.生成Angular应用程序
Angular应用程序要求其余服务器正在运行以连接到Fabric实例。执行此操作时,请确保在后台运行REST服务器。运行Yeoman生成器时,您还需要与.BNA文件位于同一目录中。
yo hyperledger-composer
请遵循以下内容,以便您的输出匹配。
Welcome to the Hyperledger Composer project generator
? Please select the type of project: Angular
You can run this generator using: 'yo hyperledger-composer:angular'
Welcome to the Hyperledger Composer Angular project generator
? Do you want to connect to a running Business Network? Yes
? Project name: [insert]
? Description: Hyperledger Composer Angular project
? Author name: [insert]
? Author email: [insert]
? License: Apache-2.0
? Name of the Business Network card: admin@tutorial-network
? Do you want to generate a new REST API or connect to an existing REST API? Connect to an existing REST
API
? REST server address: http://localhost
? REST server port: 3000
? Should namespaces be used in the generated REST API? Namespaces are not used
Created application!
生成的应用程序将位于以Project name
上面输入的名称命名的子目录中。
最后输入此目录并运行应用程序,运行:
npm start
它将在http:// localhost:4200上可用
参考文献
订阅事件
Node.js应用程序可以使用composer-client.BusinessNetworkConnection.on
API调用从业务网络订阅事件。事件在业务网络模型文件中定义,并由事务处理器功能文件中的指定事务发出。有关发布事件的更多信息,请参见发布事件。
在你开始之前
在应用程序可以订阅事件之前,您必须定义一些事件以及将触发它们的事务。还必须部署业务网络,并且您必须具有可以连接到它的连接配置文件。
程序
- 应用程序必须发送特定的API调用以订阅业务网络中发出的事件。当前,订阅事件的应用程序将接收所有发出的事件。API调用应采用以下格式:
businessNetworkConnection.on('event', (event) => {
// event: { "$class": "org.namespace.BasicEvent", "eventId": "0000-0000-0000-000000#0" }
console.log(event);
});
这包括一个称为的事件BasicEvent
,该事件在发布事件文档中创建。该eventId
属性始终与transactionId
发出事件的事务的属性相同,并带有形式为的附加数字"eventId": "<transactionId>#number"
。
接下来是什么?
现在,该应用程序将接收到业务网络发出的所有事件,并且由应用程序决定这些事件的集成程度。
集成现有系统
生成REST API
安装REST服务器
可以使用npm或Docker安装Hyperledger Composer REST服务器。
要使用npm进行安装,请运行以下命令:
npm install -g composer-rest-server@0.20
要使用Docker安装REST服务器,请参阅部署REST服务器。
运行REST服务器
Hyperledger Composer包含一个独立的Node.js流程,该流程将业务网络公开为REST API。LoopBack框架用于生成Swagger文档描述的Open API。
要启动REST Server,只需键入:
composer-rest-server
然后,将要求您输入有关您的业务网络的一些简单详细信息。下面显示了使用已部署的业务网络的示例。
? Enter the name of the business network card to use: admin@basic-sample-network
? Specify if you want namespaces in the generated REST API: always use namespaces
? Specify if you want to enable authentication for the REST API using Passport: No
? Specify if you want to enable event publication over WebSockets: Yes
? Specify if you want to enable TLS security for the REST API: No
To restart the REST server using the same options, issue the following command:
composer-rest-server -c admin@basic-sample-network -n always -w true
Discovering types from business network definition ...
Discovered types from business network definition
Generating schemas for all types in business network definition ...
Generated schemas for all types in business network definition
Adding schemas for all types to Loopback ...
Added schemas for all types to Loopback
Web server listening at: http://localhost:3000
Browse your REST API at http://localhost:3000/explorer
该composer-rest-server
命令
该composer-rest-server
命令具有许多用于定义安全性和身份验证的选项:
Options:
-c, --card The name of the business network card to use [string]
-n, --namespaces Use namespaces if conflicting types exist [string] [choices: "always", "required", "never"] [default: "always"]
-p, --port The port to serve the REST API on [number]
-y, --apikey The API key to get access to the REST API [string] [default:undefined]
-a, --authentication Enable authentication for the REST API using Passport [boolean] [default: false]
-m, --multiuser Enable multiple user and identity management using wallets (implies -a) [boolean] [default: false]
-w, --websockets Enable event publication over WebSockets [boolean] [default: true]
-t, --tls Enable TLS security for the REST API [boolean] [default: false]
-e, --tlscert File containing the TLS certificate [string] [default: "/usr/local/lib/node_modules/composer-rest-server/cert.pem"]
-k, --tlskey File containing the TLS private key [string] [default: "/usr/local/lib/node_modules/composer-rest-server/key.pem"]
-u, --explorer Enable the test explorer web interface [boolean] [default: true]
-d, --loggingkey Specify the key to enable dynamic logging for the rest server (just pressing enter will not enable this feature) [string]
-h, --help Show help [boolean]
-v, --version Show version number [boolean]
动态Rest Server日志记录
其余服务器的日志记录可以通过与其他Composer应用程序相同的方式进行控制。但是,这样做需要在设置了环境变量的情况下启动其余服务器,并且该服务器要连续记录日志。这具有创建大型日志,降低其余服务器性能的缺点,如果需要记录日志,则需要重新启动其余服务器,这可能是一项繁重的任务。
您可以通过指定密钥来启用动态Rest Server日志记录。该密钥用作URL路径的一部分。这意味着,除非有人知道了密钥,即使他们已通过身份验证,他们也无法更改其余服务器的日志记录。
例如,如果已为日志记录密钥设置了密钥45645-575835-A58684,则可以使用rest服务器资源管理器(在“管理”部分下)更改日志记录或编写应用程序或使用curl
。例如,在一个简单的情况下,假设身份验证被禁用,您可以
curl -X POST 'http://localhost:3000/api/admin/loglevel/45645-575835-A58684/composer%5Bdebug%5D%3A*/true/false'
这composer[debug]:*
会将debug设置为,第一个布尔值表示是否将输出发送到控制台,第二个布尔值表示是否将输出发送到文件系统。在上面的示例中,它声明将日志发送到控制台而不是文件系统。响应看起来像这样
{
"oldlevel":"composer[error]:*",
"newlevel":"composer[debug]:*",
"oldConsoleLevel":"none",
"newConsoleLevel":"silly",
"oldFileLevel":"silly",
"newFileLevel":"none"
}
指示以前的值和现在的值。
查看生成的API
启动浏览器并转到给定的URL(http://0.0.0.0:3000/explorer)。您会看到与此类似的屏幕。
更新REST服务器
在更新业务网络定义之后,可以更新REST服务器以生成新API,以反映对业务网络定义的更新。
要更新REST服务器,首先必须使用停止REST服务器ctrl-C
。然后,可以使用重启REST服务器composer-rest-server
。
使用APIKEY生成REST API
API密钥可用于提供第一层安全性,以在开发环境中访问REST API。
composer-rest-server -y YOUR_API_KEY
这将仅接受标头x-api-key
设置为的请求YOUR_API_KEY
。
摘要
在Hyperledger Composer运行时之上使用Loopback框架,使我们能够基于已部署的业务网络模型生成特定于业务域的REST API!
从REST服务器发布事件
可以将REST服务器配置为订阅从已部署的业务网络发出的事件,并发布这些业务事件以供客户端应用程序使用。当前,REST服务器支持通过WebSocket将事件发布到客户端应用程序。
客户端应用程序可以使用WebSocket客户端来订阅REST服务器发布的业务事件。WebSocket客户端可用于所有主要的编程语言和应用程序类型,例如,客户端Web用户界面,后端服务器进程,移动应用程序和集成工具。
启用WebSockets
您可以-w
在命令行中使用参数启用WebSockets :
composer-rest-server -c alice1@my-network -w
另外,您可以使用COMPOSER_WEBSOCKETS
环境变量启用WebSockets :
export COMPOSER_WEBSOCKETS=true
composer-rest-server -c alice1@my-network
成功启用WebSockets后,就可以将WebSocket客户端连接到REST服务器输出中显示的基本URL:
Web server listening at: http://localhost:3000
Browse your REST API at http://localhost:3000/explorer
在此示例中,要使用的基本URL是http://localhost:3000
。你必须从改变协议转换为WebSocket的URL这个http
来ws
。在此示例中,要使用的WebSocket URL是ws://localhost:3000
。
测试已启用WebSockets
您可以使用WebSocket客户端订阅事件来测试是否已启用WebSockets。开源命令行应用程序wscat
可用于此目的。
要安装wscat
,可以使用npm
。如果您没有全局安装npm
模块的正确权限,则可能需要使用sudo或以root用户身份运行此命令:
npm install -g wscat
然后,您可以wscat
用来连接和订阅REST服务器发布的业务事件。收到的任何业务事件都将打印到控制台:
$ wscat -c ws://localhost:3000
connected (press CTRL+C to quit)
< {"$class":"org.example.basic.SampleEvent","asset":"resource:org.example.basic.SampleAsset#assetId:1","oldValue":"","newValue":"hello world","eventId":"a80d220b-09db-4812-b04b-d5d03b663671#0","timestamp":"2017-08-23T12:47:17.685Z"}
>
为REST服务器启用身份验证
可以将REST服务器配置为对客户端进行身份验证。启用此选项后,客户端必须先向REST服务器进行身份验证,然后才能允许他们调用REST API。
选择身份验证策略
REST服务器使用开源Passport身份验证中间件。REST服务器的管理员必须选择Passport策略来验证客户端。可以选择多种Passport策略,从而允许REST服务器的客户端选择首选的身份验证机制。Passport包含多种策略(在撰写本文时为300多种),包括社交媒体(Google,Facebook,Twitter)和企业(SAML,LDAP)策略的混合。
本文档的其余部分将演示如何使用该passport-github
策略通过其GitHub ID对用户进行身份验证。passport-github
通过执行以下命令来安装策略:
npm install -g passport-github
配置REST服务器以使用身份验证策略
REST服务器必须配置有要使用的Passport策略列表,然后才能启用REST API身份验证。此配置既包括要使用的策略的名称,又包括每个策略的单独配置。
为了配置passport-github
策略,我们将需要在GitHub上注册OAuth应用程序并检索客户端ID和客户端密码。请按照以下步骤在GitHub上注册OAuth应用程序:
- 导航到GitHub并使用您的用户名和密码登录。
- 单击右上角的个人资料图片,然后从下拉菜单中单击设置。
- 点击左侧栏中“ 开发者设置 ” 下的OAuth应用程序。
- 单击注册新应用程序。
- 指定以下设置:
- 应用名称:作曲家
- 主页:http:// localhost:3000 /
- 应用说明:Composer的OAuth应用
- 授权回调网址:http:// localhost:3000 / auth / github / callback
- 单击注册应用程序。
- 记下Client ID和Client Secret的值。
REST服务器的配置应使用环境变量指定COMPOSER_PROVIDERS
。通过将REPLACE_WITH_CLIENT_ID
和REPLACE_WITH_CLIENT_SECRET
的值替换为从步骤7中检索到的值,并执行以下命令来设置REST服务器的配置:
export COMPOSER_PROVIDERS='{
"github": {
"provider": "github",
"module": "passport-github",
"clientID": "REPLACE_WITH_CLIENT_ID",
"clientSecret": "REPLACE_WITH_CLIENT_SECRET",
"authPath": "/auth/github",
"callbackURL": "/auth/github/callback",
"successRedirect": "/",
"failureRedirect": "/"
}
}'
在启用REST API身份验证的情况下启动REST服务器
COMPOSER_PROVIDERS
设置环境变量后,您可以使用该-a true
参数在启用身份验证的情况下启动REST服务器。启用身份验证后,客户端必须先进行身份验证,然后才能向业务网络发出任何请求。
例如,这是作为开发人员教程的一部分部署的业务网络的命令,但是您可能需要修改业务网络的命令:
composer-rest-server -c admin@my-network -a true
现在,通过http:// localhost:3000 / explorer /导航到REST API资源管理器。如果已成功启用身份验证,则使用HTTP 401 Authorization Required
消息拒绝任何使用REST API资源管理器调用业务网络REST API操作之一的尝试。
使用Web浏览器向REST服务器进行身份验证
此步骤取决于REST服务器使用的Passport策略的配置和行为。
- 通过导航到
authPath
环境变量中指定的属性的值来对REST服务器进行身份验证COMPOSER_PROVIDERS
。在上面的示例中,这是http:// localhost:3000 / auth / github。 - REST服务器会将您重定向到GitHub以执行OAuth Web服务器身份验证流程。GitHub会询问您是否要授权Composer应用程序访问您的帐户。单击授权按钮。
- 如果成功,GitHub会将您重定向回REST服务器。
现在,通过http:// localhost:3000 / explorer /导航到REST API资源管理器。尝试使用REST API资源管理器再次调用业务网络REST API操作之一。这次,呼叫应该成功。
使用HTTP或REST客户端向REST服务器进行身份验证
当用户对REST服务器进行身份验证时,将生成唯一的访问令牌并将其分配给已身份验证的用户。当用户使用Web浏览器进行身份验证时,访问令牌存储在用户Web浏览器本地存储中的cookie中。当经过身份验证的用户发出后续请求时,将从cookie中检索访问令牌,并验证访问令牌,而不是重新验证用户。
访问令牌可用于验证希望调用REST服务器的任何HTTP或REST客户端。当HTTP或REST客户端无法执行已配置的Passport策略所需的身份验证流时,这是必需的。例如,所有OAuth2 Web身份验证流程都需要使用Web浏览器来导航到身份验证提供程序的网站。
为了使用访问令牌,必须首先使用Web浏览器检索访问令牌。当您对REST服务器进行身份验证时,位于http:// localhost:3000 / explorer /的REST API资源管理器将在页面顶部显示访问令牌。默认情况下,访问令牌是隐藏的,但是可以通过单击Show
按钮显示它。访问令牌是一个长字母数字字符串,例如:e9M3CLDEEj8SDq0Bx1tkYAZucOTWbgdiWQGLnOxCe7K9GhTruqlet1h5jsw10YjJ
一旦检索到访问令牌,就可以将访问令牌传递到任何HTTP或REST请求中以认证HTTP或REST客户端。有两个传递访问令牌的选项-使用查询字符串参数或HTTP标头。对于以下两个示例,将字符串替换xxxxx
为访问令牌的值。
查询字符串-将access_token
查询字符串参数添加到所有HTTP或REST请求:
curl -v http://localhost:3000/api/system/ping?access_token=xxxxx
HTTP标头-将X-Access-Token
标头添加到所有HTTP或REST请求:
curl -v -H 'X-Access-Token: xxxxx' http://localhost:3000/api/system/ping
为REST服务器启用多用户模式
默认情况下,Hyperledger Composer REST服务器使用启动时在命令行上指定的区块链标识来服务所有请求。例如,使用以下命令时,将通过使用区块链标识alice1对所有事务进行数字签名来满足对REST服务器的所有请求:
composer-rest-server -c alice1@my-network
这意味着业务网络无法区分REST服务器的不同客户端。在某些用例中,例如,如果区块链身份仅具有只读访问权限,并且使用API管理网关保护REST服务器,则这是可以接受的。
REST服务器可以配置为多用户模式。多用户模式允许REST服务器的客户端为数字签名交易提供自己的区块链身份。这使业务网络能够区分REST服务器的不同客户端。
多用户模式需要REST API认证已启用,如果没有明确指定,就会自动启用REST API认证。您必须选择并配置用于验证用户身份的Passport策略。需要REST API身份验证,以便可以识别客户端。
客户端通过REST API身份验证后,该客户端即可将Blockchain身份添加到钱包。钱包是该客户专用的,其他客户无法访问。当客户端向REST服务器发出请求时,客户端钱包中的区块链身份将用于对该客户端进行的所有交易进行数字签名。
请注意,此功能要求客户端信任REST服务器。需要这种信任,因为此功能要求REST服务器存储客户端的区块链身份,包括私钥。因此,强烈建议客户端仅使用由受信方(例如其组织内的管理员)管理的REST服务器。
在启用多用户模式的情况下启动REST服务器
您必须先配置环境变量,COMPOSER_PROVIDERS
然后再继续。有关如何执行此任务的说明,请在继续之前阅读以下主题:为REST服务器启用身份验证
您可以使用该-m true
参数在启用多用户模式的情况下启动REST服务器。启用多用户模式后,客户端必须先进行身份验证,然后才能向业务网络发出任何请求。
例如,这是作为开发人员教程的一部分部署的业务网络的命令,但是您可能需要修改业务网络的命令:
composer-rest-server -c admin@my-network -m true
该-m true
参数自动启用REST API身份验证。-a true -m true
如果希望是明确的,也可以提供两个参数。在继续之前,您必须使用配置的身份验证机制对REST API进行身份验证。COMPOSER_MULTIUSER
可以在命令行上将环境变量设置为true
或false
代替使用-m
。
现在,通过http:// localhost:3000 / explorer /导航到REST API资源管理器。如果已成功启用多用户模式,则应使用A business network card has not been specified
错误消息拒绝任何使用REST API资源管理器调用业务网络REST API操作之一的尝试。
如果看到HTTP 401 Authorization Required
错误消息,则说明您未正确通过REST API进行身份验证。
在钱包中添加名片
首先,您必须向业务网络中的参与者颁发区块链身份。本示例将假定您已向alice1
参与者颁发了区块链身份org.example.mynetwork.Trader#alice@email.com
,并且已为此文件中存储的该区块链身份创建了一个商务网卡alice1@my-network.card
。
请按照以下步骤将业务网络卡添加到钱包中:
-
在http:// localhost:3000 / explorer /上导航到REST API资源管理器,然后通过扩展Wallet类别导航到电子钱包API 。
-
通过调用
GET /wallet
操作,检查钱包中是否包含任何商务网卡。该操作的响应应为:[]
-
通过调用
POST /wallet/import
操作将商务网卡导入钱包。您必须alice1@my-network.card
通过单击选择文件按钮来指定商务网卡文件。该操作的响应应为:no content
现在,商务网卡
alice1@my-network
已导入钱包。 -
alice1@my-network
通过调用GET /wallet
操作,检查钱包是否包含商务网卡。该操作的响应应为:[ { "name": "alice1@my-network", "default": true } ]
显示商务网卡
alice1@my-network
。该default
属性的值为true
,这意味着与商务网络进行交互时,默认情况下将使用此商务网卡。
现在,通过http:// localhost:3000 / explorer /导航到REST API资源管理器。尝试使用REST API资源管理器再次调用业务网络REST API操作之一。这次,呼叫应该成功。
您可以通过调用GET /system/ping
操作来测试正在使用的区块链身份。该操作将向其颁发区块链身份的参与者返回完全限定的标识符:
{
"version": "0.8.0",
"participant": "org.example.mynetwork.Trader#alice@email.com"
}
最后的笔记
在启用多用户模式的情况下启动REST服务器时,客户端发出的所有REST API请求都将使用存储在客户端钱包中的区块链身份。启动时在命令行上指定的区块链身份不用于处理任何请求;它仅用于最初连接到业务网络并下载业务网络定义,这是生成REST API所必需的。因此,在命令行上指定的区块链身份仅需要最低限度的权限-连接能力和下载业务网络定义的能力-不需要任何资产,参与者或交易的权限。
通过使用LoopBack连接器,所有用户信息都将保留在LoopBack数据源中。默认情况下,REST服务器使用LoopBack“内存”连接器来保留用户信息,当REST服务器终止时,该信息将丢失。REST服务器应配置有LoopBack连接器,该连接器将数据存储在高度可用的数据源(例如数据库)中。有关更多信息,请参阅部署REST服务器。
使用HTTPS和TLS保护REST服务器
在生产环境中部署Hyperledger Composer REST服务器时,应将REST服务器配置为使用HTTPS和TLS(传输层安全性)保护。一旦使用HTTPS和TLS配置了REST服务器,在REST服务器和所有REST客户端之间传输的所有数据都会被加密。
您必须同时提供证书和私钥对,才能配置REST服务器。REST服务器包括一个示例证书和私钥对,可用于轻松上手,但是仅建议此配置是为了在初始开发过程中易于使用。不要在生产环境中使用样本证书和私钥对。
通过使用示例证书和私钥对启用HTTPS和TLS
您可以使用示例证书和私钥对通过-t
以下命令行参数启用HTTPS和TLS :
composer-rest-server -c alice1@my-network -t
或者,您可以通过COMPOSER_TLS
环境变量使用示例证书和私钥对来启用HTTPS和TLS :
export COMPOSER_TLS=true
composer-rest-server -c alice1@my-network
成功启用HTTPS和TLS后,您将看到REST服务器的输出指定一个https://
URL而不是http://
URL:
Web server listening at: https://localhost:3000
Browse your REST API at https://localhost:3000/explorer
仅建议此配置是为了在初始开发过程中易于使用。对于测试,质量检查或生产部署,应提供自己的证书和私钥以启用HTTPS和TLS。
通过提供证书和私钥对来启用HTTPS和TLS
您可以通过提供自己的证书和私钥对来启用HTTPS和TLS。证书和私钥对必须作为两个单独的文件以PEM格式提供。这些文件必须在运行REST服务器的系统的文件系统上可用,并且REST服务器必须对这些文件具有读取权限。
您可以通过在命令行中使用“ -e”(证书文件)和“ -k”(私钥文件)参数来配置REST服务器使用证书和私钥对文件:
composer-rest-server -c alice1@my-network -t -e /tmp/cert.pem -k /tmp/key.pem
或者,您可以通过使用COMPOSER_TLS_CERTIFICATE
和COMPOSER_TLS_KEY
环境变量来配置THE REST服务器以使用证书和私钥对文件:
export COMPOSER_TLS=true
export COMPOSER_TLS_CERTIFICATE=/tmp/cert.pem
export COMPOSER_TLS_KEY=/tmp/key.pem
composer-rest-server -c alice1@my-network
为业务网络部署REST服务器
在生产环境中(例如,使用Docker Swarm或Kubernetes)部署Hyperledger Composer REST服务器时,应将REST服务器配置为高度可用。这意味着您必须部署REST服务器的多个实例,并且应该将这些实例配置为共享数据。例如,应该共享诸如商务网卡,区块链身份和REST API身份验证设置之类的数据,以便REST API客户端可以向任何实例发出请求,而无需重新进行身份验证。
商业网卡和商业网卡存储
REST服务器使用启动期间指定的业务网卡来连接并发现已部署的业务网络中的资产,参与者和交易。为了生成REST API,此信息是必需的。该名片被称为发现名片。默认情况下,发现商务网卡还用于处理对REST API的所有请求。但是,REST服务器也可以配置为多用户模式,这允许经过身份验证的用户提供自己的商务网卡,以处理对REST API的请求。
为了使用发现商务网卡,必须首先将该商务网卡导入REST服务器可用的商务网卡存储中。默认的商务网卡存储是带有路径的本地文件系统目录~/.composer
(其中~
是当前用户的主目录)。将Docker映像用于REST服务器时,必须将卷安装到包含导入的发现业务网卡的默认业务网卡存储的位置。在REST服务器的Docker映像中,REST服务器使用的商务卡存储在目录中/home/composer/.composer
(因为Docker映像中的REST服务器始终在composer
用户下运行)。
商业网卡包含一个连接配置文件,该配置文件描述了如何连接到运行已部署商业网络的Hyperledger Fabric网络。请注意,连接配置文件必须有效,才能在REST服务器的Docker映像中使用,并且主机名必须正确且可由该Docker映像访问。
使用持久数据存储配置REST服务器
通过使用LoopBack连接器,有关经过身份验证的用户及其钱包(在启用多用户模式时包含该用户的业务网卡)的所有信息都保存在LoopBack数据源中。默认情况下,REST服务器使用LoopBack“内存”连接器来保留用户信息,当REST服务器终止时,该信息将丢失。REST服务器应配置有LoopBack连接器,该连接器将数据存储在高度可用的数据源(例如数据库)中。
您应该能够使用任何LoopBack连接器,但是我们建议您对NoSQL数据库使用LoopBack连接器。例如,MongoDB或Apache CouchDB。
需要安装LoopBack连接器,以便REST服务器找到并使用它。您可以使用来安装其他LoopBack连接器npm
,例如:
npm install -g loopback-connector-mongodb
最后,您需要向REST服务器提供LoopBack连接器所需的连接信息。应该使用COMPOSER_DATASOURCES
环境变量来提供此连接信息。有关可用于配置REST服务器的环境变量的更多信息,请参见参考文档:Hyperledger Composer REST Server
使用其他Node.js模块扩展REST服务器的Docker映像
为了将REST服务器部署为具有其他LoopBack连接器和Passport策略的Docker容器,必须扩展hyperledger/composer-rest-server
Docker映像。
这是一个示例Dockerfile,该示例将适用于MongoDB的LoopBack连接器和适用于GitHub的Passport策略添加到Docker映像中:
FROM hyperledger/composer-rest-server
RUN npm install --production loopback-connector-mongodb passport-github && \
npm cache clean --force && \
ln -s node_modules .node_modules
您可以通过将上面的Dockerfile放在目录中并使用以下docker build
命令来构建此Docker映像,例如:
docker build -t myorg/my-composer-rest-server .
您可能需要将此Docker映像发布到Docker映像存储库,例如Docker Hub,以便将其与基于云的Docker部署服务一起使用。
使用Docker部署持久且受保护的REST服务器
以下示例将演示如何使用Docker部署REST服务器。部署的REST服务器将使用MongoDB持久化数据,并使用GitHub身份验证进行保护。
这些示例基于作为开发人员教程的一部分部署到Hyperledger Fabric v1.2的业务网络,并且可能需要根据您的配置进行调整,例如,如果Docker网络名称不匹配。
-
通过运行以下
composer network ping
命令,确保本地网络卡存储中有适用于您的企业网络的有效商业网卡。本示例为企业网络上的admin
用户使用my-network
企业网卡:composer network ping -c admin@my-network
请注意,在继续操作之前,必须使用
composer network ping
命令测试与业务网络的连接。如果商务网卡仅包含用户ID和注册机密,则该composer network ping
命令将触发注册过程,并将证书存储在商务网卡中。这是不建议使用泊坞窗图像的REST服务器时使用商业网络卡只有一个用户ID和注册的秘密。 -
启动名为MongoDB的Docker映像的实例
mongo
。此MongoDB实例将用于为REST服务器保留有关经过身份验证的用户及其钱包(在启用多用户模式时包含该用户的业务网卡)的所有信息。docker run -d --name mongo --network composer_default -p 27017:27017 mongo
请注意,MongoDB实例已连接到名为的Docker网络
composer_default
。这意味着MongoDB实例将在composer_default
使用主机名命名的Docker网络上可用mongo
。mongo
在后续步骤中,我们将使用主机名来配置REST服务器。根据您的Docker网络配置,您可能需要指定其他Docker网络名称。MongoDB端口27017
也使用port在主机网络上公开27017
,因此,如果需要,您可以使用其他MongoDB客户端应用程序与此MongoDB实例进行交互。 -
通过添加用于MongoDB的LoopBack连接器和用于GitHub身份验证的Passport策略,扩展REST服务器的Docker映像。在本地文件系统上创建一个新的空目录,并
Dockerfile
在新目录中创建一个新文件,其内容如下:FROM hyperledger/composer-rest-server RUN npm install --production loopback-connector-mongodb passport-github && \ npm cache clean --force && \ ln -s node_modules .node_modules
通过
docker build
在包含Dockerfile
刚创建的名为文件的目录中运行以下命令来构建扩展的Docker映像:docker build -t myorg/my-composer-rest-server .
如果此命令成功完成,则将
myorg/my-composer-rest-server
构建一个名为的新Docker映像并将其存储在系统上的本地Docker注册表中。如果希望在其他系统上使用此Docker映像,则可能需要将Docker映像推送到Docker注册表中,例如Docker Hub。 -
REST服务器的Docker映像是使用环境变量而不是命令行选项配置的。创建一个名为的新文件
envvars.txt
来存储我们的REST服务器的环境变量,其内容如下:COMPOSER_CARD=admin@my-network COMPOSER_NAMESPACES=never COMPOSER_AUTHENTICATION=true COMPOSER_MULTIUSER=true COMPOSER_PROVIDERS='{ "github": { "provider": "github", "module": "passport-github", "clientID": "REPLACE_WITH_CLIENT_ID", "clientSecret": "REPLACE_WITH_CLIENT_SECRET", "authPath": "/auth/github", "callbackURL": "/auth/github/callback", "successRedirect": "/", "failureRedirect": "/" } }' COMPOSER_DATASOURCES='{ "db": { "name": "db", "connector": "mongodb", "host": "mongo" } }'
请注意,发现业务网卡的名称
admin@my-network
已设置为COMPOSER_CARD
环境变量的值。通过指定never
为COMPOSER_NAMESPACES
环境变量的值,我们已禁用了生成的REST API中的名称空间。我们已经通过设置启用REST API客户端身份验证COMPOSER_AUTHENTICATION
的环境变量true
,并通过设置启用多用户模式COMPOSER_MULTIUSER
环境变量true
。通过在
COMPOSER_PROVIDERS
环境变量中为GitHub配置Passport策略,我们已将REST服务器配置为使用GitHub身份验证。请注意,您必须同时替换两者REPLACE_WITH_CLIENT_ID
和REPLACE_WITH_CLIENT_SECRET
GitHub中的适当配置,以使此配置成功运行。通过在
COMPOSER_DATASOURCES
环境变量中为MongoDB配置LoopBack连接器,我们已将REST服务器配置为使用MongoDB实例。请注意,mongo
已经在host
名为的LoopBack数据源的属性中指定了MongoDB实例的主机名db
。通过运行以下命令将环境变量加载到当前的shell中:
source envvars.txt
如果打开新的外壳(例如新的终端窗口或选项卡),则必须
source
再次运行相同的命令以将环境变量加载到新的外壳中。有关可用于配置REST服务器的环境变量的更多信息,请参见参考文档:Hyperledger Composer REST Server
-
通过运行以下
docker run
命令,为在步骤3中创建的REST服务器启动扩展Docker映像的新实例:docker run \ -d \ -e COMPOSER_CARD=${COMPOSER_CARD} \ -e COMPOSER_NAMESPACES=${COMPOSER_NAMESPACES} \ -e COMPOSER_AUTHENTICATION=${COMPOSER_AUTHENTICATION} \ -e COMPOSER_MULTIUSER=${COMPOSER_MULTIUSER} \ -e COMPOSER_PROVIDERS="${COMPOSER_PROVIDERS}" \ -e COMPOSER_DATASOURCES="${COMPOSER_DATASOURCES}" \ -v ~/.composer:/home/composer/.composer \ --name rest \ --network composer_default \ -p 3000:3000 \ myorg/my-composer-rest-server
请注意,我们已经通过使用多个
-e
选项遍历了在先前步骤中设置的所有环境变量。如果需要添加或删除任何其他环境变量来配置REST服务器,则还必须添加或删除适当的-e
选项。通过指定将我们的本地业务网络卡存储区安装到REST服务器Docker容器中
-v ~/.composer:/home/composer/.composer
。当尝试加载使用COMPOSER_CARD
环境变量指定的发现业务网卡时,这允许REST服务器访问和使用我们的本地业务网卡存储。我们还指定了Docker网络名称
composer_default
,并将Docker容器的名称指定为rest
。这意味着REST服务器实例将在composer_default
使用主机名命名的Docker网络上可用rest
。REST服务器端口3000
也使用port在主机网络上公开3000
。您可以使用以下
docker logs
命令检查REST服务器是否已成功启动:docker logs -f rest
如果REST服务器已成功启动,则您将看到它输出类似于的日志消息
Browse your REST API at http://localhost:3000/explorer
。
现在REST服务器已成功启动,您可以使用以下URL访问在Docker容器内运行的REST服务器:http:// localhost:3000 / explorer /。
最后的笔记
在本指南中,您已经了解了如何使用Docker启动REST服务器的单个实例,其中该单个实例配置为使用MongoDB作为持久数据存储。为了真正实现REST服务器的高可用性生产部署,您需要:
- 配置持久性数据存储的高可用性实例,例如MongoDB副本集。
- 运行REST服务器Docker映像的多个实例。通过使用
--name
参数更改Docker容器的名称,并使用参数更新或删除后续REST服务器实例的主机端口映射,可以轻松做到这一点-p 3000:3000
。 - 部署一个负载平衡器(例如Nginx),以在所有REST服务器实例之间分配来自客户端的REST请求。
一旦执行了这三个任务,就应该能够停止,重新启动或删除任何REST服务器实例(但不是全部!),而不会失去对REST的访问。
为业务网络定制REST服务器
默认情况下,Hyperledger Composer REST服务器包含的功能可为部署的业务网络中的所有资产,参与者和交易生成一组RESTful API。
Hyperledger Composer REST服务器还包括以下功能:
- 使用WebSockets 发布事件。
- 使用开源Passport身份验证中间件启用身份验证。
- 启用多用户模式,以便经过身份验证的用户可以提供自己的区块链凭证。
- 启用HTTPS和TLS以进行安全的客户端-服务器通信。
这些功能都是通用设计的,易于使用。Hyperledger Composer REST服务器作为名为的应用程序进行分发composer-rest-server
,可以使用npm或Docker进行安装,并且包括所有这些功能。
但是,这些功能可能无法满足所有用户的所有要求。例如,Hyperledger Composer REST服务器的用户可能希望使用其他形式的身份验证中间件,而不是使用Passport。
作为使用Hyperledger Composer REST服务器应用程序的替代方法composer-rest-server
,您可以在磁盘上生成功能等效的LoopBack应用程序。通过在此生成的LoopBack应用程序中编辑代码,可以自定义REST服务器以满足所有要求。
生成LoopBack应用程序
您可以使用Yeoman生成器生成LoopBack应用程序。在运行Yeoman Generator之前,您必须已部署了业务网络,并且必须具有可用于访问该业务网络的业务网卡。
在下面的示例中,我们已经部署了tutorial-network
业务网络,并且可以使用业务网卡admin@tutorial-network
连接到该业务网络。
通过在终端中发出以下命令来运行Yeoman生成器:
yo hyperledger-composer
Yeoman生成器将在生成LoopBack应用程序之前询问一系列问题。确保选择LoopBack
作为项目类型,并为商业网卡指定正确的名称,而不是下面的示例中显示的名称:
Welcome to the Hyperledger Composer project generator
? Please select the type of project: LoopBack
You can run this generator using: 'yo hyperledger-composer:loopback'
Welcome to the Hyperledger Composer LoopBack project generator
? Do you want to connect to a running Business Network? Yes
? Project name: my-loopback-app
? Description: Hyperledger Composer LoopBack project
? Author name: Simon Stone
? Author email: simon@congaverse.com
? License: Apache-2.0
? Name of the Business Network card: admin@tutorial-network
如果成功,Yeoman生成器将在当前工作目录的子目录中创建一个应用程序,该子目录以指定的命名Project name
。在上面的示例中,子目录将称为my-loopback-app
。
您可以通过输入子目录并运行以下命令来启动生成的应用程序:
npm start
生成的应用程序将为您提供一个URL,可用于与RESTful API进行交互:
> my-loopback-app@1.0.0 start /private/tmp/my-loopback-app
> node .
Web server listening at: http://localhost:3000
Browse your REST API at http://localhost:3000/explorer
自定义LoopBack应用程序
生成的LoopBack应用程序是标准的LoopBack应用程序。它在子目录下包含一组LoopBack模型文件,对于业务网络中的每种模型类型,每个文件都包含一个common/models
。每个模型文件都包含一个JSON文件(例如Commodity.json
)和一个JavaScript文件(例如Commodity.js
)。也有用于通用业务网络RESTful API(例如API)的LoopBack模型文件/system/ping
。
生成的LoopBack应用程序包括一个名为的单个数据源composer
,该数据源使用Hyperledger Composer的LoopBack连接器loopback-connector-composer
。文件中的数据源配置server/datasources.json
包括名片的名称;如果您更改商务网卡的名称,则还必须更改数据源配置:
{
"composer": {
"name": "composer",
"connector": "loopback-connector-composer",
"card": "admin@tutorial-network",
"namespaces": false
}
}
生成的LoopBack应用程序包括模型配置,该配置将所有LoopBack模型文件绑定到名为的数据源composer
,并通过将标志设置为public
来通过RESTful API公开它们true
。server/model-config.json
可以编辑文件中的模型配置,以隐藏或禁用特定建模类型的RESTful API:
{
...
"Commodity": {
"dataSource": "composer",
"public": true
}
...
}
有关LoopBack应用程序结构的更多信息,包括如何自定义应用程序并向该应用程序添加其他功能,请阅读LoopBack文档。生成的LoopBack应用程序使用Loopback v3.0,并且可以在以下位置找到LoopBack v3.0的文档:https : //loopback.io/doc/en/lb3/
与Node-RED集成
Node-RED是一种用JavaScript编写的轻量级开源集成技术。它使用图形流来集成不同的节点,节点可以在其中接收数据,转换数据和输出数据。
Node-RED通常用于快速创建物联网样式的应用程序原型,或将现有的Internet服务连接在一起。
您可以将Hyperledger Composer Node-RED贡献用于:
- 提交交易
- 阅读和更新资产和参与者
- 订阅活动
- 删除资产和参与者
该Hyperledger作曲家节点RED节点分布作为一个独立的NPM包,发表在这里: - https://www.npmjs.com/package/node-red-contrib-composer
Hyperledger Composer节点-RED节点
Hyperledger-Composer-out
红色节点输出节点,可用于创建,更新或删除资产或参与者并提交事务。例如,将hyperledger-composer-out节点与inject节点结合使用,可以通过提交参与者的JSON定义来创建参与者。
Hyperledger-Composer-Mid
节点红色中间流节点,它使您可以从注册表中创建,检索,更新或删除资产和参与者。例如,将hyperledger-composer-mid与注入节点结合使用,可以通过提交正确的注册表并将字段标识为JSON对象来检索资产或参与者。
Hyperledger-Composer-In
订阅来自区块链事件的Node-RED输入节点。
从事务处理器功能调用HTTP或REST API
在某些情况下,希望能够从事务处理器功能调用HTTP或REST API。这使您可以将复杂或昂贵的计算从区块链转移到中央或对等托管服务。
或者,事务处理器功能可能希望调用提供外部数据的第三方HTTP或REST API。例如,第三方API可以提供有关股票当前价格或当前天气和温度的数据,这些数据可用于确定合同条件是否已得到满足。
Hyperledger Composer允许事务处理器功能开发人员从事务处理器功能内调用HTTP或REST API。
请注意,使用此功能可能会导致由于共识失败而导致的错误,应谨慎使用。有关更多信息,请参见下面的共识注意事项。
使用请求模块
该request
模块(https://github.com/request/request)是许多Node.js应用程序使用的流行HTTP客户端。Hyperledger Composer嵌入了该request
模块,以便事务处理器功能可以使用它来调用HTTP或REST API。
标准request
模块使用面向回调的API。但是,事务处理器功能是基于承诺的,面向回调的API导致许多不必要的代码将回调包装在承诺中。为了使交易处理器功能开发人员更轻松地体验,我们改为公开了基于promise的request-promise
模块(https://github.com/request/request-promise)。
该request-promise
模块可通过request
全局变量自动提供给所有交易处理器功能。您不需要将request
或request-promise
模块添加到package.json
文件中,也不需要使用该require
函数来加载模块。
全局request
方法和所有的便利方法的各种HTTP方法(request.get
,request.post
等)可用于交易处理器功能。这些方法提供了用于处理请求正文,响应正文,HTTP标头,身份验证,cookie,代理和TLS / SSL的全套选项。
有关这些方法和可用选项的详细信息,请查看request
和request-promise
模块的文档。
例子
向HTTP服务器发出HTTP GET请求,该请求以字符串形式返回当前股价:
/**
* Buy a given amount of CONGA stocks.
* @param {org.example.BuyStocks} transaction The transaction.
* @transaction
*/
async function buyStocks(transaction) {
// Look up the current price of the CONGA stock, and parse it into a float.
const priceAsStr = await request.get('http://stocks.org/CONGA');
const price = parseFloat(priceAsStr);
// Get the current participant, and update their stock and balance.
const participant = getCurrentParticipant();
const units = transaction.units;
participant.stockUnits += units;
participant.balance -= price * units;
// Update the current participant in the participant registry.
const participantRegistry = await getParticipantRegistry('org.example.Trader');
await participantRegistry.update(participant);
}
向HTTP服务器发出HTTP GET请求,该请求以JSON结构返回当前股价:
/**
* Buy a given amount of CONGA stocks.
* @param {org.example.BuyStocks} transaction The transaction.
* @transaction
*/
async function buyStocks(transaction) {
// Look up the current price of the CONGA stock, and extract the price.
// The option "json: true" automatically parses JSON from the HTTP response.
const stock = await request.get({ uri: 'http://stocks.org/CONGA', json: true });
const price = stock.price;
// Get the current participant, and update their stock and balance.
const participant = getCurrentParticipant();
const units = transaction.units;
participant.stockUnits += units;
participant.balance -= price * units;
// Update the current participant in the participant registry.
const participantRegistry = await getParticipantRegistry('org.example.Trader');
await participantRegistry.update(participant);
}
向包含当前参与者作为HTTP请求正文的HTTP服务器发出HTTP POST请求,并以字符串形式返回当前股价:
/**
* Buy a given amount of CONGA stocks.
* @param {org.example.BuyStocks} transaction The transaction.
* @transaction
*/
async function buyStocks(transaction) {
// Get the current participant.
const participant = getCurrentParticipant();
// Look up the current price of the CONGA stock, and extract the price.
// The option "json" sends the participant as the HTTP request body,
// and automatically parses JSON from the HTTP response.
const stock = await request.post({ uri: 'http://stocks.org/CONGA', json: participant });
const price = stock.price;
// Get the current participant, and update their stock and balance.
const units = transaction.units;
participant.stockUnits += units;
participant.balance -= price * units;
// Update the current participant in the participant registry.
const participantRegistry = await getParticipantRegistry('org.example.Trader');
await participantRegistry.update(participant);
}
向HTTP服务器发出HTTP POST请求,该服务器返回股票资产的序列化实例:
/**
* Buy a given amount of CONGA stocks.
* @param {org.example.BuyStocks} transaction The transaction.
* @transaction
*/
async function buyStocks(transaction) {
// Look up the current price of the CONGA stock, and extract the price.
// The option "json: true" automatically parses JSON from the HTTP response.
const json = await request.get({ uri: 'http://stocks.org/CONGA', json: true });
// Parse the JavaScript object into the stock asset.
const serializer = getSerializer();
const stock = serializer.fromJSON(json);
const price = stock.price;
// Get the current participant, and update their stock and balance.
const participant = getCurrentParticipant();
const units = transaction.units;
participant.stockUnits += units;
participant.balance -= price * units;
// Update the current participant in the participant registry.
const participantRegistry = await getParticipantRegistry('org.example.Trader');
await participantRegistry.update(participant);
}
共识考虑
在Hyperledger Fabric中,通过让多个组织中的对等节点认可交易来实现业务网络中的共识。通过执行链码并签署执行结果来认可交易。为了使交易由区块链网络提交,所有支持交易的对等节点必须从执行链码中产生相同的结果。
当业务网络使用上述API发出HTTP请求时,这些HTTP请求将在支持交易的所有对等节点上执行。这将导致n个 HTTP请求,其中n是支持事务的对等节点的数量。
为了在业务网络发出HTTP请求时达成共识,您必须小心确保事务处理器功能在所有对等节点上发出相同的HTTP请求,然后对所有对等节点上的HTTP响应执行相同的处理。
例如,考虑一个使用HTTP请求从外部交易品种中查找股票价格的商业网络。然后,业务网络使用股票价格来调整参与者帐户上的余额。如果不同的对等节点收到不同的股票价格,则它们将尝试对参与者帐户的余额进行不同的调整。这将导致共识失败,并且交易将被拒绝。
HTTP请求可能由于多种原因而导致不同的响应:
- 不同组织中的对等节点可以运行在不同数据中心,不同国家,不同时区中。
- 根据公共Internet访问和防火墙的限制,不同组织中的对等节点可能无法访问HTTP服务器。
- 不同组织中的对等节点可能以不同用户身份向HTTP服务器进行身份验证,从而导致不同的HTTP响应。
为了最大程度地减少从事务处理器功能发出HTTP请求时共识失败的风险,建议您使用以下两种情况的make HTTP请求:
- 安全,因为HTTP请求不会修改HTTP服务器上的任何状态。
- 幂等的,因为可以多次发出相同的HTTP请求而没有不同的结果。
CORS(跨源资源共享)
从Hyperledger Composer Playground部署到Web浏览器连接的业务网络在Web浏览器内部运行。当这些业务网络中的事务处理器功能使用上述API发出HTTP请求时,这些HTTP请求将使用Web浏览器中内置的HTTP客户端进行处理。
Web浏览器中内置的HTTP客户端要求HTTP服务器符合CORS(跨域资源共享)标准。如果将业务网络部署到Web浏览器连接,则必须确保HTTP服务器已配置为符合CORS。有关更多信息,请参见:https : //enable-cors.org
Docker网络解析
部署到Hyperledger Fabric的业务网络在一个链码Docker容器中运行。这意味着业务网络将服从Docker提供的DNS解析和网络服务,而不是主机提供的那些服务。此外,chaincode Docker容器具有自己的IP地址。
这意味着localhost
解析为链码Docker容器,而不是主机。发出的任何HTTP请求localhost
(例如http:// localhost:3000 / api / Vehicle)均无法正常工作。最简单的解决方法是为可公开解析的REST服务器使用DNS名称。
管理商业网络
参加者和身份
参与者和身份是Hyperledger Composer的核心概念。参与者是业务网络的成员,可以代表个人或组织。参与者拥有身份证件,可以对其进行身份证明。有关更多信息,请参阅参与者和身份。
添加参与者
必须先将参与者添加到业务网络中,然后才能进行交易。参与者可以创建资产,也可以与其他参与者交换资产。参与者通过提交交易来处理资产。
创建,导出和导入业务网卡
商业网卡结合了连接配置文件,身份和证书,以允许在Hyperledger Composer Playground中连接到商业网络。可以在Hyperledger Composer Playground 的“ 我的钱包”页面中创建,导出和导入商务网卡。
向参与者颁发新身份
可以使用API或命令行将新的身份发布给参与者。一旦发布了新的身份,参与者就可以使用该身份在该参与者的上下文中与业务网络进行交互。
将现有身份绑定到参与者
可以使用API或命令行将现有身份绑定到参与者。一旦绑定了现有身份,参与者便可以使用该身份在该参与者的上下文中与业务网络进行交互。
列出业务网络中的所有身份
发出或绑定给参与者的身份将创建映射。为了在已部署的业务网络中执行身份管理操作,您将需要在身份注册表中列出并查看一组身份。
撤销参与者的身份
可以使用API或命令行从参与者撤消身份。一旦撤销身份,参与者就不能再使用该身份在该参与者的上下文中与业务网络进行交互。
与Hyperledger Fabric交互
Hyperledger Composer设计为与平台无关。本节是关于与Hyperledger Fabric交互的细节。
参加者和身份
概念
A Participant
是业务网络中的参与者。参与者可能是一个组织的个人。参与者可以创建资产,也可以与其他参与者交换资产。参与者通过提交交易来处理资产。
参与者具有一组Identity
可以验证以证明该参与者身份的文档。例如,一个人可能拥有一个或多个以下身份证明文件,以证明自己是谁:
- 护照
- 驾驶执照
- 指纹识别
- 视网膜扫描
- SSL证书
在Hyperledger Composer中,参与者与他们可以用来与业务网络进行交互的一组身份证明文件分开。
为了使新参与者加入业务网络,必须在业务网络中创建该参与者的新实例。参与者实例存储了有关该参与者的所有必需信息,但是它没有赋予该参与者访问与业务网络交互的权限。
为了向参与者授予与业务网络交互的访问权限,必须Issued
向该参与者发送身份证明文件。然后,新参与者可以使用该身份证明文件与业务网络进行交互。
参与者可能有一个现有的身份证明文件,可用于与其他业务网络或其他外部系统进行交互。这些身份证明文件可以重复使用并提供Bound
给该参与者。然后,新参与者可以使用其现有的身份文档与业务网络进行交互。
身份证明文件通常会在设定的时间后过期。身份证件也可能丢失或被盗。如果身份证明文件已过期或需要替换,则必须将其删除,Revoked
以使其不再可用于与业务网络进行交互。
但是,撤销身份证明文件不会删除有关该参与者及其拥有的任何资产的信息。吊销身份证明文件仅会删除参与者使用该身份证明文件与业务网络进行交互的能力。可以通过向参与者提供新的身份证明文件来恢复对业务网络的访问。
这些参与者和身份管理动作由业务网络中的现有参与者(例如,监管机构)或同一组织中的受信任管理该组织中的参与者/身份的参与者执行。
Hyperledger Composer中的参与者和身份
在Hyperledger Composer中,参与者的结构在模型文件中建模。此结构可以包括有关参与者的各种信息,例如,参与者的姓名,地址,电子邮件地址,出生日期等。然后可以创建该建模参与者的新实例,并将其添加到参与者注册表中。
Hyperledger Composer要求使用区块链身份作为身份证明文件的形式。例如,在将业务网络部署到Hyperledger Fabric时,注册证书将用作身份证明文件的形式。这些注册证书用于对提交到已部署的业务网络的交易进行加密签名。
部署的业务网络维护着一组到参与者的身份映射Identity Registry
。如果身份是参与者Issued
或Bound
参与者,则新映射将添加到身份注册表。当该参与者使用该身份将事务提交到已部署的业务网络时,Composer运行时将在身份注册表中查找该身份的有效映射。使用公用密钥签名或指纹完成查找,本质上是证书内容的哈希值,该哈希值对该证书和身份唯一。
在身份注册表中找到映射后,将从该映射中检索该身份的参与者。该参与者成为Current Participant
提交交易的参与者。Hyperledger Composer中的所有访问控制均基于当前参与者。访问控制规则,用于定义哪些参与者可以对当前参与者执行对哪些资源进行的所有操作。
参与者首次使用身份将事务提交到已部署的业务网络时,该身份为Activated
。这意味着将更新身份注册表中的条目,以记录首次使用身份的事实。如果在发布身份或将其绑定到参与者时不可用,则有关身份的其他信息(例如证书)也可能会在激活期间记录在身份注册表中。
如果并且当某个身份被吊销时,该身份的身份注册表中的条目将更新以将状态更改为Revoked
。撤销身份后,如果参与者尝试使用该身份向已部署的业务网络提交交易,则该交易将被拒绝。
Hyperledger Composer游乐场中的身份和业务网卡
在Hyperledger Composer Playground中,有一个包含本地存储的Business网卡的钱包。商业网卡是商业网络的访问卡,包括身份数据,连接配置文件和用于商业网络访问的正确证书。可以导出身份证以允许将身份分配给其他人。
在Hyperledger Composer中执行身份管理任务
Hyperledger Composer Node.js客户端API,REST API和命令行界面都可以用于执行身份管理操作。例如,以下身份管理操作可通过所有Hyperledger Composer界面使用:
- 将新参与者添加到参与者注册表
- 向参与者颁发新身份
- 将现有身份绑定到参与者
- 撤销参与者的身份
- 列出已部署的业务网络中的所有身份
有关更多信息,请参阅本文档底部的相关任务和参考资料。
相关概念
相关任务
创建业务网络定义
添加参与者向参与者
发布新身份将
现有身份绑定到参与者
列出商业网络中的所有身份
撤消参与者的身份
相关参考
作曲者参与者添加
作曲者身份问题
作曲者身份绑定
作曲者身份撤消
作曲者身份列表
添加参与者
可以使用API或命令行将参与者添加到参与者注册表中。
在你开始之前
在执行这些步骤之前,您必须已经为业务网络定义中的参与者建模并将其部署为业务网络。
下面的过程显示了一个示例,该示例使用来自Digital Property示例业务网络定义的参与者的以下模型:digitalproperty-network
请注意:如果要使用composer participant add
命令添加参与者,请确保参与者的JSON表示形式用单引号引起来。
namespace net.biz.digitalPropertyNetwork
participant Person identified by personId {
o String personId
o String firstName
o String lastName
}
程序
- 将参与者添加到参与者注册表
- JavaScript API
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
async function addParticipant() {
let businessNetworkConnection = new BusinessNetworkConnection();
try {
await businessNetworkConnection.connect('admin@digitalPropertyNetwork');
let participantRegistry = await businessNetworkConnection.getParticipantRegistry('net.biz.digitalPropertyNetwork');
let factory = businessNetworkConnection.getFactory();
let participant = factory.newResource('net.biz.digitalPropertyNetwork', 'Person', 'mae@biznet.org');
participant.firstName = 'Mae';
participant.lastName = 'Smith';
await participantRegistry.add(participant);
await businessNetworkConnection.disconnect();
} catch(error) {
console.error(error);
process.exit(1);
}
}
addParticipant();
-
命令行
composer participant add -c admin@network -d '{"$class":"net.biz.digitalPropertyNetwork.Person","personId":"mae@biznet.org","firstName":"Mae","lastName":"Smith"}'
创建,导出和导入业务网卡
商业网卡由.card
包含metadata.JSON
文件,连接配置文件和可选证书的文件表示。
可以在Hyperledger Composer Playground中使用商务网卡来管理不同商务网络和连接配置文件的身份。
创建商务网卡
可以在钱包屏幕中创建商务网卡,可以从组件文件创建商务网卡,也可以在商务网中创建商务网卡。
请注意:如果卡是从钱包屏幕创建的,或者是从组件文件创建的,则必须在业务网络中已经创建了相应的标识。
在业务网络中创建业务网卡
-
在“ 我的钱包”屏幕中,选择一个用于连接到您的企业网络的身份。单击立即连接。请注意:您必须使用具有创建新身份的权限的身份。
-
可选:要创建分配给该身份的参与者,请点击“ 测试”标签,然后点击“ 创建新参与者”。
-
点击右上角的身份名称,然后点击ID Registry。
-
单击发布新ID。
-
选择一个ID名称,然后选择一个与新身份相关联的参与者。
-
点击新建。
-
点击添加到我的钱包。将商业网络卡添加到您的钱包后,您就可以使用它来连接到商业网络,或者将其导出以供其他人使用。
现在,“ 我的钱包”屏幕应显示新的名片。
从电子钱包创建名片
可以从“ 我的钱包”页面创建商务网卡,但是,必须已经在商务网中创建了相应的标识。从“ 我的钱包”页面创建商务网卡要求您使用与在商务网络中创建身份时相同的用户ID,用户密码和正确的商务网络名称凭据。
要从“ 我的钱包”页面创建名片,请执行以下操作:
-
收到有效的用户ID和用户密码后,单击“ 我的钱包”页面右上方的“ 创建商务网卡”按钮。
-
选择一个连接配置文件,然后单击下一步。
-
输入创建身份时生成的用户ID和用户密码。
-
输入正确的业务网络名称,然后单击创建。
现在,应该在“ 我的钱包”页面中显示商务网卡。
从组件文件创建名片
商业网卡是包含最多三个元素的复合文件:
- 连接配置文件。(
connection.json
) - 一个元数据文件,其中包含用于连接到业务网络的身份数据。(
metadata.json
) - 可选
credentials
目录,分别包含名为certificate
和的文件中的身份证明书和证书privateKey
。
请注意:如果没有credentials
目录,则元数据文件必须包含获取具有属性名enrollmentSecret的凭据所需的注册密钥。如果指定了enrollmentSecret且使用商务网卡连接到商务网络,则如果导出商务网卡,则将创建并填充包含证书的凭证目录。
元数据文件应采用以下格式:
{
"version": 1,
"userName": "alice",
"description": "Alice's identity for basic-sample-network",
"businessNetwork": "basic-sample-network",
"enrollmentSecret": "UserSecret",
"roles": [
]
}
该businessNetworkName,说明,enrollmentSecret和角色属性是可选的。可用角色为PeerAdmin
和ChannelAdmin
。
要创建商务网卡文件,请运行composer card create
命令。
现在可以使用Hyperledger Composer Playground导入此商务网卡。
导入和导出名片
导入和导出业务网卡是在Playground中向业务网络的其他用户授予访问权限的最简单方法。必须使用上述方法之一创建有效的商务网卡,然后可以将其导出并发送给其他用户。
导出商务网卡
-
要导出商务网卡,请使用商务网络创建一个身份,然后将该商务网卡添加到您的钱包中。
-
在“ 我的钱包”页面上,单击要导出的名片上的“ 导出”图标。名片应下载为
.card
文件。
请注意:如果您导出从未使用过的商业网络卡(例如,发送给新参与者),它将包含获取证书和私钥所需的注册ID和注册机密,然后将其用于识别参与者。或者,如果导出以前使用过的商业网卡,则该商业网卡将已经包含证书和私钥。
重要提示:导出的身份证应谨慎处理,因为其中包含不受保护的凭据。例如,您永远不要通过电子邮件或其他未加密的通信方式发送身份证。
导入商务网卡
导入商务网卡使您无需创建连接配置文件,身份和证书即可连接到商务网络。商业网络的成员可以创建商业网络卡并导出它们,以使其他人可以访问商业网络。
-
在“ 我的钱包”屏幕上,单击右上角的导入名片。
-
拖放或浏览以选择
.card
要导入的名片()文件。点击导入。
现在,您的钱包中应该可以看到名片。
向参与者颁发新身份
可以使用API,命令行或使用Hyperledger Composer Playground中的ID卡向参与者颁发新的身份。一旦发布了新的身份,参与者就可以使用该身份在该参与者的上下文中与业务网络进行交互。
使用Hyperledger Fabric时,Hyperledger Composer通过使用Hyperledger Fabric证书颁发机构(CA)来注册新的注册证书来颁发新的身份。Hyperledger Fabric证书颁发机构会生成一个注册机密,可以将其提供给参与者,然后参与者可以使用该注册机密向Hyperledger Fabric证书颁发机构请求其注册证书和私钥。
在你开始之前
在执行这些步骤之前,您必须已将参与者添加到参与者注册表中。该发行人新的身份(是否使用命令行或使用的JavaScript API下文)本身必须具有“发行人”的权威和适当的,允许他们出具身份的ACL Hyperledger作曲(与参与者相关的)。
下面的过程显示了一个示例,该示例使用来自Digital Property示例业务网络定义的参与者的以下模型:digitalproperty-network
namespace net.biz.digitalPropertyNetwork
participant Person identified by personId {
o String personId
o String firstName
o String lastName
}
该示例假定net.biz.digitalPropertyNetwork#mae@biznet.org
已创建该参与者的实例,并将其放入参与者注册表中。
程序
- 连接到业务网络并向参与者发出新的身份
- JavaScript API
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
async function identityIssue() {
let businessNetworkConnection = new BusinessNetworkConnection();
try {
await businessNetworkConnection.connect('admin@digitalPropertyNetwork');
let result = await businessNetworkConnection.issueIdentity('net.biz.digitalPropertyNetwork.Person#mae@biznet.org', 'maeid1')
console.log(`userID = ${result.userID}`);
console.log(`userSecret = ${result.userSecret}`);
await businessNetworkConnection.disconnect();
} catch(error) {
console.log(error);
process.exit(1);
}
}
identityIssue();
- 命令行
composer identity issue -c admin@network -f maeid1.card -u maeid1 -a "resource:net.biz.digitalPropertyNetwork.Person#mae@biznet.org"
这将为用户maeid1发行卡,并将卡文件导出到当前目录中。
- 作为参与者,测试与业务网络的连接
- JavaScript API
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
async function testConnection() {
let businessNetworkConnection = new BusinessNetworkConnection();
try {
await businessNetworkConnection.connect('admin@digitalPropertyNetwork');
let result = await businessNetworkConnection.ping();
console.log(`participant = ${result.participant ? result.participant : '<no participant found>'}`);
await businessNetworkConnection.disconnect();
} catch((error) {
console.error(error);
process.exit(1);
}
}
testConnection();
- 命令行
composer card import -f maeid1@network.card
composer network ping -c maeid1@network
在ping之前,您需要确保将卡导入业务网络。
将现有身份绑定到参与者
可以使用API或命令行将现有身份发布给参与者。一旦绑定了现有身份,参与者便可以使用该身份在该参与者的上下文中与业务网络进行交互。
使用Hyperledger Fabric时,您可以绑定通过使用Hyperledger Fabric证书颁发机构(CA)或使用其他工具创建的现有证书cryptogen
。现有证书必须有效,可用于在Hyperledger Fabric网络上提交事务。
在你开始之前
在执行这些步骤之前,您必须已将参与者添加到参与者注册表中。您必须具有PEM格式的现有证书才能绑定到参与者。现有身份的绑定程序(无论使用命令行还是下面的Javascript API)必须具有ACL,以允许它们绑定Hyperledger Composer中的身份(与参与者相关联)。
下面的过程显示了一个示例,该示例使用来自Digital Property示例业务网络定义的参与者的以下模型:digitalproperty-network
namespace net.biz.digitalPropertyNetwork
participant Person identified by personId {
o String personId
o String firstName
o String lastName
}
该示例假定net.biz.digitalPropertyNetwork#mae@biznet.org
已创建该参与者的实例,并将其放入参与者注册表中。
程序
- 连接到业务网络并将现有身份绑定到参与者
- JavaScript API
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
async function bind() {
let businessNetworkConnection = new BusinessNetworkConnection();
let certificate = `-----BEGIN CERTIFICATE-----
MIIB8DCCAZegAwIBAgIURanHh55fqrUecvHNHtcMKiHJRkwwCgYIKoZIzj0EAwIw
czELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh
biBGcmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMT
E2NhLm9yZzEuZXhhbXBsZS5jb20wHhcNMTcwNzI3MTc0MzAwWhcNMTgwNzI3MTc0
MzAwWjAQMQ4wDAYDVQQDEwVhZG1pbjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA
BAANIGFIrXXr5+h0NfUNJhx5YFQ4w6r182eZYRhc9KvYQhYo5D0ZbecfR9sGX2b6
0aW+C7bUaXc6DU3pJSD4fNijbDBqMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E
AjAAMB0GA1UdDgQWBBRwuAyWrGlzVQFqRf0OqoTNuoq7QDArBgNVHSMEJDAigCAZ
q2WruwSAfa0S5MCpqqZknnCGjjq9AhejItieR+GmrjAKBggqhkjOPQQDAgNHADBE
AiBcj/JvxmKHel4zQ3EmjITEFhdYku5ijIZEDuR5v9HK3gIgTUbVEfq3MuasVZKx
rkM5DH3e5ECM7T+T1Ovr+1AK6bs=
-----END CERTIFICATE-----`
try {
await businessNetworkConnection.connect('admin@digitalPropertyNetwork');
await businessNetworkConnection.bindIdentity('net.biz.digitalPropertyNetwork.Person#mae@biznet.org', certificate);
await businessNetworkConnection.disconnect();
} catch(error) {
console.error(error);
process.exit(1);
}
}
bind();
-
命令行
composer identity bind -c admin@digitalPropertyNetwork -a "resource:net.biz.digitalPropertyNetwork.Person#mae@biznet.org" -e mae-pub.pem
- 作为参与者,测试与业务网络的连接
- JavaScript API
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
async function testConnection() {
let businessNetworkConnection = new BusinessNetworkConnection();
try {
await businessNetworkConnection.connect('admin@digitalPropertyNetwork');
let result = await businessNetworkConnection.ping();
console.log(`participant = ${result.participant ? result.participant : '<no participant found>'}`);
await businessNetworkConnection.disconnect();
} catch(error) {
console.error(error);
process.exit(1);
}
}
testConnection();
-
命令行
composer network ping -c admin@digitalPropertyNetwork
参与者ID将被打印到控制台,并且应与composer identity bind
命令中指定的参与者ID相匹配。
列出业务网络中的所有身份
当向参与者颁发新身份或将现有身份绑定到参与者时,将在部署的业务网络中的身份注册表中创建身份和参与者之间的映射。当该参与者使用该身份将事务提交到已部署的业务网络时,Composer运行时将在身份注册表中查找该身份的有效映射。使用公用密钥签名或指纹完成查找,本质上是证书内容的哈希值,该哈希值对该证书和身份唯一。
为了在已部署的业务网络中执行身份管理操作,您将需要在身份注册表中列出并查看一组身份。
在你开始之前
在执行这些步骤之前,您应该已经将参与者添加到参与者注册表中,并发布了新的标识或将现有标识绑定到该参与者。否则,身份注册表将为空,并且您将看不到任何结果。
程序
- 连接到业务网络并在身份注册表中列出身份
- JavaScript API
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
async function identityList() {
let businessNetworkConnection = new BusinessNetworkConnection();
try {
await businessNetworkConnection.connect('admin@digitalPropertyNetwork');
let identityRegistry = await businessNetworkConnection.getIdentityRegistry();
let identities = await identityRegistry.getAll();
identities.forEach((identity) => {
console.log(`identityId = ${identity.identityId}, name = ${identity.name}, state = ${identity.state}`);
});
await businessNetworkConnection.disconnect();
} catch(error) {
console.log(error);
process.exit(1);
}
}
-
命令行
composer identity list -c admin@digitalPropertyNetwork
撤销参与者的身份
可以使用API或命令行从参与者撤消身份。一旦撤销身份,参与者就不能再使用该身份在该参与者的上下文中与业务网络进行交互。
使用Hyperledger Fabric时,Hyperledger Composer当前不尝试通过使用Hyperledger Fabric证书颁发机构(CA)API撤销身份。该身份仍然可以用于将交易提交到底层的区块链网络,但是交易将被部署的业务网络拒绝。
在你开始之前
在执行这些步骤之前,您必须已将参与者添加到参与者注册表中,并且向该参与者颁发或绑定了身份。您还必须在身份注册表中找到该身份的唯一标识符。有关查找身份的唯一标识符的更多信息,请参见列出业务网络中的所有身份。
下面的过程显示了一个示例,该示例使用来自Digital Property示例业务网络定义的参与者的以下模型:digitalproperty-network
namespace net.biz.digitalPropertyNetwork
participant Person identified by personId {
o String personId
o String firstName
o String lastName
}
该示例假定net.biz.digitalPropertyNetwork#mae@biznet.org
已创建该参与者的实例,并将其放入参与者注册表中。
该示例还假定maeid1
已向该参与者颁发了身份,并且该身份的唯一标识符为“ f1c5b9fe136d7f2d31b927e0dcb745499aa039b201f83fe34e243f36e1984862”。
程序
- 连接到业务网络并撤消参与者的现有身份
- JavaScript API
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
async function revoke() {
let businessNetworkConnection = new BusinessNetworkConnection();
try {
await businessNetworkConnection.connect('admin@digitalPropertyNetwork');
await businessNetworkConnection.revokeIdentity('f1c5b9fe136d7f2d31b927e0dcb745499aa039b201f83fe34e243f36e1984862')
await businessNetworkConnection.disconnect();
} catch(error) {
console.log(error);
process.exit(1);
}
}
revoke();
-
命令行
composer identity revoke -c admin@digitalPropertyNetwork -u f1c5b9fe136d7f2d31b927e0dcb745499aa039b201f83fe34e243f36e1984862
超级账本面料
有几种情况下,特定信息Hyperledger面料必须包含在Hyperledger作曲家命令,包括composer network install
,composer network start
和composer identity issue
。该--option, -o
选项和该--optionsFile, -O
选项允许发送连接器特定的信息。
可以--option, -o
通过重复使用标签来指定多个选项,例如:
composer somecmd -o thisOpt=value2 -o thatOpt=value2
或者,您可以创建一个包含多个选项的文件,例如,一个名为的文件someCmdOpts.txt
可以包含:
thisOpt=value1
thatOpt=value2
要引用选项文件,请使用以下格式:
composer somecmd --optionsFile=someCmdOpts.txt
一些API的还将包括选择通过通用的选择对象,包括AdminConnection.start()
和AdminConnection.install()
提供用于安装的npm配置设置
命令行界面
该npmrcFile
选项在composer network install
命令上可用。
该npmrcFile
选项允许您在Hyperledger Fabric为Hyperledger Composer运行时构建链码映像时指定npm配置信息。
例如,您可以使用registry
选项文件中的选项来指定组织内部的注册表,而不是使用默认的npm注册表:
registry=http://mycompanynpmregistry.com:4873
作为安装命令的一部分,提供标准文件名,例如,如果文件在/ home / user1 / config目录中被称为npmConfig:
composer network install --c PeerAdmin@hlfv1 --a tutorial-network@0.0.1.bna -o npmrcFile=/home/user1/config/npmConfig
文件内容可以是.npmrc
npm配置文件中允许的任何内容。
管理员API
通过npmrcFile
在installOptions
对象上指定属性,您可以在安装方法中作为AdminConnection api的一部分提供文件名。例如,传递要在安装时提供的npm配置选项文件的名称:
await AdminConnection.install(businessNetworkDefinition, {npmrcFile: '/tmp/npmrc'});
Hyperledger Fabric认可政策
您可以为网络启动请求和网络升级请求提供Hyperledger Fabric认可策略。下面的示例显示了,start
但是方法也相同upgrade
。
作曲者网络启动/升级CLI
可以使用-o
和-O
选项以多种方式发送Hyperledger Fabric认可策略。
- 使用该
-o
选项,可以以单行JSON字符串或完全限定的文件路径发送认可策略:
composer network start ... -o endorsementPolicy='{"identities": [.... }'
composer network start ... -o endorsementPolicyFile=/path/to/file/endorsementPolicy.json
指定文件路径后,背书策略文件应遵循以下格式:
{"identities":[...],
"policy": {...}}
-
使用该
-O
选项,必须将背书策略作为文件路径发送,如下所示:composer network start ... -O /path/to/file/options.json
在这种情况下,选项文件应遵循以下格式:
{"endorsementPolicy": {"Identities": [...]. "policy: {...}" }, "someOtherOption": "A Value" }
有关编写Hyperledger Fabric背书策略的更多信息,请参阅Hyperledger Fabric Node.js SDK文档,其中提供了背书策略的示例。
管理员API
要通过Admin API发送认可策略,当分别调用start或deploy时,认可策略文件必须作为startOptions
或deployOptions
对象的一部分包括在内。要传递背书策略文件,必须在对象属性中指定该文件endorsementPolicyFile
。要将策略提供为JSON对象,endorsementPolicy
必须指定object属性。
await adminConnection.start('tutorial-network', '0.0.1', { networkAdmins: networkAdmins, endorsementPolicyFile: 'endorsement-policy.json'} );
身份问题
颁发新身份时,您可能要指定所颁发的身份是否具有向Hyperledger Fabric证书颁发机构服务器注册新身份的权限。
命令行界面
要授予身份从命令行向证书颁发机构注册新身份的权限,该-x
选项可用(这是的快捷替代-o issuer=true
)。
composer identity issue -c admin@digitalproperty-network -u MyUser -a net.biz.digitalPropertyNetwork.Person#P1 -x
定义要使用的隶属关系-o affiliation=org2.department1
。如果您特别不想指定从属关系,并且没有默认的org1
used,那么请指定以下内容-o affiliation=''
。
composer identity issue -c admin@digitalproperty-network -u MyUser -a net.biz.digitalPropertyNetwork.Person#P1 -o affiliation=org2.department1
API
要指定issuer属性,您可以在对象中设置它,并将该对象作为issueOptions
on的一部分传递issueIdentity
。例如,发布具有发行者权限的身份
await businessNetworkConnection.issueIdentity(participantId, newUserId, {issuer: true});
指定从属属性
await businessNetworkConnection.issueIdentity(participantId, newUserId, {affiliation: 'org.department1'});
参考资料
官网:https://hyperledger.github.io/composer/
博客:
https://www.jianshu.com/p/13d5de69f73a