Mollusk
Mollusk adalah alat pengujian ringan untuk menguji program Solana. Mollusk menyediakan antarmuka sederhana untuk menguji instruksi program Solana dalam lingkungan Solana Virtual Machine (SVM) yang diminimalkan. Semua akun pengujian harus didefinisikan secara eksplisit, memastikan tes yang deterministik dan dapat diulang.
Instalasi
Tambahkan mollusk-svm sebagai dependensi di Cargo.toml:
Terminal
$cargo add mollusk-svm --dev
Cargo.toml
[dev-dependencies]mollusk-svm = "0.7"
Untuk melakukan benchmark penggunaan unit komputasi, tambahkan
mollusk-svm-bencher sebagai dependensi di Cargo.toml:
Terminal
$cargo add mollusk-svm-bencher --dev
Cargo.toml
[dev-dependencies]mollusk-svm-bencher = "0.7"
Untuk menggunakan Token Program, Token2022 Program (Token Extensions), dan
Associated Token Program untuk pengujian dengan Mollusk, tambahkan
mollusk-svm-programs-token sebagai dependensi di Cargo.toml:
Terminal
$cargo add mollusk-svm-programs-token --dev
Cargo.toml
[dev-dependencies]mollusk-svm-programs-token = "0.7"
Mollusk SVM
Contoh berikut menunjukkan pengaturan minimal untuk menguji program Solana dasar menggunakan Mollusk.
Program Hello World
Contoh ini mendemonstrasikan cara menguji program Solana dasar menggunakan Mollusk. Program ini hanya mencetak "Hello, world!" ke log program saat dipanggil.
Menjalankan cargo build-sbf menghasilkan program terkompilasi di
/target/deploy/<program_name>.so.
src/lib.rs
use solana_program::{account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, msg, pubkey::Pubkey,};entrypoint!(process_instruction);pub fn process_instruction(_program_id: &Pubkey,_accounts: &[AccountInfo],_instruction_data: &[u8],) -> ProgramResult {msg!("Hello, world!");Ok(())}#[cfg(test)]mod tests {use mollusk_svm::{result::Check, Mollusk};use solana_sdk::{instruction::Instruction, pubkey::Pubkey};#[test]fn test_hello_world() {let program_id = Pubkey::new_unique();let mollusk = Mollusk::new(&program_id, "target/deploy/hello_world");let instruction = Instruction::new_with_bytes(program_id, &[], vec![]);mollusk.process_and_validate_instruction(&instruction, &[], &[Check::success()]);}}
Untuk menguji program Solana dengan Mollusk:
- Buat instance
Mollusk- Inisialisasi Mollusk dengan program ID dan jalur ke program terkompilasi (file.so) - Bangun instruksi - Buat instruksi untuk memanggil program
- Proses dan validasi - Proses instruksi menggunakan Mollusk dan validasi hasilnya
src/lib.rs
#[cfg(test)]mod tests {use mollusk_svm::{result::Check, Mollusk};use solana_sdk::{instruction::Instruction, pubkey::Pubkey};#[test]fn test_hello_world() {let program_id = Pubkey::new_unique();let mollusk = Mollusk::new(&program_id, "target/deploy/hello_world");let instruction = Instruction::new_with_bytes(program_id, &[], vec![]);mollusk.process_and_validate_instruction(&instruction, &[], &[Check::success()]);}}
Untuk menjalankan pengujian, jalankan cargo test.
Ketika pengujian berjalan dengan sukses, Anda akan melihat output yang mirip dengan berikut ini:
Terminal
running 1 test[2025-09-22T19:25:50.427685000Z DEBUG solana_runtime::message_processor::stable_log] Program 11157t3sqMV725NVRLrVQbAu98Jjfk1uCKehJnXXQs invoke [1][2025-09-22T19:25:50.429669000Z DEBUG solana_runtime::message_processor::stable_log] Program log: Hello, world![2025-09-22T19:25:50.429690000Z DEBUG solana_runtime::message_processor::stable_log] Program 11157t3sqMV725NVRLrVQbAu98Jjfk1uCKehJnXXQs consumed 211 of 1400000 compute units[2025-09-22T19:25:50.429726000Z DEBUG solana_runtime::message_processor::stable_log] Program 11157t3sqMV725NVRLrVQbAu98Jjfk1uCKehJnXXQs successtest tests::test_hello_world ... oktest result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02sDoc-tests hello_world
Struct
Mollusk
menyediakan antarmuka sederhana untuk menguji program Solana. Semua bidang dapat
dimanipulasi melalui beberapa metode pembantu, tetapi pengguna juga dapat
langsung mengakses dan memodifikasinya jika mereka menginginkan kontrol yang
lebih besar.
Untuk menginisialisasi Mollusk dengan instance default, gunakan metode
Mollusk::default.
Example
// Default instance with no custom programslet mollusk = Mollusk::default();
Untuk menginisialisasi Mollusk dengan program tertentu, gunakan metode
Mollusk::new.
Example
// Initialize Mollusk with a specific program from a file pathlet program_id = Pubkey::new_unique();let mollusk = Mollusk::new(&program_id, "target/deploy/my_program");
Untuk menambahkan program ke Mollusk, gunakan metode Mollusk::add_program.
Example
let mollusk = Mollusk::default();let program_id = Pubkey::new_unique();// Add a program to Molluskmollusk.add_program(&program_id,"target/deploy/my_program",&bpf_loader_upgradeable::id(),);
Saat menyediakan jalur file, jangan sertakan ekstensi .so. Misalnya,
"path/to/my_program" adalah benar, tetapi "path/to/my_program.so" tidak
benar.
Memproses instruksi
Mollusk menyediakan empat metode utama untuk memproses instruksi:
| Metode | Deskripsi |
|---|---|
process_instruction | Memproses instruksi dan mengembalikan hasilnya. |
process_and_validate_instruction | Memproses instruksi dan melakukan serangkaian pemeriksaan pada hasilnya, panik jika ada pemeriksaan yang gagal. |
process_instruction_chain | Memproses beberapa instruksi dan mengembalikan hasilnya. |
process_and_validate_instruction_chain | Memproses beberapa instruksi dan melakukan serangkaian pemeriksaan pada setiap hasil, panik jika ada pemeriksaan yang gagal. |
InstructionResult
berisi detail dari instruksi yang diproses.
Instruksi tunggal
Gunakan metode process_instruction untuk memproses instruksi tunggal tanpa
pemeriksaan pada hasilnya. Anda dapat memvalidasi hasil secara manual setelah
pemrosesan.
Method Signature
pub fn process_instruction(&self,instruction: &Instruction,accounts: &[(Pubkey, Account)],) -> InstructionResult
Contoh berikut memproses instruksi transfer SOL tanpa pemeriksaan validasi.
Contoh di bawah ini menjalankan Mollusk dalam fungsi main untuk tujuan
demonstrasi. Dalam praktiknya, Anda biasanya akan menggunakan Mollusk dalam
modul pengujian yang diberi anotasi dengan atribut #[test].
Single Instruction
use mollusk_svm::Mollusk;use solana_sdk::{account::Account, pubkey::Pubkey};use solana_system_interface::{instruction::transfer, program::ID as SYSTEM_PROGRAM_ID};fn main() {// Initialize Mollusklet mollusk = Mollusk::default();// Set up accountslet sender = Pubkey::new_unique();let recipient = Pubkey::new_unique();let initial_lamports = 1_000_000;let transfer_amount = 250_000;// Create transfer instructionlet instruction = transfer(&sender, &recipient, transfer_amount);// Define initial account stateslet accounts = vec![(sender,Account {lamports: initial_lamports,data: vec![],owner: SYSTEM_PROGRAM_ID,executable: false,rent_epoch: 0,},),(recipient,Account {lamports: 0,data: vec![],owner: SYSTEM_PROGRAM_ID,executable: false,rent_epoch: 0,},),];// Process the instructionlet result = mollusk.process_instruction(&instruction, &accounts);println!("{:#?}", result);// Check the resultassert!(result.program_result.is_ok());assert_eq!(result.get_account(&sender).unwrap().lamports, 750_000);assert_eq!(result.get_account(&recipient).unwrap().lamports, 250_000);}
Console
Click to execute the code.
Instruksi Tunggal dengan Pemeriksaan
Gunakan metode process_and_validate_instruction untuk memproses instruksi
tunggal dengan pemeriksaan validasi. Metode ini akan menimbulkan panic jika ada
pemeriksaan yang gagal.
Method Signature
pub fn process_and_validate_instruction(&self,instruction: &Instruction,accounts: &[(Pubkey, Account)],checks: &[Check],) -> InstructionResult
Contoh berikut memproses instruksi transfer SOL dengan pemeriksaan validasi.
With Validation
use {mollusk_svm::{result::Check, Mollusk},solana_sdk::{account::Account, pubkey::Pubkey},solana_system_interface::{instruction::transfer, program::ID as SYSTEM_PROGRAM_ID},};fn main() {let mollusk = Mollusk::default();let sender = Pubkey::new_unique();let recipient = Pubkey::new_unique();let initial_lamports = 1_000_000;let transfer_amount = 250_000;let instruction = transfer(&sender, &recipient, transfer_amount);let accounts = vec![(sender,Account {lamports: initial_lamports,data: vec![],owner: SYSTEM_PROGRAM_ID,executable: false,rent_epoch: 0,},),(recipient,Account {lamports: 0,data: vec![],owner: SYSTEM_PROGRAM_ID,executable: false,rent_epoch: 0,},),];// Define validation checkslet checks = vec![Check::success(),Check::account(&sender).lamports(750_000).build(),Check::account(&recipient).lamports(250_000).build(),];// Process and validate (will panic if any check fails)let result = mollusk.process_and_validate_instruction(&instruction, &accounts, &checks);println!("{:#?}", result);}
Console
Click to execute the code.
Beberapa Instruksi
Gunakan metode process_instruction_chain untuk memproses beberapa instruksi
secara berurutan tanpa pemeriksaan validasi.
Method Signature
pub fn process_instruction_chain(&self,instructions: &[Instruction],accounts: &[(Pubkey, Account)],) -> InstructionResult
Contoh berikut memproses dua instruksi transfer SOL tanpa pemeriksaan validasi.
Multiple Instructions
use {mollusk_svm::Mollusk,solana_sdk::{account::Account, pubkey::Pubkey},solana_system_interface::{instruction::transfer, program::ID as SYSTEM_PROGRAM_ID},};fn main() {let mollusk = Mollusk::default();// Set up accountslet alice = Pubkey::new_unique();let bob = Pubkey::new_unique();let charlie = Pubkey::new_unique();let initial_lamports = 1_000_000;// Create chain of transferslet instructions = vec![transfer(&alice, &bob, 300_000), // Alice -> Bobtransfer(&bob, &charlie, 100_000), // Bob -> Charlie];let accounts = vec![(alice,Account {lamports: initial_lamports,data: vec![],owner: SYSTEM_PROGRAM_ID,executable: false,rent_epoch: 0,},),(bob,Account {lamports: 0,data: vec![],owner: SYSTEM_PROGRAM_ID,executable: false,rent_epoch: 0,},),(charlie,Account {lamports: 0,data: vec![],owner: SYSTEM_PROGRAM_ID,executable: false,rent_epoch: 0,},),];// Process the instruction chainlet result = mollusk.process_instruction_chain(&instructions, &accounts);println!("{:#?}", result);// Final balances: Alice=700K, Bob=200K, Charlie=100Kassert_eq!(result.get_account(&alice).unwrap().lamports, 700_000);assert_eq!(result.get_account(&bob).unwrap().lamports, 200_000);assert_eq!(result.get_account(&charlie).unwrap().lamports, 100_000);}
Console
Click to execute the code.
Beberapa Instruksi dengan Pemeriksaan
Gunakan metode process_and_validate_instruction_chain untuk memproses beberapa
instruksi dengan pemeriksaan validasi setelah setiap instruksi. Setiap instruksi
memiliki serangkaian pemeriksaan sendiri yang harus lulus.
Method Signature
pub fn process_and_validate_instruction_chain(&self,instructions: &[(&Instruction, &[Check])],accounts: &[(Pubkey, Account)],) -> InstructionResult
Contoh berikut memproses rangkaian dua instruksi transfer SOL dengan pemeriksaan validasi setelah setiap instruksi.
With Validation
use {mollusk_svm::{result::Check, Mollusk},solana_sdk::{account::Account, pubkey::Pubkey},solana_system_interface::{instruction::transfer, program::ID as SYSTEM_PROGRAM_ID},};fn main() {let mollusk = Mollusk::default();// Create accountslet alice = Pubkey::new_unique();let bob = Pubkey::new_unique();let charlie = Pubkey::new_unique();let initial_lamports = 1_000_000;// Create transfer instructionslet transfer1 = transfer(&alice, &bob, 300_000);let transfer2 = transfer(&bob, &charlie, 100_000);// Initial accountslet accounts = vec![(alice,Account {lamports: initial_lamports,data: vec![],owner: SYSTEM_PROGRAM_ID,executable: false,rent_epoch: 0,},),(bob,Account {lamports: 0,data: vec![],owner: SYSTEM_PROGRAM_ID,executable: false,rent_epoch: 0,},),(charlie,Account {lamports: 0,data: vec![],owner: SYSTEM_PROGRAM_ID,executable: false,rent_epoch: 0,},),];// Define checks for each instructionlet checks_after_transfer1 = vec![Check::success(),Check::account(&alice).lamports(700_000) // 1M - 300K.build(),Check::account(&bob).lamports(300_000) // 0 + 300K.build(),Check::account(&charlie).lamports(0) // Unchanged.build(),];let checks_after_transfer2 = vec![Check::success(),Check::account(&alice).lamports(700_000) // Unchanged from previous.build(),Check::account(&bob).lamports(200_000) // 300K - 100K.build(),Check::account(&charlie).lamports(100_000) // 0 + 100K.build(),];// Process with validation at each steplet instruction_and_checks = [(&transfer1, checks_after_transfer1.as_slice()),(&transfer2, checks_after_transfer2.as_slice()),];// Execute chain (panics if any check fails)let result = mollusk.process_and_validate_instruction_chain(&instruction_and_checks, &accounts);println!("{:#?}", result);}
Console
Click to execute the code.
Pemeriksaan Validasi
Mollusk menyediakan serangkaian metode pembantu untuk memeriksa hasil dari instruksi yang diproses.
Example
use mollusk_svm::result::Check;
Gunakan metode berikut untuk memvalidasi hasil instruksi:
Example
// Program execution succeededCheck::success()// Program returned specific errorCheck::err(ProgramError::InvalidArgument)// Instruction level errorCheck::instruction_err(InstructionError::InsufficientFunds)// Check with specific program resultCheck::program_result(ProgramResult::Success)// Compute units consumedCheck::compute_units(1000)// Execution timeCheck::time(100)// Return data from instruction executionCheck::return_data(&[1, 2, 3, 4])
Gunakan berikut ini untuk memvalidasi status Akun:
Example
// Single account validationCheck::account(&pubkey).lamports(1_000_000) // Exact lamports.owner(&program_id) // Account owner.data(&expected_data) // Exact data match.data_slice(8, &[1, 2, 3]) // Partial data match at offset.executable(false) // Executable flag.space(100) // Account data size.closed() // Account is closed (0 lamports).rent_exempt() // Account is rent-exempt.build()// Check all accounts are rent exemptCheck::all_rent_exempt()
Status Akun Persisten
MolluskContext
adalah pembungkus untuk Mollusk yang mempertahankan status akun di beberapa
panggilan instruksi melalui account_store. Metode untuk memproses instruksi
identik dengan Mollusk.
Tidak seperti Mollusk, yang memerlukan pengiriman accounts ke setiap metode
(misalnya process_instruction), MolluskContext mengelola akun secara
internal melalui account_store. Ini menghilangkan kebutuhan parameter
accounts saat memproses instruksi.
Buat account_store menggunakan metode with_context:
Example
use std::collections::HashMap;use solana_sdk::{account::Account, pubkey::Pubkey};use solana_system_interface::program::ID as SYSTEM_PROGRAM_ID;use mollusk_svm::Mollusk;let mollusk = Mollusk::default();let account_address = Pubkey::new_unique();let mut account_store = HashMap::new();account_store.insert(account_address,Account {lamports: 1_000_000,data: vec![],owner: SYSTEM_PROGRAM_ID,executable: false,rent_epoch: 0,},);let context = mollusk.with_context(account_store);
Contoh berikut memproses dua instruksi transfer SOL terpisah dengan status akun
persisten antara instruksi melalui account_store.
Stateful Testing
use {mollusk_svm::Mollusk,solana_sdk::{account::Account, pubkey::Pubkey},solana_system_interface::{instruction::transfer, program::ID as SYSTEM_PROGRAM_ID},std::collections::HashMap,};fn main() {// Initialize Mollusklet mollusk = Mollusk::default();// Create accountslet sender = Pubkey::new_unique();let recipient = Pubkey::new_unique();// Create account store with initial balanceslet mut account_store = HashMap::new();account_store.insert(sender,Account {lamports: 1_000_000,data: vec![],owner: SYSTEM_PROGRAM_ID,executable: false,rent_epoch: 0,},);account_store.insert(recipient,Account {lamports: 0,data: vec![],owner: SYSTEM_PROGRAM_ID,executable: false,rent_epoch: 0,},);// Create a stateful contextlet context = mollusk.with_context(account_store);// First transfer: 200,000 lamportslet instruction1 = transfer(&sender, &recipient, 200_000);context.process_instruction(&instruction1);// Second transfer: 100,000 lamports (state persists from first transfer)let instruction2 = transfer(&sender, &recipient, 100_000);context.process_instruction(&instruction2);// Check final balanceslet store = context.account_store.borrow();let sender_account = store.get(&sender).unwrap();let recipient_account = store.get(&recipient).unwrap();println!("Sender: {:#?}", sender_account);println!("Recipient: {:#?}", recipient_account);}
Console
Click to execute the code.
Sysvars Mollusk
Mollusk menyediakan struktur
Sysvars
kustom untuk memodifikasi nilai-nilainya untuk pengujian.
Gunakan metode warp_to_slot untuk memperbarui jam sysvar untuk mensimulasikan
pergerakan maju atau mundur dalam waktu ke slot tertentu.
Warp to Slot
use mollusk_svm::Mollusk;fn main() {// Initialize Mollusklet mut mollusk = Mollusk::default();// Show initial slotprintln!("Initial slot: {}", mollusk.sysvars.clock.slot);// Warp to slot 1000mollusk.warp_to_slot(100);println!("After warp: {}", mollusk.sysvars.clock.slot);// Warp to slot 10mollusk.warp_to_slot(10);println!("After second warp: {}", mollusk.sysvars.clock.slot);}
Console
Click to execute the code.
Contoh berikut menunjukkan cara memodifikasi sysvar Mollusk secara langsung
dengan mengakses bidang sysvars untuk mengubah parameter rent. Anda dapat
memodifikasi nilai sysvar lainnya dengan cara yang sama.
Modify Sysvars
use {mollusk_svm::Mollusk, solana_sdk::rent::Rent};fn main() {let mut mollusk = Mollusk::default();// Show default rentprintln!("Default rent exemption for 1000 bytes: {} lamports",mollusk.sysvars.rent.minimum_balance(1000));// Customize rent parametersmollusk.sysvars.rent = Rent {lamports_per_byte_year: 1,exemption_threshold: 1.0,burn_percent: 0,};// Show custom rentprintln!("Custom rent exemption for 1000 bytes: {} lamports",mollusk.sysvars.rent.minimum_balance(1000));}
Console
Click to execute the code.
Benchmarking Unit Komputasi
MolluskComputeUnitBencher
melacak penggunaan unit komputasi dari instruksi program. Hasil ditulis ke file
markdown.
Memerlukan
mollusk-svm-bencher
sebagai dependensi.
Contoh berikut melakukan benchmark penggunaan unit komputasi dari instruksi transfer SOL.
Benchmark Compute Units
use {mollusk_svm::Mollusk,mollusk_svm_bencher::MolluskComputeUnitBencher,solana_sdk::{account::Account, pubkey::Pubkey},solana_system_interface::{instruction::transfer, program::ID as SYSTEM_PROGRAM_ID},};fn main() {// Initialize Mollusklet mollusk = Mollusk::default();// Create test accountslet sender = Pubkey::new_unique();let receiver = Pubkey::new_unique();// Transfer instructionlet transfer = transfer(&sender, &receiver, 100_000);let accounts = vec![(sender,Account {lamports: 1_000_000,data: vec![],owner: SYSTEM_PROGRAM_ID,executable: false,rent_epoch: 0,},),(receiver,Account {lamports: 0,data: vec![],owner: SYSTEM_PROGRAM_ID,executable: false,rent_epoch: 0,},),];// Run benchmarkMolluskComputeUnitBencher::new(mollusk).bench(("transfer", &transfer, &accounts)).must_pass(true).out_dir("./target/benches").execute();}
Hasil benchmark ditulis ke out_dir yang ditentukan sebagai file markdown
bernama compute_units.md.
comput_units.md
#### 2025-09-19 22:28:53.691839 UTCSolana CLI Version: solana-cli 2.2.20 (src:dabc99a5; feat:3073396398,client:Agave)| Name | CUs | Delta || -------- | --- | ------- || transfer | 150 | - new - |
Pengujian Token Program
Gunakan
mollusk-svm-programs-token
crate untuk menambahkan token program, token2022 program (token extensions), dan
associated token program ke Mollusk untuk pengujian.
Example
use {mollusk_svm::Mollusk,mollusk_svm_programs_token::{associated_token, token, token2022},};let mut mollusk = Mollusk::default();// Add SPL Token Programtoken::add_program(&mut mollusk);// Add SPL Token-2022 Programtoken2022::add_program(&mut mollusk);// Add Associated Token Account Programassociated_token::add_program(&mut mollusk);
Contoh berikut mendemonstrasikan pengujian transfer token menggunakan Mollusk.
Contoh di bawah ini mendefinisikan akun pengujian secara manual untuk tujuan
demonstrasi. mollusk-svm-programs-token juga menyertakan fungsi pembantu
untuk membuat akun mint dan token.
Token Transfer Example
use {mollusk_svm::{result::Check, Mollusk},mollusk_svm_programs_token::token,solana_sdk::{account::Account, program_pack::Pack, pubkey::Pubkey},spl_token_interface::{instruction::transfer_checked,state::{Account as TokenAccount, AccountState, Mint},},};fn main() {// Initialize Mollusk with Token programlet mut mollusk = Mollusk::default();token::add_program(&mut mollusk);// Create account keyslet mint = Pubkey::new_unique();let source = Pubkey::new_unique();let destination = Pubkey::new_unique();let authority = Pubkey::new_unique();// Token configurationlet decimals = 6;let transfer_amount = 1_000_000; // 1 token with 6 decimalslet initial_balance = 10_000_000; // 10 tokens// Calculate rent-exempt minimumslet mint_rent = mollusk.sysvars.rent.minimum_balance(Mint::LEN);let account_rent = mollusk.sysvars.rent.minimum_balance(TokenAccount::LEN);// Create mint accountlet mut mint_data = vec![0u8; Mint::LEN];Mint::pack(Mint {mint_authority: Some(authority).into(),supply: initial_balance,decimals,is_initialized: true,freeze_authority: None.into(),},&mut mint_data,).unwrap();// Create source token accountlet mut source_data = vec![0u8; TokenAccount::LEN];TokenAccount::pack(TokenAccount {mint,owner: authority,amount: initial_balance,delegate: None.into(),state: AccountState::Initialized,is_native: None.into(),delegated_amount: 0,close_authority: None.into(),},&mut source_data,).unwrap();// Create destination token accountlet mut destination_data = vec![0u8; TokenAccount::LEN];TokenAccount::pack(TokenAccount {mint,owner: Pubkey::new_unique(),amount: 0,delegate: None.into(),state: AccountState::Initialized,is_native: None.into(),delegated_amount: 0,close_authority: None.into(),},&mut destination_data,).unwrap();// Setup accounts for transfer_checkedlet accounts = vec![(source,Account {lamports: account_rent,data: source_data,owner: token::ID,executable: false,rent_epoch: 0,},),(mint,Account {lamports: mint_rent,data: mint_data,owner: token::ID,executable: false,rent_epoch: 0,},),(destination,Account {lamports: account_rent,data: destination_data,owner: token::ID,executable: false,rent_epoch: 0,},),(authority,Account {lamports: 1_000_000,data: vec![],owner: Pubkey::default(),executable: false,rent_epoch: 0,},),];// Create transfer_checked instructionlet instruction = transfer_checked(&token::ID,&source,&mint,&destination,&authority,&[],transfer_amount,decimals,).unwrap();// Expected balances after transferlet expected_source_balance = (initial_balance - transfer_amount).to_le_bytes();let expected_dest_balance = transfer_amount.to_le_bytes();// Define validation checkslet checks = vec![Check::success(),Check::account(&source).data_slice(64, &expected_source_balance) // Token amount is at offset 64.build(),Check::account(&destination).data_slice(64, &expected_dest_balance).build(),];// Process and validate the instructionlet result = mollusk.process_and_validate_instruction(&instruction, &accounts, &checks);println!("{:#?}", result);// Deserialize token account datalet source_account = result.get_account(&source).unwrap();let source_token = TokenAccount::unpack(&source_account.data).unwrap();println!("Source Token Account: {:#?}", source_token);let destination_account = result.get_account(&destination).unwrap();let dest_token = TokenAccount::unpack(&destination_account.data).unwrap();println!("Destination Token Account: {:#?}", dest_token);}
Console
Click to execute the code.
Is this page helpful?