Instruction Ordering & Dependencies
Clientes compõem múltiplas instruções Anchor em uma transação. A ordem importa quando instruções posteriores dependem de contas criadas ou mutadas por instruções anteriores.
Receita
1. create_user (init PDA)
2. create_ata (init token account)
3. deposit (transfer tokens)Quando usar: Você projeta fluxos de cliente ou documenta etapas de integração.
Exemplo Prático
// Client sends ordered instructions in one transaction
const tx = await program.methods
.createUser()
.accounts({ /* ... */ })
.preInstructions([/* compute budget if needed */])
.rpc();
// Or batch:
// tx = new Transaction().add(ix1, ix2, ix3);// Program: deposit assumes user PDA already initialized
#[account(
seeds = [b"user", owner.key().as_ref()],
bump = user.bump,
constraint = user.initialized @ UserError::NotInitialized,
)]
pub user: Account<'info, UserState>,O que isso demonstra:
- Init deve preceder uso na mesma tx ou em tx anterior
- Lotes atômicos têm sucesso ou falham juntos
- Instruções idempotentes simplificam retries
- Documente a ordem obrigatória na documentação do IDL
Aprofundamento
Padrões de dependência
- Setup + ação - Separe instruções de criação e operação.
- Init na mesma tx - Múltiplas instruções; conta da ix0 visível na ix1.
- Prefetch - Cliente lê PDAs off-chain e passa para ix posterior.
Use erros explícitos quando pré-requisitos estiverem ausentes em vez de panics.
Erros comuns
- Deposit antes do init - Conta ausente.. Correção: Retorne erro
NotInitialized. - Assumir atomicidade entre txs - Apenas uma tx é atômica.. Correção: Trate conclusão parcial na UI.
- Blockhash expirado em lotes longos - Retry com blockhash novo.. Correção: Mantenha lotes enxutos.
- Init duplicado no retry - Segunda tx falha.. Correção: Use design idempotente ou verifique existência no cliente.
- Mutabilidade de conta errada no lote - Ix posterior falha.. Correção: Marque contas mut em todas as instruções que escrevem.
Alternativas
| Alternativa | Use quando | Não use quando |
|---|---|---|
| Uma instrução faz tudo | Cliente mais simples | CU maior por chamada |
| init_if_needed | Menos ix no cliente | Segurança mais fraca se mal usado |
| Txs versionadas com ALTs | Muitas contas | Txs legacy simples |
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 ordenação.
Relacionados
- init & init_if_needed - criação
- Transaction Assembly - txs no cliente
- Building Transaction Messages - @solana/kit
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.