Встановлення
Переконайтеся, що у вас є всі необхідні залежності:
cargo add --dev litesvm litesvm-token solana-sdk spl-token spl-associated-token-account
Основи SPL Token
У Solana створення token account є двоетапним процесом.
Створіть Mint Account
- Не має балансу токенів
- Зберігає всю глобальну інформацію про токен, наприклад загальну пропозицію, десяткові знаки, авторитет тощо
- Існує один mint account на токен
- Власником є Token Program (TokenKeg або Token 2022)
Створіть Token Account
- Зберігає баланс для конкретного токена SPL
- Містить mint account для визначення того, який токен SPL знаходиться на цьому рахунку
- Для одного mint account може бути кілька token accounts
- Власник — це той, хто має контроль над токенами всередині цього рахунку
Типи Token Accounts
Звичайний 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/власника
- •Гнучкість — можна використовувати будь-яку адресу
✗ Недоліки
- •Недетермінований — потрібно відстежувати адреси вручну
- •Одержувач повинен повідомити вам, на який рахунок надсилати
- •Створює плутанину за наявності кількох рахунків
Коли використовувати: Тимчасові/ескроу-рахунки, рахунки, що належать програмі з нестандартною логікою, коли потрібно кілька рахунків для одного токена, складні DeFi-стратегії.
Associated Token Account (ATA)
ATA — це token account за детермінованою PDA-адресою:
// 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);
✓ Переваги
- •Один канонічний рахунок на пару власник/mint
- •Детермінований — будь-хто може обчислити адресу
- •Спрощує платежі — потрібна лише адреса гаманця + mint
- •Стандартний підхід у всіх додатках Solana
✗ Недоліки
- •Можна мати лише ОДИН ATA на пару власник/mint (за задумом)
Рекомендовано для більшості випадків: Гаманці, 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 | Недостатньо lamport для rent або токенів для переказу | Забезпечте достатнє фінансування/карбування |
OwnerMismatch | Акаунт належить неправильній програмі | Перевірте правильний ідентифікатор програми під час створення |
Is this page helpful?