Las Restricciones #[account]
Los atributos de campo en los miembros de la struct de cuentas componen las reglas de validación. Anchor las evalúa en un orden definido antes de que se ejecute tu manejador de instrucciones.
Receta
#[account(
mut,
has_one = authority,
constraint = amount > 0 @ MyError::InvalidAmount,
)]
pub vault: Account<'info, Vault>,Cuándo usar esto: Expresas propiedad, relaciones o invariantes personalizados de forma declarativa.
Ejemplo Funcional
#[derive(Accounts)]
pub struct SetFee<'info> {
#[account(
mut,
seeds = [b"config"],
bump = config.bump,
has_one = admin,
constraint = new_fee_bps <= 10_000 @ ConfigError::FeeTooHigh,
)]
pub config: Account<'info, Config>,
pub admin: Signer<'info>,
}Lo que esto demuestra:
mutmarca las cuentas escribibleshas_onecomprueba la igualdad de la pubkey con el campo anidadoconstraintejecuta expresiones booleanas arbitrarias- El error después de
@se mapea a una variante de enum de error personalizada
Análisis Profundo
Atributos Comunes
| Atributo | Propósito |
|---|---|
mut | La cuenta es escribible |
signer | Debe ser firmante (en tipos que no son Signer) |
has_one = field | El campo de la cuenta coincide con la clave de otra cuenta |
address = expr | Coincidencia exacta de pubkey |
owner = prog | Comprobación del programa propietario |
constraint = expr | Invariante personalizado |
Combina atributos; todos deben pasar.
Trampas Comunes
- constraint sin @ error - Mensaje genérico de violación de restricción. Solución: Añade
@ MyError::Variantpara mayor claridad. - typo en has_one - Fallo silencioso al compilar o campo incorrecto. Solución: El nombre del campo debe existir en la struct de cuenta.
- address = clave incorrecta - Bloquea mainnet si se codifica una clave de prueba. Solución: Usa constantes
pubkey!por feature flags del clúster. - falta mut en el objetivo de has_one - Solo lectura cuando necesitas escribir. Solución: Añade
muten las cuentas que persistes. - superposición de constraint y comprobación en el manejador - La lógica duplicada se desvía. Solución: Elige declarativo o manejador, no ambos para la misma regla.
Alternativas
| Alternativa | Úsala Cuando | No la Uses Cuando |
|---|---|---|
| require! en el manejador | Lógica dinámica entre cuentas | Comprobaciones de relaciones estáticas |
| Tokens de restricción personalizados (0.32) | Patrones reutilizables | Reglas simples de un solo uso |
| Comprobaciones nativas manuales | No usas Anchor | Usas Anchor por 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 keypairs, airdrops e inspección de solana program.
¿Dónde vive el IDL después de la compilación?
target/idl/<program>.json en tu espacio de trabajo.
¿Puedo mezclar UncheckedAccount con Signer?
Sí, pero cada campo no verificado necesita restricciones explícitas o comprobaciones en el manejador.
¿Cómo pruebo sin devnet?
Usa 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 elimines al dimensionar space.
¿Debo confirmar el IDL generado?
Sí, o publica el IDL en la cadena para que los clientes tengan una fuente canónica.
¿Cómo depuro fallos de restricciones?
Ejecuta con logs; Anchor imprime el nombre de la restricción y el índice de la cuenta.
¿Funciona Anchor 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?
Consulta los artículos hermanos en Relacionados para temas más profundos sobre restricciones de cuentas.
Relacionado
- Restricciones Personalizadas - expresiones avanzadas
- Orden de Validación de Cuentas - orden de evaluación
- init & init_if_needed - restricciones de ciclo de vida
Versiones de la pila: Esta página fue 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, y LiteSVM 0.6.x.