Accessing Accounts
Use ctx.accounts para campos tipados, ctx.bumps para seeds de PDA e ctx.remaining_accounts para listas variáveis de contas passadas após o layout fixo.
Receita
pub fn route(ctx: Context<Route>) -> Result<()> {
let bump = ctx.bumps.vault;
let vault = &mut ctx.accounts.vault;
for acc in ctx.remaining_accounts.iter() {
require!(acc.owner == &crate::ID, MyError::BadRemaining);
}
Ok(())
}Quando usar: Handlers leem ou mutam contas validadas e extras opcionais.
Exemplo Prático
pub fn swap(ctx: Context<Swap>) -> Result<()> {
let user = &ctx.accounts.user;
let pool = &mut ctx.accounts.pool;
let bump = ctx.bumps.pool;
msg!("user: {}, pool bump: {}", user.key(), bump);
for meta in ctx.remaining_accounts.iter() {
let ai = meta.to_account_info();
require!(ai.is_writable, SwapError::ReadonlyAccount);
}
Ok(())
}O que isso demonstra:
- Campos de conta são referências com lifetimes ligados ao Context
ctx.bumps.<name>corresponde ao nome do campo em seedsremaining_accountsé um slice de AccountInfo- Use
to_account_info()para account metas em CPI
Aprofundamento
Mutação de conta
&mut Account<'info, T> serializa mudanças ao final da instrução se a conta foi marcada mut nas constraints.
remaining_accounts
Clientes acrescentam contas após a ordem do IDL. Documente a ordem esperada e valide cada entrada.
Erros comuns
- remaining_accounts sem validação - Vulnerabilidade crítica.. Correção: Verifique owner, discriminator e signer conforme necessário.
- Nome de bump errado em ctx.bumps - O nome do campo deve corresponder ao campo de conta em seeds.. Correção: Use o nome exato do campo da struct.
- Clonar AccountInfo desnecessariamente - Desperdício de CU.. Correção: Passe referências para helpers de CPI.
- Assumir ordem de remaining a partir do IDL - Apenas contas fixas estão no IDL.. Correção: Publique documentação separada para extras.
- Ler dados antes da validação em outro crate - Só se aplica a caminhos não verificados.. Correção: Mantenha validação nas constraints primeiro.
Alternativas
| Alternativa | Use quando | Não use quando |
|---|---|---|
| Vec explícito de contas na struct | Conjuntos fixos pequenos | Roteamento dinâmico grande |
| AccountLoader::load | Leituras zero-copy | Account<T> padrão |
| Contas Sysvar na struct | Clock, rent | remaining_accounts para sysvars raros |
FAQs
Qual versão do Anchor é assumida?
0.32.1 em toda esta seção.
Uma PDA pode ser Signer na struct de contas?
Não. Use constraints de seeds e assinatura em CPI.
Onde o bump é armazenado?
No campo da struct de conta, definido na inicialização.
Como os clientes derivam PDAs?
Use @solana/kit 7.0.0 com os mesmos bytes de seed.
Qual program id é usado para PDAs?
O endereço declare_id do seu programa Anchor.
Seeds incluem bump?
Não no array de seeds; bump é parâmetro separado em find_program_address.
Como depurar falhas de PDA?
Compare chaves logadas; verifique seeds e program id no client-side.
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 em cada CPI.
O que ler em seguida?
Veja os links em Relacionados para tópicos mais profundos sobre acesso a contas.
Relacionados
- remaining_accounts - conjuntos dinâmicos
- Passing Remaining Accounts - extras em CPI
- Instruction Handlers - visão geral do Context
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.