在基于truffle框架实现以太坊公开拍卖智能合约中我们已经实现了以太坊智能合约的编写及部署,但其工作方式注定其只能应用于有限的业务场景中。相比之下,基于超级账本的Fabric
具有高可扩展性和高可定制性,能够应用在更为复杂的商业场景中,但Fabric
技术涉及很多新的概念,源代码跟新速度快且各版本间兼容性差,对初学者很不友好。为了使能够快速掌握Fabric
,本文基于其目前最新的2.4版本搭建了一套区块链运行环境,并在此之上部署了官方示例chaincode
并对其进行交互调试,最终整个环境及示例代码能够正常运行且得出预期结果。
环境搭建
网上几乎所有的Fabric
教程都是基于Ubuntu
环境而不是Windows
,其原因主要是Fabric
的运行需要的Docker
环境在Windows
下表现不佳,此外Fabric
许多官方文档也是基于Ubuntu
纂写,在windows
下运行可能会遇到难以预估的bug
。原本为了方便后期部署至公网服务器想在CentOS上搭建环境,但由于CentOS8停止维护,且CentOS Stream使用体验颇差,于是最终选择了Debian系统。
本环境各系统、软件版本如下:
本环境各Docker镜像版本如下:
警告:建议Fabric所有实验过程皆在root权限下进行,否则在sudo权限切换的过程中会出现很多环境变量的问题。
为了帮助开发者快速搭建Fabric
环境,官方创建了一个Fabric
环境搭建的批处理工具bootstrap.sh
,可以通过该工具直接安装环境:
wget https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap.sh chmod +x bootstrap.sh ./bootstrap.sh
不出意外的话会看见脚本顺利的环境安装过程:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NgTStb2P-1649231335512)(https://cdn.jsdelivr.net/gh/wefantasy/FileCloud/img/202108131408966.png ‘./bootstrap.sh’)]
当然,直接使用官方脚本不出意外的话肯定会出意外(网络原因),在此我们可以通过手动安装需要的各项环境。
wget https://github.com/hyperledger/fabric/releases/download/v2.4.0/hyperledger-fabric-linux-amd64-2.4.0.tar.gz mkdir /usr/local/fabric tar -xzvf hyperledger-fabric-linux-amd64-2.3.2.tar.gz -C /usr/local/fabric
wget https://github.com/hyperledger/fabric-ca/releases/download/v1.5.2/hyperledger-fabric-ca-linux-amd64-1.5.2.tar.gz tar -xzvf hyperledger-fabric-ca-linux-amd64-1.5.2.tar.gz mv bin/* /usr/local/fabric/bin
#Fabric export FABRIC=/usr/local/fabric export PATH=$PATH:$FABRIC/bin
apt remove docker docker-engine docker.io containerd runc
apt update apt install \ apt-transport-https \ ca-certificates \ curl \ gnupg \ lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \ "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update apt install docker-ce docker-ce-cli containerd.io
apt install docker-compose
Fabric
相关镜像均可以在DockerHub官方镜像网站进行下载,搜索需要的镜像则可获取安装方法,本试验用到的所有镜像为:
docker pull hyperledger/fabric-tools:2.4 docker pull hyperledger/fabric-peer:2.4 docker pull hyperledger/fabric-orderer:2.4 docker pull hyperledger/fabric-ccenv:2.4 docker pull hyperledger/fabric-baseos:2.4 docker pull hyperledger/fabric-ca:1.5
使用docker images
命令查看安装完成后镜像:
hyperledger/fabric-tools 2.4 625237d887db 4 weeks ago 473MB hyperledger/fabric-peer 2.4 ee643d889779 4 weeks ago 62.3MB hyperledger/fabric-orderer 2.4 df64446ac2df 4 weeks ago 37.3MB hyperledger/fabric-ccenv 2.4 da4f00cb576a 4 weeks ago 517MB hyperledger/fabric-baseos 2.4 0287ebf8aaf3 4 weeks ago 6.94MB hyperledger/fabric-ca 1.5 4ea287b75c63 6 months ago 69.8MB
示例代码中使用的镜像标签都为latest
,但如果在pull
时直接选择latest
可能会报错,因此我们在上面镜像拉取完成后手动使用以下命令为镜像打上latest
标签:
# docker tag IMAGEID(镜像id) REPOSITORY:TAG(仓库:标签) docker tag 625237d887db hyperledger/fabric-tools:latest docker tag ee643d889779 hyperledger/fabric-peer:latest docker tag df64446ac2df hyperledger/fabric-orderer:latest docker tag da4f00cb576a hyperledger/fabric-ccenv:latest docker tag 0287ebf8aaf3 hyperledger/fabric-baseos:latest docker tag 4ea287b75c63 hyperledger/fabric-ca:latest
最终的镜像为:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4rE5aU7F-1649231335514)(https://cdn.jsdelivr.net/gh/wefantasy/FileCloud/img/202203301519799.png “最终的镜像”)]
运行测试
cd fabric-samples/test-network
Creating network "fabric_test" with the default driver Creating volume "docker_orderer.example.com" with default driver Creating volume "docker_peer0.org1.example.com" with default driver Creating volume "docker_peer0.org2.example.com" with default driver Creating peer0.org1.example.com ... done Creating orderer.example.com ... done Creating peer0.org2.example.com ... done Creating cli ... done CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7738c1e84751 hyperledger/fabric-tools:latest "/bin/bash" Less than a second ago Up Less than a second cli 1f24de2c6cd5 hyperledger/fabric-peer:latest "peer node start" 2 seconds ago Up Less than a second 0.0.0.0:9051->9051/tcp, :::9051->9051/tcp, 0.0.0.0:19051->19051/tcp, :::19051->19051/tcp peer0.org2.example.com bfc48b20360c hyperledger/fabric-orderer:latest "orderer" 2 seconds ago Up Less than a second 0.0.0.0:7050->7050/tcp, :::7050->7050/tcp, 0.0.0.0:7053->7053/tcp, :::7053->7053/tcp, 0.0.0.0:17050->17050/tcp, :::17050->17050/tcp orderer.example.com b9a61fdaf47a hyperledger/fabric-peer:latest "peer node start" 2 seconds ago Up Less than a second 0.0.0.0:7051->7051/tcp, :::7051->7051/tcp, 0.0.0.0:17051->17051/tcp, :::17051->17051/tcp peer0.org1.example.com
最终出现以上输出日志则表示网络启动成功,每个加入Fabric网络的Node和User都需要隶属于某个组织,以上网络中包含了两个平行组织————peer0.org1.example.com
和peer0.org2.example.com
,它还包括一个作为ordering service维护网络的orderer.example.com
。
上节已经在机器上运行了peer节点和orderer节点,现在可以使用network.sh为Org1和Org2之间创建channel。channel是特定网络成员之间的私有通道,只能被属于该通道的组织使用,并且对网络的其他成员是不可见的。每个channel都有一个单独的区块链账本,属于该通道的组织可以让其下peer加入该通道,以让peer能够存储channel上的帐本并验证账本上的交易。
使用以下命令创建自定义通道testchannel:
./network.sh createChannel -c testchannel
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XEXE761B-1649231335514)(https://cdn.jsdelivr.net/gh/wefantasy/FileCloud/img/202108151123057.png ‘./network.sh createChannel -c testchannel’)]
建议部署操作全部在
root
账户下进行,否则可能发生未知错误,以下流程为笔者在非root
用户下所遇问题,最终重建虚拟机全部指令在root
账户下才完成部署。
创建通道后,您可以开始使用智能合约与通道账本交互。智能合约包含管理区块链账本上资产的业务逻辑,由成员运行的应用程序网络可以在账本上调用智能合约创建,更改和转让这些资产。可以通过./network.sh deployCC
命令部署智能合约,但本过程可能会出现很多问题。
使用以下命令部署chaincode:
./network.sh deployCC -c testchannel -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go
此命令执行后可能会出现错误:scripts/deployCC.sh: line 114: log.txt: Permission denied
,很明显这是权限不足所致,加上sudo试试:
./network.sh deployCC -c testchannel -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go
加上sudo后出现新的错误:deployCC.sh: line 59: go: command not found
。检查本用户go
命令可用,检查root
用户go
命令可用,单单sudo
后不能用。查阅资料后发现这是因为linux
系统为了安全,限制在使用sudo
时会清空自定义的环境变量,最简单的解决方法是在/etc/sudoers
文件中直接将该限制注释:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hAOc9s5n-1649231335514)(https://cdn.jsdelivr.net/gh/wefantasy/FileCloud/img/202108131722335.png ‘vim /etc/sudoers’)]
加上注释后重新执行上条命令,又出现了新的错误:
go: github.com/golang/protobuf@v1.3.2: Get "https://proxy.golang.org/github.com/golang/protobuf/@v/v1.3.2.mod": dial tcp 172.217.160.81:443: i/o timeout
很明显这是因为本地网络无法访问proxy.golang.org所致,在命令行输入go env -w GO111MODULE=on && go env -w GOPROXY=https://goproxy.cn,direct
命令配置国内代理后再次执行。令人意外的是错误不变,设置的代理没有生效?手动使用go get github.com/golang/protobuf
手动下载安装后再次运行错误还是不变,此时检查本地GOPATH
目录下已有github.com/golang/protobuf
包,为什么没有识别到?此时灵机一动,使用go env
查看GOPATH
环境变量,发现与本地用户不一致,原来sudo
命令会使用root
的go
环境变量,而之前设置的代理、下载的包都只能在本地用户下生效,因此这个问题最终的解决方案是直接切换到root
用户下重新配置go
代理并运行。成功运行后可看见如下结果:
2021-08-15 00:45:54.064 PDT [chaincodeCmd] ClientWait -> INFO 001 txid [ebeb8df6904f45b81fb30714f7eecb30b4bbfd32f4acc809f34f7c660e396eb8] committed with status (VALID) at localhost:7051 2021-08-15 00:45:54.144 PDT [chaincodeCmd] ClientWait -> INFO 002 txid [ebeb8df6904f45b81fb30714f7eecb30b4bbfd32f4acc809f34f7c660e396eb8] committed with status (VALID) at localhost:9051 Chaincode definition committed on channel 'testchannel' Using organization 1 Querying chaincode definition on peer0.org1 on channel 'testchannel'... Attempting to Query committed status on peer0.org1, Retry after 3 seconds. + peer lifecycle chaincode querycommitted --channelID testchannel --name basic + res=0 Committed chaincode definition for chaincode 'basic' on channel 'testchannel': Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true] Query chaincode definition successful on peer0.org1 on channel 'testchannel' Using organization 2 Querying chaincode definition on peer0.org2 on channel 'testchannel'... Attempting to Query committed status on peer0.org2, Retry after 3 seconds. + peer lifecycle chaincode querycommitted --channelID testchannel --name basic + res=0 Committed chaincode definition for chaincode 'basic' on channel 'testchannel': Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true] Query chaincode definition successful on peer0.org2 on channel 'testchannel' Chaincode initialization is not required
export FABRIC_CFG_PATH=$PWD/../config/ # export FABRIC_CFG_PATH=/usr/local/fabric/config/
# Environment variables for Org1 # CORE_PEER_TLS_ROOTCERT_FILE和CORE_PEER_MSPCONFIGPATH环境变量指向Org1的organizations文件夹中的身份证书。 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
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 testchannel -n basic --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":[]}'
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tLBgzBUh-1649231335515)(https://cdn.jsdelivr.net/gh/wefantasy/FileCloud/img/202108151634613.png ‘初始化chaincode’)]
4. 查询账本资产列表
peer chaincode query -C testchannel -n basic -c '{"Args":["GetAllAssets"]}'
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-APLs128t-1649231335515)(https://cdn.jsdelivr.net/gh/wefantasy/FileCloud/img/202108151637440.png ‘查询账本资产列表’)]
5. 修改账本资产
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 testchannel -n basic --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":"TransferAsset","Args":["asset6","Christopher"]}'
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-anN9BqkY-1649231335516)(https://cdn.jsdelivr.net/gh/wefantasy/FileCloud/img/202108151646082.png ‘修改账本资产’)]
6. 关闭网络
./network.sh down
该命令将停止并删除节点和链码容器、组织加密材料、删除之前运行的通道项目和docker卷,并从Docker Registry移除链码镜像。
因为
asset-transfer (basic)
链码的背书策略需要交易同时被Org1
和Org2
签名,所以链码调用指令需要使用--peerAddresses
标签来指向peer0.org1.example.com
和peer0.org2.example.com
;因为网络的TLS
被开启,指令也需要用--tlsRootCertFiles
标签指向每个peer
节点的TLS
证书。
相关实验源码已上传:https://github.com/wefantasy/FabricLearn
原文链接:https://blog.csdn.net/cx776474961/article/details/123992057?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165934461816782246452974%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=165934461816782246452974&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~times_rank-17-123992057-null-null.nonecase&utm_term=%E6%90%AD%E5%BB%BAcdn
原创文章,作者:优速盾-小U,如若转载,请注明出处:https://www.cdnb.net/bbs/archives/7576