用正确的姿势开发Hyperledger Fabric系列Step By Step

计划要写一系列关于Hyperledger Fabric开发相关的技术文章,基于版本Fabric v1.2.0,面向有一定区块链开发基础的编程人员,侧重标准和规范方面,如果您有任何疑问、建议,欢迎通过公众号下方回复!这是系列的第四篇,这篇文章在之前推送过,是基于Fabric 1.0版本的Step By Step,在Fabric 1.0版本之后,开放上大体没有变化,所以再推送一次。

0x01.运行环境

OS: MacOS Sierra 10.12.4 (16E195)

Docker for Mac : Version 17.03.1-ce-mac12 (17661)

Go version: go version go1.8.1 darwin/amd64

Node version: v6.10.0

NPM version: 3.10.10

0x02.先看官方到sample例子运行步骤

参照 :https://github.com/hyperledger/fabric/blob/master/examples/e2e_cli/end-to-end.rst

1).下载fabric到Go Path目录下

cd $GOPATH/src/github.com/hyperledger

git clone https://github.com/hyperledger/fabric.git

2).生成configtxgen工具

cd $GOPATH/src/github.com/hyperledger/fabric

make configtxgen

3).制作docker镜像(从alpha1之后的某个commit开始需要make镜像)

cd $GOPATH/src/github.com/hyperledger/fabric

make docker

4).启动脚本

./network_setup.sh up my-channel-name

5).查看容器

注意这里修改了docker-compose.yaml文件,使得cli可以继续运行,206行增加了代码sleep 1000

6).进入CLI容器,通过peer命令可以看到peer 版本以及peer目录下生成的genesis block等信息

可以看到peer chaincode命令和0.6版本相比有了较大改变

7).查看chaincode运行结果

8).结束并清理

./network_setup.sh down my-channel-name

0x03.代码分析

script.sh

instantiate/invoke/query会生成chaincode container和image,dev-peer[x]-CHAINCODENAME-1.0

改写script.sh脚本,测试运行结果

测试delete entity

编写脚本执行example_02代码中,Deletes an entity from state代码段(这段代码在0.7版本中存在bug,无法真正删除实体A)

编写类似invoke类似脚本,执行删除操作,然后在query,提示结果

Error: Error endorsing query: rpc error: code = 2 desc = {"Error":"Nil amount for a"}

0x04.迁移0.6版本代码到1.0 alpha

这里将之前做过的(0.6版本的ticket的sample)chaincode代码迁移到fabric 1.0 alpha上

首先,将代码按照1.0的方式改写(主要是返回值的变化,以及error被封装),然后在compose文件中,用挂载的方式加载到容器中

其次,在脚本中,设置channel name、chaincode name以及chaincode path

然后,仿照e2e_cli执行example_02的例子,改写invoke、query,按照后面的说明测试,在后面分别执行脚本(invoke之间加上sleep,否则会出现后面8.3的错误,这个错误也被做为bug发现过 https://jira.hyperledger.org/browse/FAB-2822)

说明一下整个过程

设置5个peer节点(外加cli)和一个orderer节点的blockchain网络

创建channel(my-channel-name),使得peer0、peer1、peer2加入该channel,并把chaincode(my-chaincode-name)代码挂载到cli上

在peer1、peer2、peer3上install chaincode代码(peer3不在这个channel上,后面可以看到不会产生chaincode代码运行)

在peer1、peer2上instantiate chaincode(初始化)

生成新镜像dev-peer1-my-chaincode-name-1.0,dev-peer2-my-chaincode-name-1.0

查看chaincode的镜像logs,dev-peer1-my-chaincode-name-1.0,dev-peer2-my-chaincode-name-1.0都有init的记录,以及query的记录,dev-peer1-my-chaincode-name-1.0并没有invoke的操作记录,但是query的结果是相同的,整个过程在orderer节点得到共识并写入ledger

0x05.SDK

1.Node SDK

一般来说,一个Node开源项目,分为两种方式,一种就是直接提供完整的项目在github上,那么用户直接clone就可以使用了,另外一种是提供SDK,发布到npm上,习惯上也会针对这个npm发布一个repo在github上,二者基本上是同步的,大多包的名称和github上的地址也是一致的,github上的代码可能会稍稍新一些,github上一般会在readme里面就提供了接口的使用方法,同时也习惯上在根目录examples目录,是直接可以运行的示例,对用户来说清晰明了,而fabric 1.0 alpha对应的node sdk在github上的repo失去了这个意义。

fabric 1.0 alpha在github上的对应REPO,

https://github.com/hyperledger/fabric-sdk-node

在npm上对应的是fabric- client,以及fabric-ca-client,版本为1.0.0 alpha,

https://www.npmjs.com/package/fabric-client

https://github.com/hyperledger/fabric-sdk-node

github上的代码是一个项目工程,其中使用到了这两个SDK,而不是对fabric SDK的使用说明。

这里我们仅仅针对e2e的例子说明SDK的使用

1).克隆https://github.com/hyperledger/fabric-sdk-node到本地

2).将fabric-sdk-node/test/integration/e2e/中的e2e相关代码拷贝出来,构造成如下目录

3).执行npm install,然后将fabric-sdk-node目录下fabric-client和fabric-ca-client拷贝到node_modules下(实际上可以通过npm install的方式直接拉取npm上的两个包,但是代码比当前工程中的要旧一些,没有办法运行当前代码)

4).适当调整重新规划目录后的代码(有些文件在转移目录后调用目录层次会发生改变)

5).进入fixtures目录,然后执行 docker-compose -f docker-compose.yaml up

6).在根目录下执行node e2e.js

查看启动的容器以及chaincode log

将example_02的chaincode改成自己的chaincode工程,再调整对应的调用代码就可以运行自己的chaincode了

Alpha 2版本上,balance的example例子可以运行(之前一直都无法运行)

2.Go SDK

Go SDK官方例子比较简单

1).克隆https://github.com/hyperledger/fabric-sdk-go到本地$GOPATH/src/github.com/hyperledger目录下(不要更改目录)

2).分别进入fabric-client 和 fabric-ca-client 两个目录执行go test

3).进入fixtures目录,然后执行 docker-compose -f docker-compose.yaml up

4).在Node的SDK中,执行create-channel.js 两个 join-channel.js脚本

5).进入test/integration目录,执行go test

查看启动的容器以及chaincode log

0x06.Fabric CA的一些说明

1).安装依赖

sudo apt install libtool libltdl-dev

2).下载fabric-ca到Go Path目录下

git clone https://github.com/hyperledger/fabric-ca.git

3).安装fabric-ca server以及clien命令行

cd $GOPATH/src/github.com/hyperledger/fabric-ca

go get -u github.com/hyperledger/fabric-ca/cmd/...

4).CA server 与 client命令

fabric-ca-server init命令,会生成fabric-ca-server-config.yaml文件(可以根据参数设置文件位置),然后可以手动配置,start命令启动服务fabric-ca-client enroll命令,会生成fabric-ca-client-config.yaml文件(可以根据参数设置文件位置),然后可以手动配置,再执行其他操作

5).SQLite测试

Init并且start server(通过命令行以及docker形式都可以启动server),Ca默认是使用的DB是SQLite,所以这里不用改动ca server config文件

fabric-ca-server init -b admin:adminpw

fabric-ca-server start -b admin:adminpw

Enroll对应admin用户

fabric-ca-client enroll -u http://admin:adminpw@localhost:7054

对应需要修改client config文件,如下

注册一个新用户,然后查看SQLite数据库

fabric-ca-client register --id.name tanzhiguo

查看对应的server端监控

6).LDAP测试

LDAP环境不需要自己手动安装,make docker会自动产生hyperledger/openldap镜像,是以osixia/docker-openldap为基础的镜像,可以参考 https://github.com/osixia/docker-openldap

启动openldap容器,可以自己编写脚本,并且注册用户到LDAP,通过图形化工具可以查看到注册的jsmith用户

以jsmith用户身份Enroll

fabric-ca-client enroll -u http://jsmith:jsmithpw@localhost:7054

0x07.关于1.0架构方面

可以参考官方关于架构的proposal

http://hyperledger-fabric.readthedocs.io/en/latest/arch-deep-dive.html

中文有一篇文章写的也挺不错

Transaction workflow那个图片比较能说明问题,

在一些meetup中,架构方面的东西都反复被提到了,这里不再赘述。

0x08.问题

1.make configtxgen 报错

tams-MacBook-Pro:fabric tam$ make configtxgen

build/bin/configtxgen

CGO_CFLAGS=" " GOBIN=/Users/tam/Work/Go/src/github.com/hyperledger/fabric/build/bin go install -ldflags "-X github.com/hyperledger/fabric/common/metadata.Version=1.0.0-snapshot-22c1a1f -X github.com/hyperledger/fabric/common/metadata.BaseVersion=0.3.0 -X github.com/hyperledger/fabric/common/metadata.BaseDockerLabel=org.hyperledger.fabric" github.com/hyperledger/fabric/common/configtx/tool/configtxgen

# github.com/hyperledger/fabric/vendor/github.com/miekg/pkcs11

vendor/github.com/miekg/pkcs11/pkcs11.go:29:10: fatal error: 'ltdl.h' file not found

#include

^

1 error generated.

make: *** [build/bin/configtxgen] Error 2

或者类似错误,原因是没有安装libtool或者libtool有问题,重新安装(比如用port安装过可能也会有问题,用homebrew再安装一次就可以了)

2.Chaincode Install Error 错误

2017-03-20 08:27:56.969 UTC [logging] InitFromViper -> DEBU 001 Setting default logging level to DEBUG for command 'chaincode'

2017-03-20 08:27:56.977 UTC [msp] GetLocalMSP -> DEBU 002 Returning existing local MSP

2017-03-20 08:27:56.977 UTC [msp] GetDefaultSigningIdentity -> DEBU 003 Obtaining default signing identity

2017-03-20 08:27:56.984 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004 Using default escc

2017-03-20 08:27:56.984 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 005 Using default vscc

2017-03-20 08:27:56.985 UTC [msp] Sign -> DEBU 006 Sign: plaintext: 0A8F050A59080322096D796368616E6E...314D53500A04657363630A0476736363

2017-03-20 08:27:56.985 UTC [msp] Sign -> DEBU 007 Sign: digest: 7B9D9A0F1F2F1819717379314CA59615B39B6A22C1A296CC1AE0519834EE6E12

Error: Error endorsing chaincode: rpc error: code = 2 desc = Error starting container: Get https://registry-1.docker.io/v2/hyperledger/fabric-baseos/manifests/x86_64-0.3.0: EOF

这个错误偶尔发生,原因未知,下拉镜像hyperledger/fabric-baseos:x86_64-0.3.0后没有再发生

3.failed to obtain cds错误

Error: Error endorsing invoke: rpc error: code = 2 desc = failed to obtain cds for your-chaincode-name - transaction not found your-chaincode-name/your-channel-name

invoke之前的操作需要sleep一些时间,比如

sleep 30

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180805G0BWE200?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券