وثائق سولاناLiteSVMRustاختبار برنامجك

تنفيذ التعليمات

نظرة عامة

بعد نشر برنامج على LiteSVM، ستحتاج إلى تنفيذ التعليمات للتفاعل مع البرنامج المنشور.

يوفر LiteSVM واجهة برمجية بسيطة لإنشاء المعاملات وإرسالها ومحاكاتها، وهي متوافقة تمامًا مع نموذج معاملات سولانا.

تدفق المعاملة الأساسي

التدفق المعتاد لتنفيذ تعليمة هو:

  1. إنشاء تعليمة - حدّد البرنامج الذي تريد استدعاءه والبيانات المطلوبة
  2. بناء رسالة - دمج تعليمة واحدة أو أكثر
  3. إنشاء معاملة - توقيع الرسالة بالموقّعين المطلوبين
  4. الإرسال أو المحاكاة - تنفيذ المعاملة ومعالجة النتائج

إنشاء التعليمات

هيكل التعليمة الأساسي

use solana_instruction::{Instruction, AccountMeta};
use solana_pubkey::Pubkey;
let instruction = Instruction {
program_id: Pubkey::new_unique(), // The program to call
accounts: vec![ // Accounts the program needs
AccountMeta::new(account_pubkey, false), // Writable, not signer
AccountMeta::new_readonly(readonly_pubkey, false), // Read-only, not signer
AccountMeta::new(signer_pubkey, true), // Writable, signer
],
data: vec![0, 1, 2, 3], // Instruction data (program-specific)
};

بناء المعاملات وإرسالها

الطريقة الأولى: المعاملة الأساسية

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 fees
svm.airdrop(&payer.pubkey(), 1_000_000_000).unwrap();
// Create instruction
let instruction = /* your instruction */;
// Build message with payer
let message = Message::new(&[instruction], Some(&payer.pubkey()));
// Create and sign transaction
let tx = Transaction::new_signed_with_payer(
&[instruction], // Your instructions
Some(&payer.pubkey()), // Who pays transaction fees
&[&payer], // All required signers
svm.latest_blockhash(), // Recent blockhash
);
// Send transaction
let result = svm.send_transaction(tx);

ما الذي تقوم به new_signed_with_payer:

  • تبني رسالةً تلقائيًا من تعليماتك
  • توقّع المعاملة تلقائيًا بجميع keypairs المقدَّمة
  • تُعيد معاملةً موقَّعة بالكامل وجاهزة للإرسال

الطريقة الثانية: معاملة برسالة مخصصة

let payer = Keypair::new();
// Manually construct message
let message = Message::new(&[instruction], Some(&payer.pubkey()));
// Create transaction with signers, message, and blockhash
let 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 transaction
let 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 failure
println!("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 sending
match 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 instruction
Program 11111111111111111111111111111111 consumed 2000 compute units
Program 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 transaction
ComputeBudgetInstruction::set_compute_unit_limit(400_000),
ComputeBudgetInstruction::set_compute_unit_price(1),
// Your actual instruction
your_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 SOL
let transfer_ix = system_instruction::transfer(
&alice.pubkey(),
&bob.pubkey(),
1_000_000_000, // 1 SOL
);
// Create new account
let create_ix = system_instruction::create_account(
&payer_pubkey,
&new_account_pubkey,
lamports,
space as u64,
&owner_program_id,
);

ملخص

يتبع تنفيذ التعليمات في LiteSVM نموذج معاملات سولانا القياسي:

  1. إنشاء كائنات Instruction مع معرّف البرنامج والحسابات والبيانات
  2. بناء Transaction بالتعليمة والموقّعين المطلوبين
  3. استخدام send_transaction() للتنفيذ أو simulate_transaction() للاختبار
  4. معالجة النتائج عبر فحص TransactionMetadata أو تفاصيل الخطأ

يوفر LiteSVM تنفيذاً فورياً مع سجلات تفصيلية ومعلومات تصحيح أخطاء، مما يجعله مثالياً لاختبار برامج سولانا بكفاءة.

Is this page helpful?