Eventos con emit!
Los tipos #[event] y la macro emit! escriben logs estructurados que los indexadores pueden parsear. Prefiere eventos sobre msg! ad-hoc para cambios de estado observables.
Receta
#[event]
pub struct TradeExecuted {
pub user: Pubkey,
pub amount_in: u64,
pub amount_out: u64,
}
emit!(TradeExecuted { user: ctx.accounts.user.key(), amount_in, amount_out });Cuándo usar esto: Los indexadores, analíticas o clientes necesitan observación fiable a posteriori.
Ejemplo de Trabajo
#[event]
pub struct PositionOpened {
pub owner: Pubkey,
pub market: Pubkey,
pub size: u64,
pub timestamp: i64,
}
pub fn open_position(ctx: Context<OpenPosition>, size: u64) -> Result<()> {
let clock = Clock::get()?;
emit!(PositionOpened {
owner: ctx.accounts.owner.key(),
market: ctx.accounts.market.key(),
size,
timestamp: clock.unix_timestamp,
});
Ok(())
}Lo que esto demuestra:
- Eventos registrados en IDL
emit!usa el patrón self-CPI internamente- Los campos deben ser serializables con Borsh
- Los indexadores se suscriben a los logs del programa
Análisis Profundo
Self-CPI
emit! clásico activa un self-CPI en el que algunos indexadores confían. Para una captura garantizada en todos los runtimes, consulta emit_cpi!.
Diseño de Campos
Incluye las claves necesarias para unir datos off-chain; evita grandes bloques en los eventos.
Errores Comunes
- Cargas útiles de eventos enormes - Límites de CU y logs. Solución: Almacena el hash en la cadena, los detalles fuera de la cadena.
msg!solo para depuración - No es interpretable por máquinas. Solución: Usa#[event].- Campos privados no en IDL - Deben ser
puben la struct del evento. Solución: Todos los campos de evento deben serpub. - Emitir secretos - Los logs son públicos. Solución: Nunca emitas claves privadas.
- Evento faltante en la ruta de error - Analíticas incompletas. Solución: Emite antes del fallo o usa eventos de error separados.
Alternativas
| Alternativa | Úsalo Cuando | No lo Uses Cuando |
|---|---|---|
emit_cpi! | Captura fiable | Desarrollo local simple |
| Solo estado de cuenta | No se necesitan logs | Analíticas impulsadas por indexador |
| Geyser gRPC | Requiere mucha infraestructura | Eventos a nivel de aplicación |
Preguntas Frecuentes
¿Formato de error de Anchor 0.32.1?
Códigos personalizados en IDL más strings #[msg].
¿emit! vs emit_cpi!?
emit_cpi! cuesta más CU pero mejora la fiabilidad de captura.
¿Debería usar msg! en mainnet?
Evítalo excepto detrás de flags de características.
¿Cómo obtienen los clientes los códigos de error?
Desde IDL a través de Anchor o la generación de código de Codama.
¿Los eventos aparecen en IDL?
Sí, los tipos #[event] están listados.
¿Pueden las restricciones devolver errores personalizados?
Sí, con @MyError::Variant.
¿Qué usa CU en el logging?
Cada línea de log y string formateado.
¿Cómo probar errores?
anchor test esperando códigos de error.
¿Son los logs datos de consenso?
Sí, pero no un contrato de API; usa eventos.
¿Próxima lectura?
Ver Relacionados para eventos.
Relacionados
- emit_cpi! y Eventos Self-CPI - emit fiable
- Logging y Costo de CU - CU
- Construyendo un Indexador - indexadores
Versiones de Stack: 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.