Fundamentos de Serialización
10 ejemplos para empezar con la Serialización de Cuentas: 7 básicos y 3 intermedios.
Prerrequisitos
- Familiaridad con Borsh de Rust para Solana.
Ejemplos Básicos
1. Struct de cuenta Borsh
Serializa el estado estructurado en datos de cuenta.
#[derive(BorshSerialize, BorshDeserialize)]
pub struct Config { pub fee_bps: u16 }- Opción predeterminada para estados pequeños/medianos.
- Fácil versionado con campos adicionales al final.
- El coste de cómputo escala con el tamaño.
2. Constante de tamaño de cuenta
Declara previamente el espacio para create_account.
impl Config { pub const LEN: usize = 2; }- Un desajuste causa un fallo de serialización.
- Incluye los bytes del discriminador en el total.
InitSpacede Anchor se calcula automáticamente.
3. Prefijo discriminador
Etiqueta el tipo de cuenta para evitar confusiones.
pub const DISCRIMINATOR: [u8; 8] = [0xC0, 0xFF, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x01];- Anchor usa discriminadores hash de 8 bytes.
- Comprueba antes de deserializar.
- Los tipos diferentes deben ser distintos.
4. Guardia de deserialización
Valida la longitud y el discriminador primero.
if data.len() < Config::LEN { return Err(ProgramError::InvalidAccountData); }- Nunca deserialices cuentas no confiables.
- Mapea errores a
InvalidAccountData. - Rechaza datos sobrantes para diseños fijos.
5. Zero-copy cuando es grande
Usa Pod para arrays fijos grandes.
#[repr(C)]
#[derive(Pod, Zeroable, Clone, Copy)]
pub struct Book { pub bids: [u64; 256] }- Evita los CUs del bucle de análisis.
- Requiere disciplina
repr(C). - Consulta la página de cuentas zero-copy.
6. Instrucción vs. cuenta
Las instrucciones a menudo usan Borsh; las cuentas pueden ser híbridas.
// ix: enum Instruction { Update { val: u64 } }- Los datos de la instrucción son efímeros por transacción.
- Los datos de la cuenta persisten en la cadena.
- Mantén los esquemas separados.
7. Rent y tamaño
Las cuentas más grandes necesitan más lamports.
let rent = Rent::get()?.minimum_balance(Config::LEN);- Se requiere un mínimo exento de renta.
reallocaumenta la renta necesaria.- Los usuarios pagan en la creación/realloc.
Ejemplos Intermedios
8. Migración de byte de versión
El primer byte indica la versión del esquema.
pub enum Version { V1 = 1, V2 = 2 }- La instrucción de migración lee V1, escribe V2.
- Nunca asumas que todas las cuentas se han actualizado.
- Soporta ambas durante el despliegue.
Relacionado: Versionado y Migración de Datos
9. realloc para crecer
Expande la cuenta cuando el esquema crece.
// CPI realloc + transferencia de renta y luego nuevos campos- Necesita lamports del pagador.
- Cero bytes nuevos o inicialización explícita.
- Consulta el artículo de
realloc.
Relacionado: realloc y Cuentas en Crecimiento
10. Cálculo de espacio
Suma el discriminador + campos + relleno.
pub const SPACE: usize = 8 + Config::LEN;- Documenta la fórmula en el código.
- Prueba en host con serialización.
- Macro
init spacede Anchor.
Relacionado: Cálculo de Espacio
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.