Token 测试

在 Solana 上测试 token 逻辑,意味着在测试实际关心的转账逻辑之前,需要先设置铸币账户、token account 和权限。来自 @solana-program/tokentokenProgram() 插件将这些设置压缩为几个方法调用——并自动处理 ATA 的创建。

安装

pnpm add @solana/kit @solana/kit-plugin-litesvm @solana/kit-plugin-signer @solana-program/token

创建铸币账户

import { createClient, generateKeyPairSigner, lamports } from "@solana/kit";
import { litesvm } from "@solana/kit-plugin-litesvm";
import { signer } from "@solana/kit-plugin-signer";
import { tokenProgram } from "@solana-program/token";
const mySigner = await generateKeyPairSigner();
const client = createClient()
.use(signer(mySigner))
.use(litesvm())
.use(tokenProgram());
client.svm.airdrop(client.payer.address, lamports(10_000_000_000n));
const mintAuthority = await generateKeyPairSigner();
const newMint = await generateKeyPairSigner();
await client.token.instructions
.createMint({
newMint,
decimals: 9,
mintAuthority: mintAuthority.address
})
.sendTransaction();
// Verify
const mintAccount = await client.token.accounts.mint.fetch(newMint.address);
console.log(mintAccount.data.supply); // 0n
console.log(mintAccount.data.decimals); // 9

铸造 Token

mintToATA 将 token 发行至所有者的 associated token account。如果该 ATA 不存在,则会在同一笔交易中自动创建。

await client.token.instructions
.mintToATA({
mint: newMint.address,
owner: client.payer.address,
mintAuthority,
amount: 1_000_000_000_000n, // 1000 tokens (9 decimals)
decimals: 9
})
.sendTransaction();

decimals 参数是一项安全检查——它必须与铸币账户的小数位数完全一致,否则 Token Program 将以错误 0x24 拒绝该交易。这可防止意外铸造出多达 1000 倍数量的 token。

转账 Token

transferToATA 在用户之间转移 token。如有需要,接收方的 ATA 将自动创建。

const alice = await generateKeyPairSigner();
const bob = await generateKeyPairSigner();
// Mint to Alice
await client.token.instructions
.mintToATA({
mint: newMint.address,
owner: alice.address,
mintAuthority,
amount: 1_000_000_000_000n,
decimals: 9
})
.sendTransaction();
// Transfer 400 tokens from Alice to Bob
await client.token.instructions
.transferToATA({
mint: newMint.address,
authority: alice,
recipient: bob.address,
amount: 400_000_000_000n,
decimals: 9
})
.sendTransaction();

authority 是拥有源 token 的签名者。该插件根据其地址与铸币账户推导出源地址和目标地址的 ATA。

验证余额

要读取代币余额,请使用 findAssociatedTokenPda 推导 ATA 地址并获取已解码的账户:

import {
findAssociatedTokenPda,
TOKEN_PROGRAM_ADDRESS
} from "@solana-program/token";
const [aliceAta] = await findAssociatedTokenPda({
owner: alice.address,
mint: newMint.address,
tokenProgram: TOKEN_PROGRAM_ADDRESS
});
const aliceAccount = await client.token.accounts.token.fetch(aliceAta);
console.log(aliceAccount.data.amount); // 600_000_000_000n
console.log(aliceAccount.data.mint); // newMint.address
console.log(aliceAccount.data.owner); // alice.address

精度位数

代币数量始终以最小单位表示。9 位小数的 1000 个代币应为 1_000_000_000_000n,而非 1000n

// USDC has 6 decimals
const oneUSDC = 10n ** 6n; // 1_000_000n
// SOL has 9 decimals
const oneSOL = 10n ** 9n; // 1_000_000_000n

代币数量请始终使用 BigInt。JavaScript 的 Number 在超过 2^53 时会丢失精度。

插件参考

方法描述
client.token.instructions.createMint()创建新的 SPL token mint
client.token.instructions.mintToATA()将代币铸造至所有者的 ATA(如需则自动创建 ATA)
client.token.instructions.transferToATA()将代币转账至接收方的 ATA(如需则自动创建 ATA)
client.token.accounts.mint.fetch()获取并解码 mint account
client.token.accounts.token.fetch()获取并解码 token account

常见错误

错误原因解决方法
custom program error: 0x24decimals 与 mint 不匹配使用与传入 createMint 时相同的精度值
AccountNotFound账户尚不存在请确保在铸造前已创建 mint
InsufficientFundslamport 不足,无法支付 rent向付款方空投更多 SOL
OwnerMismatch账户的所属程序不正确检查程序 ID

Is this page helpful?

Table of Contents

Edit Page
©️ 2026 Solana 基金会版权所有