Cross Program Invocation

Dalam bagian ini, program CRUD dari bagian PDA sebelumnya diperbarui dengan menambahkan Cross Program Invocations (CPIs), fitur yang memungkinkan program Solana untuk memanggil satu sama lain.

Tutorial ini juga menunjukkan bagaimana program dapat "menandatangani" untuk Program Derived Addresses (PDAs) ketika membuat Cross Program Invocations.

Instruksi update dan delete perlu dimodifikasi untuk menangani transfer SOL antara akun dengan memanggil System Program.

Tujuan dari bagian ini termasuk memandu proses implementasi CPIs dalam program Solana menggunakan framework Anchor, melanjutkan konsep PDA yang telah dibahas di bagian sebelumnya. Untuk detail lebih lanjut, lihat Cross Program Invocation.

Sebagai referensi, tautan ini mencakup kode final setelah menyelesaikan kedua bagian PDA dan CPI.

Kode awal untuk bagian ini hanya mencakup bagian PDA yang telah diselesaikan.

Memperbarui Instruksi Update

Pertama, program membutuhkan mekanisme "bayar-untuk-memperbarui" sederhana dengan mengubah struktur Update dan fungsi update.

Mulailah dengan memperbarui file lib.rs untuk memasukkan item dari modul system_program.

lib.rs
use anchor_lang::system_program::{transfer, Transfer};

Selanjutnya, perbarui struktur Update untuk menyertakan akun baru yang disebut vault_account. Akun ini, yang dikendalikan oleh program, menerima SOL dari pengguna ketika mereka memperbarui akun pesan mereka.

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

Selanjutnya, tambahkan logika CPI dalam instruksi update untuk mentransfer 0,001 SOL dari akun pengguna ke akun vault.

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

Bangun ulang program.

Terminal
$
build

Perbarui Instruksi Delete

Sekarang tambahkan mekanisme "pengembalian dana saat penghapusan" dengan mengubah struct Delete dan fungsi delete.

Pertama, perbarui struct Delete untuk menyertakan vault_account. Ini memungkinkan transfer SOL yang ada di vault kembali ke pengguna ketika mereka menutup akun pesan mereka.

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

Juga tambahkan system_program karena CPI untuk transfer memerlukan pemanggilan System Program.

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

Selanjutnya, tambahkan logika CPI dalam instruksi delete untuk mentransfer SOL dari akun vault kembali ke akun pengguna.

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

Perhatikan bahwa _ctx: Context<Delete> berubah menjadi ctx: Context<Delete> untuk menggunakan konteks dalam badan fungsi.

Bangun ulang program.

Terminal
$
build

Mendeploy ulang program

Setelah membuat perubahan ini, deploy ulang program yang telah diperbarui. Ini memastikan program yang dimodifikasi tersedia untuk pengujian. Di Solana, memperbarui program hanya memerlukan deployment program pada ID program yang sama.

Pastikan dompet Playground Anda memiliki SOL devnet. Dapatkan SOL devnet dari Solana Faucet.

Terminal
$
deploy

Memperbarui file pengujian

Selanjutnya, perbarui file anchor.test.ts untuk menyertakan akun vault baru dalam instruksi. Ini memerlukan derivasi vault PDA dan menyertakannya dalam panggilan instruksi update dan delete.

Derive Vault PDA

Pertama, tambahkan derivasi vault PDA:

anchor.test.ts
const [vaultPda, vaultBump] = PublicKey.findProgramAddressSync(
[Buffer.from("vault"), wallet.publicKey.toBuffer()],
program.programId
);

Ubah Update Test

Kemudian, perbarui instruksi update untuk menyertakan vaultAccount

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

Ubah Delete Test

Kemudian, perbarui instruksi delete untuk menyertakan vaultAccount

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

Jalankan Ulang Test

Setelah membuat perubahan ini, jalankan test untuk memastikan semuanya berfungsi sebagaimana yang diharapkan:

Terminal
$
test

Anda kemudian dapat memeriksa tautan SolanaFM untuk melihat detail transaksi, di mana Anda akan menemukan CPI untuk instruksi transfer dalam instruksi update dan delete.

Update CPIUpdate CPI

Delete CPIDelete CPI

Jika Anda mengalami kesalahan, Anda dapat merujuk ke kode final.

Langkah Selanjutnya

Selamat telah menyelesaikan panduan Quickstart Solana. Anda telah mendapatkan pengalaman langsung dengan konsep-konsep kunci Solana termasuk:

  • Mengambil dan membaca data dari akun
  • Membangun dan mengirim transaksi
  • Men-deploy dan memperbarui program Solana
  • Bekerja dengan Program Derived Address (PDA)
  • Membuat Cross-Program Invocation (CPI)

Untuk memperdalam pemahaman Anda tentang konsep-konsep ini, lihat dokumentasi Konsep Inti yang memberikan penjelasan detail tentang topik-topik yang dibahas dalam panduan ini.

Jelajahi Contoh Lainnya

Jika Anda lebih suka belajar melalui contoh, lihat Program Examples Repository untuk berbagai contoh program.

Solana Playground menawarkan fitur yang memudahkan Anda untuk mengimpor atau melihat proyek menggunakan tautan GitHub mereka. Misalnya, buka tautan Solana Playground ini untuk melihat proyek Anchor dari repo Github ini.

Klik tombol Import dan masukkan nama proyek untuk menambahkannya ke daftar proyek Anda di Solana Playground. Setelah proyek diimpor, semua perubahan akan secara otomatis disimpan dan dipertahankan.

Is this page helpful?

Daftar Isi

Edit Halaman