前言
前几天折腾实验 Fabric CA 网络搭建 ,今天直接使用官方脚本一键搭建测试网络,涉及了一点智能合约相关的内容。
测试网络中没有 CA 节点, 教程 最底下有些相关内容,结构刚好对应 Fabric CA 网络搭建中的 拓扑结构 。
实验环境
Ubuntu 18.04.5 Desktop
Docker version 19.03.12
Docker Compose version 1.26.2
Go version go1.15.1
部署链码时遇到如下错误,未找到解决方法
Fabric v2.2.0 + Fabric CA v1.4.7
Fabric v2.1.1 + Fabric CA v1.4.7
1 2 ~/fabric-samples/asset-transfer-basic/chaincode-go ~/fabric-samples/test-network verifying github.com/cucumber/godog@v0.8.0/go.mod: checksum mismatch
相关搜索:
改用 Fabric v2.0.1 + Fabric CA v1.4.6 成功复现实验
1 2 curl -sSL https://bit.ly/2ysbOFE | bash -s -- 2.0.1 1.4.6 0.4.18
部署测试网络
建立测试网络
Peer 节点负责验证和存储区块链交易信息,测试网络中有两个组织 Org1 和 Org2,每个组织都有一个节点 Peer0
peer0.org1.example.com
peer0.org2.example.com
Orderer 节点基于共识机制对交易进行排序,并将交易信息打包到区块链中,测试网络中有一个使用 Raft 共识算法的排序节点 Orderer
1 2 3 4 5 6 7 8 9 10 11 12 13 cd fabric-samples/test-network./network.sh -h ./network.sh down ./network.sh up docker ps -a
创建通道
为两个组织创建通道,通道是区块链网络成员之间的私有“子网”,所有交易都在通道中进行
1 2 3 ./network.sh createChannel
通道上启动链码
智能合约用于管理资产,区块链网络成员运行的程序可以调用智能合约生成、交易资产
为了确保交易的有效性,打包进区块链的交易必须由多个组织签名,节点通过背书策略确定交易有效性
信任模型(trust model)
防止交易被篡改、伪造
关于链码和智能合约
一个智能合约定义在一个链码中,多个智能合约也可以定义在同一个链码中
管理员通常使用链码将相关的智能合约组织起来进行部署,并且链码也可以用于 Fabric 的底层系统编程
以上命令首先在两个组织的 Peer 节点上安装名称为 fabcar 链码(及其依赖),然后将其部署到它们之间的通道 mychannel
中
与网络交互
在 Peer 节点上使用终端和区块链网络进行交互,调用已经部署的智能合约
1 2 3 4 5 export PATH=${PWD} /../bin:${PWD} :$PATH export FABRIC_CFG_PATH=$PWD /../config/
Org1
1 2 3 4 5 6 7 8 9 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.crtexport CORE_PEER_MSPCONFIGPATH=${PWD} /organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/mspexport CORE_PEER_ADDRESS=localhost:7051peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryAllCars"]}'
当区块链网络成员想要转移或改变资产时,将会调用链码
fabcar
链码的倍数策略是 Org1 和 Org2 都要对交易进行签名
1 2 3 4 5 6 7 8 9 10 11 12 peer chaincode invoke -o localhost:7050 \ --ordererTLSHostnameOverride orderer.example.com \ --tls \ --cafile ${PWD} /organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \ -C mychannel \ -n fabcar \ --peerAddresses localhost:7051 \ --tlsRootCertFiles ${PWD} /organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \ --peerAddresses localhost:9051 \ --tlsRootCertFiles ${PWD} /organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \ -c '{"function":"changeCarOwner","Args":["CAR9","Dave"]}'
Ogr2
1 2 3 4 5 6 7 8 9 export CORE_PEER_TLS_ENABLED=true export CORE_PEER_LOCALMSPID="Org2MSP" export CORE_PEER_TLS_ROOTCERT_FILE=${PWD} /organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crtexport CORE_PEER_MSPCONFIGPATH=${PWD} /organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/mspexport CORE_PEER_ADDRESS=localhost:9051peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryCar","CAR9"]}'
停止网络
部署智能合约实验需要重新搭建网络
部署智能合约
搭建测试网络
重新搭建网络并创建通道,手动打包和部署智能合约
1 2 3 4 5 6 7 8 9 10 cd fabric-samples/test-network./network.sh down ./network.sh up ./network.sh createChannel
打包智能合约
确认并下载依赖的 Go 模块,智能合约 fabric-samples/chaincode/fabcar/go/fabcar.go
1 2 3 4 5 6 7 cd ../chaincode/fabcar/gocat go.modGO111MODULE=on go mod vendor
将链码进行打包,生成 fabcar.tar.gz
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 cd ../../../test-networkexport PATH=${PWD} /../bin:${PWD} :$PATH export FABRIC_CFG_PATH=$PWD /../config/peer version export CORE_PEER_MSPCONFIGPATH=${PWD} /organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msppeer lifecycle chaincode package fabcar.tar.gz \ --path ../chaincode/fabcar/go/ \ --lang golang \ --label fabcar_1
安装智能合约
链码需要安装在所有可执行交易的节点上,Peer 节点负责验证和存储区块链交易信息,测试网络中有两个组织 Org1 和 Org2,每个组织都有一个节点 Peer0 ,需要在这两个节点上安装链码
peer0.org1.example.com
peer0.org2.example.com
Org1
1 2 3 4 5 6 7 8 9 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.crtexport CORE_PEER_MSPCONFIGPATH=${PWD} /organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/mspexport CORE_PEER_ADDRESS=localhost:7051peer lifecycle chaincode install fabcar.tar.gz
Org2
1 2 3 4 5 6 7 8 9 export CORE_PEER_LOCALMSPID="Org2MSP" export CORE_PEER_TLS_ROOTCERT_FILE=${PWD} /organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crtexport CORE_PEER_TLS_ROOTCERT_FILE=${PWD} /organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crtexport CORE_PEER_MSPCONFIGPATH=${PWD} /organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/mspexport CORE_PEER_ADDRESS=localhost:9051peer lifecycle chaincode install fabcar.tar.gz
审批链码定义
使用链码前必须审批链码定义,审批以组织为单位
背书策略决定需要多少节点进行审批
审批将通过 gossip 通信发送给组织中的其他成员
建议所有通道成员在链码提交至通道前审批链码
执行审批的节点需要拥有管理员权限
Package ID
:安装成功返回链码标识
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 peer lifecycle chaincode queryinstalled CC_PACKAGE_ID=fabcar_1:533e8c6699b013f5b79a74e15be1bc1063f46f947da2c95fc679deb08e10acff peer lifecycle chaincode approveformyorg \ -o localhost:7050 \ --ordererTLSHostnameOverride orderer.example.com \ --channelID mychannel \ --name fabcar \ --version 1.0 \ --package-id $CC_PACKAGE_ID \ --sequence 1 \ --tls \ --cafile ${PWD} /organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem export CORE_PEER_LOCALMSPID="Org1MSP" export CORE_PEER_MSPCONFIGPATH=${PWD} /organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/mspexport CORE_PEER_TLS_ROOTCERT_FILE=${PWD} /organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crtexport CORE_PEER_ADDRESS=localhost:7051peer lifecycle chaincode approveformyorg \ -o localhost:7050 \ --ordererTLSHostnameOverride orderer.example.com \ --channelID mychannel \ --name fabcar \ --version 1.0 \ --package-id $CC_PACKAGE_ID \ --sequence 1 \ --tls \ --cafile ${PWD} /organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
提交链码定义
组织可以将链码定义提交给通道,如果大多数通道成员已经审批过链码定义,则提交事务将成功,通道将根据链码定义中约定的参数执行链码
通道成员审批的链码将被提交至排序节点,添加到区块中并分发给通道,通道成员根据背书策略验证是否有足够的节点审批
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 peer lifecycle chaincode checkcommitreadiness \ --channelID mychannel \ --name fabcar \ --version 1.0 \ --sequence 1 \ --tls \ --cafile ${PWD} /organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \ --output json peer lifecycle chaincode commit \ -o localhost:7050 \ --ordererTLSHostnameOverride orderer.example.com \ --channelID mychannel \ --name fabcar \ --version 1.0 \ --sequence 1 \ --tls \ --cafile ${PWD} /organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \ --peerAddresses localhost:7051 \ --tlsRootCertFiles ${PWD} /organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \ --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD} /organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt peer lifecycle chaincode querycommitted \ --channelID mychannel \ --name fabcar \ --cafile ${PWD} /organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
调用链码
链码提交至通道后,安装了链码的通道成员运行链码,可以通过客户端程序进行调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 peer chaincode invoke \ -o localhost:7050 \ --ordererTLSHostnameOverride orderer.example.com \ --tls \ --cafile ${PWD} /organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \ -C mychannel \ -n fabcar \ --peerAddresses localhost:7051 \ --tlsRootCertFiles ${PWD} /organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \ --peerAddresses localhost:9051 \ --tlsRootCertFiles ${PWD} /organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \ -c '{"function":"initLedger","Args":[]}' peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryAllCars"]}'
问题解决
curl - connection refused
1 curl: (7) failed to connect to raw.githubusercontent.com port 443: connection refused
修改 hosts 文件,添加 github 域名记录
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 sudo vi /etc/hosts sudo reboot
docker - permission denied
1 Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.40/containers/json: dial unix /var/run/docker.sock: connect: permission denied
根据 Manage Docker as a non-root user 将当前用户加入 docker
用户组
1 2 3 4 5 6 7 8 sudo groupadd docker sudo usermod -aG docker $USER newgrp docker
查找指定目录中包含指定字符串的文件
当时排查下载的 godog v0.8.0
哈希值不对应,将目录中所有文件对应的字符串改为 godog@v0.8.1
,问题并没有解决xd
1 grep -rnw '/home/jck/fabric-samples/' -e 'godog'
总结
阅读官方教程花了点时间,本以为可以无脑 copy 代码,没想到在哈希值错误的问题上花费了很长时间,结果还是没解决,转而使用旧版本进行实验了。
测试网络搭建完发现教程底下还有 CA 相关的内容,突然想到这不是和前几天做的实验对应上了吗(当时做得挺不清楚的,没有验证整个网络的可用性),应该是可以读脚本源代码学 CA 网络搭建的orz
Hyperledger Fabric 真厉害
参阅