Akun PDA

Ringkasan

Buat akun PDA melalui invoke_signed dengan seed PDA. Hanya program pemilik yang dapat menandatangani untuk PDA. Constraint init Anchor mengotomatiskan pembuatan akun PDA.

Penandatanganan PDA melalui invoke_signed

Ketika program perlu menandatangani atas nama PDA selama CPI, program tersebut menggunakan invoke_signed dengan seed PDA. Runtime memverifikasi seed menurunkan PDA yang diharapkan menggunakan ID program pemanggil, memastikan hanya program pemilik yang dapat menandatangani. Untuk alur verifikasi lengkap, lihat Penandatanganan PDA.

Membuat akun PDA

Menurunkan PDA dan membuat akun di PDA adalah operasi terpisah. Anda harus secara eksplisit membuat akun setelah menurunkan alamat.

Untuk membuat akun di PDA, program penurunan memanggil instruksi create_account System Program melalui invoke_signed, meneruskan seed PDA sehingga runtime dapat memverifikasi otoritas program atas alamat tersebut.

Contoh di bawah ini menggunakan framework Anchor untuk membuat akun baru dengan alamat yang diturunkan program. Program ini mencakup satu instruksi initialize untuk membuat akun baru, yang akan menyimpan alamat pengguna dan bump seed yang digunakan untuk menurunkan PDA.

Program
use anchor_lang::prelude::*;
declare_id!("75GJVCJNhaukaa2vCCqhreY31gaphv7XTScBChmr1ueR");
#[program]
pub mod pda_account {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
let account_data = &mut ctx.accounts.pda_account;
// store the address of the `user`
account_data.user = *ctx.accounts.user.key;
// store the canonical bump
account_data.bump = ctx.bumps.pda_account;
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(mut)]
pub user: Signer<'info>,
#[account(
init,
// define the seeds to derive the PDA
seeds = [b"data", user.key().as_ref()],
// use the canonical bump
bump,
payer = user,
space = 8 + DataAccount::INIT_SPACE // 8 bytes for Anchor account discriminator
)]
pub pda_account: Account<'info, DataAccount>,
pub system_program: Program<'info, System>,
}
#[account]
#[derive(InitSpace)]
pub struct DataAccount {
pub user: Pubkey,
pub bump: u8,
}

Constraint init memberi tahu Anchor untuk memanggil System Program untuk membuat akun baru menggunakan PDA sebagai alamat. Seed yang digunakan untuk membuat PDA adalah:

  • String tetap: "data"
  • Alamat akun pengguna yang disediakan dalam instruksi
  • Canonical bump seed

Dalam contoh ini, constraint bump tidak diberi nilai, sehingga Anchor akan menggunakan find_program_address untuk menurunkan PDA dan menemukan bump.

pda_account
#[account(
init,
seeds = [b"data", user.key().as_ref()],
bump,
payer = user,
space = 8 + DataAccount::INIT_SPACE // 8 bytes for Anchor account discriminator
)]
pub pda_account: Account<'info, DataAccount>,

File pengujian di bawah ini berisi transaksi yang memanggil instruksi initialize untuk membuat akun baru dengan program-derived address. File ini berisi kode untuk menurunkan PDA.

Contoh ini juga menunjukkan cara mengambil akun baru yang akan dibuat.

Test
import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import { PdaAccount } from "../target/types/pda_account";
import { PublicKey } from "@solana/web3.js";
describe("pda-account", () => {
const provider = anchor.AnchorProvider.env();
anchor.setProvider(provider);
const program = anchor.workspace.PdaAccount as Program<PdaAccount>;
const user = provider.wallet as anchor.Wallet;
// Derive the PDA address using the seeds specified on the program
const [PDA] = PublicKey.findProgramAddressSync(
[Buffer.from("data"), user.publicKey.toBuffer()],
program.programId
);
it("Is initialized!", async () => {
const transactionSignature = await program.methods
.initialize()
.accounts({
user: user.publicKey
})
.rpc();
console.log("Transaction Signature:", transactionSignature);
});
it("Fetch Account", async () => {
const pdaAccount = await program.account.dataAccount.fetch(PDA);
console.log(JSON.stringify(pdaAccount, null, 2));
});
});

Jika Anda memanggil instruksi initialize lagi dengan seed alamat user yang sama, transaksi akan gagal. Ini terjadi karena akun sudah ada di alamat yang diturunkan.

Is this page helpful?

Daftar Isi

Edit Halaman

Dikelola oleh

© 2026 Yayasan Solana.
Semua hak dilindungi.
Terhubung