Discriminadores de Cuenta
Los discriminadores identifican qué tipo de struct posee el diseño de bytes de una cuenta. Bloquean ataques de confusión de tipos donde una cuenta maliciosa se interpreta como el tipo incorrecto.
Receta
if data[..8] != Account::DISCRIMINATOR { return Err(ProgramError::InvalidAccountData); }Cuándo usar esto:
- Múltiples tipos de cuenta en un solo programa.
- Migración de diseños entre versiones.
- Coincidencia del comportamiento de validación de cuentas de Anchor.
Ejemplo de Trabajo
pub const VAULT_DISC: [u8; 8] = *b"vault___";
pub fn load_vault(data: &[u8]) -> Result<Vault, ProgramError> {
if data.len() < 8 || data[..8] != VAULT_DISC { return Err(ProgramError::InvalidAccountData); }
Vault::deserialize(&mut &data[8..]).map_err(|_| ProgramError::InvalidAccountData)
}Lo que esto demuestra:
- Prefijo de 8 bytes verificado antes del cuerpo de Borsh.
- Discriminador constante por tipo.
- Discriminador incorrecto rechazado tempranamente.
Análisis Profundo
Discriminadores de Anchor
SHA256("account:TypeName")[:8] en 0.32.1.
Nativo
Elige constantes únicas; documenta en IDL.
Notas de Rust
// Incluye el discriminador en ESPACIO: 8 + cuerpoErrores Comunes
- Sin discriminador - Cuenta de token analizada como estado personalizado. Solución: Siempre anteponer tipos.
- Discriminadores duplicados - Dos tipos colisionan. Solución: Único por struct.
- Discriminador olvidado en ESPACIO - La serialización se trunca. Solución: Añadir 8 bytes a LEN.
- El cliente inicializa el tipo incorrecto - El manejador de inicialización debe escribir el discriminador. Solución: Establecer solo al crear.
- Cambio de discriminador de actualización - Rompe cuentas. Solución: Nunca cambiar el discriminador en vivo.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| Tipado solo por propietario | Un tipo de cuenta por programa | Programas multotipo |
| Byte de versión solamente | Más simple | Seguridad de tipo más débil |
| Discriminador automático de Anchor | Por defecto | Manual nativo |
Preguntas Frecuentes
¿8 bytes requeridos?
Convención de Anchor; nativo puede diferir si es consistente.
¿Discriminador en Borsh?
Generalmente antepuesto manualmente o con un envoltorio de Anchor.
¿La inicialización establece el discriminador?
Sí, la primera escritura.
¿El cierre borra el discriminador?
Cero datos completos.
¿Discriminador en IDL?
Anchor incluye nombres de cuenta.
¿Ataque de fuerza bruta al discriminador?
No es un límite de seguridad; la coincidencia del diseño es lo que importa.
¿Discriminador de cuenta de token?
El programa de token tiene su propio diseño; es diferente.
¿Múltiples versiones del mismo tipo?
Usar campo de versión después del discriminador.
¿Probar discriminador incorrecto?
LiteSVM prueba negativa.
¿Hash del discriminador?
Interno de Anchor; reproducible.
¿Pub en SDK?
Exportar constantes para clientes.
¿Discriminador cero?
Bytes válidos, pero evitar la ambigüedad de todos los ceros.
Relacionado
- Structs de Borsh - Diseños
- Patrones de Inicialización de Cuentas - Inicialización
- Ataques de Reinicialización - Ataques de confusión
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.