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.
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 bumpaccount_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 PDAseeds = [b"data", user.key().as_ref()],// use the canonical bumpbump,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.
#[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.
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 programconst [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?