程序测试与部署
在完成合约代码编写后,严谨的测试是确保资金安全的最后一道防线。Solana 的测试通常分为单元测试 (Rust) 和 集成测试 (TypeScript)。本章主要关注集成测试,因为它能模拟最真实的用户交互。
1. 搭建本地测试环境
Anchor 默认使用 solana-test-validator 在本地启动一个全新的区块链网络。
关键挑战:外部程序依赖
我们的 NFT Minter 程序需要调用 Metaplex Token Metadata 程序。但是,本地启动的验证器是一个“空”的区块链,上面没有 Metaplex 程序。
如果直接运行测试,会报错:Program not found。
解决方案
我们需要在启动验证器时,将 Metaplex 程序的二进制文件加载进去。
bash# 1. 获取 Metaplex 程序二进制文件 (metadata.so) # 2. 启动验证器并加载程序 solana-test-validator \ --bpf-program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s metadata.so \ --reset
或者,在 Anchor.toml 中配置自动克隆(Clone):
toml[test.validator] url = "https://api.mainnet-beta.solana.com" # 自动从主网下载并加载这个账户/程序的数据 [[test.validator.clone]] address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"
2. 编写测试脚本 (TypeScript)
Anchor 生成的测试文件位于 tests/ 目录。我们使用 Mocha + Chai 框架。
测试结构
- Setup: 配置 Provider,生成测试用的 Keypair,计算 PDA。
- Test Initialization: 调用
initialize指令,验证全局配置是否正确写入链上。 - Test Logic: 调用
mint等指令,验证代币是否到了用户手里,属性是否正确。 - Test Failure: 故意发送错误参数(如非管理员调用更新),验证程序是否正确拒绝(报错)。
typescriptdescribe("nft-minter", () => { const provider = anchor.AnchorProvider.env(); anchor.setProvider(provider); const program = anchor.workspace.NftMinter as Program<NftMinter>; it("Initializes config", async () => { // 1. 发送交易 await program.methods .initialize(collectionMint, new BN(price), maxSupply) .accounts({ ... }) .rpc(); // 2. 验证状态 const config = await program.account.mintConfig.fetch(configPda); expect(config.maxSupply).to.equal(maxSupply); }); });
3. 部署到 Devnet
本地测试通过后,我们可以部署到公开测试网 (Devnet)。
步骤 1: 准备环境
bashsolana config set --url devnet solana airdrop 2 # 确保有足够的 SOL 支付部署租金
步骤 2: 构建与同步 ID
Anchor 构建时会生成一个程序密钥对。必须确保 Rust 代码中的 declare_id! 与这个密钥对的公钥一致。
bashanchor build # 获取生成的 Program ID solana address -k target/deploy/nft_minter-keypair.json # -> 复制这个地址,去 lib.rs 修改 declare_id!("...") # -> 然后再次运行 anchor build
步骤 3: 部署
bashanchor deploy
部署成功后,你会获得一个 Program ID。前端可以通过这个 ID 与合约交互。
步骤 4: 验证
bashsolana program show <PROGRAM_ID>
你应该能看到 "Executable: Yes" 和 "Authority: <Your_Wallet>"。