개요
LiteSVM에 프로그램을 배포한 후, 배포된 프로그램과 상호작용하려면 명령어를 실행해야 합니다.
LiteSVM은 트랜잭션을 생성, 전송 및 시뮬레이션하기 위한 간단한 API를 제공하며, Solana의 트랜잭션 모델과 완전히 호환됩니다.
기본 트랜잭션 흐름
명령어를 실행하는 일반적인 흐름은 다음과 같습니다:
- 명령어 생성 - 호출할 프로그램과 전달할 데이터를 정의합니다
- 메시지 빌드 - 하나 이상의 명령어를 결합합니다
- 트랜잭션 생성 - 필요한 서명자로 메시지에 서명합니다
- 전송 또는 시뮬레이션 - 트랜잭션을 실행하고 결과를 처리합니다
명령어 생성
기본 명령어 구조
use solana_instruction::{Instruction, AccountMeta};use solana_pubkey::Pubkey;let instruction = Instruction {program_id: Pubkey::new_unique(), // The program to callaccounts: vec![ // Accounts the program needsAccountMeta::new(account_pubkey, false), // Writable, not signerAccountMeta::new_readonly(readonly_pubkey, false), // Read-only, not signerAccountMeta::new(signer_pubkey, true), // Writable, signer],data: vec![0, 1, 2, 3], // Instruction data (program-specific)};
트랜잭션 빌드 및 전송
방법 1: 기본 트랜잭션
use litesvm::LiteSVM;use solana_keypair::Keypair;use solana_message::Message;use solana_transaction::Transaction;use solana_signer::Signer;let mut svm = LiteSVM::new();let payer = Keypair::new();// Airdrop SOL for feessvm.airdrop(&payer.pubkey(), 1_000_000_000).unwrap();// Create instructionlet instruction = /* your instruction */;// Build message with payerlet message = Message::new(&[instruction], Some(&payer.pubkey()));// Create and sign transactionlet tx = Transaction::new_signed_with_payer(&[instruction], // Your instructionsSome(&payer.pubkey()), // Who pays transaction fees&[&payer], // All required signerssvm.latest_blockhash(), // Recent blockhash);// Send transactionlet result = svm.send_transaction(tx);
new_signed_with_payer의 동작:
- 명령어로부터 메시지를 자동으로 빌드합니다
- 제공된 모든 keypair로 트랜잭션에 자동으로 서명합니다
- 완전히 서명된, 전송 준비가 완료된 트랜잭션을 반환합니다
방법 2: 커스텀 메시지 트랜잭션
let payer = Keypair::new();// Manually construct messagelet message = Message::new(&[instruction], Some(&payer.pubkey()));// Create transaction with signers, message, and blockhashlet tx = Transaction::new(&[&payer],message,svm.latest_blockhash(),);let result = svm.send_transaction(tx);
다음과 같이 Message를 직접 제어해야 할 때 이 방법을 사용하세요:
- 버전 트랜잭션 (조회 테이블이 포함된 v0)
- 부분/다중 서명 워크플로
- 지속 가능한 논스
- 서명 전 시뮬레이션 또는 검사
- 커스텀 수수료 납부자 로직
- 트랜잭션 크기 최적화
버전 트랜잭션
LiteSVM은 레거시 트랜잭션과 버전 트랜잭션을 모두 지원합니다:
use solana_transaction::versioned::VersionedTransaction;use solana_message::VersionedMessage;// Legacy transaction (most common)let legacy_msg = Message::new(&[instruction], Some(&payer.pubkey()));let versioned_tx = VersionedTransaction::try_new(VersionedMessage::Legacy(legacy_msg),&[&payer]).unwrap();// Send versioned transactionlet result = svm.send_transaction(versioned_tx);
트랜잭션 결과
성공한 트랜잭션
match svm.send_transaction(tx) {Ok(meta) => {println!("Signature: {}", meta.signature);println!("Compute units: {}", meta.compute_units_consumed);println!("Logs:");for log in &meta.logs {println!(" {}", log);}}Err(err) => {println!("Transaction failed: {:?}", err.err);// Logs are still available on failureprintln!("Failure logs: {:?}", err.meta.logs);}}
트랜잭션 메타데이터 필드
pub struct TransactionMetadata {pub signature: Signature,pub logs: Vec<String>,pub inner_instructions: InnerInstructionsList,pub compute_units_consumed: u64,pub return_data: TransactionReturnData,pub fee: u64,}
트랜잭션 시뮬레이션
트랜잭션 시뮬레이션을 사용하면 상태를 변경하지 않고 트랜잭션을 테스트할 수 있습니다:
// Simulate instead of sendingmatch svm.simulate_transaction(tx) {Ok(sim_result) => {println!("Simulation successful!");println!("Logs: {:?}", sim_result.meta.logs);println!("Compute units: {}", sim_result.meta.compute_units_consumed);}Err(err) => {println!("Simulation failed: {:?}", err.err);}}
오류 처리
일반적인 트랜잭션 오류
use solana_transaction_error::TransactionError;use solana_instruction::error::InstructionError;match svm.send_transaction(tx) {Err(failed_tx) => {match failed_tx.err {TransactionError::InsufficientFundsForFee => {println!("Not enough SOL for fees");}TransactionError::InvalidProgramForExecution => {println!("Program doesn't exist or isn't executable");}TransactionError::InstructionError(index, err) => {println!("Instruction {} failed: {:?}", index, err);match err {InstructionError::Custom(code) => {println!("Custom error code: {}", code);}InstructionError::AccountNotFound => {println!("An account doesn't exist");}_ => {}}}TransactionError::BlockhashNotFound => {println!("Blockhash expired or invalid");}_ => println!("Other error: {:?}", failed_tx.err),}}Ok(_) => {}}
프로그램 로그 활용
로그 접근
let result = svm.send_transaction(tx).unwrap();// All logs (including system logs)for log in &result.logs {println!("{}", log);}// Pretty-printed logs (formatted)println!("{}", result.pretty_logs());
로그 출력 예시
Program 11111111111111111111111111111111 invoke [1]Program log: Processing instructionProgram 11111111111111111111111111111111 consumed 2000 compute unitsProgram 11111111111111111111111111111111 success
컴퓨트 버짓 설정
글로벌 컴퓨트 버짓 설정
use solana_compute_budget::compute_budget::ComputeBudget;let mut svm = LiteSVM::new().with_compute_budget(ComputeBudget {compute_unit_limit: 200_000,..Default::default()});
트랜잭션별 컴퓨트 버짓
use solana_compute_budget_interface::ComputeBudgetInstruction;let instructions = vec![// Set compute budget for this transactionComputeBudgetInstruction::set_compute_unit_limit(400_000),ComputeBudgetInstruction::set_compute_unit_price(1),// Your actual instructionyour_instruction,];
System Program 명령어
LiteSVM은 System Program을 지원합니다:
use solana_keypair::Keypair;use solana_signer::Signer;use solana_system_interface::instruction as system_instruction;use solana_transaction::Transaction;// Transfer SOLlet transfer_ix = system_instruction::transfer(&alice.pubkey(),&bob.pubkey(),1_000_000_000, // 1 SOL);// Create new accountlet create_ix = system_instruction::create_account(&payer_pubkey,&new_account_pubkey,lamports,space as u64,&owner_program_id,);
요약
LiteSVM에서 명령어 실행은 표준 Solana 트랜잭션 모델을 따릅니다:
- 프로그램 ID, 계정, 데이터를 포함한
Instruction객체 생성 - 명령어와 필수 서명자로
Transaction구성 - 실행 시
send_transaction(), 테스트 시simulate_transaction()사용 TransactionMetadata또는 오류 세부 정보를 확인하여 결과 처리
LiteSVM은 상세한 로그와 디버깅 정보를 제공하며 즉각적인 실행이 가능하여 Solana 프로그램을 효율적으로 테스트하기에 최적화되어 있습니다.
Is this page helpful?