Noções Básicas de PDA
10 exemplos para você começar com PDAs - 7 básicos e 3 intermediários.
Pré-requisitos
- Entenda Pubkeys.
- Solana CLI 3.0.10 para helpers
solana addressoff-chain.
Exemplos Básicos
1. Derivar off-chain
Clientes encontram PDA + bump antes de montar transações.
use solana_program::pubkey::Pubkey;
let program_id = Pubkey::new_unique();
let (pda, bump) = Pubkey::find_program_address(&[b"vault"], &program_id);find_program_addresstenta bumps de 255 a 0.- PDA está off-curve - nenhuma chave privada existe.
- Mesmas seeds + program id sempre produzem o mesmo endereço.
2. PDA como chave de conta
Transações referenciam o pubkey da PDA como qualquer conta.
// AccountMeta::new(pda, false) - PDA não é signatário de carteira- Carteiras assinam; PDAs assinam apenas via
invoke_signeddo programa. - PDAs podem ser owner de contas de token e contas de dados.
- Armazene o bump nos dados da conta para re-derivação mais barata.
3. Slices de seeds
Seeds são strings de bytes - pubkeys, strings, números.
let seeds: &[&[u8]] = &[b"escrow", buyer.as_ref(), seller.as_ref()];- Regras de tamanho máximo de seed se aplicam por seed.
- Use prefixos constantes para namespacing de PDAs.
- Documente a ordem das seeds para clientes.
4. Program id na derivação
Mudar o program id muda o endereço da PDA.
Pubkey::find_program_address(seeds, program_id);- Deploys de upgrade mantêm o program id.
- PDAs cross-program usam o program id do callee.
- Nunca hardcode PDAs - sempre derive.
5. PDA não pode assinar tx
Usuários finais nunca possuem chaves privadas de PDA.
// Apenas o programa proprietário pode assinar pela PDA via invoke_signed- Modelo de segurança: a lógica do programa é a autoridade.
- Programa comprometido = PDAs comprometidas.
- Mantenha a upgrade authority do programa segura.
6. On-curve vs off-curve
PDAs são intencionalmente off da curva ed25519.
// Off-chain: Pubkey::create_program_address valida o bumpcreate_program_addressfalha se on-curve.find_program_addressbusca o bump válido.- Explorers ainda mostram a PDA como endereço normal.
7. Autoridade de programa única
Apenas o programa que derivou pode assinar pela PDA.
invoke_signed(&ix, accounts, &[&[b"vault", &[bump]]])?;- Seeds devem corresponder à derivação.
- Program id errado não pode assinar.
- CPI passa signer seeds ao runtime.
Exemplos Intermediários
8. Armazenar bump canônico
Salve o bump no init para evitar busca on-chain.
pub struct Vault { pub bump: u8, pub total: u64 }- Verifique
seeds[bump] == stored_bumpem cada ix. - Previne griefing de bump hunting.
- Veja a página Canonical Bumps.
Relacionado: Bumps Canônicos - armazenamento de bump
9. Conta de token com owner PDA
Contas de token podem usar PDA como autoridade.
// seeds: [b"token", mint.key.as_ref(), owner.as_ref()]- Programa assina transferências de token com
invoke_signed. - Valide mint e owner nas seeds.
- Padrão comum de vault.
Relacionado: PDAs como Autoridades - vaults
10. Consciência de colisão
Conjuntos de seeds diferentes não devem colidir semanticamente.
const PREFIX_VAULT: &[u8] = b"vault";
const PREFIX_ESCROW: &[u8] = b"escrow";- Use prefixos estáticos distintos.
- Inclua pubkeys para PDAs por usuário.
- Documente a gramática de seeds.
Relacionado: Design de Seeds e Colisões - regras de design
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.