如何在本地多客户端测试网上开发和测试去中心化应用 (dapp)
简介
本指南将引导你完成实例化可配置的本地以太坊测试网、向其部署智能合约以及使用该测试网对你的去中心化应用 (dapp) 运行测试的过程。本指南专为希望在部署到实时测试网或主网之前,针对不同网络配置在本地开发和测试其 dapp 的 dapp 开发者而设计。
在本指南中,你将:
- 使用 Kurtosis (opens in a new tab) 通过
eth-network-package(opens in a new tab) 实例化本地以太坊测试网, - 将你的 Hardhat dapp 开发环境连接到本地测试网,以编译、部署和测试 dapp,以及
- 配置本地测试网,包括节点数量和特定的执行层 (EL)/共识层 (CL) 客户端配对等参数,以支持针对各种网络配置的开发和测试工作流。
什么是 Kurtosis?
Kurtosis (opens in a new tab) 是一个可组合的构建系统,专为配置多容器测试环境而设计。它特别使开发者能够创建需要动态设置逻辑的可重现环境,例如区块链测试网。
在本指南中,Kurtosis eth-network-package 启动了一个本地以太坊测试网,支持 geth (opens in a new tab) 执行层 (EL) 客户端,以及 teku (opens in a new tab)、lighthouse (opens in a new tab) 和 lodestar (opens in a new tab) 共识层 (CL) 客户端。该包可作为 Hardhat Network、Ganache 和 Anvil 等框架中网络的可配置且可组合的替代方案。Kurtosis 为开发者提供了对其所用测试网的更大控制权和灵活性,这也是以太坊基金会使用 Kurtosis 测试合并 (The Merge) (opens in a new tab) 并继续使用它来测试网络升级的主要原因。
设置 Kurtosis
在继续之前,请确保你已:
- 在本地计算机上安装并启动了 Docker 引擎 (opens in a new tab)
- 安装了 Kurtosis CLI (opens in a new tab)(如果你已经安装了 CLI,请将其升级到最新版本)
- 安装了 Node.js (opens in a new tab)、yarn (opens in a new tab) 和 npx (opens in a new tab)(用于你的 dapp 环境)
实例化本地以太坊测试网
要启动本地以太坊测试网,请运行:
kurtosis --enclave local-eth-testnet run github.com/kurtosis-tech/eth-network-package
注意:此命令使用 --enclave 标志将你的网络命名为:“local-eth-testnet”。
Kurtosis 在解释、验证并执行指令时,会打印出其在后台执行的步骤。最后,你应该会看到类似如下的输出:
INFO[2023-04-04T18:09:44-04:00] ======================================================
INFO[2023-04-04T18:09:44-04:00] || Created enclave: local-eth-testnet ||
INFO[2023-04-04T18:09:44-04:00] ======================================================
Name: local-eth-testnet
UUID: 39372d756ae8
Status: RUNNING
Creation Time: Tue, 04 Apr 2023 18:09:03 EDT
========================================= Files Artifacts =========================================
UUID Name
d4085a064230 cl-genesis-data
1c62cb792e4c el-genesis-data
bd60489b73a7 genesis-generation-config-cl
b2e593fe5228 genesis-generation-config-el
d552a54acf78 geth-prefunded-keys
5f7e661eb838 prysm-password
054e7338bb59 validator-keystore-0
========================================== User Services ==========================================
UUID Name Ports Status
e20f129ee0c5 cl-client-0-beacon http: 4000/tcp -> <http://127.0.0.1:54261> RUNNING
metrics: 5054/tcp -> <http://127.0.0.1:54262>
tcp-discovery: 9000/tcp -> 127.0.0.1:54263
udp-discovery: 9000/udp -> 127.0.0.1:60470
a8b6c926cdb4 cl-client-0-validator http: 5042/tcp -> 127.0.0.1:54267 RUNNING
metrics: 5064/tcp -> <http://127.0.0.1:54268>
d7b802f623e8 el-client-0 engine-rpc: 8551/tcp -> 127.0.0.1:54253 RUNNING
rpc: 8545/tcp -> 127.0.0.1:54251
tcp-discovery: 30303/tcp -> 127.0.0.1:54254
udp-discovery: 30303/udp -> 127.0.0.1:53834
ws: 8546/tcp -> 127.0.0.1:54252
514a829c0a84 prelaunch-data-generator-1680646157905431468 <none> STOPPED
62bd62d0aa7a prelaunch-data-generator-1680646157915424301 <none> STOPPED
05e9619e0e90 prelaunch-data-generator-1680646157922872635 <none> STOPPED
恭喜!你已使用 Kurtosis 在 Docker 上实例化了一个包含共识层 (CL) 客户端 (lighthouse) 和执行层 (EL) 客户端 (geth) 的本地以太坊测试网。
回顾
在本节中,你执行了一条命令,指示 Kurtosis 使用远程托管在 GitHub 上的 eth-network-package (opens in a new tab) 在 Kurtosis Enclave (opens in a new tab) 中启动本地以太坊测试网。在你的 enclave 中,你会发现“文件工件 (file artifacts)”和“用户服务 (user services)”。
你的 enclave 中的文件工件 (opens in a new tab)包含生成并用于引导 EL 和 CL 客户端的所有数据。这些数据是使用从此 Docker 镜像 (opens in a new tab)构建的 prelaunch-data-generator 服务创建的。
用户服务显示在你的 enclave 中运行的所有容器化服务。你会注意到,已经创建了一个同时包含 EL 客户端和 CL 客户端的单个节点。
将你的 dapp 开发环境连接到本地以太坊测试网
设置 dapp 开发环境
现在你已经有了一个运行中的本地测试网,你可以连接你的 dapp 开发环境来使用你的本地测试网。本指南将使用 Hardhat 框架将一个二十一点 (blackjack) dapp 部署到你的本地测试网。
要设置你的 dapp 开发环境,请克隆包含我们示例 dapp 的仓库并安装其依赖项,运行:
git clone https://github.com/kurtosis-tech/awesome-kurtosis.git && cd awesome-kurtosis/smart-contract-example && yarn
此处使用的 smart-contract-example (opens in a new tab) 文件夹包含使用 Hardhat (opens in a new tab) 框架的 dapp 开发者的典型设置:
contracts/(opens in a new tab) 包含用于二十一点 dapp 的几个简单智能合约scripts/(opens in a new tab) 包含一个将代币合约部署到本地以太坊网络的脚本test/(opens in a new tab) 包含一个针对你的代币合约的简单 .js 测试,以确认我们二十一点 dapp 中的每个玩家都铸造了 1000 个代币hardhat.config.ts(opens in a new tab) 配置你的 Hardhat 设置
配置 Hardhat 以使用本地测试网
设置好 dapp 开发环境后,你现在将连接 Hardhat 以使用通过 Kurtosis 生成的本地以太坊测试网。为此,请将 hardhat.config.ts 配置文件中 localnet 结构体里的 <$YOUR_PORT> 替换为任何 el-client-<num> 服务输出的 rpc uri 端口。在此示例中,端口将是 64248。你的端口会有所不同。
hardhat.config.ts 中的示例:
localnet: {
url: 'http://127.0.0.1:<$YOUR_PORT>',// TODO: 将 $YOUR_PORT 替换为由 ETH 网络 Kurtosis 包生成的节点 URI 的端口
// 这些是与由 eth-network-package 创建的预充值测试账户相关联的私钥
// <https://github.com/kurtosis-tech/eth-network-package/blob/main/src/prelaunch_data_generator/genesis_constants/genesis_constants.star>
accounts: [
"ef5177cd0b6b21c87db5a0bf35d4084a8a57a9d6a064f86d51ac85f2b873a4e2",
"48fcc39ae27a0e8bf0274021ae6ebd8fe4a0e12623d61464c498900b28feb567",
"7988b3a148716ff800414935b305436493e1f25237a2a03e5eebc343735e2f31",
"b3c409b6b0b3aa5e65ab2dc1930534608239a478106acf6f3d9178e9f9b00b35",
"df9bb6de5d3dc59595bcaa676397d837ff49441d211878c024eabda2cd067c9f",
"7da08f856b5956d40a72968f93396f6acff17193f013e8053f6fbb6c08c194d6",
],
},
保存文件后,你的 Hardhat dapp 开发环境现在已连接到你的本地以太坊测试网!你可以通过运行以下命令来验证你的测试网是否正常工作:
npx hardhat balances --network localnet
输出应类似如下所示:
0x878705ba3f8Bc32FCf7F4CAa1A35E72AF65CF766 has balance 10000000000000000000000000
0x4E9A3d9D1cd2A2b2371b8b3F489aE72259886f1A has balance 10000000000000000000000000
0xdF8466f277964Bb7a0FFD819403302C34DCD530A has balance 10000000000000000000000000
0x5c613e39Fc0Ad91AfDA24587e6f52192d75FBA50 has balance 10000000000000000000000000
0x375ae6107f8cC4cF34842B71C6F746a362Ad8EAc has balance 10000000000000000000000000
0x1F6298457C5d76270325B724Da5d1953923a6B88 has balance 10000000000000000000000000
这确认了 Hardhat 正在使用你的本地测试网,并检测到了由 eth-network-package 创建的预注资账户。
在本地部署和测试你的 dapp
随着 dapp 开发环境完全连接到本地以太坊测试网,你现在可以使用本地测试网针对你的 dapp 运行开发和测试工作流。
要编译并部署 ChipToken.sol 智能合约以进行本地原型设计和开发,请运行:
npx hardhat compile
npx hardhat run scripts/deploy.ts --network localnet
输出应类似如下所示:
ChipToken deployed to: 0xAb2A01BC351770D09611Ac80f1DE076D56E0487d
现在尝试针对你的本地 dapp 运行 simple.js 测试,以确认我们二十一点 dapp 中的每个玩家都铸造了 1000 个代币:
输出应类似如下所示:
npx hardhat test --network localnet
输出应类似如下所示:
ChipToken
mint
✔ should mint 1000 chips for PLAYER ONE
1 passing (654ms)
回顾
至此,你已经设置了一个 dapp 开发环境,将其连接到了由 Kurtosis 创建的本地以太坊网络,并针对你的 dapp 编译、部署和运行了一个简单的测试。
现在让我们探讨如何配置底层网络,以便在不同的网络配置下测试我们的 dapp。
配置本地以太坊测试网
更改客户端配置和节点数量
你的本地以太坊测试网可以配置为使用不同的 EL 和 CL 客户端配对,以及不同数量的节点,具体取决于你想要开发或测试的场景和特定网络配置。这意味着,一旦设置完毕,你就可以启动一个定制的本地测试网,并使用它在各种网络配置下运行相同的工作流(部署、测试等),以确保一切按预期工作。要了解有关你可以修改的其他参数的更多信息,请访问此链接。
试一试吧!你可以通过 JSON 文件将各种配置选项传递给 eth-network-package。此网络参数 JSON 文件提供了 Kurtosis 将用于设置本地以太坊网络的特定配置。
采用默认配置文件并对其进行编辑,以启动具有不同 EL/CL 配对的两个节点:
- 节点 1 使用
geth/lighthouse - 节点 2 使用
geth/lodestar - 节点 3 使用
geth/teku
此配置创建了一个以太坊节点实现的异构网络,用于测试你的 dapp。你的配置文件现在应如下所示:
{
"participants":
[
{
"el_client_type": "geth",
"el_client_image": "",
"el_client_log_level": "",
"cl_client_type": "lighthouse",
"cl_client_image": "",
"cl_client_log_level": "",
"beacon_extra_params": [],
"el_extra_params": [],
"validator_extra_params": [],
"builder_network_params": null,
},
{
"el_client_type": "geth",
"el_client_image": "",
"el_client_log_level": "",
"cl_client_type": "lodestar",
"cl_client_image": "",
"cl_client_log_level": "",
"beacon_extra_params": [],
"el_extra_params": [],
"validator_extra_params": [],
"builder_network_params": null,
},
{
"el_client_type": "geth",
"el_client_image": "",
"el_client_log_level": "",
"cl_client_type": "teku",
"cl_client_image": "",
"cl_client_log_level": "",
"beacon_extra_params": [],
"el_extra_params": [],
"validator_extra_params": [],
"builder_network_params": null,
},
],
"network_params":
{
"preregistered_validator_keys_mnemonic": "giant issue aisle success illegal bike spike question tent bar rely arctic volcano long crawl hungry vocal artwork sniff fantasy very lucky have athlete",
"num_validator_keys_per_node": 64,
"network_id": "3151908",
"deposit_contract_address": "0x4242424242424242424242424242424242424242",
"seconds_per_slot": 12,
"genesis_delay": 120,
"capella_fork_epoch": 5,
},
}
每个 participants 结构体映射到网络中的一个节点,因此 3 个 participants 结构体将告诉 Kurtosis 在你的网络中启动 3 个节点。每个 participants 结构体将允许你指定用于该特定节点的 EL 和 CL 配对。
network_params 结构体配置用于为每个节点创建创世文件的网络设置,以及诸如网络每个时隙的秒数等其他设置。
将编辑后的参数文件保存在你希望的任何目录中(在下面的示例中,它保存在桌面上),然后通过运行以下命令使用它来运行你的 Kurtosis 包:
kurtosis clean -a && kurtosis run --enclave local-eth-testnet github.com/kurtosis-tech/eth-network-package "$(cat ~/eth-network-params.json)"
注意:此处使用 kurtosis clean -a 命令指示 Kurtosis 在启动新测试网之前销毁旧测试网及其内容。
同样,Kurtosis 会运行一段时间并打印出正在发生的各个步骤。最终,输出应类似如下所示:
Starlark code successfully run. No output was returned.
INFO[2023-04-07T11:43:16-04:00] ==========================================================
INFO[2023-04-07T11:43:16-04:00] || Created enclave: local-eth-testnet ||
INFO[2023-04-07T11:43:16-04:00] ==========================================================
Name: local-eth-testnet
UUID: bef8c192008e
Status: RUNNING
Creation Time: Fri, 07 Apr 2023 11:41:58 EDT
========================================= Files Artifacts =========================================
UUID Name
cc495a8e364a cl-genesis-data
7033fcdb5471 el-genesis-data
a3aef43fc738 genesis-generation-config-cl
8e968005fc9d genesis-generation-config-el
3182cca9d3cd geth-prefunded-keys
8421166e234f prysm-password
d9e6e8d44d99 validator-keystore-0
23f5ba517394 validator-keystore-1
4d28dea40b5c validator-keystore-2
========================================== User Services ==========================================
UUID Name Ports Status
485e6fde55ae cl-client-0-beacon http: 4000/tcp -> http://127.0.0.1:65010 RUNNING
metrics: 5054/tcp -> http://127.0.0.1:65011
tcp-discovery: 9000/tcp -> 127.0.0.1:65012
udp-discovery: 9000/udp -> 127.0.0.1:54455
73739bd158b2 cl-client-0-validator http: 5042/tcp -> 127.0.0.1:65016 RUNNING
metrics: 5064/tcp -> http://127.0.0.1:65017
1b0a233cd011 cl-client-1-beacon http: 4000/tcp -> 127.0.0.1:65021 RUNNING
metrics: 8008/tcp -> 127.0.0.1:65023
tcp-discovery: 9000/tcp -> 127.0.0.1:65024
udp-discovery: 9000/udp -> 127.0.0.1:56031
validator-metrics: 5064/tcp -> 127.0.0.1:65022
949b8220cd53 cl-client-1-validator http: 4000/tcp -> 127.0.0.1:65028 RUNNING
metrics: 8008/tcp -> 127.0.0.1:65030
tcp-discovery: 9000/tcp -> 127.0.0.1:65031
udp-discovery: 9000/udp -> 127.0.0.1:60784
validator-metrics: 5064/tcp -> 127.0.0.1:65029
c34417bea5fa cl-client-2 http: 4000/tcp -> 127.0.0.1:65037 RUNNING
metrics: 8008/tcp -> 127.0.0.1:65035
tcp-discovery: 9000/tcp -> 127.0.0.1:65036
udp-discovery: 9000/udp -> 127.0.0.1:63581
e19738e6329d el-client-0 engine-rpc: 8551/tcp -> 127.0.0.1:64986 RUNNING
rpc: 8545/tcp -> 127.0.0.1:64988
tcp-discovery: 30303/tcp -> 127.0.0.1:64987
udp-discovery: 30303/udp -> 127.0.0.1:55706
ws: 8546/tcp -> 127.0.0.1:64989
e904687449d9 el-client-1 engine-rpc: 8551/tcp -> 127.0.0.1:64993 RUNNING
rpc: 8545/tcp -> 127.0.0.1:64995
tcp-discovery: 30303/tcp -> 127.0.0.1:64994
udp-discovery: 30303/udp -> 127.0.0.1:58096
ws: 8546/tcp -> 127.0.0.1:64996
ad6f401126fa el-client-2 engine-rpc: 8551/tcp -> 127.0.0.1:65003 RUNNING
rpc: 8545/tcp -> 127.0.0.1:65001
tcp-discovery: 30303/tcp -> 127.0.0.1:65000
udp-discovery: 30303/udp -> 127.0.0.1:57269
ws: 8546/tcp -> 127.0.0.1:65002
12d04a9dbb69 prelaunch-data-generator-1680882122181135513 <none> STOPPED
5b45f9c0504b prelaunch-data-generator-1680882122192182847 <none> STOPPED
3d4aaa75e218 prelaunch-data-generator-1680882122201668972 <none> STOPPED
恭喜!你已成功将本地测试网配置为具有 3 个节点而不是 1 个节点。要针对你的 dapp 运行与之前相同的工作流(部署和测试),请执行与之前相同的操作,将 hardhat.config.ts 配置文件中 localnet 结构体里的 <$YOUR_PORT> 替换为新的 3 节点本地测试网中任何 el-client-<num> 服务输出的 rpc uri 端口。
结论
就是这样!回顾这篇简短的指南,你:
- 使用 Kurtosis 在 Docker 上创建了本地以太坊测试网
- 将你的本地 dapp 开发环境连接到了本地以太坊网络
- 在本地以太坊网络上部署了 dapp 并对其运行了简单的测试
- 将底层以太坊网络配置为具有 3 个节点
我们很乐意听取你的意见,了解哪些方面对你来说很顺利,哪些方面可以改进,或者回答你的任何问题。请随时通过 GitHub (opens in a new tab) 或向我们发送电子邮件 (opens email client)与我们联系!
其他示例和指南
我们鼓励你查看我们的快速入门 (opens in a new tab)(你将在其中构建一个 Postgres 数据库并在其上构建 API)以及我们 awesome-kurtosis 仓库 (opens in a new tab)中的其他示例,你将在其中找到一些很棒的示例,包括用于以下用途的包:
- 启动相同的本地以太坊测试网 (opens in a new tab),但连接了其他服务,例如交易垃圾邮件发送器(用于模拟交易)、分叉监视器以及连接的 Grafana 和 Prometheus 实例
- 针对相同的本地以太坊网络执行子网测试 (opens in a new tab)
页面最后更新: 2026年3月3日