Cross Program Invocation

Σε αυτήν την ενότητα, το πρόγραμμα CRUD από την προηγούμενη ενότητα PDA ενημερώνεται με την προσθήκη Cross Program Invocations (CPIs), ένα χαρακτηριστικό που επιτρέπει στα προγράμματα Solana να καλούν το ένα το άλλο.

Αυτό το tutorial δείχνει επίσης πώς τα προγράμματα μπορούν να "υπογράφουν" για Program Derived Addresses (PDAs) όταν κάνουν Cross Program Invocations.

Οι εντολές update και delete χρειάζονται τροποποίηση για να χειριστούν μεταφορές SOL μεταξύ λογαριασμών καλώντας το System Program.

Ο σκοπός αυτής της ενότητας περιλαμβάνει την καθοδήγηση στη διαδικασία υλοποίησης CPIs σε ένα πρόγραμμα Solana χρησιμοποιώντας το πλαίσιο Anchor, βασιζόμενοι στις έννοιες PDA που εξερευνήθηκαν στην προηγούμενη ενότητα. Για περισσότερες λεπτομέρειες, ανατρέξτε στη σελίδα Cross Program Invocation.

Για αναφορά, αυτός ο σύνδεσμος περιλαμβάνει τον τελικό κώδικα μετά την ολοκλήρωση τόσο των ενοτήτων PDA όσο και CPI.

Ο αρχικός κώδικας για αυτήν την ενότητα περιλαμβάνει μόνο την ολοκληρωμένη ενότητα PDA.

Ενημέρωση της εντολής Update

Πρώτα, το πρόγραμμα χρειάζεται έναν απλό μηχανισμό "πληρωμής για ενημέρωση" αλλάζοντας τη δομή Update και τη συνάρτηση update.

Ξεκινήστε ενημερώνοντας το αρχείο lib.rs για να εισάγετε στο πεδίο εφαρμογής στοιχεία από τη μονάδα system_program.

lib.rs
use anchor_lang::system_program::{transfer, Transfer};

Στη συνέχεια, ενημερώστε τη δομή Update για να συμπεριλάβει έναν νέο λογαριασμό που ονομάζεται vault_account. Αυτός ο λογαριασμός, που ελέγχεται από το πρόγραμμα, λαμβάνει SOL από έναν χρήστη όταν ενημερώνει τον λογαριασμό μηνυμάτων του.

lib.rs
#[account(
mut,
seeds = [b"vault", user.key().as_ref()],
bump,
)]
pub vault_account: SystemAccount<'info>,

Στη συνέχεια, προσθέστε τη λογική CPI στην εντολή update για να μεταφέρετε 0.001 SOL από τον λογαριασμό του χρήστη στον λογαριασμό του θησαυροφυλακίου.

lib.rs
let transfer_accounts = Transfer {
from: ctx.accounts.user.to_account_info(),
to: ctx.accounts.vault_account.to_account_info(),
};
let cpi_context = CpiContext::new(
ctx.accounts.system_program.to_account_info(),
transfer_accounts,
);
transfer(cpi_context, 1_000_000)?;

Επαναδημιουργήστε το πρόγραμμα.

Terminal
$
build

Ενημέρωση της εντολής διαγραφής

Τώρα προσθέστε έναν μηχανισμό "επιστροφής χρημάτων κατά τη διαγραφή" αλλάζοντας τη δομή Delete και τη συνάρτηση delete.

Πρώτα, ενημερώστε τη δομή Delete για να συμπεριλάβει το vault_account. Αυτό επιτρέπει τη μεταφορά οποιουδήποτε SOL στο θησαυροφυλάκιο πίσω στον χρήστη όταν κλείνουν τον λογαριασμό μηνυμάτων τους.

lib.rs
#[account(
mut,
seeds = [b"vault", user.key().as_ref()],
bump,
)]
pub vault_account: SystemAccount<'info>,

Επίσης προσθέστε το system_program καθώς το CPI για τη μεταφορά απαιτεί την κλήση του System Program.

lib.rs
pub system_program: Program<'info, System>,

Στη συνέχεια, προσθέστε τη λογική CPI στην εντολή delete για να μεταφέρετε SOL από τον λογαριασμό θησαυροφυλακίου πίσω στον λογαριασμό του χρήστη.

lib.rs
let user_key = ctx.accounts.user.key();
let signer_seeds: &[&[&[u8]]] =
&[&[b"vault", user_key.as_ref(), &[ctx.bumps.vault_account]]];
let transfer_accounts = Transfer {
from: ctx.accounts.vault_account.to_account_info(),
to: ctx.accounts.user.to_account_info(),
};
let cpi_context = CpiContext::new(
ctx.accounts.system_program.to_account_info(),
transfer_accounts,
).with_signer(signer_seeds);
transfer(cpi_context, ctx.accounts.vault_account.lamports())?;

Σημειώστε ότι το _ctx: Context<Delete> αλλάζει σε ctx: Context<Delete> για να χρησιμοποιήσει το context στο σώμα της συνάρτησης.

Επαναδημιουργήστε το πρόγραμμα.

Terminal
$
build

Επανατοποθέτηση προγράμματος

Μετά την πραγματοποίηση αυτών των αλλαγών, επανατοποθετήστε το ενημερωμένο πρόγραμμα. Αυτό διασφαλίζει ότι το τροποποιημένο πρόγραμμα θα είναι διαθέσιμο για δοκιμή. Στο Solana, η ενημέρωση ενός προγράμματος απλά απαιτεί την τοποθέτηση του προγράμματος στο ίδιο αναγνωριστικό προγράμματος.

Βεβαιωθείτε ότι το πορτοφόλι του Playground σας έχει devnet SOL. Αποκτήστε devnet SOL από το Solana Faucet.

Terminal
$
deploy

Ενημέρωση αρχείου δοκιμής

Στη συνέχεια, ενημερώστε το αρχείο anchor.test.ts για να συμπεριλάβετε το νέο λογαριασμό θησαυροφυλακίου στις εντολές. Αυτό απαιτεί την παραγωγή του PDA θησαυροφυλακίου και τη συμπερίληψή του στις κλήσεις εντολών ενημέρωσης και διαγραφής.

Εξαγωγή PDA θησαυροφυλακίου

Πρώτα, προσθέστε την εξαγωγή του PDA θησαυροφυλακίου:

anchor.test.ts
const [vaultPda, vaultBump] = PublicKey.findProgramAddressSync(
[Buffer.from("vault"), wallet.publicKey.toBuffer()],
program.programId
);

Αλλαγή δοκιμής ενημέρωσης

Στη συνέχεια, ενημερώστε την εντολή ενημέρωσης ώστε να συμπεριλάβει το vaultAccount

anchor.test.ts
const transactionSignature = await program.methods
.update(message)
.accounts({
messageAccount: messagePda,
vaultAccount: vaultPda
})
.rpc({ commitment: "confirmed" });

Αλλαγή δοκιμής διαγραφής

Στη συνέχεια, ενημερώστε την εντολή διαγραφής ώστε να συμπεριλάβει το vaultAccount

anchor.test.ts
const transactionSignature = await program.methods
.delete()
.accounts({
messageAccount: messagePda,
vaultAccount: vaultPda
})
.rpc({ commitment: "confirmed" });

Επανεκτέλεση δοκιμής

Μετά από αυτές τις αλλαγές, εκτελέστε τις δοκιμές για να βεβαιωθείτε ότι όλα λειτουργούν όπως αναμένεται:

Terminal
$
test

Στη συνέχεια, μπορείτε να εξετάσετε τους συνδέσμους SolanaFM για να δείτε τις λεπτομέρειες της συναλλαγής, όπου θα βρείτε τα Cross Program Invocation για τις εντολές μεταφοράς μέσα στις εντολές ενημέρωσης και διαγραφής.

Ενημέρωση CPIΕνημέρωση CPI

Διαγραφή CPIΔιαγραφή CPI

Αν αντιμετωπίσετε οποιαδήποτε σφάλματα, μπορείτε να ανατρέξετε στον τελικό κώδικα.

Επόμενα βήματα

Συγχαρητήρια για την ολοκλήρωση του οδηγού Solana Quickstart. Αποκτήσατε πρακτική εμπειρία με βασικές έννοιες του Solana, συμπεριλαμβανομένων:

  • Λήψη και ανάγνωση δεδομένων από λογαριασμούς
  • Δημιουργία και αποστολή συναλλαγών
  • Ανάπτυξη και ενημέρωση προγραμμάτων Solana
  • Εργασία με Program Derived Addresses (PDAs)
  • Πραγματοποίηση Cross-Program Invocations (CPIs)

Για να εμβαθύνετε την κατανόησή σας σε αυτές τις έννοιες, ανατρέξτε στην τεκμηρίωση Βασικές Έννοιες που παρέχει λεπτομερείς εξηγήσεις των θεμάτων που καλύπτονται σε αυτόν τον οδηγό.

Εξερευνήστε περισσότερα παραδείγματα

Αν προτιμάτε να μαθαίνετε μέσω παραδειγμάτων, ρίξτε μια ματιά στο Αποθετήριο Παραδειγμάτων Προγραμμάτων για μια ποικιλία παραδειγμάτων προγραμμάτων.

Το Solana Playground προσφέρει ένα βολικό χαρακτηριστικό που σας επιτρέπει να εισάγετε ή να προβάλλετε έργα χρησιμοποιώντας τους συνδέσμους GitHub τους. Για παράδειγμα, ανοίξτε αυτόν τον σύνδεσμο Solana Playground για να δείτε το έργο Anchor από αυτό το αποθετήριο Github.

Κάντε κλικ στο κουμπί Import και εισαγάγετε ένα όνομα έργου για να το προσθέσετε στη λίστα των έργων σας στο Solana Playground. Μόλις εισαχθεί ένα έργο, όλες οι αλλαγές αποθηκεύονται και διατηρούνται αυτόματα.

Is this page helpful?