基于hyperledger fabric网络的第一个应用
摘要
本文基本 hyperledger fabric 区块链网络,编写一个简单的应用,旨在讲述以下几点:
- 如何启动一个 hyperledger fabric 区块链网络
- 如何编写一个简单的智能合约
- 如何将区块链应用与现有系统整合
准备工作
1
2git clone https://github.com/hyperledger/fabric-samples.git
cd fabric-samples/fabcar启动区块链网络
1
./startFabric.sh
来看一下上面的 startFabric.sh 这个脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
# Exit on first error
set -e
# don't rewrite paths for Windows Git Bash users
export MSYS_NO_PATHCONV=1
starttime=$(date +%s)
if [ ! -d ~/.hfc-key-store/ ]; then
mkdir ~/.hfc-key-store/
fi
cp $PWD/creds/* ~/.hfc-key-store/
# launch network; create channel and join peer to channel
# 进入同级目录basic-network
cd ../basic-network
# 运行start.sh脚本
./start.sh
# Now launch the CLI container in order to install, instantiate chaincode
# and prime the ledger with our 10 cars
# 使用docker-compose 启动cli容器
docker-compose -f ./docker-compose.yml up -d cli
# 在cli容器中执行peer chaincode install来安装合约
docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp" cli peer chaincode install -n fabcar -v 1.0 -p github.com/fabcar
# 在cli容器中执行peer chaincode instantiate来初始化合约,这个操作将会调用合约里的Init函数
# -C 指定通道名称
# -c 指定初始化参数
# -P 指定背书策略,这里只要是Org1MSP或Org2MSP任一成员即可
docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp" cli peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n fabcar -v 1.0 -c '{"Args":[""]}' -P "OR ('Org1MSP.member','Org2MSP.member')"
sleep 10
# 在cli容器里执行peer chaincode invoke操作来调用合约中的initLedger函数
docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp" cli peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n fabcar -c '{"function":"initLedger","Args":[""]}'
printf "\nTotal execution time : $(($(date +%s) - starttime)) secs ...\n\n"看一下startFabric.sh*脚本中用到的../basic-network/start.sh*脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
# Exit on first error, print all commands.
set -ev
# don't rewrite paths for Windows Git Bash users
export MSYS_NO_PATHCONV=1
# 根据docker-compose.yml文件停止相关的容器
docker-compose -f docker-compose.yml down
# 根据docker-compose.yml文件启动如下容器:
# ca.example.com容器提供CA认证服务
# orderer.example.com提供排序(共识)服务
# peer0.org1.example.com提供背书和账本服务,
# couchdb作为Key-Value服务来存储区块链状态(world state)
docker-compose -f docker-compose.yml up -d ca.example.com orderer.example.com peer0.org1.example.com couchdb
# wait for Hyperledger Fabric to start
# incase of errors when running later commands, issue export FABRIC_START_TIMEOUT=<larger number>
export FABRIC_START_TIMEOUT=10
#echo ${FABRIC_START_TIMEOUT}
sleep ${FABRIC_START_TIMEOUT}
# Create the channel
# 创建通道
docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/users/Admin@org1.example.com/msp" peer0.org1.example.com peer channel create -o orderer.example.com:7050 -c mychannel -f /etc/hyperledger/configtx/channel.tx
# Join peer0.org1.example.com to the channel.
# 将peer1.org1.example.com加入通道
docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/users/Admin@org1.example.com/msp" peer0.org1.example.com peer channel join -b mychannel.block
4) ### 智能合约关键内容解释
合约代码在../chaincode/fabcar/fabcar.go文件中定义,
1 | package main |
fabric 使用 go 语言来编写智能合约,使用 docker 容器来运行合约代码。每份合约只需要实现如下接口
1 | type Chaincode interface { |
可以将 fabric 的账本(world state)理解为一个 Key-Value 数据库或是 map(对象,字典等),这也是为什么可以使用couchdb的原因,合约的主要功能就是与这个数据库打交道,如:
- APIstub.GetState(key) 读取 Key 对应的 Value
- APIstub.PutState(key, value),将 key-value 值对写入数据库中
5) ### 调用合约功能
区块链网络已经启动,合约也已经部署好,现在来看看如何访问合约中的功能,先看看 query.js,其他的 js 文件如 invoke.js 程序结构相似。
1 | ; |
6) ### 总结
看到这里,是不是已经懵了:(
想用区块链写个合约是不是好麻烦啊,要用到 docker,还要会 go,再来点 Nodejs,好难啊。。。想必 hyperledger 社区也意识到了这个问题,所以他们推出了Hyperledger Composer项目,不用专门学 go——其实学 go 也没坏处:),composer 主页上介绍说可以将开发时间变成以周为单位,而不是月为单位。后续会推出Hyperledger Composer相关文章,敬请关注。