Passando Contas para CPIs
Listas de contas de CPI devem espelhar a ordem esperada pelo chamador, flags de signatário e capacidade de escrita. Seu programa é responsável por não elevar privilégios além do que a transação externa pretendia.
Receita
let metas = vec![
AccountMeta::new(source, false),
AccountMeta::new(dest, false),
AccountMeta::new_readonly(authority, true),
];Quando usar isto:
- Construindo CPIs personalizadas para programas SPL.
- Auditando escalonamento de privilégios.
- Compondo múltiplas CPIs em uma instrução.
Exemplo Funcional
// Valida se a origem é gravável apenas se o chamador pretendia mutação
if !source.is_writable { return Err(ProgramError::InvalidAccountData); }
let ix = spl_token::instruction::transfer(...)?;
invoke(&ix, &[source.clone(), dest.clone(), authority.clone(), token_program.clone()])?;O que isto demonstra:
- Verificação explícita de gravabilidade antes da CPI.
- Autoridade marcada como signatário nas
metas. - Conta do programa de token incluída.
Análise Detalhada
Escalonamento de Privilégios
Passar writable + signer para o chamado quando a transação externa não autorizou é um bug crítico.
Ordenação
Siga as definições de origem do chamado (spl-token, system).
Notas de Rust
// AccountMeta::new_readonly(key, is_signer)Armadilhas
- Contas graváveis extras - Chamado modifica a conta do atacante. Correção: Metas de privilégio mínimo.
- Conta de programa ausente - CPI falha. Correção: Inclua a conta do ID do programa chamado.
- Escalonamento de signatário - Marcando não-signatário como signatário. Correção: Corresponda às flags da transação externa, a menos que seja um PDA.
- Troca de ordem de conta - Contas de token erradas. Correção: Copie dos auxiliares SPL.
- Duplicado não verificado - Mesma conta duas vezes. Correção: Rejeite se for inseguro.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
| Construtores de instrução SPL | Metas corretas | Programas personalizados |
| Módulo cpi do Anchor | Gerado | Manual |
| Clientes Codama | Apenas off-chain | On-chain ainda manual |
FAQs
Quem verifica as metas?
O programa chamado revalida.
Signatário de telhado?
Signatários da transação externa + apenas invoke_signed.
Tentativa de gravação somente leitura?
O chamado gera um erro.
Endereços ALT?
Resolvidos antes do tempo de execução.
Muitas contas?
Use o padrão de contas restantes no Anchor.
CPI para seu programa?
Considerações sobre reentrância.
Programa gravável?
Geralmente conta de programa somente leitura.
Sysvar em CPI?
Se o chamado exigir.
Multisig de token?
Contas de signatário extras.
Logs de simulação?
Mostra o ID do programa chamado.
Custo do clone de AccountInfo?
Barato.
Testar ordem errada?
Testes negativos do LiteSVM.
Relacionado
- Validação Manual de Contas - Validação
- CPI para SPL Token - Layout do token
- Reentrância e Segurança - Callbacks de CPI
Versões do 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.