本文档演示使用Hyperledger Fabric V1.0来部署一个开发者环境并运行一个简单例子。文档包括创建和加入通道(账本)、客户端认证以及部署和调用智能合约。CLI将用于创建和加入通道(账本),NodeJS SDK将用于客户端身份验证和使用账本的智能合约功能。
Docker Compose将用于创建包含三个Peer节点的联盟链、一个独立的Orderer和一个证书颁发机构(CA)。为了加快部署进度,预先生成了基于标准PKI实现的加密要素并打包进fabpre.tar.gz。证书颁发机构(CA)负责签发、撤销和维护代表一个企业的加密要素,这些要素提供给客户端(Node SDK)用于身份认证。
Fabric网络将通过执行docker-compose自动生成,创建通道和加入通道的API将会自动被调用;同时,开发者也可以通过手动步骤生成自己的Fabric网络和通道(账本)或直接使用开发者模式进行应用开发。
一、前置条件和系统配置
· Docker – v1.12 及更高版本
· Docker Compose – v1.8 及更高版本
· Node.js – v2.1.8 及更高版本
yum –y install docker.x86_64
yum –y install python-pip
pip install docker-compose
yum –y install npm
验证npm安装:
npm install npm@latest
查看npm版本:
npm -v
二、下载源代码并创建Fabric网络
·下载并安装 Curl 工具
· 创建 Fabric 工程和项目目录.
mkdir -p <workspace>
cd <workspace>
然后, 执行如下代码:
curl -L https://raw.githubusercontent.com/voodoo12345/polaris/master/fabpre.tar.gz -o fabpre.tar.gz 2> /dev/null; tar -xvf fabpre.tar.gz
执行完这条命令,会下载并解压缩部署Fabric网络的相关组件 ,包括Docker Compose 脚本, 通道创建/加入脚本, 认证使用的加密要素等.
你当前目录看上去是这样的:
ls
ccenv channel_test.sh docker-compose.yml fabpre.tar.gz src tmp
三、使用 Docker
你不需要手工拖取Docker镜像,通过执行docker-compose命令, fabric-peer, fabric-orderer, fabric-ca和 cli 都会自动下载、解压缩相关的镜像。
通道相关的命令:
“create” –在 orderer上创建并命名一个通道,返回一个通道的创世区块,生成的创世块以通道的名字命名
“join” – 使用 create 命令生成的创世区块向Peer节点发出加入通道的请求
四、使用Docker 创建Fabric网络 & 创建/加入通道(账本)
1)确保 hyperledger/fabric-ccenv 镜像的标签是 latest:
执行docker-compose build
2)创建Fabric网络,创建通道(正本), 将Peer节点加入通道:
执行docker-compose up
3)查看你的容器:
docker ps
终端应该显示有6个独立运行的容器(3 个peer节点, 1个 独立的 orderer, CLI 和 CA). 嵌入在docker-compose.yml里的channel_test.sh会在CLI容器里执行创建通道和加入通道命令。执行结束,应该只有一个Fabric网络和一个通道(账本),通道包含三个节点peer0,Peer1,Peer2。
4)确保通道已成功创建,并且节点都成功加入:
执行docker exec -it cli sh
5)查看通道创建/节点加入的结果:
cat results.txt
屏幕显示的结果如下:
6)验证成功创建了创世块,执行如下命令:
ls -ltr myc1.block
五、下载演示程序和SDK 模块
· 创建案例程序目录:
mkdir –p test
curl -OOOOOO https://raw.githubusercontent.com/hyperledger/fabric-sdk-node/master/examples/balance-transfer/{config.json,deploy.js,helper.js,invoke.js,query.js,package.json}
这条命令会下载用于部署、调用和查询案例智能合约的 javascript 代码 ,同时,它也包含了node SDK 依赖的模块
· 安装node 模块:
npm install
现在你已经拥有了全部Fabric网络运行需要的组件.
六、使用 node SDK 注册/登录一个用户并执行部署/调用/查询操作
这个案例程序将通过Node SDK &APIs以及预先准备的CA认证所需的加密要素来实现客户端的登记、注册和登录。一旦客户端完成身份验证,就可以执行程序包含的智能合约功能(部署、调用、查询)。
1a)注册/登录 & 部署智能合约 (Linux or OSX):
GOPATH=$PWD node deploy.js
1b)注册/登录& 部署智能合约 (Windows):
SET GOPATH=%cd%
node deploy.js
2)执行一个调用操作. 从 “a” 转移一定资产到 “b”:
node invoke.js
3)查询键值 “a”:
node query.js
你会在终端上得到一个数值为200的结果
你可以浏览NodeJS SDK 和APIs的文档来实现更多功能。
七、手工创建和加入通道
为了在CLI容器里手动执行创建通道和加入通道API,我们需要编辑Docker Compose文件。用任意文本编辑器打开docker-compose.yml注释掉channel_test.sh脚本,编辑操作如下:
cli:
container_name: cli
<CONTENT REMOVED FOR BREVITY>
working_dir: /opt/gopath/src/http://github.com/hyperledger/fabric/peer
# command: sh -c ‘./channel_test.sh; sleep 1000′
# command: /bin/sh
1)进入cli 容器:
docker exec -it cli sh
2)发送createChannel API 给 Orderer:
CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer channel create -c myc1
3)发送joinchannel API 给 Peer0:
CreateChannel执行完毕将返回一个创世区块(myc1.block),然后你可以执行加入通道的指令,把Genesis block作为参数发送joinchannel API给 peer0。
注:通道的定义都保存在创世块内:
CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 CORE_PEER_ADDRESS=peer0:7051 peer channel join -b myc1.block
4)如果想要加入其它节点,只需重新发送上述命令给peer1或Peer2即可
CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 CORE_PEER_ADDRESS=peer1:7051 peer channel join -b myc1.block
一旦全部Peer节点都加入了通道,你可以查询账本而无需在每个节点都部署智能合约。
八、使用命令行工具部署/调用/查询智能合约
1)运行部署命令:这个命令是在通道myc1上的Peer节点0上部署一个名叫MYCC的智能合约。构造函数把A和B的值分别初始化为100和200。
CORE_PEER_ADDRESS=peer0:7051 CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer chaincode deploy -C myc1 -n mycc -phttp://github.com/hyperledger/fabric/examples -c ‘{“Args”:["init","a","100","b","200"]}’
2)运行调用命令:这个命令是从A移动10个单位到B
CORE_PEER_ADDRESS=peer0:7051 CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer chaincode invoke -C myc1 -n mycc -c ‘{“function”:”invoke”,”Args”:["move","a","b","10"]}’
3)运行查询命令:按照预期,查询a的返回值应该是90
CORE_PEER_ADDRESS=peer0:7051 CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer chaincode query -C myc1 -n mycc -c ‘{“function”:”invoke”,”Args”:["query","a"]}’
你可以在任何时间发出exit命令退出CLI容器。
九、故障排除
1)如果已有容器在运行,执行docker-compose命令可能会收到报错,显示端口已被占用。如果发生这种情况,则需要杀死使用该端口的容器。
2)如果发现缺失部分文件,请确保Curl命令成功执行,并确保已经cd到了代码下载的目录。
3)如果你是用自动化步骤创建通道/加入通道的(即没有在yml文件注释channel_test.sh步骤),且通道myc1和创世区块myc1.block已经成功创建。这时,如果你想在CLI容器中手工执行后续的步骤:
CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer channel create -c myc1
你可能看到类似的错误信息如下:
<EXACT_TIMESTAMP> UTC [msp] Sign -> DEBU 064 Sign: digest: 5ABA6805B3CDBAF16C6D0DCD6DC439F92793D55C82DB130206E35791BCF18E5F
Error: Got unexpected status: BAD_REQUEST
Usage:
peer channel create [flags]
这是因为你正试图创建一个重名的通道(myc1),这个通道已经存在!有两种解决方法,1)我们可以使用一个不同的通道名称来重新创建通道,例如:
CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 peer channel create -c myc2
然后,执行加入通道指令:
CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 CORE_PEER_ADDRESS=peer0:7051 peer channel join -b myc2.block
如果您选择创建一个新的通道,需要在config.json文件编辑“channelid”参数来匹配新的通道名称,例如:
{
"chainName":"fabric-client1",
"chaincodeID":"mycc",
"channelID":"myc2",
"goPath":"../../test/fixtures",
"chaincodePath":"github.com/example_cc",
2)如果你想继续使用原有的通道名称(myc1),可以删除所有的容器然后参照手动创建和加入通道部分的步骤继续执行。
十、常用docker命令:
1)删除一个容器
docker rm <containerID>
2)强制删除一个容器
docker rm -f <containerID>
3)强制删除全部容器
docker rm -f $(docker ps -aq)
4)删除一个镜像:
docker rmi <imageID>
5)强制删除一个镜像:
docker rmi -f <imageID>
6)强制删除全部镜像
docker rmi -f $(docker images -q)