IBM Blockchain Platform Extension for VS Code 可帮助开发者创建、测试和调试智能合约。但对于开发人员来说,还有一个关键问题:开发的智能合约的性能如何?

Hyperledger Caliper 是一种区块链基准测试工具,旨在对已部署的智能合约执行基准测试,从而能够分析在使用智能合约时区块链网络的吞吐量、延迟和资源消耗情况。本教程向您展示如何通过 Hyperledger Caliper 对使用 IBM Blockchain Platform VS Code 扩展开发和部署的 Hyperledger Fabric 智能合约进行性能测试。

前提条件

要完成本教程,您将需要:

完成了内置的 IBM Blockchain Platform VS Code 教程 1,其中开发并部署了 demoContract@0.0.1,以便与 MyAsset 类型的资产进行交互。

预估时间

一旦完成 VS Code 教程(大约需要 20 到 30 分钟),您就可以开始以下构建过程:

获取并配置 Caliper

创建 Caliper 测试资产

运行性能基准测试

这些后续步骤大约需要 30 到 40 分钟。

步骤

要完成本教程,您需要完成三个主要步骤,详细说明如下:

获取 Caliper

创建 Caliper 测试资产

运行基准测试

第 1 步. 获取 Caliper

在本教程中,您将使用 Caliper CLI,这是一个可以通过 npm 获取并安装的节点模块。一旦安装了 Caliper CLI,您就需要将该工具绑定到目标区块链的指定 SDK。本教程便是使用 Caliper-CLI 版本 0.1.0 和 Fabric-SDK-Node 版本 1.4.4 制作的。

任务:

使用以下终端命令全局安装 Caliper CLI 模块:

npm install -g --only=prod @hyperledger/caliper-cli@0.1.0Show moreShow more icon

使用终端命令绑定到所需的 SDK:

caliper bind --caliper-bind-sut fabric --caliper-bind-sdk 1.4.4 --caliper-bind-args=-gShow moreShow more icon

现在,您可以使用 Caliper,利用配置为使用指定 1.4.4 SDK 的客户端对 Fabric 网络进行基准测试。

第 2 步. 创建 Caliper 测试资产

Caliper 需要两个配置文件:

网络配置文件,用于描述受测系统并提供网络连接要求

基准测试配置,用于描述性能基准测试工作负载并引用用户指定的测试文件

所有必需的测试资产都将在一个新目录中创建,该目录充当工作区。

任务:

在 VS Code 中,创建一个名为 benchmarks 的新文件夹。

右键单击此文件夹,然后选择 Open in Terminal。

现在,您将使用网络配置文件填充此目录,并对 Caliper 所需的资产进行基准测试。

网络配置文件

网络配置文件用于描述受测系统,并提供与网络交互的客户端的连接要求。可以使用 YAML 或 JSON 格式来指定此文件。

对于 Fabric 网络,网络配置文件是扩展的通用连接配置文件,通过 Caliper 所需的元素进行了扩充。

任务:

切换到 IBM Blockchain Platform 扩展窗口,并断开与任何网关的连接。

从 VS Code 导出连接配置文件:在 Fabric Gateways -> Local Fabric 下,右键单击并选择以导出连接配置文件。

将此配置文件保存在 benchmarks 文件夹下,并且另存为 network_config.json。

从 VS Code 中导出本地 Fabric 钱包:在 Fabric Wallets -> Local Fabric Wallet 下,右键单击并导出钱包。

将钱包保存在 benchmarks 文件夹下,并且另存为 myWallet。

接下来,编辑导出的连接配置文件,添加以下必需属性:

{

"caliper": {},

"wallet": "",

"clients": {},

"channels": {}

}Show moreShow more icon

任务:

打开导出的连接配置文件 network_config.json。

标识正在测试的分布式账本技术 (DLT) 引擎。在文件的顶部,将 caliper 对象添加到模式,该模式包含单个名为 blockchain 的属性,其字符串值为 fabric。

"caliper": {

"blockchain": "fabric"

},Show moreShow more icon

标识其中包含与网络交互所需身份的钱包:

添加名为 wallet 的密钥。

在 VS Code 中,右键单击 wallet 文件夹,选择 Copy Path,然后将其提供为 wallet 属性的值:

"wallet": "",Show moreShow more icon

通过提供客户端身份到客户端对象的映射,指定 Caliper 可用于与网络交互的客户端:

将现有的 client 对象嵌套在一个新的 JSON 对象中,该对象使用所导出钱包中某个身份的名称。在此场景中,名为 admin。

将上面创建的映射身份嵌套在名为 clients 的新 JSON 对象中。

"clients": {

"admin": {

"client": {

"organization": "Org1",

"connection": {

"timeout": {

"peer": {

"endorser": "300"

},

"orderer": "300"

}

}

}

}

},Show moreShow more icon

标识可用的通道以及部署到这些通道的智能合约:

在 clients 对象下的模式中添加一个 channels 对象。

在 channels 对象中,添加另一个名为 mychannel 的对象,这是由 VS Code 创建且在其中部署了智能合约的默认通道的名称。

在 mychannel 对象中,添加一个名为 chaincodes 的数组对象。在此数组中,添加一个对象,其中包含已部署智能合约的 ID 和版本的键/值对,它们分别为 demoContract 和 0.0.1:

"channels": {

"mychannel": {

"chaincodes": [

{

"id": "demoContract",

"version": "0.0.1"

}

]

}

},Show moreShow more icon

保存修改后的文件。

现在,您已具有了可供 Caliper 使用的网络配置文件。

基准测试配置

基准测试包括在几轮测试中重复执行指定的测试回调文件,每一轮的持续时间均受到控制,并且在这几轮测试中,负载由客户端(可能是多个)驱动,这些客户端本身通过速率控制机制进行控制。

基准测试配置需要:

一个或多个测试回调文件,这些文件与已部署的智能合约交互并定义要调查的操作

一个配置文件,用于定义基准测试轮次并引用已定义的回调

接下来,您将创建一个用于与部署的智能合约进行交互的测试回调文件,以及一个在单轮测试中引用该测试回调文件的配置文件。

测试回调文件

测试回调文件是在每轮基准测试期间与已部署智能合约的交互点。每个测试回调文件都必须导出以下函数:

init 函数 — 用于初始化要在 run 部分中使用的任何必需项目

run 函数 — 用于在监控的基准测试阶段与智能合约方法进行交互

end 函数 — 用于在运行阶段完成后执行清理操作

部署的智能合约包含资产的完整 CRUD 操作集;为简洁起见,我们仅研究“readMyAsset”智能合约方法。

Caliper 区块链对象使用以下方法与已部署的智能合约进行交互:

invokeSmartContract (ctx, contractId, contractVersion, args)

querySmartContract (ctx, contractId, contractVersion, args)

其中:

ctx 是用户上下文

contractId 是智能合约名称

contractVersion 是智能合约版本

args 是包含以下内容的对象:chaincodeFunction — 要调用的智能合约函数的名称

invokerIdentity — 执行函数调用时使用的身份

chaincodeArguments — 调用时传递到函数的参数数组

下面是一个基本测试回调模板,该模板与版本为 0.0.1 的已部署智能合约 demoContract 进行交互:

'use strict';

module.exports.info = 'Template callback';

const contractID = 'demoContract';

const version = '0.0.1';

let bc, ctx, clientArgs, clientIdx;

module.exports.init = async function(blockchain, context, args) {

};

module.exports.run = function() {

return Promise.resolve();

};

module.exports.end = async function() {

};Show moreShow more icon

任务:

在 benchmarks 文件夹中创建一个名为 callbacks 的子文件夹。

在 callbacks 文件夹中创建一个名为 queryAssetBenchmark.js 的文件。

打开该文件并插入上面的模板代码。

保存该文件。

现在应该填充 init、run 和 end 模板函数了。

init 函数

该函数用于持久化传递的参数,并准备 run 函数中所需的所有项目。至少,您需要持久化 blockchain 和 context 参数,但是由于 readMyAsset 函数需要一组要查询的资产,因此您还需要创建这些资产。您可以将用户指定的一组参数传递给 init 函数,这意味着您可以指定一个变量来表示要在测试期间创建的资产数量。应该注意的是,由于在基准测试期间可能会使用多个客户端,并且这些客户端都将调用同一测试回调,因此务必要避免客户端之间出现歧义。最简单的方法就是使用唯一客户端标识符,这也是上下文的属性。

任务:

将区块链、上下文和参数分别作为全局变量 bc、ctx 和 clientArgs 来持久化。

假设要创建的所需资产数量以 clientArgs.assets 形式给出,然后创建一个介于 0 到要创建的资产数量之间的 for 循环。

您将使用智能合约方法 createMyAsset 在 for 循环内创建资产。如果发生错误,该方法可能会抛出错误,因此您应该在 try-catch 函数块中为此设定条件,并将错误打印输出到控制台以便于调试。在 for 循环中创建一个 try-catch 函数块。

在 catch 中,添加一个用于报告错误的信息语句。

在 try 中,等待对区块链对象调用 invokeSmartContract 完成,并传递已知的上下文、合约名称、合约版本以及包含以下内容的对象:设置为 createMyAsset 的 chaincodeFunction

设置为 admin 的 invokerIdentity,这是导出的钱包中的身份

带有数组的 chaincodeArguments,该数组包含: 由客户端标识符和当前 for 循环索引构成的唯一资产标识

要持久存储在资产身份下的字符串

module.exports.init = async function(blockchain, context, args) {

bc = blockchain;

ctx = context;

clientArgs = args;

clientIdx = context.clientIdx.toString();

for (let i=0; i

try {

const assetID = `${clientIdx}_${i}`;

console.log(`Client ${clientIdx}: Creating asset ${assetID}`);

const myArgs = {

chaincodeFunction: 'createMyAsset',

invokerIdentity: 'admin',

chaincodeArguments: [assetID, `UUID: ${assetID}`]

};

await bc.bcObj.invokeSmartContract(ctx, contractID, version, myArgs);

} catch (error) {

console.log(`Client ${clientIdx}: Smart Contract threw with error: ${error}` );

}

}

};Show moreShow more icon

run 函数

这是在记录的基准测试阶段中反复运行的函数,因此应尽可能简洁。您的目标是评估 readMyAsset智能合约函数,对 init 阶段中创建的其中一个资产执行查询。函数必须返回一个未解析的 promise,而不阻塞,这样驱动客户端便可以进行多个并发的 run 调用。

任务:

创建要查询的资产的字符串身份,这一身份是通过将测试客户端索引与 0 到创建的资产数量之间的随机整数相连接而构成。

返回对 querySmartContract 的调用,并传递已知的上下文、合约名称、合约版本以及包含以下内容的对象:设置为 readMyAsset 的 chaincodeFunction

设置为 admin 的 invokerIdentity,这是导出的钱包中的身份

含数组的 chaincodeArguments,该数组包含要在这个调用中查询的资产

module.exports.run = function() {

const randomId = Math.floor(Math.random()*clientArgs.assets);

const myArgs = {

chaincodeFunction: 'readMyAsset',

invokerIdentity: 'admin',

chaincodeArguments: [`${clientIdx}_${randomId}`]

};

return bc.bcObj.querySmartContract(ctx, contractID, version, myArgs);

};Show moreShow more icon

end 函数

end 函数用于在测试完成之后执行清理操作。为了确保测试的可重复性,您需要删除在 init 阶段创建的所有资产。您可以使用 init 阶段中使用的同一个 for 循环,但将其修改为调用智能合约函数 deleteMyAsset,并且仅传递要删除的资产身份。

module.exports.end = async function() {

for (let i=0; i

try {

const assetID = `${clientIdx}_${i}`;

console.log(`Client ${clientIdx}: Deleting asset ${assetID}`);

const myArgs = {

chaincodeFunction: 'deleteMyAsset',

invokerIdentity: 'admin',

chaincodeArguments: [assetID]

};

await bc.bcObj.invokeSmartContract(ctx, contractID, version, myArgs);

} catch (error) {

console.log(`Client ${clientIdx}: Smart Contract threw with error: ${error}` );

}

}

};Show moreShow more icon

现在,您已经指定了一项测试回调,该测试回调在 init 阶段创建测试资产,在 run 阶段查询所创建的资产,并在 end 阶段删除测试资产。

基准测试配置文件

基准测试配置文件是一个 YAML 文件,此文件通过指定以下内容来定义根据部署的智能合约要运行的完整性能测试:

生成测试负载时要使用的测试客户端数量

测试轮数

每轮持续时间

每轮的负载生成方法

每轮中要使用的回调(测试交互)

现在,您将开始构建一个使用 queryAsssetBenchmark.js 测试回调的 YAML 基准测试配置文件。请注意,YAM 文件区分大小写。所有标签均应以小写格式指定。

任务:

在 benchmarks 文件夹中创建一个名为 myAssetBenchmark.yaml 的新文件,然后打开该文件进行编辑。

添加一个名为 test 的根级字段,用于描述要运行的测试,其中包含:name 键,其值为 my-asset-benchmark

description 键,值是简短描述

一个名为 clients 的字段,定义要使用的测试客户端的类型和数量。现在,添加以下键/值对:type: local

number: 2

一个名为 rounds 的字段,留为空白

添加一个名为 monitor 的根级字段,其中包含一个名为 type 的键,并以单个数组项 none 作为值。这表明在基准测试期间,您将不会执行任何资源监视。

---

test:

name: my-asset-benchmark

description: Benchmarking for VS Code sample

clients:

type: local

number: 2

rounds:

monitor:

type:

- noneShow moreShow more icon

rounds 字段包含将以序列格式运行的每轮基准测试,并以唯一的轮次标签作为标题。轮次可用于对不同的智能合约方法进行基准测试,或以不同方式对同一方法进行基准测试。每一轮测试块都包含以下内容:

label — 该轮次使用的唯一标签

description — 正在运行的轮次的描述

chaincodeId — 正在测试的链码(智能合约)的 ID

[txDuration | txNumber] — 轮次时间长度的说明符,可以是持续时间,也可以基于事务

rateControl — 含选项的速率控制方法

callback — 正在调查的智能合约的用户定义测试文件的相对路径

arguments — 可选的参数数组,在调用时将传递到用户测试文件 (callback)

您现在将填充这些内容。

任务:

使用键名称 label 和值 queryAsset 创建一个新序列。

在 queryAsset 序列中,添加一个名为 description 的键,其值为“Query asset benchmark test”。

在 queryAsset 序列中,添加一个名为chaincodeId 的键,其值为 demoContract。

在 queryAsset 序列中,添加一个名为 txDuration 的字段,其单个序列条目为 30。这表明基准测试将运行一次,持续时间为 30 秒。

在 queryAsset 序列中,添加一个名为 rateControl 的字段,其中包含一个具有以下内容的序列条目:名为 type 的键,其字符串值为 fixed-backlog。这表明对于暂挂事务,您将使基准测试保持固定的事务积压量。

名为 ops 的字段,其键为 unfinished_per_client,值为 2。这表明将以一定速度驱动每个客户端,以保持 2 个暂挂事务。

在 queryAsset 序列中,向 queryAssetBenchmark.js 文件中添加含有相对路径的回调。相对路径介于要创建的基准测试文件和回调文件之间。

在 queryAsset 序列中,添加一个名为 arguments 的字段。添加一个名为 assets 的键,其值为 10。这将在 init 阶段传递给测试回调。

---

test:

name: my-asset-benchmark

description: Benchmarking for VS Code sample

clients:

type: local

number: 2

rounds:

- label: queryAsset

description: Query asset benchmark test

chaincodeId: demoContract

txDuration:

- 30

rateControl:

- type: fixed-backlog

opts:

unfinished_per_client: 2

callback: callbacks/queryAssetBenchmark.js

arguments:

assets: 10

monitor:

type:

- noneShow moreShow more icon

现在,您已有了一个基准测试配置文件,以及可由 Caliper 使用的配套测试回调文件。

第 3 步. 运行基准测试

您现在将使用在前述步骤中创建的资源,通过 Caliper CLI 对默认的 IBM Blockchain Platform VS Code 网络完成性能基准测试。要发出的命令是 caliper benchmark run,必须在该命令中提供网络配置文件、基准测试配置文件和正在使用的工作区的详细信息。根据您已创建的资源,必须提供以下参数对:

caliper-networkconfig: network_config.json

caliper-benchconfig: myAssetBenchmark.yaml

caliper-workspace: ./

由于已经配置了网络,并且链码也已安装和实例化,因此,Caliper 唯一要执行的操作就是测试阶段(使用启用了发现的 Fabric 网关)。为指定这些选项,您需要将以下附加标志传递给 CLI 命令:

caliper-flow-only-test

caliper-fabric-usegateway

caliper-fabric-discovery

任务:

确保您位于步骤 2 中创建的 benchmarks 目录中,该目录中现在应存在以下资源:

.

├── callbacks

│ └── queryAssetBenchmark.js

├── myAssetBenchmark.yaml

├── myWallet

│ └── admin

│ ├── -priv

│ ├── -pub

│ └── admin

└── network_config.jsonShow moreShow more icon

运行 Caliper CLI 命令

caliper benchmark run --caliper-benchconfig myAssetBenchmark.yaml --caliper-networkconfig network_config.json --caliper-workspace ./--caliper-flow-only-test --caliper-fabric-usegateway --caliper-fabric-discoveryShow moreShow more icon

随着测试的进行,您将在控制台上看到 Caliper 的操作,最终会显示基准测试的输出摘要。同时还将生成 HTML 报告,其中包含在基准测试过程中打印到控制台的相同信息。

该报告将详细介绍每一轮基准测试的以下信息:

Name — 轮次名称,这与基准测试配置文件中的测试轮次标签相关

Succ/Fail — 成功/失败事务的数量

Send Rate — Caliper 发出事务的速率

Latency (max/min/avg) — 关于发出事务到收到响应之间所用秒数的统计信息

Throughput — 平均每秒处理的事务数

结束语

现在,您已经在 IBM Blockchain Platform VS Code 扩展提供的默认本地网络上成功地对已部署的智能合约进行了基准测试。您可以通过更改基准测试参数来重复进行测试:有关完整参数集的信息,请参见 Caliper 官方文档。

特别感谢 IBM 袁怿对本文的翻译建议!

vscode 智能打印_使用 Hyperledger Caliper 对 VS Code 中开发的智能合约进行性能测试...相关推荐

  1. vscode 智能打印_【Vscode官方下载】Vscode中文版官方下载 v1.41.0 免费版-开心电玩...

    软件介绍 Vscode是一款可编译性的程序编程软件,它能够智能感应代码,自动填充完成后续代码,很大程度上帮助程序员提高敲代码的编辑速度,减少输入代码进行循环调试等时间,内置了Git命令,从Vscode ...

  2. 三体智能革命_华为郑叶来:AI正由“人工”智能走向真正的人工智能

    11月24日,以"育新机 开新局"为主题的世界互联网大会人工智能论坛在乌镇互联网国际会展中心举行,华为公司副总裁.华为云计算技术有限公司董事长郑叶来发表主题演讲--"创新 ...

  3. c++ eos智能合约开发_十分钟教你开发EOS智能合约

    EOS环境搭建和启动节点 下面从EOS入门的环境搭建.编译运行一个智能合约.发送一些Aigsen,给大家做一些展示,希望能让非技术人员也有一些收获. 首先下载EOS环境搭建和启动节点.这一步其实还是比 ...

  4. vscode更改编码_装上后这 10个扩展后,VSCode 真的是无敌的存在

    转CSDN 装上后这 10个扩展后,VSCode 真的是无敌的存在​blog.csdn.net VS Code是目前最受欢迎的代码编辑器之一,也是大多数Web开发人员的首选武器.没错,它快速,高效并且 ...

  5. vscode css提示_锋利码农武器之vscode

    俗话说,工欲善其事必先利其器,我们码农的器是什么尼?没错,就是我们亲爱的IDE,前端开发者最爱的编辑器应该是vscode了吧.但是我们要怎么去锋利它尼?不外乎就是熟悉它的使用方法.快捷键以及第三方的插 ...

  6. c++ 智能指针_详解 C++ 11 中的智能指针

    C/C++ 语言最为人所诟病的特性之一就是存在内存泄露问题,因此后来的大多数语言都提供了内置内存分配与释放功能,有的甚至干脆对语言的使用者屏蔽了内存指针这一概念.这里不置贬褒,手动分配内存与手动释放内 ...

  7. ip登录打印机怎么打印_不要打印,登录。

    ip登录打印机怎么打印 Often on Python, especially as a beginner, you might print( ) a variable in order to see ...

  8. Hyperledger caliper 安装记录

    更多精彩内容请访问我的新博客站点 文章目录 Pre-requisites 1. 安装 make,g++ 编译工具 2. 安装node.js 3. 安装 node-gyp 4. 安装 Docker 5. ...

  9. 电报注册网络代理_如何在电报开放网络(TON)中开发和发布智能合约

    电报注册网络代理 这篇文章是关于什么的? (What is this article about?) In this article, I will tell about my participati ...

最新文章

  1. 到底什么样的程序员能称为架构师?
  2. 根据 *_train_test.prototxt文件生成 *_deploy.prototxt文件
  3. openAI general intuition
  4. 项目管理纵横谈(1)──项目的管理的目标
  5. 动效设计中的隐喻-1
  6. hdu 2709 递推
  7. APR分析-共享内存篇
  8. linux命令行安装谷歌浏览器,Linux(ubuntu) 三行代码搞定安装谷歌浏览器
  9. 基于React开发范式的思考:写在Lesx发布之际
  10. 使用JDBC连接数据库(MySQL)的源代码
  11. [BJOI2017]树的难题 点分治,线段树合并
  12. SQL:统计一个数据库中所有表记录的数量
  13. 深层网络搜索核心技术研讨
  14. 21幅非常有创意的倒影摄影作品欣赏
  15. Want To Say Something
  16. docker常用到的一些命令
  17. 后缀树c语言算法,C语言数据结构之中缀树转后缀树的实例
  18. 适合女孩子的高颜值蓝牙耳机推荐?2020新款高人气蓝牙耳机
  19. QQ浏览器怎么关闭云加速 QQ浏览器云加速关闭方法
  20. raw数据拆分成rggb四通道,拆分与合成

热门文章

  1. 零基础转行新媒体运营,有哪些必须要掌握的技能
  2. WF(Workflow foundation)与Asp.net结合(二)
  3. Android wifi属性简介 及 wifi信息获取(wifi列表、配置信息
  4. 要命!《程序员延寿指南》火爆 GitHub,日涨1500+星,跟着码农干多活 20 年
  5. 点划线的两种实现方法
  6. 书中内力图如何用计算机绘制,计算机绘图制图基础.doc
  7. (图解)一步一步使用CPP实现深度学习中的卷积
  8. Scene…… couldn‘t be loaded because it has not been added to the build settings or the AssetBundle...
  9. DataGridView 控件中自动生成列
  10. Redis实现分布式锁(setnx、getset、incr)以及如何处理超时情况(二)