インストール
必要な依存関係がすべて揃っていることを確認してください:
cargo add --dev litesvm litesvm-token solana-sdk spl-token spl-associated-token-account
SPLトークンの基本
Solanaでは、token accountの作成は2つのステップで行われます。
Mint Accountを作成する
- トークン残高は持たない
- 総供給量、小数点以下の桁数、権限など、トークンのすべてのグローバル情報を保持する
- トークンごとに1つのmint accountが存在する
- オーナーはToken Program(TokenKegまたはToken 2022)
Token Accountを作成する
- 特定のSPLトークンの残高を保存する
- このアカウントに含まれるSPLトークンを定義するためにmint accountを保持する
- 1つのmint accountに対して複数のtoken accountを持つことができる
- オーナーはこのアカウント内のトークンを管理する権限を持つ者
Token Accountの種類
通常のToken Account
token accountは特定のSPLトークンの残高を保存します:
// Can create token accounts at ANY addresslet token_account = Keypair::new(); // Random addresslet create_ix = system_instruction::create_account(&payer.pubkey(),&token_account.pubkey(), // Any address you wantrent,165, // Token account size&spl_token::id(),);let init_ix = spl_token::instruction::initialize_account(&spl_token::id(),&token_account.pubkey(),&mint,&owner.pubkey(),)?;
✓ メリット
- •同じmint/オーナーに対して複数のアカウントを作成できる
- •柔軟性が高く、任意のアドレスを使用できる
✗ デメリット
- •決定論的でない — アドレスを手動で追跡する必要がある
- •受取人がどの account に送金すべきか伝える必要がある
- •複数の account が存在することで混乱が生じる
使用場面: 一時的・エスクロー account、カスタムロジックを持つプログラム所有の account、同一トークンに複数の account が必要な場合、高度な DeFi 戦略。
Associated Token Account (ATA)
ATA とは、決定論的な PDA アドレスに存在する token account です:
// ATA address is ALWAYS the same for owner + mintlet ata = get_associated_token_address(&owner.pubkey(), &mint);// Address derived from: [owner_pubkey, token_program_id, mint]
ATA アドレスの導出方法:
// ATA is a PDA owned by the Associated Token Programlet (ata, bump) = Pubkey::find_program_address(&[owner.as_ref(),spl_token::id().as_ref(),mint.as_ref(),],&spl_associated_token_account::id(), // ATA program);
✓ メリット
- •オーナー/ミントペアごとに 1 つの正規 account
- •決定論的 — 誰でもアドレスを計算できる
- •支払いが簡素化される — ウォレットアドレスとミントだけあれば良い
- •すべての Solana アプリで共通の標準規約
✗ デメリット
- •オーナー/ミントごとに ATA は 1 つしか持てない(仕様上)
ほとんどのケースに推奨: ウォレットアプリケーション、DeFiプロトコル、NFTの保有、決済システム、およびユーザー向けのトークン転送。
クイック例
トークンミントの作成とトークンの発行の完全な例を以下に示します:
use litesvm::LiteSVM;use litesvm_token::{get_spl_account,spl_token::{native_mint::DECIMALS, state::Account as TokenAccount},CreateAccount, CreateMint, MintTo, Transfer,};use solana_sdk::{native_token::LAMPORTS_PER_SOL,signature::{Keypair, Signer},};#[test]fn test_create_and_mint_tokens() {let mut svm = LiteSVM::new();// Create payer account and fund itlet payer = Keypair::new();svm.airdrop(&payer.pubkey(), 10 * LAMPORTS_PER_SOL).unwrap();// Create a new SPL token mint with the payer as the mint authoritylet mint = CreateMint::new(&mut svm, &payer).authority(&payer.pubkey()).decimals(DECIMALS).send().unwrap();// Create a token account for the payerlet token_account = CreateAccount::new(&mut svm, &payer, &mint).owner(&payer.pubkey()).send().unwrap();// Mint tokens into the payer's token accountMintTo::new(&mut svm, &payer, &mint, &token_account, 1000).owner(&payer).send().unwrap();// Verify balancelet token_account: TokenAccount = get_spl_account(&svm, &token_account).unwrap();let account_balance = token_account.amount;assert_eq!(account_balance, 1000)}
主要な概念
トークンの小数点
ほとんどのトークンは小数点を使用して端数を表します:
// SOL has 9 decimalslet one_sol = 10_u64.pow(9); // 1_000_000_000 lamports// USDC has 6 decimalslet one_usdc = 10_u64.pow(6); // 1_000_000 micro-USDC// Always account for decimals in calculationslet amount_tokens = 100;let amount_raw = amount_tokens * 10_u64.pow(decimals as u32);
アカウントの関係
アカウント間の関係を理解することは非常に重要です:
- ミントアカウント: トークンを定義します(供給量、小数点、権限)
- token account: 特定のオーナーのトークンを保持します
- associated token account: オーナーとミントのペアに対する決定論的なtoken account
- ミント権限: 新しいトークンを作成できます
- フリーズ権限: token accountをフリーズできます(オプション)
トラブルシューティング
よくあるエラー
| エラー | 原因 | 解決策 |
|---|---|---|
AccountNotFound | 存在しないアカウントを使用しようとしている | 使用前にアカウントが作成されていることを確認してください |
AccountAlreadyInitialized | すでに初期化済みのアカウントを初期化しようとしている | 作成前にアカウントが存在するか確認してください |
InsufficientFunds | rentまたはトークン転送のためのlamportが不足している | 十分な資金調達または発行を確認してください |
OwnerMismatch | アカウントが間違ったプログラムによって所有されている | 作成時に正しいプログラムIDを確認してください |
Is this page helpful?