У цьому розділі програма CRUD з попереднього розділу PDA оновлюється шляхом додавання Cross Program Invocations (CPIs), функції, яка дозволяє програмам Solana викликати одна одну.
Цей посібник також показує, як програми можуть "підписуватися" за Program Derived Addresses (PDAs) при здійсненні Cross Program Invocations.
Інструкції update та delete потребують модифікації для обробки переказів SOL
між акаунтами шляхом виклику System Program.
Мета цього розділу включає покроковий процес реалізації CPIs у програмі Solana за допомогою фреймворку Anchor, спираючись на концепції PDA, розглянуті в попередньому розділі. Для отримання додаткової інформації зверніться до сторінки Cross Program Invocation.
Для довідки, це посилання містить фінальний код після завершення обох розділів PDA та CPI.
Початковий код для цього розділу включає лише завершений розділ PDA.
Оновлення інструкції Update
Спочатку програмі потрібен простий механізм "плати-за-оновлення" шляхом зміни
структури Update та функції update.
Почніть з оновлення файлу lib.rs, щоб імпортувати елементи з модуля
system_program.
use anchor_lang::system_program::{transfer, Transfer};
Далі оновіть структуру Update, щоб включити новий акаунт під назвою
vault_account. Цей акаунт, контрольований програмою, отримує SOL від
користувача, коли той оновлює свій акаунт повідомлення.
#[account(mut,seeds = [b"vault", user.key().as_ref()],bump,)]pub vault_account: SystemAccount<'info>,
Далі додайте логіку CPI в інструкцію update для переказу 0.001 SOL з акаунта
користувача на акаунт сховища.
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)?;
Перебудуйте програму.
$build
Оновлення інструкції видалення
Тепер додайте механізм "повернення коштів при видаленні", змінивши структуру
Delete та функцію delete.
Спочатку оновіть структуру Delete, щоб включити vault_account. Це
дозволить перевести будь-які SOL зі сховища назад користувачеві, коли він
закриває свій акаунт повідомлення.
#[account(mut,seeds = [b"vault", user.key().as_ref()],bump,)]pub vault_account: SystemAccount<'info>,
Також додайте system_program, оскільки CPI для переказу вимагає виклику System
Program.
pub system_program: Program<'info, System>,
Далі додайте логіку CPI в інструкцію delete для переказу SOL з акаунта сховища
назад на акаунт користувача.
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())?;
Зверніть увагу, що _ctx: Context<Delete> змінюється на
ctx: Context<Delete>, щоб використовувати контекст у тілі функції.
Перебудуйте програму.
$build
Повторне розгортання програми
Після внесення цих змін повторно розгорніть оновлену програму. Це забезпечить доступність модифікованої програми для тестування. У Solana оновлення програми просто вимагає розгортання програми з тим самим ідентифікатором програми.
Переконайтеся, що ваш гаманець Playground має devnet SOL. Отримайте devnet SOL з Solana Faucet.
$deploy
Оновлення тестового файлу
Далі оновіть файл anchor.test.ts, щоб включити новий акаунт сховища в
інструкції. Це вимагає виведення vault PDA та включення його у виклики
інструкцій update та delete.
Отримання PDA сховища
Спочатку додайте отримання PDA сховища:
const [vaultPda, vaultBump] = PublicKey.findProgramAddressSync([Buffer.from("vault"), wallet.publicKey.toBuffer()],program.programId);
Зміна тесту оновлення
Потім оновіть інструкцію оновлення, щоб включити vaultAccount
const transactionSignature = await program.methods.update(message).accounts({messageAccount: messagePda,vaultAccount: vaultPda}).rpc({ commitment: "confirmed" });
Зміна тесту видалення
Потім оновіть інструкцію видалення, щоб включити vaultAccount
const transactionSignature = await program.methods.delete().accounts({messageAccount: messagePda,vaultAccount: vaultPda}).rpc({ commitment: "confirmed" });
Повторний запуск тесту
Після внесення цих змін запустіть тести, щоб переконатися, що все працює як очікувалося:
$test
Потім ви можете переглянути посилання SolanaFM для перегляду деталей транзакції, де ви знайдете CPIs для інструкцій переказу в межах інструкцій оновлення та видалення.
CPI оновлення
CPI видалення
Якщо ви зіткнулися з помилками, ви можете звернутися до фінального коду.
Наступні кроки
Вітаємо із завершенням посібника Solana Quickstart. Ви отримали практичний досвід роботи з ключовими концепціями Solana, включаючи:
- Отримання та читання даних з облікових записів
- Створення та надсилання транзакцій
- Розгортання та оновлення програм Solana
- Робота з Program Derived Addresses (PDAs)
- Виконання Cross-Program Invocations (CPIs)
Щоб поглибити розуміння цих концепцій, перегляньте документацію Основні концепції, яка надає детальні пояснення тем, висвітлених у цьому посібнику.
Дослідіть більше прикладів
Якщо ви віддаєте перевагу навчанню на прикладах, перегляньте Репозиторій прикладів програм для різноманітних прикладів програм.
Solana Playground пропонує зручну функцію, яка дозволяє імпортувати або переглядати проєкти за допомогою їхніх посилань на GitHub. Наприклад, відкрийте це посилання Solana Playground, щоб переглянути проєкт Anchor з цього репозиторію Github.
Натисніть кнопку Import і введіть назву проєкту, щоб додати його до вашого
списку проєктів у Solana Playground. Після імпорту проєкту всі зміни автоматично
зберігаються та зберігають постійність.
Is this page helpful?