乐趣区

关于区块链:基于Debian搭建Hyperledger-Fabric-24开发环境及运行简单案例

相干试验源码已上传: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 权限切换的过程中会呈现很多环境变量的问题。

杂项装置

  1. 装置最新版本Git

    apt install git
  2. 装置最新版本cURL

    apt install curl
  3. 装置Golang
  4. 装置 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

    不出意外的话会看见脚本顺利的环境装置过程:

手动装置

当然,间接应用官网脚本不出意外的话必定会出意外(网络起因),在此咱们能够通过手动装置须要的各项环境。

  1. 装置 fabric-samples
    fabric-samplesFabric 的官网 Demo 汇合,其外部蕴含多个示例,每个示例有 GolangJavaScripttypescriptJava 的链码实现,并且这些链码能够间接部署到对应的 Fabric 上,对初学者很有帮忙。fabric-samples装置非常简单,应用 git clone git@github.com:hyperledger/fabric-samples.git 将我的项目源码克隆到本地即可,若始终失败也能够间接在 release 中下载对应版本的压缩包。
  2. 装置 Fabric
    Fabric 是联盟链的外围开发工具,蕴含了咱们开发、编译、部署过程中的所有命令。
  3. 下载 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
  4. 下载 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
  5. 设置环境变量,在 /etc/profile 开端增加

    #Fabric
    export FABRIC=/usr/local/fabric
    export PATH=$PATH:$FABRIC/bin
  6. 更新环境变量source /etc/profile

    装置 Docker

  7. 如果存在则移除旧的版本

    apt remove docker docker-engine docker.io containerd runc
  8. 更新 apt 索引包并容许其应用 HTTPS 装置

    apt update
    apt install \
     apt-transport-https \
     ca-certificates \
     curl \
     gnupg \
     lsb-release
  9. 增加 Docker 官网 GPG 密钥

    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
  10. 增加 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
  11. 装置 Docker 引擎

    apt update
    apt install docker-ce docker-ce-cli containerd.io
  12. 装置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 网络

  1. 进入 fabric-sample 的 test-network 目录

    cd fabric-samples/test-network
  2. 运行 ./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.compeer0.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 命令会应用 rootgo环境变量,而之前设置的代理、下载的包都只能在本地用户下失效,因而这个问题最终的解决方案是间接切换到 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 命令。

  1. 设置 FABRIC_CFG_PATH 变量,其下需蕴含 core.yaml 文件

    export FABRIC_CFG_PATH=$PWD/../config/
    # export FABRIC_CFG_PATH=/usr/local/fabric/config/
  2. 设置其它 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
  3. 初始化 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":[]}'

  4. 查问账本资产列表

    peer chaincode query -C testchannel -n basic -c '{"Args":["GetAllAssets"]}'

  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"]}'

  6. 敞开网络

    ./network.sh down

    该命令将进行并删除节点和链码容器、组织加密资料、删除之前运行的通道我的项目和 docker 卷,并从 Docker Registry 移除链码镜像。

因为 asset-transfer (basic) 链码的背书策略须要交易同时被 Org1Org2签名,所以链码调用指令须要应用 --peerAddresses 标签来指向 peer0.org1.example.compeer0.org2.example.com;因为网络的 TLS 被开启,指令也须要用 --tlsRootCertFiles 标签指向每个 peer 节点的 TLS 证书。

参考


  1. qq_JWang_03215367. 解决 command not found 报错. 慕课. [2018-07-31] ↩
  2. 沐沐子枫. failed to normalize chaincode path: ‘go list’ failed with: go. 博客园. [2020-11-27] ↩
退出移动版