Документация SolanaLiteSVMRustДополнительные контейнерыlitesvm-token

Быстрый старт

Установка

Убедитесь, что у вас есть все необходимые зависимости:

cargo add --dev litesvm litesvm-token solana-sdk spl-token spl-associated-token-account

Основы SPL-токенов

В 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 address
let token_account = Keypair::new(); // Random address
let create_ix = system_instruction::create_account(
&payer.pubkey(),
&token_account.pubkey(), // Any address you want
rent,
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 + mint
let 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 Program
let (ata, bump) = Pubkey::find_program_address(
&[
owner.as_ref(),
spl_token::id().as_ref(),
mint.as_ref(),
],
&spl_associated_token_account::id(), // ATA program
);

Преимущества

  • Один канонический аккаунт на пару владелец/минт
  • Детерминированный — любой может вычислить адрес
  • Упрощает платежи — нужны только адрес кошелька и минт
  • Стандартное соглашение во всех приложениях Solana

Недостатки

  • Можно иметь только ОДИН ATA на пару владелец/минт (по замыслу)

Рекомендуется в большинстве случаев: Кошельковые приложения, 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 it
let payer = Keypair::new();
svm.airdrop(&payer.pubkey(), 10 * LAMPORTS_PER_SOL).unwrap();
// Create a new SPL token mint with the payer as the mint authority
let mint = CreateMint::new(&mut svm, &payer)
.authority(&payer.pubkey())
.decimals(DECIMALS)
.send()
.unwrap();
// Create a token account for the payer
let token_account = CreateAccount::new(&mut svm, &payer, &mint)
.owner(&payer.pubkey())
.send()
.unwrap();
// Mint tokens into the payer's token account
MintTo::new(&mut svm, &payer, &mint, &token_account, 1000)
.owner(&payer)
.send()
.unwrap();
// Verify balance
let token_account: TokenAccount = get_spl_account(&svm, &token_account).unwrap();
let account_balance = token_account.amount;
assert_eq!(account_balance, 1000)
}

Ключевые концепции

Десятичные знаки токена

Большинство токенов используют десятичные знаки для представления дробных количеств:

// SOL has 9 decimals
let one_sol = 10_u64.pow(9); // 1_000_000_000 lamports
// USDC has 6 decimals
let one_usdc = 10_u64.pow(6); // 1_000_000 micro-USDC
// Always account for decimals in calculations
let amount_tokens = 100;
let amount_raw = amount_tokens * 10_u64.pow(decimals as u32);

Связи между аккаунтами

Понимание связей между аккаунтами имеет ключевое значение:

  • Mint Account: Определяет токен (эмиссию, десятичные знаки, полномочия)
  • Token Account: Хранит токены для конкретного владельца
  • Associated Token Account: Детерминированный token account для пары владелец+минт
  • Mint Authority: Может создавать новые токены
  • Freeze Authority: Может замораживать token account (необязательно)

Устранение неполадок

Распространённые ошибки

ОшибкаПричинаРешение
AccountNotFoundПопытка использовать аккаунт, который не существуетУбедитесь, что аккаунт создан перед использованием
AccountAlreadyInitializedПопытка инициализировать уже инициализированный аккаунтПроверьте, существует ли аккаунт перед созданием
InsufficientFundsНедостаточно lamport для rent или токенов для переводаОбеспечьте достаточное финансирование/выпуск
OwnerMismatchАккаунт принадлежит неверной программеПроверьте правильность ID программы при создании

Is this page helpful?