init & init_if_needed
init crea una nueva cuenta en la misma instrucción. init_if_needed crea solo cuando falta, lo que introduce el riesgo de reinicialización si las restricciones son débiles.
Receta
#[account(
init,
payer = payer,
space = 8 + MyAccount::INIT_SPACE,
seeds = [b"vault", user.key().as_ref()],
bump
)]
pub vault: Account<'info, Vault>,Cuándo usar esto: Una instrucción debe asignar estado propiedad del programa por primera vez.
Ejemplo Funcional
#[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: solo cuando es idempotente y seguro
#[account(
init_if_needed,
payer = payer,
space = 8 + Stats::INIT_SPACE,
seeds = [b"stats"],
bump,
)]
pub stats: Account<'info, Stats>,Lo que esto demuestra:
initfalla si la cuenta ya existepayerfinancia lamports exentos de alquilerspaceincluye el discriminador de 8 bytesinit_if_neededpuede omitir la creación cuando la cuenta existe
Análisis Profundo
Requisitos de init
- El pagador debe ser un firmante mutable con SOL.
- Se requiere el programa del sistema para asignar/asignar.
- El espacio debe ajustarse al tamaño de la cuenta serializada.
Riesgo de init_if_needed
Si los datos de la cuenta existente no se validan, un atacante pasa datos basura no inicializados que pasan verificaciones débiles. Prefiera init o valide el discriminador y la autoridad en cada ruta.
Errores Comunes
- init sin espacio - Error de compilación o alquiler incorrecto. Solución: Use
INIT_SPACEospace = 8 + .... - init_if_needed en datos propiedad del usuario - Ataques de reinicialización posibles. Solución: Use
initoconstraintestricto en el estado existente. - Se olvidó system_program - La creación de cuenta CPI falla. Solución: Incluya
Program<System>. - Payer no es mut - La transferencia de alquiler falla. Solución: Marque el pagador como
#[account(mut)]. - Doble init con las mismas semillas - La segunda llamada falla; planifique un flujo idempotente. Solución: Use
init_if_neededsolo con salvaguardias sólidas.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| Instrucción de creación separada | Ciclo de vida claro | Experiencia de configuración única |
| CPI al programa del sistema manualmente | Programas nativos | Macros init de Anchor |
| init_if_needed + constraint | Incorporación idempotente | Bóvedas de alta seguridad |
Preguntas Frecuentes
¿Qué versión de Anchor utiliza este sitio?
0.32.1 para anchor-lang, Anchor CLI y ejemplos en esta sección.
¿Necesito Solana CLI junto con Anchor?
Sí. Solana CLI 3.0.10 maneja pares de claves, airdrops e inspección de solana program.
¿Dónde vive el IDL después de la compilación?
target/idl/<program>.json en su espacio de trabajo.
¿Puedo mezclar UncheckedAccount con Signer?
Sí, pero cada campo no verificado necesita restricciones explícitas o verificaciones del manejador.
¿Cómo pruebo sin devnet?
Use anchor test con Surfpool 0.12.0 o LiteSVM 0.6.x en CI.
¿Qué es el prefijo de 8 bytes en los datos de la cuenta?
Discriminador de cuenta de Anchor; no lo elimine al dimensionar space.
¿Debo confirmar el IDL generado?
Sí, o publique el IDL en la cadena para que los clientes tengan una fuente canónica.
¿Cómo depuro fallos de restricciones?
Ejecute con registros; Anchor imprime el nombre de la restricción y el índice de la cuenta.
¿Anchor funciona en Agave 4.1.1?
Sí. Esta pila se dirige a validadores Agave con Solana CLI 3.0.10.
¿Qué debo leer a continuación en esta sección?
Consulte los artículos hermanos vinculados en Relacionados para temas más profundos sobre init.
Relacionados
- Space & Rent - dimensionamiento
- Seeds & Bump Constraints - init de PDA
- Account Initialization Patterns - patrones de diseño
Versiones de la pila: Esta página se escribió 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 y LiteSVM 0.6.x.