솔라나 문서LiteSVMRust추가 크레이트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 토큰의 잔액을 저장
  • 이 계정에 있는 SPL 토큰을 정의하기 위해 mint account를 보유
  • 하나의 mint account에 여러 token account가 존재할 수 있음
  • 소유자는 이 계정 내 토큰에 대한 제어권을 가진 자

Token Account 유형

일반 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(),
)?;

장점

  • 동일한 민트/소유자에 대해 여러 계정 생성 가능
  • 유연성 - 임의의 주소 사용 가능

단점

  • 결정론적이지 않음 - 주소를 수동으로 추적해야 함
  • 수신자가 어떤 계정으로 전송할지 직접 알려줘야 함
  • 여러 계정으로 인해 혼란이 발생할 수 있음

사용 시기: 임시/에스크로 계정, 커스텀 로직이 있는 프로그램 소유 계정, 동일한 토큰에 대해 여러 계정이 필요한 경우, 고급 DeFi 전략.

Associated Token Account (ATA)

ATA는 결정론적 PDA 주소에 위치한 token account입니다:

// 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 보유, 결제 시스템, 그리고 사용자 대면 토큰 전송.

빠른 예제

다음은 token mint를 생성하고 토큰을 발행하는 완전한 예제입니다:

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 계정: 토큰을 정의합니다 (공급량, 소수점, 권한)
  • token account: 특정 소유자의 토큰을 보유합니다
  • associated token account: 소유자+mint 쌍에 대한 결정론적 token account
  • Mint Authority: 새로운 토큰을 생성할 수 있습니다
  • Freeze Authority: token account를 동결할 수 있습니다 (선택 사항)

문제 해결

일반적인 오류

오류원인해결책
AccountNotFound존재하지 않는 계정을 사용하려는 시도사용 전 계정이 생성되었는지 확인
AccountAlreadyInitialized이미 초기화된 계정을 다시 초기화하려는 시도생성 전 계정 존재 여부 확인
InsufficientFundsrent 또는 토큰 전송을 위한 lamport 부족충분한 자금 조달/발행 확인
OwnerMismatch잘못된 프로그램이 계정을 소유생성 시 올바른 프로그램 ID 확인

Is this page helpful?

목차

페이지 편집