区块链 Hyperledger composer 发布商业环境(二)

1. 业务网络定义

业务网络定义是Hyperledger Composer编程模型的一个关键概念。它们由模块中BusinessNetworkDefinition定义表示,composer-common并由两者composer-admincomposer-client


业务网络定义由以下部分组成:

  • 一组模型文件
  • 一组JavaScript文件
  • 一个访问控制文件

模型文件定义了业务网络的业务领域,而JavaScript文件包含事务处理器功能。事务处理器功能在Hyperledger Fabric上运行,并可访问存储在Hyperledger Fabric区块链世界状态中的资产注册表。

模型文件通常由业务分析师创建,因为它们定义模型元素之间的结构和关系:资产,参与者和事务。

JavaScript文件通常由正在实施业务分析师提供的业务需求的开发人员创建。

访问控制文件包含一组访问控制规则,用于定义业务网络中不同参与者的权限。

一旦定义,可以使用composer命令行界面将业务网络定义打包到归档中然后可以使用模块中AdminConnection在Fabric上部署或更新这些存档composer-admin


2. 创建业务网络定义

业务网络定义具有以下布局:

Copy 复制
models/ (optional)
lib/
permissions.acl (optional)
package.json
README.md (optional)

创建新的业务网络定义的最简单方法是git clone示例,或者使用Hyperledger Composer Yeoman生成器来创建骨架业务网络。

README.md

使用Markdown标记语言描述商业网络的用途。

的package.json

业务网络定义有一个名称(仅限于基本的ASCII字母数字字符和-),一个可读的描述和一个版本号。网络的版本号应采用Major.Minor.Micro格式,并且 在增加版本号时应使用语义版本原则。

网络的标识符由其名称,-字符和版本号组成。因此有效的标识符(和示例)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目录下。

生成业务网络定义

  1. yo hyperledger-composer
Copy 复制
? Please select the type of project: (Use arrow keys)
❯ Angular
  Business Network
  Model

并选择 Business Netork

  1. 回答所有问题
Copy 复制
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

这产生了骨架业务网络与assetparticipanttransaction定义,以及一个mocha单元测试。

还包括,是一个'最佳实践'eslint配置文件,它定义了JS代码的示例linting规则。



3. 部署商业网络

在部署业务网络定义之前,必须将其打包到业务网络存档(.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 upgradeCLI命令。

将业务网络部署到Hyperledger Fabric v1.1

在Hyperledger Fabric v1.1中,同行实施管理员和成员的概念。管理员有权将新建商业网络的Hyperledger Fabric链接代码安装到同行。会员没有安装链码的权限。为了将业务网络部署到一组对等方,您必须提供对所有这些对等方具有管理权限的标识。

要使该身份及其证书可用,您必须使用与对等管理员标识关联的证书和私钥创建对等管理业务网卡。Hyperledger Composer提供了一个示例Hyperledger Fabric v1.1网络。该网络的对等管理员被调用PeerAdmin,并且当您使用示例脚本启动网络时,会自动为您导入标识。请注意,对等管理员可能会被赋予其他Hyperledger Fabric网络的不同名称。

重要提示:在将业务网络部署到Hyperledger Fabric v1.1时,在Hyperledger Fabric认证中心(CA)配置中定义了引导注册器。Hyperledger Composer开发环境包含Hyperledger Fabric的预配置实例,其中包含特定注册ID和引导注册器的注册机密。

业务网络管理员

在部署业务网络时,按照业务网络定义中指定的访问控制规则强制实施访问控制。每个业务网络必须至少有一个参与者,并且该参与者必须具有访问业务网络的有效标识。否则,客户端应用程序无法与业务网络进行交互。

业务网络管理员是负责在部署业务网络后为其组织配置业务网络的参与者,并负责为其组织中的其他参与者加入。由于业务网络包括多个组织,因此任何特定业务网络都应有多个业务网络管理员。

org.hyperledger.composer.system.NetworkAdminHyperledger 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.1时,作为部署过程的一部分,您必须选择如何为初始业务网络参与者提供凭据。初始参与者将是NetworkAdmin

使用操场部署商业网络时,系统会提示您输入初始参与者的凭证。可以提供证书作为证书或作为预先定义的注册ID和注册机密。如果您使用Hyperledger Composer开发环境中设置的Hyperledger Fabric实例,则引导注册器注册ID是admin引导注册器注册秘密adminpw此初始参与者使用Hyperledger Fabric认证中心(CA)中的启动注册器所设置的凭据,并将成为NetworkAdmin

在本地部署使用Playground的业务网络时,您必须至少拥有一个具有PeerAdmin角色的业务网卡和至少一个具有该ChannelAdmin角色的业务网卡每个这些业务网卡都必须包含正确的管理员证书。

4. 发射事件

事件可由Hyperledger Composer发出并由外部应用程序订阅。事件在业务网络定义的模型文件中定义,并由事务处理函数文件中的事务JavaScript发出。

在你开始之前

在开始将事件添加到业务网络之前,您应该对业务网络的建模语言以及构成完整业务网络定义的内容有很好的理解。

程序

  1. 事件在.cto业务网络定义的模型文件()中定义,与资产和参与者相同。事件使用以下格式:

    Copy 复制
    event BasicEvent {
    }
    
  2. 为了发布事件,创建事件的事务必须调用三个函数,第一个getFactory函数。getFactory允许作为交易的一部分被创建的事件。接下来,必须使用创建事件factory.newEvent('org.namespace', 'BasicEvent')这会BasicEvent在指定的名称空间中创建一个定义。然后必须设置事件所需的属性。最后,该事件必须通过使用发射emit(BasicEvent)调用此事件的简单事务将如下所示:

    Copy 复制
    /**
     * @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文档


5. 测试业务网络

Hyperledger Composer支持三种类型的测试:交互式测试,自动化单元测试和自动系统测试。三者都有不同的用途,对确保区块链项目的成功至关重要。

在部署了业务网络定义之后,通常运行一个互动的“冒烟测试”以确保部署成功。composerCLI公开运行这样冒烟测试的命令。

在另一端,您可以使用Docker Compose和Mocha / Chai编写完整的系统测试,这些测试启动运行时,部署您的业务网络定义,然后以编程方式创建资产,提交交易并检查资产注册状态。

单元测试专注于确保在处理交易时对世界状态进行正确的更改。

单元测试和系统测试的执行可以使用CI / CD构建流水线(例如Jenkins,Travis CI或Circle CI)或替代方法自动执行。

交互式测试

您可以使用Playground以交互方式测试创建参与者,资产和提交交易。

从命令行进行测试

命令行可用于检查运行时的状态并提交事务。使用该composer network list命令查看资产和参与者注册表的状态。使用该composer transaction submit命令提交事务。

创建单元测试

事务处理函数中的业务逻辑应该具有单元测试,理想情况下具有100%的代码覆盖率。这将确保您在业务逻辑中不存在拼写错误或逻辑错误。

您可以使用标准的JavaScript测试库(例如Mocha,Chai,Sinon和Istanbul)来单元测试事务处理器功能中的逻辑。

embedded运行时进行单元测试非常有用,因为它可以让你快速在一个模拟的Node.js blockchain环境中测试的业务逻辑,而不必站立一个Hyperledger面料。



6.发布模型或业务网络定义以供应用程序使用

Hyperledger Composer可以选择使用npm软件包管理器来发布业务网络和模型。通过将业务网络发布到npm需要引用业务网络的应用程序(例如对其进行反思或部署),可以在发布的npm上声明二进制包的依赖关系对商业网络使用npm软件包的语义版本还允许应用程序指定他们接受对商业网络不兼容的变更的容忍度。

npm软件包管理器是一个功能强大的(互联网规模)机制来分发任何二进制文件,并在一个表达元数据package.json文件。

同样,可以将一组Composer域模型(CTO文件)打包到一个npm包中进行发布。发布模型的能力允许模型在多个商业网络中重复使用(通过声明package.json依赖关系),并确保语义版本控制可用于控制模型本身的演变。

但是,发布到npm不需要使用Composer。您可以在应用程序中捆绑商业网络,并使用git等版本控制软件来管理其源文件。

发布模型或业务网络定义的最简单方法,供应用程序使用它来将业务网络定义推送到npm使用该npm publish命令程序包管理器这将允许希望使用业务网络定义的应用程序(例如通过API部署它)将业务网络定义引用为其package.json文件中的依赖项



7.升级部署的业务网络

业务网络成功部署到区块链后,可能需要升级业务网络定义。要升级业务网络定义,请首先将希望部署到本地业务网络组件文件副本(模型,脚本,查询,访问控制和事务处理器文件)的更新进行更新,然后更新本地业务网络的版本文件。更新版本后,将新版本的版本安装.bna到您的区块链中,并使用该composer network upgrade命令切换为使用新版本。

在你开始之前

在升级部署的业务网络定义之前:

  • 确保您的业务网络已成功部署。
  • 对您希望部署的商业网络进行必要的更新。

第一步:更新商业网络版本

package.json在将新版商业网络安装到您的区块链之前更新文件非常重要

  1. package.json在您的商业网络目录中打开该文件。

  2. 更新版本属性。版本属性必须是.分隔的数字,例如0.0.21.16.4请务必记下您设置的版本号,因为它是以下步骤所需的版本号。

第二步:打包你的商业网络

更新版本号后,业务网络必须打包到业务网络存档(.bna)中。然后.bna可以将其安装在区块链上并启动。composer archive create命令可以打包一个目录或一个npm模块,在这个例子中我们将使用目录命令。

  1. 从您的业务网络目录运行composer archive create命令:

    Copy 复制
    composer archive create -t dir -n .
    

第三步:安装新的业务网络

当业务网络已经打包时,它必须安装到区块链中。它使用与原始业务网络安装时相同的过程进行安装。

  1. 使用以下命令将业务网络安装到您的区块链中:

    Copy 复制
    composer network install -a NETWORK-FILENAME.bna -c peeradmin@hlfv1
    

    该命令中使用的商业网卡必须是对等管理卡才能将商业网络安装到区块链对等方。

第四步:升级到新的业务网络

现在业务网络已经安装到同行,它必须启动。composer network upgrade命令将指示对等方停止使用旧版本的业务网络,并开始使用该命令中指定的版本。

  1. 升级到使用以下命令安装的业务网络:

    Copy 复制
    composer network upgrade -c peeradmin@hlfv1 -n NETWORK-NAME -V NETWORK-VERSION
    

    网络名称和网络版本必须与package.json已安装的业务网络中的内容相匹配



8. 查询和过滤商业网络数据

查询用于返回有关区块链世界状态的数据; 例如,您可以编写一个查询来返回指定时间内的所有驱动程序,或具有特定名称的所有驱动程序。composer-rest-server组件通过生成的REST API公开命名查询。

查询是业务网络定义的可选组件,用单个查询文件(queries.qry编写

注意:使用Hyperledger Fabric v1.1时,Hyperledger Fabric必须配置为使用CouchDB持久性。

过滤器与查询类似,但使用LoopBack过滤器语法,并且只能使用Hyperledger Composer REST API进行发送。目前只WHERE支持LoopBack过滤器。其中支持的操作符WHERE是:=gtgteltlteneq使用GET针对资产类型,参与者类型或交易类型调用来提交过滤器; 该过滤器将作为参数提供。筛选器将返回指定类的结果,并且不会返回扩展指定类的类的结果。

查询类型

Hyperledger Composer支持两种类型的查询:命名查询和动态查询。命名查询在业务网络定义中指定,并由composer-rest-server组件公开为GET方法。动态查询可以在交易处理器功能中的运行时动态构建,也可以从客户端代码动态构建。

编写命名查询

查询必须包含说明和声明。查询描述是一个描述查询功能的字符串。查询语句包含控制查询行为的操作符和函数。

查询描述可以是任何描述性字符串。查询语句必须包括SELECT运营商,可以选择包括FROMWHEREANDORDER BYSKIP,和LIMIT

查询应采用以下格式:

Copy 复制
query Q1{
  description: "Select all drivers older than 65."
  statement:
      SELECT org.example.Driver
          WHERE (age>65)
}
查询参数

查询可以使用_$语法嵌入参数请注意,查询参数必须是基元类型(字符串,整数,双精度,长整数,布尔值,日期时间),关系或枚举。

下面的命名查询是根据3个参数定义的:

Copy 复制
query Q18 {
    description: "Select all drivers aged older than PARAM"
    statement:
        SELECT org.example.Driver
            WHERE (_$ageParam < age)
                ORDER BY [lastName DESC, firstName DESC]
                    LIMIT _$limitParam
                        SKIP _$skipParam
}

查询参数通过由composer-rest-server为命名查询创建的GET方法自动公开。

有关Hyperledger Composer查询语言的详细信息,请参阅查询语言参考文档

使用API​​进行查询

查询可以通过调用buildQuery查询 API 来调用所述BuildQuery对于 API需要指定作为API输入的一部分的整个查询字符串。查询 API需要你指定要运行查询的名称。

有关查询API的更多信息,请参阅API文档

查询访问控制

在返回查询结果时,您的访问控制规则将应用于结果。当前用户无权查看的任何内容将从结果中删除。

例如,如果当前用户发送将返回所有资产的查询,但如果他们只有权查看有限的资产选择,则查询将仅返回该有限的一组资产。

使用过滤器

过滤器只能使用Hyperledger Composer REST API提交,并且必须使用LoopBack语法要提交查询,必须针对资产类型,参与者类型或交易类型提交GET REST调用,并将过滤器作为参数提供。支持的要过滤参数的数据类型是数字布尔值日期时间字符串基本过滤器采用以下格式,其中op表示操作员:

Copy 复制
{"where": {"field1": {"op":"value1"}}}

请注意:只有顶级WHERE操作员可以有两个以上的操作数。

目前只WHERE支持LoopBack过滤器。其中支持的操作符WHERE是:=gtgteltlteneq过滤器可以组合多个运算符,在下面的示例中,运算符嵌套在or运算符中。

Copy 复制
{"where":{"or":[{"and":[{"field1":"foo"},{"field2":"bar"}]},{"field3":"foobar"}]}}

之间操作者返回给定的范围之间的值。它接受数字,日期时间值和字符串。如果提供了字符串,则between运算符会按字母顺序返回提供的字符串之间的结果。在下面的示例中,过滤器将返回ac之间的驱动程序属性按字母顺序排列的所有资源

Copy 复制
{"where":{"driver":{"between": ["a","c"]}}}



9. 程序化访问控制

建议您使用声明性访问控制来实现业务网络定义中的访问控制规则。但是,您可以通过检索和测试当前参与者或当前身份来在事务处理器中实施编程访问控制。您可以针对当前参与者的属性或当前身份运行测试,以允许或拒绝交易处理器功能的执行。

交易处理器功能可以调用getCurrentParticipant函数来获取当前参与者:

Copy 复制
let currentParticipant = getCurrentParticipant();

当前参与者是来自业务网络定义的建模参与者的实例或系统类型的实例org.hyperledger.composer.system.NetworkAdmin

事务处理函数可以调用getCurrentIdentity函数来获取当前标识:

Copy 复制
let currentIdentity = getCurrentIdentity();

当前身份是系统类型的一个实例org.hyperledger.composer.system.Identity,它表示部署的业务网络中的身份。

在你开始之前

在您执行这些步骤之前,您必须将参与者建模为业务网络定义并将其部署为业务网络。您必须创建了这些参与者的一些实例,并向这些参与者发布了身份。

下面的过程显示了使用以下参与者模型的示例:

Copy 复制
namespace net.biz.digitalPropertyNetwork

participant Person identified by personId {
  o String personId
  o String firstName
  o String lastName
}

participant PrivilegedPerson extends Person {

}

程序

  1. 在您的交易处理器功能中,使用以下getCurrentParticipant功能验证当前参与者的类型是否符合要求
Copy 复制
   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.
   }
  1. 在您的交易处理器功能中,使用以下getCurrentParticipant函数验证当前参与者的参与者ID
Copy 复制
   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与链接到资产的参与者(通过关系)进行比较,以验证当前参与者是否有权访问或修改资产:

Copy 复制
   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.
   }
  1. 在您的交易处理器功能中,使用以下getCurrentIdentity功能验证当前身份的证书是否符合要求
Copy 复制
   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.
   }

10 Hyperledger作曲家历史学家

Hyperledger Composer Historian是一个专门的注册机构,用于记录成功的交易,包括提交它们的参与者和身份。历史记录将事务存储为HistorianRecord资产,这些资产在Hyperledger Composer系统名称空间中定义。

历史记录注册表是Hyperledger Composer系统级实体。要将历史记录注册表作为访问控制的资源,必须将历史记录引用为:org.hyperledger.composer.system.HistorianRecord

请注意:所有参与者必须有权创建HistorianRecord资产。如果交易是由无权创建HistorianRecord资产的参与者提交的,则交易将失败。

HistorianRecord资产

历史记录注册表将成功的交易存储为HistorianRecord资产。只要事务成功完成,HistorianRecord资产就会创建并添加到历史记录注册表中。记录资产在系统名称空间中定义,并具有以下定义:

Copy 复制
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资产:

  • 添加,删除和更新资产
  • 添加,删除和更新参与者
  • 签发,绑定,激活和吊销身份
  • 更新业务网络定义

保护历史数据

作为一个注册表,可以使用访问控制规则来控制对历史数据的访问。但是,作为系统级实体,历史记录注册表的资源名称始终为org.hyperledger.composer.system.HistorianRecord

如果访问控制规则引用了他们提交的事务,则只允许成员查看历史数据。

Copy 复制
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属性的函数中

在历史数据库中使用客户端和REST API

HistorianRecord资产可以使用REST API system/historiansystem/historian/{id}使用REST API的调用返回

使用REST API时,GET调用system/historian将返回所有历史数据。此调用应谨慎使用,返回不受限制,并可能导致返回大量数据。

system/historian/{id}使用REST API的GET调用将返回HistorianRecord指定资产。

质疑史学家

历史学家可以像其他注册机构一样进行查询。例如,返回所有HistorianRecord资产的典型查询如下所示:

Copy 复制
    let historian = await businessNetworkConnection.getHistorian();
    let historianRecords = await historian.getAll();
    console.log(prettyoutput(historianRecords));

由于这是'getAll'调用,它可能会返回大量数据。因此,查询功能对于能够选择记录子集至关重要。一个典型的例子是根据时间选择记录。这使用查询功能来选择事务时间戳超过特定点的记录。返回的记录可以用相同的方式处理。

Copy 复制
  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});

可以使用更高级的查询; 例如,以下查询选择并返回“添加”,“更新”和“移除”资产系统事务。

Copy 复制
  // 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);


11. 定制卡片商店

默认卡存储是/home/username/.composer主机上的目录。对于在云环境中运行的应用程序,本地钱包可能会有问题,并且可能希望将卡存储在不同的目录位置。通过使用定制钱包,用户可以控制业务网卡以及用于Hyperledger Fabric认证的证书和私钥的存储位置。

建筑

每当一个BusinessNetworkConnectionAdminConnection制成,它具有关联CardStore每个连接都可以配置为使用特定的连接CardStore在Hyperledger Composer存储库中,存储有两个预先配置的选项:

  • composer-wallet-filesystem
  • composer-wallet-inmemory

自定义实现可以针对任何给定的后端数据库或对象存储区进行编写,从而可以CardStore指定非默认文件位置,单独的Docker容器或托管在基于云的数据存储区中。商店配置可以使用配置文件或使用环境变量来完成。

可以使用全局npm安装来安装多个云钱包实施。

有关编写新的云钱包实施的更多详细信息,请参阅以下自述文件

配置自定义钱包

有两种方法可以定义自定义钱包的.json配置:使用配置文件或定义环境变量。

请注意:任何定制的钱包实施都必须composer-wallet在模块名称中包含前缀。

使用配置文件

对于生产部署,能够在应用程序之外配置卡存储更为有用,Hyperledger Composer使用标准配置模块config配置文件从当前工作目录的子目录中调用config默认配置文件被调用default.json,配置文件名可以使用NODE_ENV环境变量进行更改

以下配置文件使用Redis格式作为示例:

Copy 复制
{
  "composer": {
    "wallet": {
      "type": "composer-wallet-redis",
      "desc": "Uses a local redis instance,
      "options": {

      }
    }
  }
}
  • type 是这个模块的名字
  • desc 是一些人类的文本

请注意:每个连接都会指定一个新的卡存储实例。如果这些解析到相同的后端存储,卡可以共享。

使用环境变量

可以通过设置一个包含与配置文件相同信息的环境变量来实现通过环境变量在命令行中指定定制钱包的细节。

以下环境变量示例使用与上述配置文件相同的格式和数据。

Copy 复制
export NODE_CONFIG={"composer":{"wallet":{"type":"composer-wallet-redis","desc":"Uses  a local redis instance,"options":{}}}}

任何在此shell中的应用程序都将使用云钱包。

配置文件系统自定义卡片存储

文件系统卡存储的位置可以通过指定storePath作为钱包选项之一的配置文件来更改

Copy 复制
{
  "composer": {
    "wallet" : {
        "type": "composer-wallet-filesystem",
        "options" : {
            "storePath" : "/my/network/location"
        }
    }
}

相同的.json片段可以作为环境变量导出。

配置基于云的自定义存储卡

以下GitHub存储库分别包含使用Redis和IBM Cloud Object Store的云定制钱包实现。

可以使用全局npm安装来安装多个云定制钱包实施。

有关编写基于云的新定制钱包实施的更多详细信息,请参阅以下自述文件

要迁移到Redis或IBM Cloud Object Store云定制钱包解决方案,请参阅相关GitHub存储库的自述文件。

从一般意义上讲,迁移到云钱包实施有三个步骤。

  1. 导出您希望在云定制钱包中使用的商业网卡。
  2. 更改配置以指定云定制钱包。
  3. 将业务网卡导入云定制钱包。

composer-wallet-filesystem是默认的存储卡,并且在光盘上遵循相同的布局,并且默认情况下位于同一位置。

一些样本和测试案例显示卡片商店是以编程方式创建的。这仍然是可能的,但在初始创建卡商店方面略有不同。

使用定制钱包和API

API CardStore配置

使用默认位置文件系统卡存储仍然是API调用中的默认选项。例如:

Copy 复制
        adminConnection = new AdminConnection();
        clientConnection = new BusinessNetworkConnection();

将在该位置使用文件系统卡存储/home/username/.composer,或者在NODE_CONFIG当且仅当在同一个shell实例内执行时指定在导出的自定义钱包中

要在API中指定自定义钱包,而不使用全局导出的值,则必须将其作为传递给连接的选项包括在内:

Copy 复制
        const connectionOptions = {
            wallet : {
                type: 'composer-wallet-filesystem',
                options : {
                    storePath :'/my/network/location'
                }
            }
        };
        adminConnection = new AdminConnection(connectionOptions);
        clientConnection = new BusinessNetworkConnection(connectionOptions);

在上面,钱包类型可以是新文件位置或者基于云的位置。

API MemoryCardStore配置

以前要使用MemoryCardStore中的代码将被写入

Copy 复制
        cardStore = new MemoryCardStore();
        const adminConnectionOptions = {
            cardStore : cardStore
        };
        adminConnection = new AdminConnection(adminConnectionOptions);
        // or more concisely
        clientConnection = new BusinessNetworkConnection({cardStore});

这现在已经改变了,卡商店现在必须有不同的指定:

Copy 复制
        const connectionOptions = {
            wallet : {
                type: 'composer-wallet-inmemory'
            }
        };
        adminConnection = new AdminConnection(connectionOptions);
        clientConnection = new BusinessNetworkConnection(connectionOptions);


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值