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 Programs zu handhaben.

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 einzubeziehen. Dieses vom Programm kontrollierte Konto empfängt SOL von einem Benutzer, wenn dieser sein Nachrichten-Konto aktualisiert.

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

Als Nächstes fügen Sie die CPI-Logik in der update Anweisung hinzu, um 0,001 SOL vom Konto des Benutzers auf das Vault-Konto zu überweisen.

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

Baue das Programm neu.

Terminal
$
build

Aktualisiere die Lösch-Anweisung

Fügen Sie nun einen "Rückerstattung bei Löschung"-Mechanismus hinzu, indem Sie die Delete Struktur und die delete Funktion ändern.

Aktualisieren Sie zunächst die Delete Struktur, um den vault_account einzuschließen. Dies ermöglicht die Übertragung von SOL im Tresor zurück an den Benutzer, wenn dieser sein Nachrichtenkonto schließt.

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

Füge außerdem das system_program hinzu, da der CPI für die Überweisung das Aufrufen des System Programs erfordert.

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

Als Nächstes füge die CPI-Logik in der delete Anweisung hinzu, um SOL vom Tresor-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())?;

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

Erstelle 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. Bei 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

Testdatei aktualisieren

Als Nächstes aktualisiere die anchor.test.ts Datei, um das neue Tresor-Konto in die Anweisungen einzubeziehen. Dies erfordert die Ableitung der Tresor-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

Aktualisieren Sie dann die Update-Anweisung, um die vaultAccount einzuschließen

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

Delete-Test ändern

Aktualisieren Sie dann die Delete-Anweisung, um die vaultAccount einzuschließen

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 Address (PDAs)
  • Durchführen von Cross Program Invocation (CPIs)

Um dein Verständnis dieser Konzepte zu vertiefen, schau dir die Core Concepts-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.

Klicken Sie auf die Schaltfläche Import und geben Sie einen Projektnamen ein, um es zu Ihrer Liste der Projekte in Solana Playground hinzuzufügen. Sobald ein Projekt importiert wurde, werden alle Änderungen automatisch gespeichert und persistent gehalten.

Is this page helpful?

Inhaltsverzeichnis

Seite bearbeiten

Verwaltet von

© 2026 Solana Foundation.
Alle Rechte vorbehalten.
Verbinden Sie sich