本文提供了一个全面的概述,介绍如何使用 Solana 本地验证器以及如何在不依赖 Devnet 的情况下测试你的程序!
近几个月来,Solana Devnet 遇到了几次可靠性问题,偶尔会离线。本周这个问题再次出现,引起了开发者们对这种不稳定性如何影响他们项目的重大担忧。
令人惊讶的是,在这些讨论中,显然许多开发者并不熟悉 Localnet 测试环境。
Trent.sol 最近的一条推文突显了这一知识差距:https://x.com/trentdotsol/status/1781369947794317371。
我今天的目标是解决这一知识差距
这个问题对我来说感觉很奇怪,因为自从我开始学习智能合约开发以来,我一直更喜欢在本地验证器上测试我的程序。
我发现这主要是因为它允许通过 explorer 直接调试,并且我可以享受 Solana 文档页面中包含的所有这些附加好处:
--bpf-program ...
)--clone ...
)--limit-ledger-size ...
)--slots-per-epoch ...
)--warp-slot ...
)本地验证器充当你的个人节点,提供一个沙盒环境用于测试应用程序,而无需连接到实时区块链网络。它操作一个本地测试账本,这是 Solana 账本的简化版本,预装了所有本地程序并启用了各种功能。这个账本是完全可定制的,以满足你特定的本地测试需求!
来自本地验证器的源代码
你可以通过安装 Solana 工具套件并运行
solana-test-validator
来设置你的本地验证器,
启动后,验证器将可通过[http://127.0.0.1:8899](http://127.0.0.1:8899)
访问,因此要建立与本地验证器的连接,请使用以下代码片段:
import { Connection } from "@solana/web3.js";
(async () => {
// 这将连接到你的本地验证器
const connection = new Connection("http://127.0.0.1:8899", "confirmed");
})();
初始化时,本地验证器将在你的用户文件夹中生成一个名为test-ledger
的目录。该目录包含所有与验证器相关的数据,包括创建的账户和部署及导入的程序。要重置你的本地验证器,你可以:
test-ledger
文件夹solana-test-validator --reset
此外,solana logs
命令对于监控链上程序的msg!()
输出非常有用。
要执行交易,钱包中必须有 SOL。
在 Devnet 上,你可以通过水龙头或使用requestAirdrop
函数接收 SOL:
const airdropSignature = await connection.requestAirdrop(
keypair.publicKey,
LAMPORTS\_PER\_SOL
);
await connection.confirmTransaction(airdropSignature);
在 localnet 上,也可以通过这种方式获取 SOL,但需要注意的是,空投到账户中的 Solana 不是来自水龙头,而是来自你的 CLI 默认密钥对,该密钥对在验证器的创世块中预加载了 1000 个 Localnet SOL。
所以如果你使用 CLI 密钥对来测试你的程序,你不需要任何空投!
对于需要主网上特定程序和账户的测试,Solana CLI 可以帮助下载和加载这些元素到你的本地验证器。以下是如何管理这些内容:
下载账户和程序:
对于账户:
solana account -u <source cluster> --output <output format> --output-file <destination file name/path> <address of account to fetch>
对于程序:
solana program dump -u <source cluster> <address of account to fetch> <destination file name/path>
加载账户和程序:
对于账户:
solana-test-validator --account <address to load the account to> <path to account file> --reset
对于程序:
solana-test-validator --bpf-program <address to load the program to> <path to program file> --reset
在探索了通过 CLI 创建自定义本地验证器的基础知识后,让我们探索更高级的技术,例如编写个性化的 bash 脚本以运行不同实例的验证器,并在其中配置不同的程序,以及配置 Anchor 以使用特定的账户和程序。
从 anchor-lang 文档中可以看到,anchor 允许通过其配置文件anchor.toml
进行广泛的自定义。在这一部分中,我们将重点关注[test]
部分,这是设置本地验证器的关键。
startup_wait
标志是一个关键设置,用于延迟solana-test-validator
的启动。当克隆多个账户时,这种延迟特别有用,因为它延长了验证器的启动时间以适应增加的负载:
[test]
startup_wait = 10000
[test.validator]
部分允许你修改本地验证器的基本方面。这些设置通过anchor test
命令直接传递给solana-test-validator
CLI:
[test.validator]
url = "https://api.mainnet-beta.solana.com" # 这是克隆账户的集群 URL(见`test.validator.clone`)。
warp_slot = 1337 # 在启动验证器后将账本跳转`warp_slot`。
slots_per_epoch = 5 # 覆盖Epoch中的Slot数量。
rpc_port = 1337 # 在此端口设置 JSON RPC,下一个端口用于 RPC websocket。
limit_ledger_size = 1337 # 在根槽中保留此数量的碎片。
ledger = "test-ledger" # 设置账本位置。
gossip_port = 1337 # 验证器的 gossip 端口号。
gossip_host = "127.0.0.1" # 验证器在 gossip 中广告的 gossip DNS 名称或 IP 地址。
faucet_sol = 1337 # 在创世块中给水龙头地址分配这么多 SOL。
faucet_port = 1337 # 在此端口启用水龙头。
dynamic_port_range = "1337 - 13337" # 用于动态分配端口的范围。
bind_address = "0.0.0.0" # 绑定验证器端口的 IP 地址。
完成所有这些设置工作后,我们终于可以开始克隆我们的账户和程序了:
你可以利用 [test.validator.clone]
部分从指定的集群克隆账户到你的测试集群。如果账户链接到由 "BPF upgradeable loader" 管理的程序,Anchor 会自动克隆相关的程序数据账户:
[test.validator]
url = "https://api.mainnet-beta.solana.com"
[[test.validator.clone]]
address = "7NL2qWArf2BbEBBH1vTRZCsoNqFATTddH6h8GkVvrLpG"
[[test.validator.clone]]
address = "2RaN5auQwMdg5efgCaVqpETBV8sacWGR8tkK4m9kjo5r"
[[test.validator.clone]]
address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" # implicitly also clones PwDiXFxQsGra4sFFTT8r1QWRMd4vfumiWC1jfWNfdYT
要将 JSON 文件中的本地账户集成到你的验证器设置中,可以使用 [test.validator.account]
标志无缝上传账户:
[[test.validator.account]]
address = "Ev8WSPQsGb4wfjybqff5eZNcS3n6HaMsBkMk9suAiuM"
filename = "some_account.json"
这是一个高级教程,需要对 bash 脚本的基本操作有一定了解,如果你不熟悉 bash 脚本,请谨慎操作。但如果你不熟悉也不用担心,因为这主要是一个演示,预计 Valid8 CLI 工具发布后,将能够直接从终端创建和管理个性化和多个本地验证器。
但让我们探索一下这个配置:
首先在你的路径中创建一个专用文件夹来存储你打算与本地验证器一起使用的程序:
mkdir ~/.local/share/valid8
接下来,将指定地址中的程序数据下载到新创建的目录中:
solana program dump -u m <address of account to fetch> ~/.local/share/valid8/<destination file name>.so
然后使用以下命令打开一个新的脚本文件:
sudo nano /usr/local/bin/<name-of-the-validator>
注意:(如果 /user/local/bin 目录不存在,可以使用 sudo mkdir -p -m 775 /usr/local/bin
创建它)。
将以下代码粘贴到编辑器中并保存:
#!/bin/bash
# Validator command
COMMAND="solana-test-validator -r --bpf-program <address of account to fetch> ~/.local/share/valid8/<destination file name>.so"
# Append any additional arguments passed to the script
for arg in "$@"
do
COMMAND+=" $arg"
done
# Execute the command
eval $COMMAND
注意: 如果需要包含多个程序,请根据需要附加 --bpf-program
选项:
[...] --bpf-program <another program address> ~/.local/share/valid8/<another destination file name>.so" [...]
之后我们需要确保脚本可以执行,因此我们修改其权限:
sudo chmod +x /usr/local/bin/<name-of-the-validator>
最后,在你的项目文件夹中测试新的验证器脚本:
<name-of-the-validator>
让我们为 Metaplex-test-validator 创建一个专门的 bash 脚本,包含 mpl-token-metadata
程序:
>> solana program dump -u m metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s ~/.local/share/valid8/metadata.so
>> sudo nano /usr/local/bin/metaplex-test-validator
使用与之前相同的脚本结构,指定 mpl-token-metadata
程序:
#!/bin/bash
# Validator command
COMMAND="solana-test-validator -r --bpf-program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s ~/.local/share/valid8/metadata.so"
# Append any additional arguments passed to the script
for arg in "$@"
do
COMMAND+=" $arg"
done
# Execute the command
eval $COMMAND
然后通过使其可执行并测试它来完成:
>> sudo chmod +x /usr/local/bin/metaplex-test-validator
>> metaplex-test-validator
恭喜! 你现在是本地验证器的高手了!希望本教程对你有所帮助,并且你学到了有价值的知识!
特别感谢来自 Valid8 团队的 Berg,Dean 创建了 Valid8 的原始 Bash 脚本(你可以在 这里 找到),以及 Turbin3 总是尝试在 Solana 上创建前沿概念。
如果你想关注我的旅程并且不想错过我的下一个教程,请在 Twitter 上关注我!