区块链100讲:Hyperledger Composer及其开发流程

image

本期区块链100讲,我们将了解Hyperledger Composer的组件,以及内部设计。然后通过一个示例看Composer如何将一个区块链应用抽象成若干概念并将这些概念体现在开发流程中。

1

Composer架构介绍

首先我们先看一下官方网站放出的一张示意图:

image
Composer-Diagram.png

很明显可以看出,Hyperledger对这个项目的定位是Fabric的上层,由Composer创建出Model File(.cto文件), Script File(.js文件), ACL(.acl文件), Query File(.qry文件)等等,进行打包成一个商业网络文件(.bna文件),发布到Fabric网络中。

它的作用很明显,就是加快Fabric项目的开发和部署的一个官方工具。在使用前需要先对商业模型进行快速建模。比如一个买卖房屋的商业模型如下:

  • Assets(资产): 房屋清单

  • Participants(参与者): 购买人和屋主

  • Transactions(交易过程): 完成买卖房屋,结算清单

参与者可以访问交易数据,但是受限于他们的角色。房屋中介可以创建一个应用程序,为买卖双方提供一个简单的用户接口,看到交易的过程。商业网络也可以集成已有的库存系统,完成房屋资产的转移。另外其他相关的角色都可以注册加入到这个网络成为参与者,比如土地局可能会参与到交易中,完成土地所有权转移。

2

Composer关键概念

Composer是一个编程模型,包含一种建模语言,以及一组API,用于快速建网和应用程序,允许参与者发起交易,转移资产(Assets)。

Composer提供了两套组件,一个基于浏览器的UI Playgroud,用于演示和展示本地Fabric网络。此外还提供一套开发工具集,为开发者提供便利的开发框架。

Blockchain State Storage

这里就是区块链的概念了,交易历史和资产都会直接保存在区块链上,用区块链做存储。

Connection Profiles

就是一组JSON配置文件,Composer通过这组被称为Connection Profiles配置文件,定义了应该连接到哪个系统上。Connection Profile通常需要由系统创建者提供,定义了各种网络连接参数。

Assets

这里的资产(Assets)可以指代任何有型的和无形的资产,可以上链的一切可交易的商品,都可以作为资产。

Assets必须有唯一标识符,此外,还可以添加一些额外的信息,用于关联其他资产或者参与者等等。

Participants

参与者(Participants)是商业网络的成员,可以拥有资产或发起交易。参与者也是模型化的,跟资产一样,必须有唯一的标识符,此外也可以包含其他可选属性。一个参与者可以有一个或多个身份。

Identities

对应Fabric的PKI认证的概念,通过密钥确认用户身份的。

Business Network cards

Business Network cards就是一个Identitie,一个connection profile,以及元数据的组合,元数据包含一个可选的连接到商业网络名称。Business Network cards简化了连接商业网络的过程。

Transactions

交易,可以抽象为资产转移的过程。

Queries

查询返回的是区块链当中的数据。只需要定义好商业网络,以及相关的变量,就可以轻松的利用Composer API从区块链网络中提取所需数据。

Events

事件是在商业网络中定义的,就跟定义资产或参与者同样的方式。定义事件之后,就可以通过交易处理函数触发。应用程序可以通过composer-client API订阅这些事件。

Access Control

商业网络可以包含一组访问控制规则。访问控制规则允许细粒度控制什么角色在什么条件下有什么样的权限控制什么资产。

Historian registry

historian是专门用于成功交易记录的,包含了发起交易的参与者和身份信息。historian将交易保存为HistorianRecord资产,定义在 Composer系统的namespace中。

到这里我们总结了Composer的一些基础概念,这些概念将用于Composer的开发过程中。接下来进一步介绍Composer的大致工作流,用Composer开发的时候是一个怎样的流程。

3

Composer开发体系架构

照例先放出一张官网的示意图:

image
ComposerArchitecture.png

可以发现相比直接使用Fabric,已经减少了大量的工作。可以通过generator-hyperledger-composer生成Angular的应用,然后通过Hyperledger Composer的SDK部署并运行在Fabric网络环境中。

整个Composer由以下组件构成:

  • 执行环境

  • JavaScript SDK

  • 命令行接口

  • REST Server

  • LoopBack连接器

  • Playground Web UI

  • Yeoman代码生成器

  • VSCode和Atom编辑器插件

4

执行环境

Hyperledger Composer设计支持多种可插拔的运行环境,目前已经实现了三种运行环境:

  • Hyperledger Fabric v1.1. State存储在分布式账本

  • Web. 直接在Web内部执行,用于Playground演示。State存储在浏览器的local storage中

  • 内嵌环境。直接在Node.js进程内部执行,主要用于商业逻辑的单元测试。State以KV形式存储在内存中。

5

Connection Profiles

Connection Profiles用于指明Composer如何连接到一个执行环境的。每一种执行环境都有不同的配置选项。

JavaScript SDK

这是一组Node.js API,给开发者提供创建应用操控和部署Business Network。这些API分成两个npm模块:

  • compser-client: 提交交易请求到business network,以及对资产和参与者执行的CURD操作

  • composer-admin: 用于管理business network,安装、启动、升级等

命令行接口

composer命令行工具提供部署和管理business network的功能

REST Server

Hyperledger Composer REST Server会自动为business network创建一个Open API(利用Swagger) REST接口。REST Server(基于LoopBack技术)将Composer模型转换为Open API的定义,并且实现CURD支持。

LoopBack连接器

Hyperledger Composer LoopBack连接器可以被REST Server使用,也可以通过支持LoopBack的集成工具单独使用。当然也可以通过LoopBack工具创建一个更复杂的自定义REST API。

Playground Web User Interface

这玩意用于定义和测试business network的。可以让商业分析人在Web上快速导入样本和商业逻辑模型。

Yeoman代码生成器

创建以下工程的脚手架:

  • Angular web application

  • Node.js application

  • business network的脚手架

VSCode和Atom编辑器插件

尽管没有直接的IDE支持,但是这个插件可以替代一些IDE功能。

6

第一个Composer应用

基本概念介绍完毕之后,让我们动手创建和部署一个应用试试看。

第一步: 创建一个business network结构

Hyperledger Composer的一个关键构成就是business network definition (BND),BND为区块链定义了数据模型,交易逻辑和访问控制规则。

最简单的方式是直接通过Yeoman创建一个脚手架business network工程:

$ yo hyperledger-composer:businessnetwork

Welcome to the business network generator

? Business network name: tutorial-network

? Description: Here is a hello world example

? Author name:  Feng Yu

? Author email: abcfy2@163.com

? License: Apache-2.0

? Namespace: org.example.mynetwork

? Do you want to generate an empty template network? No: generate a populated sample network

   create package.json

   create README.md

   create models/org.example.mynetwork.cto

   create permissions.acl

   create .eslintrc.yml

   create features/sample.feature

   create features/support/index.js

   create test/logic.js

   create lib/logic.js

在一系列交互式询问之后,我们就创建了一个business network应用程序。

第二步: 定义一个business network

一个business network是由资产、参与者、交易、访问控制规则,以及可选的时间和查询组成的。在之前创建的脚手架工程中,已经有一个model(.cto)文件了,包含了定义了在business network中存在的所有资产、参与者、交易。这个工程同样也包含了一个访问控制规则(permissions.acl),一个包含了交易过程的函数脚本(logic.js),package.json包含了business network的元数据。

模型化资产、参与者以及交易

模型文件(.cto)是由Hyperledger Composer Modelling Language编写的,我们直接编辑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

}

添加JavaScript交易逻辑代码。model中用transaction声明的Trade,指明了一个交易和参与者之间的关系。后面需要定义具体的逻辑实现。编辑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);

}

添加访问控制permission.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

}

第三步: 打包business network

在tutorial-network/目录下执行以下命令:

$ composer archive create -t dir -n .

Creating Business Network Archive

Looking for package.json of Business Network Definition

        Input directory: /home/vagrant/tutorial-network

Found:

        Description: Here is a hello world example

       Name: tutorial-network

        Identifier: tutorial-network@0.0.1

Written Business Network Definition Archive file to

        Output file: tutorial-network@0.0.1.bna

Command succeeded

整个工程被打包成了.bna文件。

第四步: 部署business network

需要按照安装Composer的文档,将docker环境启动(./startFabric.sh),然后部署:

$ composer network install --card PeerAdmin@hlfv1 --archiveFile tutorial-network@0.0.1.bna

✔ Installing business network. This may take a minute...

Successfully installed business network tutorial-network, version 0.0.1

Command succeeded

之后就可以运行了:

composer network start --networkName tutorial-network --networkVersion 0.0.1 --networkAdmin admin --networkAdminEnrollSecret adminpw --card PeerAdmin@hlfv1 --file networkadmin.card

Starting business network tutorial-network at version 0.0.1

Processing these Network Admins:

        userName: admin

✔ Starting business network definition. This may take a minute...

Successfully created business network card:

        Filename: networkadmin.card

Command succeeded

然后导入网络管理员身份作为可用的business network card:

$ composer card import --file networkadmin.card

Successfully imported business network card

        Card file: networkadmin.card

        Card name: admin@tutorial-network

Command succeeded

检查已部署的网络可以用以下命令:

$ composer network ping --card admin@tutorial-network

The connection to the network was successfully tested: tutorial-network

        Business network version: 0.0.1

        Composer runtime version: 0.19.7

        participant:org.hyperledger.composer.system.NetworkAdmin#admin

        identity:org.hyperledger.composer.system.Identity#67624c0918f6ae837d7d3b90e7df8dc305b0cb4e412cc8d4265fbf4f72823600

Command succeeded

第五步: 生成一个REST server

$ composer-rest-server

? Enter the name of the business network card to use: admin@tutorial-network

? Specify if you want namespaces in the generated REST API: never use namespaces

? Specify if you want to use an API key to secure the REST API: No

? Specify if you want to enable authentication for the REST API using Passport: Yes

? Specify if you want to enable multiple user and identity management using wallets: 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@tutorial-network -n never -a true -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

第六步: 生成应用程序

$ 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: angular-app? Description: Hyperledger Composer Angular project

? Author name: Feng Yu

? Author email: abcfy2@163.com

? 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!

Completed generation process

   create app.js

   create Dockerfile

   create e2e/app.e2e-spec.ts

   create e2e/app.po.ts

   create e2e/tsconfig.e2e.json

   create e2e/tsconfig.json

   create karma.conf.js

   create manifest.yml

   create package.json

   create protractor.conf.js

   create proxy.conf.js

   create README.md

   create src/app/app-routing.module.ts

   create src/app/app.component.css

   create src/app/app.component.html

   create src/app/app.component.spec.ts

   create src/app/app.component.ts

   create src/app/app.module.ts

   create src/app/asset/images/delete_noun_cc.svg

   create src/app/asset/images/edit_noun_cc.svg

   create src/app/asset/images/failed_noun_cc.svg

   create src/app/asset/images/success_noun_cc.svg

   create src/app/data.service.ts

   create src/app/home/home.component.css

   create src/app/home/home.component.html

   create src/app/home/home.component.ts

   create src/environments/environment.prod.ts

   create src/environments/environment.ts

   create src/favicon.ico

   create src/index.html

   create src/main.ts

   create src/polyfills.ts

   create src/styles.css

   create src/test.ts

   create src/tsconfig.app.json

   create src/tsconfig.json

   create src/tsconfig.spec.json

   create tsconfig.json

   create tslint.json

   create .angular-cli.json

   create .editorconfig

   create .gitignore

   create .dockerignore

   create .cfignore

   create .npmignore

   create src/app/Commodity/Commodity.component.ts   

create src/app/Commodity/Commodity.service.ts

   create src/app/Commodity/Commodity.component.spec.ts  

 create src/app/Commodity/Commodity.component.html   

create src/app/Commodity/Commodity.component.css   

create src/app/Trader/Trader.component.ts

   create src/app/Trader/Trader.service.ts

   create src/app/Trader/Trader.component.spec.ts

   create src/app/Trader/Trader.component.html

   create src/app/Trader/Trader.component.css

   create src/app/Trade/Trade.component.ts

   create src/app/Trade/Trade.service.ts

   create src/app/Trade/Trade.component.spec.ts

   create src/app/Trade/Trade.component.html

   create src/app/Trade/Trade.component.css

I'm all done. Running npm install for you to install the required dependencies. If this fails, try running the command yourself.

最后在angular工程下运行

npm start

最后用http://localhost:4200即可访问应用。

本篇文档大致展示了一下使用composer通过快速脚手架生成工程代码,快速部署Fabric应用。总体来说Composer开发体验比直接使用Fabric API的体验太好了。在大致了解Fabric的文档之后,开发者完全可以通过Composer上手开发应用,而不需要对接非常底层的Fabric。

本文作者:HiBlock区块链技术布道群-冯宇Ops

原文发布于简书

加微信baobaotalk_com,加入技术布道群

线上课程推荐

image

线下活动推荐

技术工坊|如何利用ERC875协议开发世界杯区块链门票?(北京)

技术工坊|理性思考区块链,数字货币与区块链的辩证对视(上海)

推荐阅读更多精彩内容