설치
필요한 모든 종속성이 있는지 확인하세요:
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 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(),)?;
✓ 장점
- •동일한 민트/소유자에 대해 여러 계정 생성 가능
- •유연성 - 임의의 주소 사용 가능
✗ 단점
- •결정론적이지 않음 - 주소를 수동으로 추적해야 함
- •수신자가 어떤 계정으로 전송할지 직접 알려줘야 함
- •여러 계정으로 인해 혼란이 발생할 수 있음
사용 시기: 임시/에스크로 계정, 커스텀 로직이 있는 프로그램 소유 계정, 동일한 토큰에 대해 여러 계정이 필요한 경우, 고급 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);
✓ 장점
- •소유자/민트 쌍당 하나의 표준 계정
- •결정론적 - 누구나 주소를 계산할 수 있음
- •결제 간소화 - 지갑 주소와 민트만 있으면 됨
- •모든 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 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);
계정 관계
계정 간의 관계를 이해하는 것은 매우 중요합니다:
- Mint 계정: 토큰을 정의합니다 (공급량, 소수점, 권한)
- token account: 특정 소유자의 토큰을 보유합니다
- associated token account: 소유자+mint 쌍에 대한 결정론적 token account
- Mint Authority: 새로운 토큰을 생성할 수 있습니다
- Freeze Authority: token account를 동결할 수 있습니다 (선택 사항)
문제 해결
일반적인 오류
| 오류 | 원인 | 해결책 |
|---|---|---|
AccountNotFound | 존재하지 않는 계정을 사용하려는 시도 | 사용 전 계정이 생성되었는지 확인 |
AccountAlreadyInitialized | 이미 초기화된 계정을 다시 초기화하려는 시도 | 생성 전 계정 존재 여부 확인 |
InsufficientFunds | rent 또는 토큰 전송을 위한 lamport 부족 | 충분한 자금 조달/발행 확인 |
OwnerMismatch | 잘못된 프로그램이 계정을 소유 | 생성 시 올바른 프로그램 ID 확인 |
Is this page helpful?