Cross Program Invocation
In diesem Abschnitt wird das CRUD-Programm aus dem vorherigen PDA-Abschnitt aktualisiert, indem Cross Program Invocations (CPIs) hinzugefügt werden, eine Funktion, die es Solana-Programmen ermöglicht, sich gegenseitig aufzurufen.
Dieses Tutorial zeigt auch, wie Programme für Program Derived Addresses (PDAs) "signieren" können, wenn sie Cross Program Invocations durchführen.
Die update
und delete
Anweisungen müssen modifiziert werden, um
SOL-Überweisungen zwischen Konten durch Aufruf des System-Programms zu
verarbeiten.
Der Zweck dieses Abschnitts umfasst die Erläuterung des Prozesses zur Implementierung von CPIs in einem Solana-Programm mit dem Anchor-Framework, aufbauend auf den PDA- Konzepten, die im vorherigen Abschnitt untersucht wurden. Weitere Details finden Sie auf der Cross Program Invocation Seite.
Als Referenz enthält dieser Link den endgültigen Code nach Abschluss beider Abschnitte, PDA und CPI.
Der Starter-Code für diesen Abschnitt enthält nur den abgeschlossenen PDA-Abschnitt.
Aktualisieren der Update-Anweisung
Zunächst benötigt das Programm einen einfachen "Pay-to-Update"-Mechanismus,
indem die Update
Struktur und die update
Funktion geändert werden.
Beginnen Sie mit der Aktualisierung der lib.rs
Datei, um Elemente aus dem
system_program
Modul in den Geltungsbereich zu bringen.
use anchor_lang::system_program::{transfer, Transfer};
Als nächstes aktualisieren Sie die Update
Struktur, um ein neues Konto
namens vault_account
einzuschließen. Dieses Konto, das vom Programm
kontrolliert wird, erhält SOL von einem Benutzer, wenn dieser sein
Nachrichtenkonto aktualisiert.
#[account(mut,seeds = [b"vault", user.key().as_ref()],bump,)]pub vault_account: SystemAccount<'info>,
Als Nächstes füge die CPI-Logik in der update
Anweisung hinzu, um 0,001 SOL
vom Konto des Benutzers auf das Tresor-Konto zu übertragen.
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)?;
Erstelle das Programm neu.
$build
Aktualisiere die Lösch-Anweisung
Füge nun einen "Rückerstattung bei Löschung"-Mechanismus hinzu, indem du die
Delete
Struktur und die delete
Funktion änderst.
Aktualisiere zuerst die Delete
Struktur, um das vault_account
einzubeziehen. Dies ermöglicht die Überweisung von SOL im Vault zurück an den
Benutzer, wenn sie ihr Nachrichten-Konto schließen.
#[account(mut,seeds = [b"vault", user.key().as_ref()],bump,)]pub vault_account: SystemAccount<'info>,
Füge auch das system_program
hinzu, da die CPI für die Überweisung den Aufruf
des System Programs erfordert.
pub system_program: Program<'info, System>,
Als Nächstes fügen Sie die CPI-Logik in der delete
Anweisung hinzu, um SOL vom
Vault-Konto zurück auf das Konto des Benutzers zu überweisen.
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())?;
Beachten Sie, dass sich _ctx: Context<Delete>
zu
ctx: Context<Delete>
ändert, um den Kontext im Funktionskörper zu
verwenden.
Baue das Programm neu.
$build
Programm erneut deployen
Nach diesen Änderungen musst du das aktualisierte Programm erneut deployen. Dies stellt sicher, dass das modifizierte Programm für Tests verfügbar wird. Auf Solana erfordert die Aktualisierung eines Programms einfach das Deployment des Programms unter derselben Programm-ID.
Stelle sicher, dass dein Playground-Wallet über Devnet-SOL verfügt. Hol dir Devnet-SOL vom Solana Faucet.
$deploy
Test-Datei aktualisieren
Als Nächstes aktualisiere die anchor.test.ts
Datei, um das neue Vault-Konto in
die Anweisungen einzubeziehen. Dies erfordert die Ableitung der Vault-PDA und
deren Einbeziehung in die Update- und Delete-Anweisungsaufrufe.
Vault-PDA ableiten
Zuerst fügen wir die Vault-PDA-Ableitung hinzu:
const [vaultPda, vaultBump] = PublicKey.findProgramAddressSync([Buffer.from("vault"), wallet.publicKey.toBuffer()],program.programId);
Update-Test ändern
Dann aktualisieren wir die Update-Anweisung, um die
vaultAccount
einzubeziehen
const transactionSignature = await program.methods.update(message).accounts({messageAccount: messagePda,vaultAccount: vaultPda}).rpc({ commitment: "confirmed" });
Delete-Test ändern
Dann aktualisieren wir die Delete-Anweisung, um die
vaultAccount
einzubeziehen
const transactionSignature = await program.methods.delete().accounts({messageAccount: messagePda,vaultAccount: vaultPda}).rpc({ commitment: "confirmed" });
Test erneut ausführen
Nach diesen Änderungen führen wir die Tests aus, um sicherzustellen, dass alles wie erwartet funktioniert:
$test
Du kannst dann die SolanaFM-Links überprüfen, um die Transaktionsdetails anzusehen, wo du die CPIs für die Transfer-Anweisungen innerhalb der Update- und Delete-Anweisungen findest.
Update CPI
Delete CPI
Falls du auf Fehler stößt, kannst du auf den finalen Code zurückgreifen.
Nächste Schritte
Herzlichen Glückwunsch zum Abschluss des Solana Quickstart-Leitfadens. Du hast praktische Erfahrungen mit wichtigen Solana-Konzepten gesammelt, darunter:
- Abrufen und Lesen von Daten aus Konten
- Erstellen und Senden von Transaktionen
- Bereitstellen und Aktualisieren von Solana-Programmen
- Arbeiten mit Program Derived Addresses (PDAs)
- Durchführen von Cross-Program Invocations (CPIs)
Um dein Verständnis dieser Konzepte zu vertiefen, schau dir die Kernkonzepte-Dokumentation an, die detaillierte Erklärungen zu den in diesem Leitfaden behandelten Themen bietet.
Weitere Beispiele erkunden
Wenn du lieber anhand von Beispielen lernst, sieh dir das Program Examples Repository an, das eine Vielzahl von Beispielprogrammen enthält.
Solana Playground bietet eine praktische Funktion, mit der du Projekte über ihre GitHub-Links importieren oder anzeigen kannst. Öffne zum Beispiel diesen Solana Playground-Link, um das Anchor-Projekt aus diesem Github-Repo anzusehen.
Klicke auf die Schaltfläche Import
und gib einen Projektnamen ein, um es zu
deiner Liste von Projekten in Solana Playground hinzuzufügen. Sobald ein Projekt
importiert wurde, werden alle Änderungen automatisch gespeichert und
beibehalten.
Is this page helpful?