前面几章内容,我们已经详细讲解过fabric 1.4.3网络搭建,fabric2.2.0本地编译。今天,我们在fabria2.2.0版本中,启动一个网络,并用SDK调用一个fabcar 的demo,体验一下fabric新版本
我们今天用Node.js编写SDK,所以我们需要安装node.js,fabric2.2.0对node有版本要求。这次,我们安装最新的nodejs,v12.18.x
1.安装最新版本nodejs
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
sudo apt-get install -y nodejs
查看版本
node -v
v12.18.2
记得一定要更新npm都最新版本,否则,SDK会不成功。这些坑都是我们踩过的
更新npm
npm install -g npm
2.下载 fabric源码、fabric-samples源码、fabric镜像
我们可以使用Git命令下载源码,首先需要建立对应的目录,然后进入该目录,Git下载源码:
mkdir -p ~/go/src/github.com/hyperledger
cd ~/go/src/github.com/hyperledger
git clone https://github.com/hyperledger/fabric.git
由于Fabric一直在更新,所有我们并不需要最新最新的源码,需要切换到v2.2.0版本的源码即可:
cd ~/go/src/github.com/hyperledger/fabric
git checkout v2.2.0
3.Fabric Docker镜像的下载
cd ~/go/src/github.com/hyperledger/fabric/script
./bootstrap.sh
下载完成后,会列出所下载的 docker 镜像,具体如下所示:
REPOSITORY TAG IMAGE ID CREATED SIZE
hyperledger/fabric-ccenv 2.2 a7ae534189c8 33 minutes ago 586MB
hyperledger/fabric-ccenv 2.2.0 a7ae534189c8 33 minutes ago 586MB
hyperledger/fabric-ccenv amd64-2.2.0-snapshot-5ea85bc a7ae534189c8 33 minutes ago 586MB
hyperledger/fabric-ccenv latest a7ae534189c8 33 minutes ago 586MB
hyperledger/fabric-baseos 2.2 0cd12fe77474 2 hours ago 6.85MB
hyperledger/fabric-baseos 2.2.0 0cd12fe77474 2 hours ago 6.85MB
hyperledger/fabric-baseos amd64-2.2.0-snapshot-5ea85bc 0cd12fe77474 2 hours ago 6.85MB
hyperledger/fabric-baseos latest 0cd12fe77474 2 hours ago 6.85MB
hyperledger/fabric-tools 2.2 5eb2356665e7 2 weeks ago 519MB
hyperledger/fabric-tools 2.2.0 5eb2356665e7 2 weeks ago 519MB
hyperledger/fabric-tools latest 5eb2356665e7 2 weeks ago 519MB
hyperledger/fabric-peer 2.2 760f304a3282 2 weeks ago 54.9MB
hyperledger/fabric-peer 2.2.0 760f304a3282 2 weeks ago 54.9MB
hyperledger/fabric-peer latest 760f304a3282 2 weeks ago 54.9MB
hyperledger/fabric-orderer 2.2 5fb8e97da88d 2 weeks ago 38.4MB
hyperledger/fabric-orderer 2.2.0 5fb8e97da88d 2 weeks ago 38.4MB
hyperledger/fabric-orderer latest 5fb8e97da88d 2 weeks ago 38.4MB
hyperledger/fabric-ccenv <none> aac435a5d3f1 2 weeks ago 586MB
hyperledger/fabric-baseos <none> aa2bdf8013af 2 weeks ago 6.85MB
hyperledger/fabric-nodeenv 2.2 ab88fe4d29dd 3 weeks ago 293MB
hyperledger/fabric-nodeenv 2.2.0 ab88fe4d29dd 3 weeks ago 293MB
hyperledger/fabric-nodeenv latest ab88fe4d29dd 3 weeks ago 293MB
hyperledger/fabric-javaenv 2.2 56c30f316b23 3 weeks ago 504MB
hyperledger/fabric-javaenv 2.2.0 56c30f316b23 3 weeks ago 504MB
hyperledger/fabric-javaenv latest 56c30f316b23 3 weeks ago 504MB
couchdb 3.1 7962d7fc8ed7 6 weeks ago 189MB
golang 1.14.4-alpine3.12 3289bf11c284 7 weeks ago 370MB
alpine 3.12 a24bb4013296 7 weeks ago 5.57MB
hyperledger/fabric-ca 1.4 743a758fae29 2 months ago 154MB
hyperledger/fabric-ca 1.4.7 743a758fae29 2 months ago 154MB
hyperledger/fabric-ca latest 743a758fae29 2 months ago 154MB
至此,下载 fabric 源码、fabric-samples 源码、fabric 镜像的工作已经完成
执行 ls 命令,查看在当前目录下多了 fabric-samples 目录:
4.启动Fabric网络
进入test-network文件夹,启动测试网络
./network.sh up
显示如下:
Starting nodes with CLI timeout of '5' tries and CLI delay of '3' seconds and using database 'leveldb'
LOCAL_VERSION=2.2.0
DOCKER_IMAGE_VERSION=2.2.0
Creating network "net_test" with the default driver
Creating volume "net_peer0.org1.example.com" with default driver
Creating volume "net_peer0.org2.example.com" with default driver
Creating volume "net_orderer.example.com" with default driver
Creating peer0.org2.example.com ...
Creating peer0.org1.example.com ...
Creating orderer.example.com ...
Creating peer0.org2.example.com
Creating orderer.example.com
Creating peer0.org2.example.com ... done
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f16b792b2b82 hyperledger/fabric-peer:latest "peer node start" 3 seconds ago Up 1 second 0.0.0.0:7051->7051/tcp peer0.org1.example.com
55253429c867 hyperledger/fabric-orderer:latest "orderer" 3 seconds ago Up Less than a second 0.0.0.0:7050->7050/tcp orderer.example.com
b6ba2d2de649 hyperledger/fabric-peer:latest "peer node start" 3 seconds ago Up Less than a second 7051/tcp, 0.0.0.0:9051->9051/tcp peer0.org2.example.com
cf8d0e038f5d hyperledger/fabric-nodeenv:2.2 "docker-entrypoint.s…" 7 hours ago Exited (137) 7 hours ago priceless_hamilton
网络启动成功;
4.1建立通道
使用network.sh脚本在Org1和Org2之间创建频道,并将其对等方加入该频道。
运行以下命令以使用默认名称创建频道mychannel:
./network.sh createChannel
通过创建成功。
4.2在通道上启动链码
./network.sh deployCC
如果出现因为访问无法下载,
解决方法:设置go代理
https://www.cnblogs.com/zhangmingcheng/p/12294156.html
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
4.3与网络交互命令
./network.sh up
./network.sh createChannel
./network.sh deployCC
./network.sh down
4.3.1在test-network目录进行操作,将这些二进制文件添加到CLI路径
export PATH=${PWD}/../bin:${PWD}:$PATH
4.3.2设置FABRIC_CFG_PATH指向存储库中的core.yaml文件fabric-samples:
export FABRIC_CFG_PATH=$PWD/../config/
4.3.3设置环境变量,以允许您以peer Org1的形式操作CLI:
# Environment variables for Org1
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051
4.3.4获取已添加到通道分类帐中的汽车的列表
peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryAllCars"]}'
显示如下:
peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryAllCars"]}'
[{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},{"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},{"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},{"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},{"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},{"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},{"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},{"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},{"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]
4.3.5关闭网络:
./network.sh down
Stopping network
Stopping peer0.org1.example.com ... done
Stopping orderer.example.com ... done
Stopping peer0.org2.example.com ... done
Removing peer0.org1.example.com ... done
Removing orderer.example.com ... done
Removing peer0.org2.example.com ... done
Removing network net_test
Removing volume net_peer0.org1.example.com
Removing volume net_peer0.org2.example.com
Removing volume net_orderer.example.com
Removing network net_test
WARNING: Network net_test not found.
Removing volume net_peer0.org3.example.com
WARNING: Volume net_peer0.org3.example.com not found.
我们现在启动一个fabcar的demo,体验一下.
进入文件夹
cd ~/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/fabcar
5.启动fabcar测试网络
cd ~/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/fabcar
./startFabric.sh
显示如下画面说明启动成功:
Committed chaincode definition for chaincode 'fabcar' on channel 'mychannel':
Version: 1, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]
===================== Query chaincode definition successful on peer0.org1 on channel 'mychannel' =====================
Using organization 2
===================== Querying chaincode definition on peer0.org2 on channel 'mychannel'... =====================
Attempting to Query committed status on peer0.org2, Retry after 3 seconds.
++ peer lifecycle chaincode querycommitted --channelID mychannel --name fabcar
++ res=0
++ set +x
Committed chaincode definition for chaincode 'fabcar' on channel 'mychannel':
Version: 1, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]
===================== Query chaincode definition successful on peer0.org2 on channel 'mychannel' =====================
Using organization 1
Using organization 2
++ fcn_call='{"function":"initLedger","Args":[]}'
++ echo invoke fcn 'call:{"function":"initLedger","Args":[]}'
invoke fcn call:{"function":"initLedger","Args":[]}
++ peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /home/cuijb/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n fabcar --peerAddresses localhost:7051 --tlsRootCertFiles /home/cuijb/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles /home/cuijb/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/test-network/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --isInit -c '{"function":"initLedger","Args":[]}'
++ res=0
++ set +x
2020-07-23 21:40:27.083 +05 [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
===================== Invoke transaction successful on peer0.org1 peer0.org2 on channel 'mychannel' =====================
6.利用SDK与fabric网络交互
可以选择javascript,typescript,java,go语言与网络交互
我们今天选择nodejs
cd ~/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/fabcar
cd javascript
npm install
我们按照合约流程依次启动
node enrollAdmin.js
Wallet path: /home/cuijb/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/fabcar/javascript/wallet
Successfully enrolled admin user "admin" and imported it into the wallet
node registerUser.js
Wallet path: /home/cuijb/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/fabcar/javascript/wallet
Successfully registered and enrolled admin user "appUser" and imported it into the wallet
我们接下来,执行一笔交易
node invoke.js
Wallet path: /home/cuijb/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/fabcar/javascript/wallet
2020-07-23T17:02:53.715Z - error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Endorser- name: peer0.org1.example.com, url:grpcs://localhost:7051, connected:false, connectAttempted:true
2020-07-23T17:02:53.716Z - error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server peer0.org1.example.com url:grpcs://localhost:7051 timeout:3000
2020-07-23T17:02:53.718Z - error: [NetworkConfig]: buildPeer - Unable to connect to the endorser peer0.org1.example.com due to Error: Failed to connect before the deadline on Endorser- name: peer0.org1.example.com, url:grpcs://localhost:7051, connected:false, connectAttempted:true
at checkState (/home/cuijb/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/fabcar/javascript/node_modules/@grpc/grpc-js/build/src/client.js:69:26)
at Timeout._onTimeout (/home/cuijb/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/fabcar/javascript/node_modules/@grpc/grpc-js/build/src/channel.js:292:17)
at listOnTimeout (internal/timers.js:549:17)
at processTimers (internal/timers.js:492:7) {
connectFailed: true
}
2020-07-23T17:02:56.725Z - error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Discoverer- name: peer0.org1.example.com, url:grpcs://localhost:7051, connected:false, connectAttempted:true
2020-07-23T17:02:56.725Z - error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server peer0.org1.example.com url:grpcs://localhost:7051 timeout:3000
Failed to submit transaction: Error: Failed to connect before the deadline on Discoverer- name: peer0.org1.example.com, url:grpcs://localhost:7051, connected:false, connectAttempted:true
发现出了很多错误。
原因:由于启动过网络并且更新了证书,在没有删除干净的环境中启动复用的之前的volume,所以导致证书认证失败。
解决方案:执行如下命令删除卷
关闭网络:
./networkDown.sh
执行如下命令删除卷。
docker rm $(docker ps -a | grep "hyperledger/*" | awk "{print \$1}")
docker-compose down --volumes --remove-orphans
docker volume prune
docker network prune
重新启动网络
./startFabric.sh
进入SDK调用环境
node enrollAdmin.js
Wallet path: /home/cuijb/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/fabcar/javascript/wallet
Successfully enrolled admin user "admin" and imported it into the wallet
接着执行
node registerUser.js
Wallet path: /home/cuijb/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/fabcar/javascript/wallet
Successfully registered and enrolled admin user "appUser" and imported it into the wallet
执行一笔交易
node invoke.js
Wallet path: /home/cuijb/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/fabcar/javascript/wallet
Transaction has been submitted
我们可以清晰看到,交易执行完成。
我们接下来查询一笔交易:
node query.js
Wallet path: /home/cuijb/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/fabcar/javascript/wallet
Transaction has been evaluated, result is: [{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},{"Key":"CAR13","Record":{"make":"Honda","model":"Accord123","colour":"Black","owner":"jake"}},{"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},{"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},{"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},{"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},{"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},{"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},{"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},{"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]
再次通过peer命令的方式,执行链码:
peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryAllCars"]}'
返回结果如下:
peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryAllCars"]}'
[{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},{"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},{"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},{"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},{"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},{"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},{"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},{"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},{"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]
我们可以核对一下,通过SDK调用查询的交易,和我们通过命令查询的交易是否一致。
谢谢大家。
2020/7月24日完成
2020/7/26修正