相干试验源码已上传:https://github.com/wefantasy/…
前言
在基于 truffle 框架实现以太坊公开拍卖智能合约中咱们曾经实现了以太坊智能合约的编写及部署,但其工作形式注定其只能利用于无限的业务场景中。相比之下,基于超级账本的 Fabric
具备高可扩展性和高可定制性,可能利用在更为简单的商业场景中,但 Fabric
技术波及很多新的概念,源代码跟新速度快且各版本间兼容性差,对初学者很不敌对。为了使可能疾速把握 Fabric
,本文基于其目前最新的 2.4 版本搭建了一套区块链运行环境,并在此之上部署了官网示例chaincode
并对其进行交互调试,最终整个环境及示例代码可能失常运行且得出预期后果。
环境搭建
网上简直所有的 Fabric
教程都是基于 Ubuntu
环境而不是 Windows
,其起因次要是Fabric
的运行须要的 Docker
环境在 Windows
下体现不佳,此外 Fabric
许多官网文档也是基于 Ubuntu
纂写,在 windows
下运行可能会遇到难以预估的 bug
。本来为了不便前期部署至公网服务器想在 CentOS 上搭建环境,但因为 CentOS8 进行保护,且 CentOS Stream 应用体验颇差,于是最终抉择了 Debian 零碎。
本环境各零碎、软件版本如下:
零碎、软件 | 版本 |
---|---|
VMware Pro | 16.0.0 |
Debian | debian-11.2.0-amd64-DVD-1.iso |
git | 2.30.2 |
curl | 7.74.0 |
docker | 20.10 |
golang | go1.17.8 |
jq | jq-1.6 |
fabric | 2.4.0 |
fabric-ca | 1.5.2 |
fabric-samples | [v2.3.0]() |
本环境各 Docker 镜像版本如下:
镜像 | 版本 |
---|---|
hyperledger/fabric-tools | 2.4 |
hyperledger/fabric-peer | 2.4 |
hyperledger/fabric-orderer | 2.4 |
hyperledger/fabric-ccenv | 2.4 |
hyperledger/fabric-baseos | 2.4 |
hyperledger/fabric-ca | 1.5 |
正告:倡议 Fabric 所有试验过程皆在 root 权限下进行,否则在 sudo 权限切换的过程中会呈现很多环境变量的问题。
杂项装置
-
装置最新版本
Git
apt install git
-
装置最新版本
cURL
apt install curl
- 装置
Golang
-
装置 jq
apt install jq
装置 Fabric
官网脚本装置
为了帮忙开发者疾速搭建
Fabric
环境,官网创立了一个Fabric
环境搭建的批处理工具bootstrap.sh
,能够通过该工具间接装置环境:wget https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap.sh chmod +x bootstrap.sh ./bootstrap.sh
不出意外的话会看见脚本顺利的环境装置过程:
手动装置
当然,间接应用官网脚本不出意外的话必定会出意外(网络起因),在此咱们能够通过手动装置须要的各项环境。
- 装置 fabric-samples
fabric-samples
是Fabric
的官网 Demo 汇合,其外部蕴含多个示例,每个示例有Golang
、JavaScript
、typescript
、Java
的链码实现,并且这些链码能够间接部署到对应的Fabric
上,对初学者很有帮忙。fabric-samples
装置非常简单,应用git clone git@github.com:hyperledger/fabric-samples.git
将我的项目源码克隆到本地即可,若始终失败也能够间接在 release 中下载对应版本的压缩包。 - 装置 Fabric
Fabric 是联盟链的外围开发工具,蕴含了咱们开发、编译、部署过程中的所有命令。 -
下载 fabric 2.4.0 并解压
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
-
下载 fabric-ca 1.5.2 并解压
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
-
设置环境变量,在
/etc/profile
开端增加#Fabric export FABRIC=/usr/local/fabric export PATH=$PATH:$FABRIC/bin
-
更新环境变量
source /etc/profile
装置 Docker
-
如果存在则移除旧的版本
apt remove docker docker-engine docker.io containerd runc
-
更新
apt
索引包并容许其应用HTTPS
装置apt update apt install \ apt-transport-https \ ca-certificates \ curl \ gnupg \ lsb-release
-
增加
Docker
官网GPG
密钥curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
-
增加
Docker
仓库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
-
装置
Docker
引擎apt update apt install docker-ce docker-ce-cli containerd.io
-
装置
docker-compose
apt install docker-compose
装置 Docker 镜像依赖
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
最终的镜像为:
运行测试
启动 fabric 网络
-
进入 fabric-sample 的 test-network 目录
cd fabric-samples/test-network
-
运行
./network.sh up
启动网络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
。
创立 channel
上节曾经在机器上运行了 peer 节点和 orderer 节点,当初能够应用 network.sh 为 Org1 和 Org2 之间创立 channel。channel 是特定网络成员之间的公有通道,只能被属于该通道的组织应用,并且对网络的其余成员是不可见的。每个 channel 都有一个独自的区块链账本,属于该通道的组织能够让其下 peer 退出该通道,以让 peer 可能存储 channel 上的帐本并验证账本上的交易。
应用以下命令创立自定义通道 testchannel:
./network.sh createChannel -c testchannel
部署 chaincode
倡议部署操作全副在
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
文件中间接将该限度正文 1:
加上正文后从新执行上条命令,又呈现了新的谬误:
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
命令配置国内代理 2 后再次执行。令人意外的是谬误不变,设置的代理没有失效?手动应用 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
合约交互
在装置 fabric 中咱们曾经设置了 fabric
可执行文件的环境变量,需保障能够胜利在 test-network
目录下应用 peer
命令。
-
设置 FABRIC_CFG_PATH 变量,其下需蕴含 core.yaml 文件
export FABRIC_CFG_PATH=$PWD/../config/ # export FABRIC_CFG_PATH=/usr/local/fabric/config/
-
设置其它
Org1
组织的变量依赖# 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
-
初始化 chaincode
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":[]}'
-
查问账本资产列表
peer chaincode query -C testchannel -n basic -c '{"Args":["GetAllAssets"]}'
-
批改账本资产
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"]}'
-
敞开网络
./network.sh down
该命令将进行并删除节点和链码容器、组织加密资料、删除之前运行的通道我的项目和 docker 卷,并从 Docker Registry 移除链码镜像。
因为
asset-transfer (basic)
链码的背书策略须要交易同时被Org1
和Org2
签名,所以链码调用指令须要应用--peerAddresses
标签来指向peer0.org1.example.com
和peer0.org2.example.com
;因为网络的TLS
被开启,指令也须要用--tlsRootCertFiles
标签指向每个peer
节点的TLS
证书。
参考
- qq_JWang_03215367. 解决 command not found 报错. 慕课. [2018-07-31] ↩
- 沐沐子枫. failed to normalize chaincode path: ‘go list’ failed with: go. 博客园. [2020-11-27] ↩