PDA hesapları

Özet

PDA hesaplarını PDA'nın seed'leriyle invoke_signed aracılığıyla oluşturun. Yalnızca sahip olan program bir PDA için imza atabilir. Anchor'un init kısıtlaması PDA hesap oluşturmayı otomatikleştirir.

invoke_signed ile PDA imzalama

Bir program CPI sırasında bir PDA adına imza atması gerektiğinde, PDA'nın seed'leriyle invoke_signed kullanır. Runtime, seed'lerin çağıran programın ID'sini kullanarak beklenen PDA'yı türettiğini doğrular ve yalnızca sahip olan programın imza atabileceğinden emin olur. Tam doğrulama akışı için PDA imzalama bölümüne bakın.

PDA hesabı oluşturma

Bir PDA türetmek ve PDA'da bir hesap oluşturmak ayrı işlemlerdir. Adresi türettikten sonra hesabı açıkça oluşturmalısınız.

Bir PDA'da hesap oluşturmak için, türeten program System Program'ın create_account talimatını invoke_signed aracılığıyla çağırır ve PDA'nın seed'lerini ileterek runtime'ın programın o adres üzerindeki yetkisini doğrulamasını sağlar.

Aşağıdaki örnek, program türevli bir adresle yeni bir hesap oluşturmak için Anchor framework kullanır. Program, PDA'yı türetmek için kullanılan kullanıcı adresini ve bump seed'ini depolayacak yeni hesabı oluşturmak için tek bir initialize talimatı içerir.

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,
}

init kısıtlaması Anchor'a PDA'yı adres olarak kullanarak yeni bir hesap oluşturmak için System Program'ı çağırmasını söyler. PDA'yı oluşturmak için kullanılan seed'ler şunlardır:

  • Sabit dize: "data"
  • Talimatta sağlanan kullanıcı hesabının adresi
  • Kanonik bump seed

Bu örnekte, bump kısıtlamasına bir değer atanmamıştır, bu nedenle Anchor PDA'yı türetmek ve bump'ı bulmak için find_program_address kullanacaktır.

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>,

Aşağıdaki test dosyası, program türevli bir adresle yeni bir hesap oluşturmak için initialize talimatını çağıran bir işlem içerir. Dosya, PDA'yı türetmek için kod içerir.

Örnek ayrıca oluşturulacak yeni hesabın nasıl alınacağını gösterir.

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

Aynı user adres seed'i ile initialize talimatını tekrar çağırırsanız, işlem başarısız olur. Bu durum, türetilen adreste zaten bir hesap bulunduğu için gerçekleşir.

Is this page helpful?

İçindekiler

Sayfayı Düzenle

Yönetici

© 2026 Solana Vakfı.
Tüm hakları saklıdır.
Bağlanın