PDA-tilit

Yhteenveto

Luo PDA-tilejä invoke_signed-komennolla käyttäen PDA:n seedejä. Vain omistava ohjelma voi allekirjoittaa PDA:n puolesta. Anchor-kehyksen init-rajoite automatisoi PDA-tilin luomisen.

PDA:n allekirjoitus invoke_signed-komennolla

Kun ohjelma tarvitsee allekirjoittaa PDA:n puolesta CPI:n aikana, se käyttää invoke_signed-komentoa PDA:n seedeillä. Ajonaikainen ympäristö vahvistaa, että seedit johtavat odotettavaan PDA:han käyttäen kutsuvan ohjelman ID:tä, varmistaen että vain omistava ohjelma voi allekirjoittaa. Täydellinen vahvistusprosessi löytyy kohdasta PDA:n allekirjoitus.

PDA-tilin luominen

PDA:n johdattaminen ja tilin luominen PDA:han ovat erillisiä operaatioita. Sinun täytyy erikseen luoda tili osoitteen johdattamisen jälkeen.

Luodakseen tilin PDA:han, johdattava ohjelma kutsuu System Program -ohjelman create_account-käskyä invoke_signed-komennon kautta, välittäen PDA:n seedit, jotta ajonaikainen ympäristö voi vahvistaa ohjelman valtuutuksen kyseiseen osoitteeseen.

Alla oleva esimerkki käyttää Anchor-kehystä luodakseen uuden tilin ohjelmasta johdetulla osoitteella. Ohjelma sisältää yhden initialize-käskyn uuden tilin luomiseksi, joka tallentaa käyttäjän osoitteen ja bump seedin, joita käytettiin PDA:n johdattamiseen.

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-rajoite kertoo Anchorille kutsua System Program -ohjelmaa luodakseen uuden tilin käyttäen PDA:ta osoitteena. PDA:n luomiseen käytetyt seedit ovat:

  • Kiinteä merkkijono: "data"
  • Ohjeessa annetun käyttäjätilin osoite
  • Kanoninen bump seed

Tässä esimerkissä bump-rajoitteelle ei ole määritetty arvoa, joten Anchor käyttää find_program_address -arvoa PDA:n johdattamiseen ja bumpin löytämiseen.

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

Alla oleva testitiedosto sisältää transaktion, joka kutsuu initialize-käskyä luodakseen uuden tilin ohjelmasta johdetulla osoitteella. Tiedosto sisältää koodin PDA:n johdattamiseen.

Esimerkki näyttää myös, kuinka hakea uusi tili, joka luodaan.

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

Jos kutsut initialize-käskyä uudelleen samalla user-osoitteen seedillä, transaktio epäonnistuu. Tämä johtuu siitä, että johdettuun osoitteeseen on jo olemassa tili.

Is this page helpful?

Sisällysluettelo

Muokkaa sivua

Hallinnoi

© 2026 Solana Foundation.
Kaikki oikeudet pidätetään.
Yhdistä