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.

lib.rs
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.

lib.rs
#[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.

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)?;

Erstelle das Programm neu.

Terminal
$
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.

lib.rs
#[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.

lib.rs
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.

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())?;

Beachten Sie, dass sich _ctx: Context<Delete> zu ctx: Context<Delete> ändert, um den Kontext im Funktionskörper zu verwenden.

Baue das Programm neu.

Terminal
$
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.

Terminal
$
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:

anchor.test.ts
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

anchor.test.ts
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

anchor.test.ts
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:

Terminal
$
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 CPIUpdate CPI

Delete CPIDelete 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?

Inhaltsverzeichnis

Seite bearbeiten