init & init_if_needed
init cria uma nova conta na mesma instrução. init_if_needed cria apenas quando ausente, o que introduz risco de reinicialização se as restrições forem fracas.
Busque em todas as páginas da documentação
init cria uma nova conta na mesma instrução. init_if_needed cria apenas quando ausente, o que introduz risco de reinicialização se as restrições forem fracas.
#[account(
init,
payer = payer,
space = 8 + MyAccount::INIT_SPACE,
seeds = [b"vault", user.key().as_ref()],
bump
)]
pub vault: Account<'info, Vault>,Quando usar isso: Uma instrução deve alocar estado de propriedade do programa pela primeira vez.
#[derive(Accounts)]
pub struct CreateProfile<'info> {
#[account(
init,
payer = user,
space = 8 + Profile::INIT_SPACE,
seeds = [b"profile", user.key().as_ref()],
bump
)]
pub profile: Account<'info, Profile>,
#[account(mut)]
pub user: Signer<'info>,
pub system_program: Program<'info, System>,
}init_if_needed é controlado por um recurso do cargo. Sem ele, a macro falha na compilação com um erro informando para habilitá-lo:
[dependencies]
anchor-lang = { version = "0.32.1", features = ["init-if-needed"] }// init_if_needed: apenas quando idempotente e seguro
#[account(
init_if_needed,
payer = payer,
space = 8 + Stats::INIT_SPACE,
seeds = [b"stats"],
bump,
)]
pub stats: Account<'info, Stats>,O que isso demonstra:
init falha se a conta já existirpayer financia lamports isentos de aluguelspace inclui um discriminador de 8 bytesinit_if_needed pode pular a criação quando a conta existeinit_if_needed nunca recria uma conta existente, então o corpo do seu manipulador ainda é executado contra o estado ativo. O Anchor executa o caminho completo Account<T> na conta existente (proprietário + discriminador de 8 bytes + Borsh) e revalida os atributos declarados, como space, owner e token::authority, mesmo quando a criação é pulada, então lixo arbitrário é rejeitado.
O ataque real de reinicialização é diferente: se o corpo do manipulador escrever incondicionalmente valores padrão (ctx.accounts.stats.owner = signer.key();), uma segunda chamada redefine uma conta legítima e já populada. Proteja com um campo initialized: bool armazenado / campo de versão, ou constraint = stats.authority == authority.key(), ou divida a criação e a atualização em duas instruções.
INIT_SPACE ou space = 8 + ....init ou constraint estrito no estado existente.Program<System>.#[account(mut)].init_if_needed apenas com guardas fortes.
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
| Instrução de criação separada | Ciclo de vida claro | Experiência de configuração única |
| CPI para o programa do sistema manualmente | Programas nativos | Macros init do Anchor |
| init_if_needed + constraint | Onboarding idempotente | Cofres de alta segurança |
0.32.1 para anchor-lang, Anchor CLI e exemplos nesta seção.
Sim. Solana CLI 3.0.10 lida com keypairs, airdrops e inspeção de solana program.
target/idl/<program>.json em seu workspace.
Sim, mas cada campo não verificado precisa de restrições explícitas ou verificações do manipulador.
Use anchor test com Surfpool 0.12.0 ou LiteSVM 0.6.x em CI.
Discriminador de conta Anchor; não o remova ao dimensionar space.
Sim, ou publique a IDL on-chain para que os clientes tenham uma fonte canônica.
Execute com logs; Anchor imprime o nome da restrição e o índice da conta.
Sim. Esta pilha tem como alvo validadores Agave com Solana CLI 3.0.10.
Veja artigos irmãos vinculados em Relacionados para tópicos mais aprofundados sobre init.
Versões da Pilha: 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.
Revisado por Chris St. John·Última atualização: 19 de jul. de 2026