1. 环境准备

本教程基于 VMware 17 Ubuntu 20.04Fabric 2.4.9 环境搭建和 Hyperledger Caliper 0.5.0 部署测试。

1.1. VMware安装

由于 VMware 被 Broadcom 收购,原官网停用,下载 VMware 需要注册 Broadcom 账户,个人觉得比较麻烦,推荐下载链接:

VMware Workstation Pro 17.5.2

VMware 17 安装教程,参考如下链接:

vmware-17虚拟机安装教程(保姆级包含图文讲解,不需注册账户)_vmware17-CSDN博客

1.2. Ubuntu安装

使用清华源下载 ios 镜像文件, Ubuntu 20.04 镜像下载链接:

Ubuntu 20.04

Ubuntu 20.04 安装教程,参考如下链接:

【Linux】Ubuntu 20.04安装教程(图文详解)_ubuntu20.04安装教程-CSDN博客

1.3. 基础环境安装

1.3.1. Git

sudo apt install git -y

安装完成后,查看版本:

git --version

1.3.2. cURL

sudo apt install curl -y

1.3.3. vim

sudo apt install vim -y

1.3.4. jq

sudo apt install jq -y

1.3.5. Docker和Docker-compose

我安装的版本分别为:docker 24.0.7 docker-compose 1.25.0

直接使用 apt 命令安装 docker-compose (并自动安装 docker )即可:

sudo apt install docker-compose

赋予 docker-compose 可执行权限:

sudo chmod +x /usr/bin/docker-compose

安装完成后,查看版本:

docker version
docker-compose version

设置 docker 自动启动:

sudo systemctl enable docker

查看 docker 启动状态:

systemctl status docker

安装 docker 时会添加名为 docker 的用户组,需要将当前的用户添加到用户组 docker 中:

sudo usermod -aG docker $USER

重启系统:

reboot

再次查看 docker 版本,确认 Server 已正常。

更换 docker 镜像源,创建目录 /etc/docker:

sudo mkdir -p /etc/docker

创建并修改 daemon.json 配置文件:

sudo vim /etc/docker/daemon.json

 添加如下内容:

{
    "registry-mirrors": [
    	"https://dockerproxy.cn",
    	"https://docker.1panel.dev",
	    "https://docker.fxxk.dedyn.io",
	    "https://docker.xn--6oq72ry9d5zx.cn",
	    "https://a.ussh.net",
	    "https://docker.zhai.cm",
	    "https://docker.m.daocloud.io",
        "https://docker.nju.edu.cn",
        "https://dockerproxy.com"
    ]
}

重启 docker:

sudo systemctl daemon-reload
sudo systemctl restart docker

查看镜像源是否配置成功:

docker info

1.3.6. Go

Fabric 2.4.9 要求 go 版本: Go 1.18.10 版本及以上

这里我安装的是 Go 1.22.4 ,安装命令:

wget https://dl.google.com/go/go1.22.4.linux-amd64.tar.gz
sudo tar -C /usr/local -zxvf go1.22.4.linux-amd64.tar.gz

配置环境变量,修改 ~/.bashrc 文件:

sudo vim ~/.bashrc

在文件开头添加如下内容:

export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin

使用 source 命令使之生效:

source ~/.bashrc

查看 go 版本信息:

go env

配置 Modules 和代理:

go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct

1.3.7. Node.js

为了方便安装和管理 Node.js 的版本,需要先在系统中安装 NVM(Node Version Manager),它是 Node.js 的版本管理软件,可以根据不同的需求在 Node.js 的各个版本之间进行切换。

在安装 Node.js 时, npm 也会跟着一起安装,它是 Node.js 的包管理工具,管理 Node.js 中的第三方依赖。

下载 NVM 的 Gitee 镜像:

git clone https://gitee.com/mirrors/nvm.git ~/.nvm && cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`

执行 install.sh:

./install.sh

创建并修改 .bash_profile 文件:

vim .bash_profile

添加如下内容:

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm

使用 source 命令使之生效:

source .bash_profile

验证 NVM 的安装是否成功:

nvm -v

Node.js 的版本要与 Fabric 的版本对应,参考如下图片:

我搭建的版本是 Fabric 2.4.9,所以 Node.js 安装 v16 版本:

nvm install v16.13.0

检查 Node.js 和 npm 的版本:

node -v && npm -v

设置镜像源:

npm config set registry https://registry.npmmirror.com/

1.3.8. nvm和npm的使用

(1)nvm

查看当前使用的 Node.js 版本:

nvm current

查看所有已安装的 Node.js 版本:

nvm ls

切换 Node.js 版本:

nvm use v16.13.0

(2)npm

列出 npm 当前的所有配置:

npm config list

查看配置的镜像源:

npm config get registry

2. Fabric 2.4.9搭建

2.1. 下载Fabric源码

进入 ~ 目录:

cd

创建如下目录:

mkdir -p go/src/github.com/hyperledger/

进入该目录:

cd go/src/github.com/hyperledger/

从 github 上拉取 Fabric 的源码:

git clone https://github.com/hyperledger/fabric.git

2.2. 执行bootstrap.sh脚本

进入如下目录:

cd ~/go/src/github.com/hyperledger/fabric/scripts

打开如下链接:https://github.com/hyperledger/fabric/blob/main/scripts/bootstrap.sh,这里的 bootstrap.sh 脚本显示的是最新版本的 Fabric ,在右边的历史中找到我们所需要的版本 Fabric 2.4.9 ,如下所示:

下载对应版本的 bootstrap.sh 文件,然后用该文件替换掉当前目录中的 bootstrap.sh 文件(或者将下面的内容直接复制到 bootstrap.sh 文件中), Fabric 2.4.9 版本的 bootstrap.sh 文件的内容如下:

#!/bin/bash
#
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

# if version not passed in, default to latest released version
VERSION=2.4.9
# if ca version not passed in, default to latest released version
CA_VERSION=1.5.5

REGISTRY=${FABRIC_DOCKER_REGISTRY:-docker.io/hyperledger}

OS=$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/windows/')
ARCH=$(uname -m | sed 's/x86_64/amd64/g' | sed 's/aarch64/arm64/g')
PLATFORM=${OS}-${ARCH}

# Fabric < 1.2 uses uname -m for architecture.
MARCH=$(uname -m)

: ${CONTAINER_CLI:="docker"}

printHelp() {
    echo "Usage: bootstrap.sh [version [ca_version]] [options]"
    echo
    echo "options:"
    echo "-h : this help"
    echo "-d : bypass docker image download"
    echo "-s : bypass fabric-samples repo clone"
    echo "-b : bypass download of platform-specific binaries"
    echo
    echo "e.g. bootstrap.sh 2.4.9 1.5.5 -s"
    echo "will download docker images and binaries for Fabric v2.4.9 and Fabric CA v1.5.5"
}

# dockerPull() pulls docker images from fabric and chaincode repositories
# note, if a docker image doesn't exist for a requested release, it will simply
# be skipped, since this script doesn't terminate upon errors.

dockerPull() {
    #three_digit_image_tag is passed in, e.g. "1.4.7"
    three_digit_image_tag=$1
    shift
    #two_digit_image_tag is derived, e.g. "1.4", especially useful as a local tag for two digit references to most recent baseos, ccenv, javaenv, nodeenv patch releases
    two_digit_image_tag=$(echo "$three_digit_image_tag" | cut -d'.' -f1,2)
    while [[ $# -gt 0 ]]
    do
        image_name="$1"
        echo "====>  ${REGISTRY}/fabric-$image_name:$three_digit_image_tag"
        ${CONTAINER_CLI} pull "${REGISTRY}/fabric-$image_name:$three_digit_image_tag"
        ${CONTAINER_CLI} tag "${REGISTRY}/fabric-$image_name:$three_digit_image_tag" "${REGISTRY}/fabric-$image_name"
        ${CONTAINER_CLI} tag "${REGISTRY}/fabric-$image_name:$three_digit_image_tag" "${REGISTRY}/fabric-$image_name:$two_digit_image_tag"
        shift
    done
}

cloneSamplesRepo() {
    # clone (if needed) hyperledger/fabric-samples and checkout corresponding
    # version to the binaries and docker images to be downloaded
    if [ -d test-network ]; then
        # if we are in the fabric-samples repo, checkout corresponding version
        echo "==> Already in fabric-samples repo"
    elif [ -d fabric-samples ]; then
        # if fabric-samples repo already cloned and in current directory,
        # cd fabric-samples
        echo "===> Changing directory to fabric-samples"
        cd fabric-samples
    else
        echo "===> Cloning hyperledger/fabric-samples repo"
        git clone -b main https://github.com/hyperledger/fabric-samples.git && cd fabric-samples
    fi

    if GIT_DIR=.git git rev-parse v${VERSION} >/dev/null 2>&1; then
        echo "===> Checking out v${VERSION} of hyperledger/fabric-samples"
        git checkout -q v${VERSION}
    else
        echo "fabric-samples v${VERSION} does not exist, defaulting to main. fabric-samples main branch is intended to work with recent versions of fabric."
        git checkout -q main
    fi
}

# This will download the .tar.gz
download() {
    local BINARY_FILE=$1
    local URL=$2
    echo "===> Downloading: " "${URL}"
    curl -L --retry 5 --retry-delay 3 "${URL}" | tar xz || rc=$?
    if [ -n "$rc" ]; then
        echo "==> There was an error downloading the binary file."
        return 22
    else
        echo "==> Done."
    fi
}

pullBinaries() {
    echo "===> Downloading version ${FABRIC_TAG} platform specific fabric binaries"
    download "${BINARY_FILE}" "https://github.com/hyperledger/fabric/releases/download/v${VERSION}/${BINARY_FILE}"
    if [ $? -eq 22 ]; then
        echo
        echo "------> ${FABRIC_TAG} platform specific fabric binary is not available to download <----"
        echo
        exit
    fi

    echo "===> Downloading version ${CA_TAG} platform specific fabric-ca-client binary"
    download "${CA_BINARY_FILE}" "https://github.com/hyperledger/fabric-ca/releases/download/v${CA_VERSION}/${CA_BINARY_FILE}"
    if [ $? -eq 22 ]; then
        echo
        echo "------> ${CA_TAG} fabric-ca-client binary is not available to download  (Available from 1.1.0-rc1) <----"
        echo
        exit
    fi
}

pullDockerImages() {
    command -v ${CONTAINER_CLI} >& /dev/null
    NODOCKER=$?
    if [ "${NODOCKER}" == 0 ]; then
        FABRIC_IMAGES=(peer orderer ccenv tools)
        case "$VERSION" in
        2.*)
            FABRIC_IMAGES+=(baseos)
            shift
            ;;
        esac
        echo "FABRIC_IMAGES:" "${FABRIC_IMAGES[@]}"
        echo "===> Pulling fabric Images"
        dockerPull "${FABRIC_TAG}" "${FABRIC_IMAGES[@]}"
        echo "===> Pulling fabric ca Image"
        CA_IMAGE=(ca)
        dockerPull "${CA_TAG}" "${CA_IMAGE[@]}"
        echo "===> List out hyperledger docker images"
        ${CONTAINER_CLI} images | grep hyperledger
    else
        echo "========================================================="
        echo "${CONTAINER_CLI} not installed, bypassing download of Fabric images"
        echo "========================================================="
    fi
}

DOCKER=true
SAMPLES=true
BINARIES=true

# Parse commandline args pull out
# version and/or ca-version strings first
if [ -n "$1" ] && [ "${1:0:1}" != "-" ]; then
    VERSION=$1;shift
    if [ -n "$1" ]  && [ "${1:0:1}" != "-" ]; then
        CA_VERSION=$1;shift
        if [ -n  "$1" ] && [ "${1:0:1}" != "-" ]; then
            THIRDPARTY_IMAGE_VERSION=$1;shift
        fi
    fi
fi

# prior to 1.2.0 architecture was determined by uname -m
if [[ $VERSION =~ ^1\.[0-1]\.* ]]; then
    export FABRIC_TAG=${MARCH}-${VERSION}
    export CA_TAG=${MARCH}-${CA_VERSION}
    export THIRDPARTY_TAG=${MARCH}-${THIRDPARTY_IMAGE_VERSION}
else
    # starting with 1.2.0, multi-arch images will be default
    : "${CA_TAG:="$CA_VERSION"}"
    : "${FABRIC_TAG:="$VERSION"}"
    : "${THIRDPARTY_TAG:="$THIRDPARTY_IMAGE_VERSION"}"
fi

# Prior to fabric 2.5, use amd64 binaries on darwin-arm64
if [[ $VERSION =~ ^2\.[0-4]\.* ]]; then
  PLATFORM=$(echo $PLATFORM | sed 's/darwin-arm64/darwin-amd64/g')
fi

BINARY_FILE=hyperledger-fabric-${PLATFORM}-${VERSION}.tar.gz
CA_BINARY_FILE=hyperledger-fabric-ca-${PLATFORM}-${CA_VERSION}.tar.gz

# then parse opts
while getopts "h?dsb" opt; do
    case "$opt" in
        h|\?)
            printHelp
            exit 0
            ;;
        d)  DOCKER=false
            ;;
        s)  SAMPLES=false
            ;;
        b)  BINARIES=false
            ;;
    esac
done

if [ "$SAMPLES" == "true" ]; then
    echo
    echo "Clone hyperledger/fabric-samples repo"
    echo
    cloneSamplesRepo
fi
if [ "$BINARIES" == "true" ]; then
    echo
    echo "Pull Hyperledger Fabric binaries"
    echo
    pullBinaries
fi
if [ "$DOCKER" == "true" ]; then
    echo
    echo "Pull Hyperledger Fabric docker images"
    echo
    pullDockerImages
fi

执行 bootstrap.sh 脚本:

./bootstrap.sh

执行 bootstrap.sh 脚本,主要会做以下3步:1. 克隆 fabric samples 的代码;2. 下载 fabric 和 fabric-ca 的二进制文件;3. 拉取 fabric 所需要的一些镜像 image 。由于直接执行 bootstrap.sh 脚本文件很有可能会出现卡死的问题或者由于网络问题而无法连接的问题,第一步一般都没有问题,主要是第二步和第三步,对于第二步,可以采用手动下载的方式,挂个梯子去 github 官网下载 fabric 和 fabric-ca 编译后的压缩包,这样速度就很快,然后将压缩包直接拖入虚拟机中,最后将其存放在当前目录下,即:~/go/src/github.com/hyperledger/fabric/scripts

如果出现下载很慢或者网络连接超时等问题,按下 Ctrl+C 键结束命令的执行,继续下面的步骤。

此时检查一下当前 scripts 目录下是否存在 fabric-samples 目录,如果存在,继续下面的步骤,如果不存在就继续重新执行 bootstrap.sh 脚本直至生成该目录。

我下载的版本分别是 fabric 2.4.9fabric-ca 1.5.5 ,在如下链接中找到对应版本下载即可:

fabric:

Releases · hyperledger/fabric · GitHub

fabric-ca:

Releases · hyperledger/fabric-ca · GitHub

 点击 Assets ,下载对应版本:

将这两个压缩包解压到 fabric-samples 目录下:

sudo tar -zxvf hyperledger-fabric-linux-amd64-2.4.9.tar.gz -C ~/go/src/github.com/hyperledger/fabric/scripts/fabric-samples
sudo tar -zxvf hyperledger-fabric-ca-linux-amd64-1.5.5.tar.gz -C ~/go/src/github.com/hyperledger/fabric/scripts/fabric-samples

再次执行 bootstrap.sh 脚本:

./bootstrap.sh -sb

在上面命令中,参数 -sb ,其中 s 表示不执行第一步,即不克隆 fabric-samples 的代码, b 表示不执行第二步,即不下载 fabric 和 fabric-ca 的二进制文件,由于在前面的步骤中我们完成了第一步和第二步,所以只需要执行第三步就可以了,即拉取 fabric 所需的一些镜像 image 。

将 fabric-samples 目录下的 bin 目录添加到 PATH 环境变量中,首先修改 ~/.bashrc 文件:

sudo vim ~/.bashrc

在文件开头添加如下内容:

export PATH=$HOME/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/bin:$PATH

使用 source 命令使之生效:

source ~/.bashrc

验证环境变量是否配置成功:

peer version

2.3. 启动测试网络

进入 test-network 目录:

cd fabric-samples/test-network

2.3.1. 启动网络

sudo ./network.sh up

2.3.2. 创建通道

sudo ./network.sh createChannel

注意:通道默认的名字是: mychannel ,也可以使用 -c 来指定通道名称,以下命令将创建一个名为 channel1 的通道:

sudo ./network.sh createChannel -c Channel1

通道创建成功,结果如下所示:

2.3.3. 启动链码

首先配置环境变量,修改 ~/.bashrc 文件:

vim ~/.bashrc

在文件开头添加如下内容:

alias sudo='sudo env PATH=$PATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH'

 使用 source 命令使之生效:

source ~/.bashrc

我们要部署的链码是 go 语言编写的代码,在 chaincode-go 目录下,执行以下命令下载相关依赖:

cd ../asset-transfer-basic/chaincode-go
go mod vendor

结果如下所示:

然后回到 test-network 目录,执行启动链码命令,在 mychannel 通道启动一个链码:

sudo ./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go

注意:如果通道名称不是 mychannel ,在命令中添加 -c 通道名称,表示在该通道上部署链码,如下命令就是在名为 channel1 的通道上部署链码:

sudo ./network.sh deployCC -c channel1 -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go

链码启动成功,结果如下所示:

2.3.4. 与网络交互

由于接下来的操作需要管理员权限,所以执行如下命令,进入 root 用户:

sudo su

在启用测试网络后,可以使用 peer cli 客户端与网络进行交互,通过 peer cli 客户端可以调用已部署的智能合约,更新通道,或安装和部署新的智能合约。

执行以下命令将 cli 客户端添加到环境变量中:

export PATH=${PWD}/../bin:$PATH

将 fabric-samples 代码库中的 FABRIC_CFG_PATH 设置为指向其中的 core.yaml 文件:

export FABRIC_CFG_PATH=$PWD/../config/

设置允许 org1 操作 peer cli 的环境变量:

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

CORE_PEER_TLS_ROOTCERT_FILE 和 CORE_PEER_MSPCONFIGPATH 环境变量指向 Org1 的 organizations 文件夹中的的加密材料。

执行以下命令用一些资产来初始化账本:

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

执行成功会返回 Chaincode invoke successful. result: status:200 如下图所示:

执行以下指令来查询通道账本中的资产列表: 

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

结果如下图所示,说明测试网络操作成功:

修改资产所有者,将 asset1 资产的所有者修改为 IDY:

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 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":["asset1","IDY"]}'

 执行成功后的结果:

查看修改后的结果:

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

到这里 Fabric 2.4.9 的搭建和测试就完成了,接下来是 Caliper 0.5.0 的部署和测试。

3. Caliper 0.5.0部署和测试

3.1. Caliper安装

3.1.1. 创建Caliper工作区

在 fabric-samples 目录的同一级别创建一个名为 caliper-workspace 的文件夹,然后在 caliper-workspace 文件夹中,分别创建三个名为 networks 、 benchmarks 和 workload 的文件夹:

mkdir -p caliper-workspace/{networks,benchmarks,workload}

如下所示:

3.1.2. 初始化项目

在 caliper-workspace 目录中初始化项目:

cd caliper-workspace && npm init -y

执行完后,在当前目录生成了 package.json 文件。

3.1.3. 安装caliper-cli

在 caliper-workspace 目录中,使用以下终端命令安装 caliper CLI:

npm install --only=prod @hyperledger/caliper-cli@0.5.0

执行完后,会将依赖下载到当前目录下的 node_modules 文件下。

验证 caliper-cli 是否安装成功:

npx caliper --version

3.1.4. 绑定Fabric 2.4

npx caliper bind --caliper-bind-sut fabric:2.4

3.2. 构建网络配置文件

在低版本中采用的是 .json 文件,而在新版本中需要采用 .yaml 文件,在 networks 文件夹下创建一个名为 networkConfig.yaml 的文件:

cd networks && touch networkConfig.yaml

添加如下内容:

name: Caliper Benchmarks
version: "2.0.0"

caliper:
  blockchain: fabric

channels:
  - channelName: mychannel
    contracts:
    - id: basic

organizations:
  - mspid: Org1MSP
    identities:
      certificates:
      - name: 'Admin@org1.example.com'
        clientPrivateKey:
          path: '../fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/priv_sk'
        clientSignedCert:
          path: '../fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/Admin@org1.example.com-cert.pem'
    connectionProfile:
      path: '../fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/connection-org1.yaml'
      discover: true

3.3. 构建测试工作负载模块

在 workload 文件夹中,创建一个名为 readAsset.js 的文件:

cd ../workload && touch readAsset.js

添加如下内容:

'use strict';

const { WorkloadModuleBase } = require('@hyperledger/caliper-core');

class MyWorkload extends WorkloadModuleBase {
    constructor() {
        super();
    }
    
    async initializeWorkloadModule(workerIndex, totalWorkers, roundIndex, roundArguments, sutAdapter, sutContext) {
        await super.initializeWorkloadModule(workerIndex, totalWorkers, roundIndex, roundArguments, sutAdapter, sutContext);

        for (let i=0; i<this.roundArguments.assets; i++) {
            const assetID = `${this.workerIndex}_${i}`;
            console.log(`Worker ${this.workerIndex}: Creating asset ${assetID}`);
            const request = {
                contractId: this.roundArguments.contractId,
                contractFunction: 'CreateAsset',
                invokerIdentity: 'Admin@org1.example.com',
                contractArguments: [assetID,'blue','20','penguin','500'],
                readOnly: false
            };

            await this.sutAdapter.sendRequests(request);
        }
    }
    
    async submitTransaction() {
        const randomId = Math.floor(Math.random()*this.roundArguments.assets);
        const myArgs = {
            contractId: this.roundArguments.contractId,
            contractFunction: 'ReadAsset',
            invokerIdentity: 'Admin@org1.example.com',
            contractArguments: [`${this.workerIndex}_${randomId}`],
            readOnly: true
        };

        await this.sutAdapter.sendRequests(myArgs);
    }
    
    async cleanupWorkloadModule() {
        for (let i=0; i<this.roundArguments.assets; i++) {
            const assetID = `${this.workerIndex}_${i}`;
            console.log(`Worker ${this.workerIndex}: Deleting asset ${assetID}`);
            const request = {
                contractId: this.roundArguments.contractId,
                contractFunction: 'DeleteAsset',
                invokerIdentity: 'Admin@org1.example.com',
                contractArguments: [assetID],
                readOnly: false
            };

            await this.sutAdapter.sendRequests(request);
        }
    }
}

function createWorkloadModule() {
    return new MyWorkload();
}

module.exports.createWorkloadModule = createWorkloadModule;

3.4. 构建基准测试配置文件

在 benchmarks 文件夹下创建一个名为 myAssetBenchmark.yaml 的文件:

cd ../benchmarks && touch myAssetBenchmark.yaml

添加如下内容:

test:
    name: basic-contract-benchmark
    description: test benchmark
    workers:
      type: local
      number: 2
    rounds:
      - label: readAsset
        description: Read asset benchmark
        txDuration: 30
        rateControl: 
          type: fixed-load
          opts:
            transactionLoad: 2
        workload:
          module: workload/readAsset.js
          arguments:
            assets: 10
            contractId: basic
monitors:
  resource:
  - module: docker
    options:
      interval: 5 
      containers:
      - all

3.5. 运行Caliper基准测试

npx caliper launch manager --caliper-workspace ./ --caliper-networkconfig networks/networkConfig.yaml --caliper-benchconfig benchmarks/myAssetBenchmark.yaml --caliper-flow-only-test --caliper-fabric-gateway-enabled --caliper-fabric-gateway-discovery

如果出现如下错误:

错误信息:

2024.10.21-20:52:36.860 error [caliper] [caliper-engine] Error while performing "test" step: Error: EACCES: permission denied, open '/home/idy/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/priv_sk'

这个错误是没有权限,无法打开 priv_sk 文件,执行如下命令授予权限: 

chmod 666 ~/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/priv_sk

成功执行启动基准测试命令后,在 caliper-workspace 目录下生成 report.html 的性能测试报告。

还可以测试 CPU Memory 等资源的消耗情况。

4. 参考资料

(1)

Hyperledger Fabric 入门笔记(三)Fabric V2.5 环境搭建_fabric_荆棘鸟骑士-开放原子开发者工作坊 (csdn.net)

(2)

​​​​​​记录搭建 区块链Hyperledger Fabric2.5.4版本环境 - 知乎 (zhihu.com) 

(3)

超级账本Fabric 2.x 详细安装步骤及可能问题解决方式-CSDN博客

(4)
https://github.com/hyperledger/fabric-samples/issues/1097

(5)

Fabric 2.2.0上搭建Hyperledger caliper进行性能测试_fabric caliper-CSDN博客

(6)

超级账本Fabric2.x 如何将智能合约部署到通道_fabric2.x部署-CSDN博客

(7)

解决超级账本测试网络配置中 Cannot run peer because error when setting up MSP of type bccsp from directory 的问题-CSDN博客

(8)

Hyperledger Fabric v2.4.9环境搭建和Caliper 0.5.0测试工具部署教程(MacOS)

(9)

Hyperledger fabric 2.4.9搭建与caliper性能测试

(10)

https://hyperledger-fabric.readthedocs.io/zh-cn/release-2.5/

(11)

hyperledger caliper的使用(以Hyperledger Fabric为例) - TR_Goldfish - 博客园

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐