Hyperledger-Fabric · 2018年2月3日 1

Hyperledger-Fabric安装开发部署(四)NodeJs-SDK

简介

  • 开发我们的区块链对外的API接口,实现之前我们在Cli中进行的查询数据、插入数据、查询区块信息、查询交易信息、安装链码等等,将这些操作统一写成对外开放的RUSTful Web API。
  • 本篇内容介绍的相关代码可能需要了解很多Nodejs相关的知识,还有许多NPM中的插件框架;诸如express、log4j、express-jwt等等。

官方英文版教程:
http://hyperledger-fabric.readthedocs.io/en/latest/index.html

官方Nodejs-SDK教程:
https://fabric-sdk-node.github.io/


1. 开发环境及配置准备

环境准备比较简单,这里只做简单的描述。

1.1 开发、IDE等环境

  • 这里我们的开发环境是Windows。确保Windows下安装了Nodejs、NPM。
  • 使用VS Code开发。
  • 在此篇中我们需要讲解的是: https://github.com/hyperledger/fabric-samples主要详解其中balance-transfer部分。无论直接下载Zip或者Git下载都可以。
    (这个项目质量相对较低,但是比没有的好;代码也不是很规范,各种NPM包版本也较低,实际开发应该替换)
  • 在项目目录下执行NPM Install,将所有引用的NPM包下载到项目中。
    (其中grpc包可能下载慢或者失败,可以尝试-g全局下载,然后复制进项目中;如果失败的很多建议在云服务器中下载完成复制到本地开发环境;可能还需要下载Python 2.7)

1.2 区块链网络配置

区块链网络使用e2e例子中生成的网络,需要做一个简单的修改,如下:
(默认的网络配置中没有ca节点,我们需要在原来的基础上添加一个ca节点;e2e的配置中已经有了对应的配置文件)

首先清理之前生成的e2e网络:

$ cd /opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli
$ ./network_setup.sh down

等待清理完成,检查docker容器都被清理成功。

$ docker ps

打开'/opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli/network_setup.sh'

UP_DOWN="$1"
CH_NAME="$2"
CLI_TIMEOUT="$3"
IF_COUCHDB="$4"

: ${CLI_TIMEOUT:="10000"}

COMPOSE_FILE=docker-compose-cli.yaml
COMPOSE_FILE_COUCH=docker-compose-couch.yaml
#COMPOSE_FILE=docker-compose-e2e.yaml
....
....

我的需要的ca节点的配置其实在'docker-compose-e2e.yaml'文件中,只是这里将其注释掉了,换一下就好,修改后如下:

....
....
#COMPOSE_FILE=docker-compose-cli.yaml
COMPOSE_FILE_COUCH=docker-compose-couch.yaml
COMPOSE_FILE=docker-compose-e2e.yaml
....
....

再打开'docker-compose-cli.yaml',将文件末尾的如下内容复制到'docker-compose-e2e-template.yaml'文件的结尾。

  cli:
    container_name: cli
    image: hyperledger/fabric-tools
    tty: true
    environment:
      - GOPATH=/opt/gopath
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - CORE_LOGGING_LEVEL=DEBUG
      - CORE_PEER_ID=cli
      - CORE_PEER_ADDRESS=peer0.org1.example.com:7051
      - CORE_PEER_LOCALMSPID=Org1MSP
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
      - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key
      - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
      - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; sleep $TIMEOUT'
    volumes:
        - /var/run/:/host/var/run/
        - ../chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go
        - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
        - ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
        - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
    depends_on:
      - orderer.example.com
      - peer0.org1.example.com
      - peer1.org1.example.com
      - peer0.org2.example.com
      - peer1.org2.example.com

注意:最好复制自己'docker-compose-cli.yaml'文件的中的对应内容,由于源码版本问题,可能会不一致。

这里有一个奇怪的地方,我们代码中执行的是'docker-compose-e2e.yaml',然而我们却在修改'docker-compose-e2e-template.yaml'。
其实在e2e这个目录下'docker-compose-e2e-template.yaml'与'docker-compose-e2e.yaml'这两个文件,在执行的过程中将前一个文件完全复制替换到第二个文件,所以修改'docker-compose-e2e.yaml'是无效的

这里其实是在我们新的网络中加入了cli节点。如果不加后边生成网络会报错,为了简单一点直接加入cli节点就OK了。

最后重新生成e2e网络:

$ cd /opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli
$ ./network_setup.sh up

1.3 项目配置

首先打开"/balance-transfer/config.js"

var util = require('util');
var path = require('path');
var hfc = require('fabric-client');

var file = 'network-config%s.json';

var env = process.env.TARGET_NETWORK;
if (env)
    file = util.format(file, '-' + env);
else
    file = util.format(file, '');

hfc.addConfigFile(path.join(__dirname, 'app', file));
hfc.addConfigFile(path.join(__dirname, 'config.json'));

这里的重点是加载了区块链网络配置文件'network-config%s.json';所有的区块链网络配置都将从这里读取,后续会有很多地方从这里读取peer、org等等信息;
当前web-API的配置在'config.json'。


打开"/balance-transfer/network-config.json"
以下是我修改过后的内容:

{
    "network-config": {
        "orderer": {
            "url": "grpcs://193.112.13.226:7050",
            "server-hostname": "orderer.example.com",
            "tls_cacerts": "../artifacts/channel/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt"
        },
        "org1": {
            "name": "peerOrg1",
            "mspid": "Org1MSP",
            "ca": "https://193.112.13.226:7054",
            "peers": {
                "peer1": {
                    "requests": "grpcs://193.112.13.226:7051",
                    "events": "grpcs://193.112.13.226:7053",
                    "server-hostname": "peer0.org1.example.com",
                    "tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt"
                },
                "peer2": {
                    "requests": "grpcs://193.112.13.226:8051",
                    "events": "grpcs://193.112.13.226:8053",
                    "server-hostname": "peer1.org1.example.com",
                    "tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt"
                }
            },
            "admin": {
                "key": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore",
                "cert": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts"
            }
        },
        "org2": {
            "name": "peerOrg2",
            "mspid": "Org2MSP",
            "ca": "https://193.112.13.226:8054",
            "peers": {
                "peer1": {
                    "requests": "grpcs://193.112.13.226:9051",
                    "events": "grpcs://193.112.13.226:9053",
                    "server-hostname": "peer0.org2.example.com",
                    "tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt"
                },
                "peer2": {
                    "requests": "grpcs://193.112.13.226:10051",
                    "events": "grpcs://193.112.13.226:10053",
                    "server-hostname": "peer1.org2.example.com",
                    "tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt"
                }
            },
            "admin": {
                "key": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/keystore",
                "cert": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/signcerts"
            }
        }
    }
}

e2e环境中:
e2e端口、节点、组织等参照对象:
'/opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli/base/docker-compose-base.yaml'
'/opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli/docker-compose-e2e.yaml'
把对应的端口、节点、组织等信息对应修改。

e2e的证书路径:
'/opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli/crypto-config'
将此路径文件全部复制到自己项目如下的路径中:
'fabric-samples\balance-transfer\artifacts\channel\crypto-config'

非e2e环境:
其他环境中基本上每一个节点都需要修改,针对自己的网络配置修改对应的地址、路径、信息等。一定要和自己生成的网络对应。以及证书路径等等,全完按照新的网络修改。

其次以上端口信息可以用如下命令查看

$ docker ps

里边有节点对应的端口映射,方便修改上述配置。


在"/balance-transfer/config.json"中默认端口4000,由于个人本地需求改为了5010。其他配置项目暂时无需修改。

2. 测试运行

确保在VScode中F5可以运行不报错。
由于这个项目中没有界面,我们需要一个post/get工具来测试。这里推荐的是谷歌浏览器插件Restlet Client。对此工具其他文章会有详细的介绍。


F5调试项目,确保无误,在浏览器中打开'http://localhost:5010/channels'

你会发先这样一个报错'No authorization token was found'。
这个报错的原因在于这个项目默认使用了Json Web Token(简称JWT,一个轻量级的认证规范)
所以直接打开是不可以的,需要在请求头里加入签名。

这里使用Restlet Client进行post

请求是成功的;并且返回了一些数据。
其中token就是刚才提到的请求头缺少的内容,在请求头中加入Authorization,值使用刚才得到的字符串,并加上前缀Bearer ;
让我们再试一次:

至此我们的Nodejs API接口已经调用成功了。
在app.js中可以看到其他接口的访问方式,大家可以逐个尝试。

在testAPIs.sh脚本中有写好的调用示例,可以参考。

3. 部署Nodejs

Nodejs运行在V8引擎下,是以单线程的方式运行的,因此在多核心处理器的系统中并不能发挥其最大的性能。所以就需要一个应用管理器帮我们解决这个问题,否则就需要大量的时间写相关的代码。

这里推荐使用pm2(Node应用的进程管理器);实际上pm2就是一个npm包,官方的教程如下:
(最常见的线上部署nodejs项目的有forever,pm2)
https://www.npmjs.com/package/pm2
http://pm2.keymetrics.io/

pm2有非常灵活的配置,带有负载均衡(Node cluster 集群模块)功能,提供 HTTP API、远程控制和实时的接口 API ( Nodejs 模块,允许和 PM2 进程管理器交互 )等很多特性。
网上有众多相关教程与介绍,不再赘述。


下一篇将详细的分析balance-transfer中的代码,重点在各个接口所使用的Fabric-SDK代码

.
.
.
.
.
.
.
.
【本文章出自NM1024.com,转载请注明作者出处。】






>>转载请注明原文链接地址:Hyperledger-Fabric安装开发部署(四)NodeJs-SDK