Εγκατάσταση
Προσθέστε τις απαραίτητες εξαρτήσεις:
cargo add --dev anchor-litesvm litesvm litesvm-utils
Τι είναι το anchor-litesvm;
Το crate anchor-litesvm παρέχει μια απλοποιημένη σύνταξη παρόμοια με το
anchor-client χωρίς το επιπλέον κόστος RPC. Επιτυγχάνει μείωση κώδικα κατά
78% σε σύγκριση με το ακατέργαστο LiteSVM, διατηρώντας παράλληλα την ασφάλεια
τύπων με τους τύπους Anchor.
AnchorContext
- Περιβάλλον δοκιμών συμβατό με παραγωγή
- Ίδια μοτίβα API με το anchor-client
- Διαχειρίζεται την παρουσία LiteSVM, τον πληρωτή και το πρόγραμμα
- Εκτέλεση εντολών χωρίς επιπλέον κόστος RPC
API Προγράμματος - Ευέλικτη κατασκευή εντολών - Ασφαλής ως προς τον τύπο διαχείριση λογαριασμών και ορισμάτων - Οικεία σύνταξη anchor-client
Αποσειριοποίηση Λογαριασμών - Ανάκτηση και αποσειριοποίηση λογαριασμών Anchor - Αυτόματη διαχείριση διακριτικών - Υποστήριξη για PDAs και προσαρμοσμένες διατάξεις
Ανάλυση Συμβάντων
- Ανάλυση συμβάντων από αρχεία καταγραφής συναλλαγών
- Επαλήθευση εκπομπής συμβάντων
- Αποσειριοποίηση συμβάντων με ασφάλεια τύπων
Γρήγορο Παράδειγμα
Με το Anchor 1.0, χρησιμοποιήστε το declare_program! για να δημιουργήσετε
τύπους πελάτη από το IDL του προγράμματός σας. Αυτή η μακροεντολή δημιουργεί τις
ενότητες client::accounts::* και client::args::* για ασφαλή ως προς τον τύπο
κατασκευή εντολών:
use anchor_litesvm::AnchorLiteSVM;use anchor_litesvm::{AssertionHelpers, TestHelpers};use anchor_lang::system_program;use solana_sdk::signature::{read_keypair_file, Signer};// Generate client types from your program's IDLanchor_lang::declare_program!(my_program);#[test]fn test_anchor_program() {// One-line setup — reads program keypair for the correct IDlet program_keypair = read_keypair_file("target/deploy/my_program-keypair.json").unwrap();let mut ctx = AnchorLiteSVM::build_with_program(program_keypair.pubkey(),include_bytes!("../target/deploy/my_program.so"),);// Create a funded account via TestHelpers on ctx.svmlet user = ctx.svm.create_funded_account(10_000_000_000).unwrap();// Derive PDAlet seed: u64 = 42;let pda = ctx.svm.get_pda(&[b"user", user.pubkey().as_ref(), &seed.to_le_bytes()],&program_keypair.pubkey(),);// Build instruction using generated client typeslet ix = ctx.program().accounts(my_program::client::accounts::Initialize {user: user.pubkey(),user_account: pda,system_program: system_program::ID,}).args(my_program::client::args::Initialize {seed,name: "test".to_string(),}).instruction().unwrap();// Execute and assert in one chainctx.execute_instruction(ix, &[&user]).unwrap().assert_success();// Fetch and deserialize the accountlet account: my_program::MyAccount = ctx.get_account(&pda).unwrap();assert_eq!(account.name, "test");}
Το declare_program!(my_program) διαβάζει το IDL από το
target/idl/my_program.json κατά τη στιγμή της μεταγλώττισης και δημιουργεί
τις ενότητες client::accounts::* και client::args::*. Αυτό απαιτεί την
προηγούμενη κατασκευή του προγράμματός σας.
Σύγκριση: Raw LiteSVM vs anchor-litesvm
Πριν (Raw LiteSVM)
use litesvm::LiteSVM;use solana_keypair::Keypair;use solana_signer::Signer;use solana_program::instruction::{AccountMeta, Instruction};use solana_message::Message;use solana_transaction::Transaction;let mut svm = LiteSVM::new();svm.add_program(program_id, program_bytes).unwrap();let payer = Keypair::new();svm.airdrop(&payer.pubkey(), 10_000_000_000).unwrap();// Manually compute 8-byte discriminatorlet discriminator = {let mut hasher = sha2::Sha256::new();hasher.update(b"global:initialize");let result = hasher.finalize();result[..8].to_vec()};// Manually serialize args and build instructionlet mut data = discriminator;data.extend_from_slice(&borsh::to_vec(&args).unwrap());let accounts = vec![AccountMeta::new(user.pubkey(), true),AccountMeta::new(user_pda, false),AccountMeta::new_readonly(system_program::id(), false),];let ix = Instruction::new_with_bytes(program_id, &data, accounts);let tx = Transaction::new_signed_with_payer(&[ix],Some(&payer.pubkey()),&[&payer],svm.latest_blockhash(),);svm.send_transaction(tx).unwrap();// Manually deserialize with discriminator skiplet account_data = svm.get_account(&pda).unwrap().data;let account: UserAccount = UserAccount::try_deserialize(&mut &account_data[8..]).unwrap();
Μετά (anchor-litesvm)
use anchor_litesvm::AnchorLiteSVM;anchor_lang::declare_program!(my_program);let mut ctx = AnchorLiteSVM::build_with_program(program_id, program_bytes);let user = ctx.svm.create_funded_account(10_000_000_000).unwrap();let ix = ctx.program().accounts(my_program::client::accounts::Initialize {user: user.pubkey(),user_account: user_pda,system_program: anchor_lang::system_program::ID,}).args(my_program::client::args::Initialize { name: "test".to_string() }).instruction().unwrap();ctx.execute_instruction(ix, &[&user]).unwrap().assert_success();let account: my_program::UserAccount = ctx.get_account(&user_pda).unwrap();
Βασικά Στοιχεία
AnchorLiteSVM Builder
| Μέθοδος | Περιγραφή |
|---|---|
new() | Δημιουργεί μια νέα παρουσία builder |
with_payer(keypair) | Ορίζει ένα προσαρμοσμένο keypair πληρωτή |
deploy_program(id, bytes) | Προσθέτει ένα πρόγραμμα για ανάπτυξη |
build() | Δημιουργεί το AnchorContext |
build_with_program(id, bytes) | Βολικό για ένα μεμονωμένο πρόγραμμα |
build_with_programs(programs) | Ανάπτυξη πολλαπλών προγραμμάτων |
AnchorContext
| Μέθοδος | Περιγραφή |
|---|---|
svm | Άμεση πρόσβαση στην υποκείμενη παρουσία LiteSVM (δημόσιο πεδίο) |
program_id | Το αναγνωριστικό προγράμματος (δημόσιο πεδίο) |
program() | Επιστρέφει Program για κατασκευή εντολών |
payer() | Λήψη του keypair πληρωτή |
execute_instruction(ix, signers) | Εκτέλεση μιας μεμονωμένης εντολής |
execute_instructions(ixs, signers) | Εκτέλεση πολλαπλών εντολών σε μία συναλλαγή |
send_and_confirm_transaction(&tx) | Αποστολή ακατέργαστης συναλλαγής |
get_account<T>(pubkey) | Ανάκτηση και αποδιασειριοποίηση ενός λογαριασμού Anchor |
get_account_unchecked<T>(pubkey) | Ανάκτηση χωρίς έλεγχο discriminator |
create_funded_account(lamports) | Δημιουργία και χρηματοδότηση νέου keypair |
airdrop(pubkey, lamports) | Airdrop SOL σε μια διεύθυνση |
latest_blockhash() | Λήψη του τρέχοντος blockhash |
account_exists(pubkey) | Έλεγχος ύπαρξης λογαριασμού |
deploy_program(id, bytes) | Ανάπτυξη επιπλέον προγράμματος (μέσω ProgramTestExt) |
Program
| Μέθοδος | Περιγραφή |
|---|---|
accounts(accounts) | Ορισμός λογαριασμών εντολής (οποιοσδήποτε τύπος ToAccountMetas) |
args(args) | Ορισμός ορισμάτων εντολής (οποιοσδήποτε τύπος InstructionData) |
instruction() | Δημιουργία της τελικής Instruction |
id() | Λήψη του αναγνωριστικού προγράμματος |
ctx.svm — TestHelpers & AssertionHelpers
Το ctx.svm είναι ένα δημόσιο πεδίο LiteSVM με τα traits TestHelpers και
AssertionHelpers διαθέσιμα μέσω litesvm-utils:
| Μέθοδος | Περιγραφή |
|---|---|
ctx.svm.create_funded_account(lamports) | Δημιουργία και χρηματοδότηση keypair |
ctx.svm.create_token_mint(authority, decimals) | Δημιουργία SPL token mint |
ctx.svm.create_associated_token_account(mint, owner) | Δημιουργία ATA |
ctx.svm.mint_to(mint, token_account, authority, amount) | Έκδοση tokens |
ctx.svm.get_pda(seeds, program_id) | Εξαγωγή διεύθυνσης PDA |
ctx.svm.get_pda_with_bump(seeds, program_id) | Εξαγωγή PDA με bump seed |
ctx.svm.assert_token_balance(token_account, expected) | Επαλήθευση υπολοίπου token |
ctx.svm.assert_account_closed(pubkey) | Επαλήθευση ότι ο λογαριασμός έκλεισε |
ctx.svm.assert_sol_balance(pubkey, expected) | Επαλήθευση υπολοίπου SOL |
Αντιμετώπιση Προβλημάτων
Συνηθισμένα Σφάλματα
| Σφάλμα | Αιτία | Λύση |
|---|---|---|
AccountNotFound | Ο λογαριασμός δεν υπάρχει | Βεβαιωθείτε ότι ο λογαριασμός έχει δημιουργηθεί πριν από την ανάκτησή του |
DiscriminatorMismatch | Λάθος τύπος λογαριασμού | Επαληθεύστε ότι χρησιμοποιείτε τη σωστή δομή λογαριασμού |
DeserializationError | Μη έγκυρα δεδομένα λογαριασμού | Ελέγξτε ότι ο λογαριασμός αρχικοποιήθηκε σωστά |
| No programs added | Κλήθηκε το build() χωρίς deploy_program() | Προσθέστε τουλάχιστον ένα πρόγραμμα πριν από τη δημιουργία |
| Missing client types | Δεν κλήθηκε το declare_program! | Εκτελέστε πρώτα το anchor build για να δημιουργήσετε IDL, στη συνέχεια καλέστε το declare_program! |
Is this page helpful?