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 się nawzajem.
Ten samouczek pokazuje również, jak programy mogą "podpisywać" Program Derived Addresses (PDAs) podczas wykonywania Cross Program Invocations.
Instrukcje update oraz delete wymagają modyfikacji, aby obsłużyć transfery
SOL pomię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 jedynie ukończoną sekcję PDA.
Zaktualizuj instrukcję Update
Najpierw program potrzebuje prostego mechanizmu „pay-to-update” poprzez zmianę
struktury Update oraz funkcji update.
Rozpocznij od zaktualizowania pliku lib.rs, aby zaimportować elementy z modułu
system_program.
use anchor_lang::system_program::{transfer, Transfer};
Następnie zaktualizuj strukturę Update, aby dodać nowe konto o nazwie
vault_account. To konto, kontrolowane przez program, otrzymuje SOL od
użytkownika, gdy ten aktualizuje 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
Teraz dodaj mechanizm "zwrotu przy usunięciu" poprzez zmianę struktury
Delete oraz funkcji delete.
Najpierw zaktualizuj strukturę Delete, aby dodać vault_account. Pozwala
to na przelanie wszystkich SOL ze skarbca z powrotem do użytkownika, gdy zamyka
on swoje konto wiadomości.
#[account(mut,seeds = [b"vault", user.key().as_ref()],bump,)]pub vault_account: SystemAccount<'info>,
Dodaj także 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())?;
Zwróć uwagę, ż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 platformie Solana aktualizacja programu wymaga jedynie wdrożenia programu pod tym samym identyfikatorem 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 wyznaczenia PDA skarbca i dodania go do wywołań
instrukcji update oraz delete.
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 ponownie test
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 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 z różnorodnymi przykładami 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 wpisz 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?