Cross Program Invocation
W tej sekcji program CRUD z poprzedniej sekcji dotyczącej PDA zostaje zaktualizowany poprzez dodanie Cross Program Invocations (CPIs), funkcji umożliwiającej programom Solana wywoływanie siebie nawzajem.
Ten samouczek pokazuje również, jak programy mogą "podpisywać" Program Derived Addresses (PDAs) podczas wykonywania Cross Program Invocations.
Instrukcje update
i delete
wymagają modyfikacji, aby obsługiwać transfery
SOL między kontami poprzez wywołanie System Program.
Celem tej sekcji jest przeprowadzenie przez proces implementacji CPIs w programie Solana za pomocą frameworka Anchor, opierając się na koncepcjach PDA omówionych w poprzedniej sekcji. Więcej szczegółów znajdziesz na stronie Cross Program Invocation.
Dla odniesienia, ten link zawiera kod końcowy po ukończeniu zarówno sekcji PDA, jak i CPI.
Kod początkowy dla tej sekcji zawiera tylko ukończoną sekcję PDA.
Zaktualizuj instrukcję Update
Najpierw program potrzebuje prostego mechanizmu "pay-to-update" poprzez zmianę
Update
struktury i funkcji update
.
Rozpocznij od aktualizacji pliku lib.rs
, aby uwzględnić elementy z modułu
system_program
.
use anchor_lang::system_program::{transfer, Transfer};
Następnie zaktualizuj strukturę Update
, aby uwzględnić nowe konto o nazwie
vault_account
. To konto, kontrolowane przez program, otrzymuje SOL od
użytkownika, gdy aktualizuje on swoje konto wiadomości.
#[account(mut,seeds = [b"vault", user.key().as_ref()],bump,)]pub vault_account: SystemAccount<'info>,
Następnie dodaj logikę CPI w instrukcji update
, aby przelać 0,001 SOL z konta
użytkownika na konto skarbca.
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)?;
Przebuduj program.
$build
Zaktualizuj instrukcję usuwania
Dodaj teraz mechanizm "zwrotu przy usunięciu" poprzez zmianę struktury
Delete
i funkcji delete
.
Najpierw zaktualizuj strukturę Delete
, aby uwzględniała vault_account
.
To pozwala na transfer dowolnych SOL w skarbcu z powrotem do użytkownika, gdy
zamykają swoje konto wiadomości.
#[account(mut,seeds = [b"vault", user.key().as_ref()],bump,)]pub vault_account: SystemAccount<'info>,
Dodaj również system_program
, ponieważ CPI dla transferu wymaga wywołania
System Programu.
pub system_program: Program<'info, System>,
Następnie dodaj logikę CPI w instrukcji delete
, aby przelać SOL z konta
skarbca z powrotem na konto użytkownika.
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())?;
Zauważ, że _ctx: Context<Delete>
zmienia się na
ctx: Context<Delete>
, aby użyć kontekstu w ciele funkcji.
Przebuduj program.
$build
Ponowne wdrożenie programu
Po wprowadzeniu tych zmian ponownie wdroż zaktualizowany program. To zapewnia, że zmodyfikowany program będzie dostępny do testowania. Na Solanie aktualizacja programu wymaga jedynie wdrożenia programu pod tym samym ID programu.
Upewnij się, że Twój portfel Playground ma devnet SOL. Zdobądź devnet SOL z Solana Faucet.
$deploy
Zaktualizuj plik testowy
Następnie zaktualizuj plik anchor.test.ts
, aby uwzględnić nowe konto skarbca w
instrukcjach. Wymaga to wyprowadzenia PDA skarbca i uwzględnienia go w
wywołaniach instrukcji aktualizacji i usunięcia.
Wyprowadź Vault PDA
Najpierw dodaj wyprowadzenie Vault PDA:
const [vaultPda, vaultBump] = PublicKey.findProgramAddressSync([Buffer.from("vault"), wallet.publicKey.toBuffer()],program.programId);
Zmień test aktualizacji
Następnie zaktualizuj instrukcję aktualizacji, aby uwzględniała
vaultAccount
const transactionSignature = await program.methods.update(message).accounts({messageAccount: messagePda,vaultAccount: vaultPda}).rpc({ commitment: "confirmed" });
Zmień test usuwania
Następnie zaktualizuj instrukcję usuwania, aby uwzględniała
vaultAccount
const transactionSignature = await program.methods.delete().accounts({messageAccount: messagePda,vaultAccount: vaultPda}).rpc({ commitment: "confirmed" });
Uruchom test ponownie
Po wprowadzeniu tych zmian uruchom testy, aby upewnić się, że wszystko działa zgodnie z oczekiwaniami:
$test
Możesz następnie sprawdzić linki SolanaFM, aby zobaczyć szczegóły transakcji, gdzie znajdziesz CPI dla instrukcji transferu w ramach instrukcji aktualizacji i usuwania.
Aktualizacja CPI
Usunięcie CPI
Jeśli napotkasz jakiekolwiek błędy, możesz odwołać się do ostatecznego kodu.
Kolejne kroki
Gratulacje z ukończenia przewodnika Solana Quickstart. Zdobyłeś praktyczne doświadczenie z kluczowymi pojęciami Solana, w tym:
- Pobieranie i odczytywanie danych z kont
- Tworzenie i wysyłanie transakcji
- Wdrażanie i aktualizowanie programów Solana
- Praca z adresami pochodnymi programu (PDAs)
- Wykonywanie wywołań międzyprogramowych (CPIs)
Aby pogłębić swoją wiedzę na temat tych pojęć, zapoznaj się z dokumentacją Podstawowe pojęcia, która zawiera szczegółowe wyjaśnienia tematów omówionych w tym przewodniku.
Odkryj więcej przykładów
Jeśli wolisz uczyć się na przykładach, sprawdź Repozytorium przykładów programów zawierające różnorodne przykłady programów.
Solana Playground oferuje wygodną funkcję umożliwiającą importowanie lub przeglądanie projektów za pomocą ich linków GitHub. Na przykład otwórz ten link do Solana Playground, aby zobaczyć projekt Anchor z tego repozytorium GitHub.
Kliknij przycisk Import
i wprowadź nazwę projektu, aby dodać go do swojej
listy projektów w Solana Playground. Po zaimportowaniu projektu wszystkie zmiany
są automatycznie zapisywane i przechowywane.
Is this page helpful?