PDAs no Anchor
Program Derived Addresses não têm chave privada; seu programa assina por elas com seeds e bump via invoke_signed ou CPI with_signer.
Receita
#[account(
seeds = [b"escrow", maker.key().as_ref()],
bump,
)]
pub escrow: Account<'info, Escrow>,Quando usar: O programa precisa custodiar ativos ou armazenar estado canônico em um endereço determinístico.
Exemplo prático
#[derive(Accounts)]
pub struct InitEscrow<'info> {
#[account(
init,
payer = maker,
space = 8 + Escrow::INIT_SPACE,
seeds = [b"escrow", maker.key().as_ref(), escrow_id.to_le_bytes().as_ref()],
bump,
)]
pub escrow: Account<'info, Escrow>,
#[account(mut)]
pub maker: Signer<'info>,
pub system_program: Program<'info, System>,
}O que isso demonstra:
- Seeds + program id determinam o endereço da PDA
bumpencontra o bump canônico fora da curva- Armazene o bump na conta para verificações mais baratas depois
- PDAs não podem ser do tipo Signer
Aprofundamento
Derivação
Pubkey::find_program_address(seeds, program_id) retorna (address, bump). O Anchor encapsula isso em constraints.
Assinatura pelo programa
Somente o programa que possui as seeds da PDA pode assinar, a menos que você use program id externo nas seeds (avançado).
Erros comuns
- Bump fora da curva não armazenado - CU extra a cada CPI.. Correção: Persista o bump no estado.
- Limites de tamanho das seeds - Restrições de tamanho máximo de dados nas seeds.. Correção: Mantenha seeds compactas.
- Padrão de PDA owned pelo system usado incorretamente - Assign ao programa após criar.. Correção: Use init do Anchor na PDA.
- Mismatch de seeds client/server - Transação falha.. Correção: Compartilhe o seed builder no SDK.
- PDA como Signer<'info> - Não compila / modelo errado.. Correção: Use Account com constraint seeds.
Alternativas
| Alternativa | Use quando | Não use quando |
|---|---|---|
| Contas owned por keypair | Assinatura externa necessária | Custódia pelo programa |
| seeds::program para PDAs externas | CPI para PDAs de outro programa | Estado do próprio programa |
FAQs
Qual versão do Anchor é assumida?
0.32.1 em toda esta seção.
Uma PDA pode ser Signer na struct accounts?
Não. Use constraints seeds e assinatura em CPI.
Onde o bump é armazenado?
No campo da sua struct de conta, definido na inicialização.
Como os clientes derivam PDAs?
Use @solana/kit 7.0.0 com bytes de seed correspondentes.
Qual program id é usado para PDAs?
O endereço declare_id do seu programa Anchor.
As seeds incluem bump?
Não no array seeds; bump é parâmetro separado para find_program_address.
Como depurar falhas de PDA?
Compare chaves logadas; verifique seeds e program id no client.
PDAs são rent-exempt?
Sim quando mantêm dados; financie com payer no init.
Uma PDA pode assinar múltiplos CPIs em uma ix?
Sim com as mesmas signer seeds para cada CPI.
O que ler em seguida?
Veja os links em Relacionados para tópicos mais profundos sobre PDAs.
Relacionados
- Assinatura com PDAs - assinatura em CPI
- Seeds & Bump Constraints - validação
- Noções básicas de PDA - modelo nativo
Versões da stack: Esta página foi escrita para Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0 e LiteSVM 0.6.x.