计划要写一系列关于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
领取专属 10元无门槛券
私享最新 技术干货