Solana[part18]_Solana DAPP-前端单元测试与合约接入

AI-摘要
sonia33 GPT
AI初始化中...
介绍自己 🙈
生成本文简介 👋
推荐相关文章 📖
前往主页 🏠
前往爱发电购买
Solana[part18]_Solana DAPP-前端单元测试与合约接入
SoniaChenSolana DAPP-前端单元测试与合约接入
一、初始化 Solana DApp 项目
1. 环境准备
先确保安装基础工具:
# 安装 Node.js(推荐 v16+)
# 安装 Solana CLI(用于本地节点和钱包管理)
sh -c "$(curl -sSfL https://release.solana.com/v1.18.4/install)"
# 检查版本
solana --version
node --version
2. 初始化项目
使用官方模板创建项目:
npx create-solana-dapp@latest my-solana-dapp
cd my-solana-dapp
3. 项目结构解析(核心文件)
my-solana-dapp/
├── app/ # 前端代码(React)
├── programs/ # 后端程序(Rust)
│ └── my_solana_dapp/ # 核心逻辑
├── tests/ # 测试文件(TypeScript)
│ └── my-solana-dapp.ts # 测试用例
├── Anchor.toml # 项目配置(集群、程序ID等)
└── package.json # 依赖管理
二、测试文件编写(TypeScript)
测试文件位于 tests/ 目录,用于验证程序逻辑,后端学员需重点关注以下几点:
1. 测试基本结构
// tests/my-solana-dapp.ts
import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import { MySolanaDapp } from "../target/types/my_solana_dapp"; // 自动生成的类型
describe("my-solana-dapp", () => {
// 1. 初始化环境
const provider = anchor.AnchorProvider.env(); // 使用环境变量配置的集群
anchor.setProvider(provider);
const program = anchor.workspace.MySolanaDapp as Program<MySolanaDapp>; // 加载程序
const wallet = provider.wallet as anchor.Wallet; // 测试钱包
it("初始化一个计数器", async () => {
// 2. 准备账户(比如创建一个计数器账户)
const counterKeypair = anchor.web3.Keypair.generate(); // 随机生成账户
// 3. 调用程序指令(比如初始化计数器)
const tx = await program.methods
.initializeCounter()
.accounts({
counter: counterKeypair.publicKey, // 计数器账户地址
user: wallet.publicKey, // 调用者地址
systemProgram: anchor.web3.SystemProgram.programId, // 系统程序(创建账户用)
})
.signers([counterKeypair]) // 新账户需要签名(因为是刚生成的)
.rpc(); // 发送交易
console.log("交易签名:", tx);
// 4. 验证结果
const counterAccount = await program.account.counter.fetch(counterKeypair.publicKey);
console.log("初始计数:", counterAccount.count.toString());
assert.equal(counterAccount.count.toString(), "0"); // 断言初始值为0
});
});
2. 测试注意事项
- 集群选择:默认使用
localnet(本地节点),测试前需启动solana-test-validator - 账户权限:
- 新生成的账户(
Keypair.generate())需要放在signers中签名 - 钱包账户(
wallet.publicKey)的签名由provider自动处理,无需手动添加
- 新生成的账户(
- 数据读取:用
program.account.xxx.fetch(地址)读取账户数据 - 错误处理:使用
try/catch捕获交易失败(如权限不足、数据错误)
3. 常用 TS 语法(测试中高频使用)
- 类型注解:
const wallet: anchor.Wallet = provider.wallet;(指定变量类型) - 异步函数:
async/await处理区块链交易(网络操作都是异步的) - 接口定义:描述账户数据结构
interface Counter { count: anchor.BN; // Solana中常用BN处理大数字 owner: anchor.web3.PublicKey; } - 解构赋值:快速获取账户字段
const { count, owner } = await program.account.counter.fetch(addr);
三、前端交互(调用 Anchor 程序)
前端通过 Anchor 客户端库与链上程序交互,核心流程:连接钱包 → 初始化程序 → 调用指令。
1. 前端项目结构(app/ 目录)
app/
├── components/ # UI组件
├── lib/ # 工具函数(连接钱包、程序初始化)
│ └── anchor.ts # 核心交互逻辑
└── pages/ # 页面(如首页)
2. 核心交互代码(lib/anchor.ts)
import * as anchor from "@coral-xyz/anchor";
import { PublicKey } from "@solana/web3.js";
import idl from "../target/idl/my_solana_dapp.json"; // 程序IDL(接口描述)
// 1. 初始化程序
export const initProgram = () => {
// 连接到浏览器钱包(如Phantom)
const provider = new anchor.AnchorProvider(
window.solana, // 钱包注入的provider
window.solana,
{ preflightCommitment: "processed" }
);
anchor.setProvider(provider);
// 加载程序(IDL + 程序地址)
const programId = new PublicKey(idl.metadata.address);
const program = new anchor.Program(idl as any, programId, provider);
return { program, provider };
};
// 2. 调用程序指令(比如增加计数器)
export const incrementCounter = async (counterAddr: string) => {
const { program, provider } = initProgram();
const counterPubkey = new PublicKey(counterAddr);
try {
// 发送交易
const tx = await program.methods
.incrementCounter() // 对应Rust中的increment_counter函数
.accounts({
counter: counterPubkey,
user: provider.wallet.publicKey,
})
.rpc(); // 钱包会自动弹出签名请求
console.log("交易成功:", tx);
return tx;
} catch (err) {
console.error("交易失败:", err);
}
};
3. 在页面中使用(React 示例)
// pages/index.tsx
import { useState } from "react";
import { incrementCounter } from "../lib/anchor";
export default function Home() {
const [counterAddr, setCounterAddr] = useState("");
const handleIncrement = async () => {
if (!counterAddr) return;
await incrementCounter(counterAddr);
};
return (
<div>
<input
placeholder="计数器地址"
value={counterAddr}
onChange={(e) => setCounterAddr(e.target.value)}
/>
<button onClick={handleIncrement}>增加计数</button>
</div>
);
}
4. 前端交互注意事项
- 钱包连接:需用户安装 Phantom 等钱包,通过
window.solana注入 - 权限请求:首次调用会请求钱包授权(访问公钥)
- 交易确认:区块链交易需要时间确认,可通过
@solana/web3.js的Connection.confirmTransaction等待确认 - 错误提示:常见错误如“用户拒绝签名”“余额不足”(需确保钱包有 SOL 支付手续费)
四、快速上手命令
# 启动本地节点
solana-test-validator
# 部署程序到本地节点
anchor deploy
# 运行测试
anchor test
# 启动前端(开发模式)
cd app && npm run dev
总结
重点理解:
- 测试文件通过模拟交易验证程序逻辑,核心是
program.methods.xxx调用指令 - 前端交互本质是通过 Anchor 客户端库将用户操作转化为链上交易,依赖钱包签名
- TypeScript 类型系统帮助匹配程序接口(IDL),减少调用错误
通过以上流程,可实现从后端程序到前端交互的完整闭环,后续可逐步深入复杂功能(如 NFT 操作、状态管理等)。







