应用程序开发人员使用composer-client
npm模块以编程方式连接到已部署的业务网络,创建,读取,更新和删除资产和参与者并提交事务。如果应用程序需要能够部署或管理业务网络,则composer-admin
可以使用npm模块。
样本landregistry.js
文件包含代表土地登记处的类别,并包含列出土地标题,添加默认标题和提交交易的方法。这已使用JavaScript类实现; 但是你可以自由地构建你的代码,只要你愿意。
值得强调的是API的风格是使用承诺。通常,Hyperledger Composer API将返回在操作成功完成时解决的承诺,或者返回操作结果(如果适用)。
如果您不熟悉基于Promise的开发,那么值得在线查看一些教程以获取想法。除此之外,在节点8中,现在支持async / await,这使得开发异步应用程序变得更加容易。这里显示的示例使用await并假定代码包含在具有async
属性的函数中
const BusinessNetworkConnection = require('composer-client').BusinessNetworkConnection;
对于Hyperledger Composer客户端应用程序,这是唯一需要的npm模块。
BusinessNetworkConnection实例已创建,然后用于连接到运行时:
this.bizNetworkConnection = new BusinessNetworkConnection();
我们要在这里创建的第一个Hyperledger Composer API调用是connect()API,用于在Hyperledger Fabric上建立与Hyperledger Composer运行时的连接。需要提供适当的cardName用于连接,例如admin@digitalproperty-network
可能是有效的卡名称,具体取决于数字资产网络的部署方式。如果成功,此API将对商业网络定义返回一个承诺:
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应用程序应该创建REST API调用。要为业务网络创建自定义REST API,请使用该composer-rest-server
命令。
要创建可与REST API交互的骨架Angular应用程序,请使用该yo hyperledger-composer
命令。
请按照开发者教程中关于如何使用composer-rest-server
和Angular生成器的例子。
构建Angular应用程序的流程如下所示:
如果您已经拥有Business Network Archive并希望构建骨架Angular应用程序,请使用以下参考说明,如果您想全面了解如何从头开发BNA并从此构建应用程序,请参阅开发人员教程。
先决条件
如果您已经安装了开发工具,则将安装Hyperledger Fabric。
前往fabric-dev-servers
目录并启动Hyperledger Fabric。如果您使用了我们的开发工具安装指南,以下代码是一个示例:
cd ~/fabric-dev-servers
./startFabric.sh
./createPeerAdminCard.sh
这也将创建一个PeerAdmin
.card文件,它需要修改在部署的同位体上运行的代码。
您可以随时通过运行以下命令列出您已安装的所有卡:
composer card list
为了将业务网络存档安装到Hyperledger Fabric网络上,您需要将业务网络安装到对等设备上。建议您从一个干净的目录开始。将您的BNA移入该目录并将终端目录更改为该目录。
您需要拥有业务网络存档才能执行此操作,下面您可以看到一个示例tutorial-network
以及用于部署的“PeerAdmin”卡。
composer network install --card PeerAdmin@hlfv1 --archiveFile [email protected]
我们将使用该composer network start
命令启动业务网络,我们将需要使用我们的PeerAdmin
卡来完成此操作。我们还需要在我们的网络上创建用户,我们将使用“管理员”用户名和密码开始。
以下是使用tutorial-network
BNA 的示例。
composer network start --networkName tutorial-network --networkVersion 0.0.1 --networkAdmin admin --networkAdminEnrollSecret adminpw --card PeerAdmin@hlfv1
这将为业务网络创建一个“管理员”卡,在前面的例子中就是这样 [email protected]
请注意:admin
用户名和adminpw
密码是针对为开发者教程中部署的Hyperledger Fabric实例配置的特定Hyperledger Fabric标识。如果您已从头开始配置Hyperledger Fabric实例,则这些身份详细信息将有所不同。
接下来我们将采用我们刚刚制作的管理卡,并将其导入以用于您的业务网络。
composer card import --file [email protected]
导航到您的目录并运行该composer-rest-server
命令。
composer-rest-server
.card
扩展名。剩下的服务器将在http:// localhost:3000 / explorer上生成并可用
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调用来订阅来自业务网络的事件。事件在业务网络模型文件中定义,并由事务处理函数文件中的指定事务处理。有关发布事件的更多信息,请参阅发布事件。
在应用程序可以订阅事件之前,您必须已经定义了一些事件以及将发出它们的事务。业务网络也必须部署,并且您必须具有可连接到它的连接配置文件。
businessNetworkConnection.on('event', (event) => {
// event: { "$class": "org.namespace.BasicEvent", "eventId": "0000-0000-0000-000000#0" }
console.log(event);
});
这包括BasicEvent
在发布事件文档中创建的一个事件。该eventId
属性总是transactionId
与发送事件的事务相同,并在表单中附加一个数字"transactionId": "
。