Publicación
Comparte tu conocimiento.
Using events for analytics in Sui Move
How do I properly emit events in Sui Move for off-chain indexing? Are there specific patterns or traits I should follow for structured logging?
- Move CLI
- Move
- Smart Contract
Respuestas
3In Sui, events are the primary mechanism for off-chain indexing. Unlike on-chain storage, which persists state in objects, events are lightweight, append-only logs that can be queried through RPC (e.g. suix_getEvents). They don’t affect consensus state directly but provide a structured way to capture what happened during a transaction.
How to Emit Events in Sui Move
- Define an event struct
Must have the drop and copy abilities (so it can be moved into the event stream).
By default, any struct you pass to event::emit is treated as an event.
module analytics::lending { use sui::event; use sui::tx_context::TxContext;
/// Event struct
struct LoanIssued has copy, drop {
borrower: address,
amount: u64,
loan_id: u64,
}
public entry fun issue_loan(borrower: address, amount: u64, loan_id: u64, ctx: &mut TxContext) {
// ... loan logic here ...
event::emit(LoanIssued { borrower, amount, loan_id });
}
}
Off-Chain Consumption
Wallets, explorers, or analytics platforms subscribe to events by package/module/event type.
For example, an indexer can call RPC with a filter:
{
"MoveEventType": "0x
Best Practices for Structured Logging
- Use strongly typed events
Define clear structs with field names (instead of unstructured strings).
This makes off-chain parsing consistent.
- Emit events only for “business logic” state changes
Don’t log trivial state like balance updates already observable on-chain.
Use them for actions: loan issued, NFT minted, auction settled, etc.
- Keep event payloads small
Gas costs scale with payload size.
Log identifiers (object IDs, addresses, amounts) instead of duplicating full state.
- Name events by action
Use verbs like LoanIssued, DepositMade, AuctionClosed.
Makes it easier for indexers and dashboards to track.
- Avoid redundant storage writes
If off-chain analytics can reconstruct history from events, don’t store extra state just for reporting.
Why Prefer Events Over On-Chain Queries?
Gas efficiency: Events don’t require mutating state; appending is cheaper than writing to storage.
Scalability: Indexers can query only the stream of relevant events instead of scanning entire object state.
Immutability: Events are append-only and tied to transaction digests, ensuring auditability.
Flexibility: You can extend analytics (e.g., track borrower behavior, trading volumes) without bloating the on-chain state.
How to Emit Events in Sui Move
- Define an Event Structure
Create a struct that represents the event payload.
Add the drop ability because events are not stored permanently on-chain; they are emitted and discarded.
module my_project::example {
use sui::event;
/// Define the event structure
struct PurchaseEvent has drop {
buyer: address,
item_id: u64,
price: u64,
}
public fun emit_purchase_event(buyer: address, item_id: u64, price: u64) {
let event = PurchaseEvent { buyer, item_id, price };
event::emit(event);
}
}
event::emit is the standard function for emitting events.
Best Practices for Structured Logging
- Use Strongly Typed Structs
Avoid raw strings or arbitrary maps.
Define fields explicitly for predictable indexing.
- Keep Events Lightweight
Emit only essential information (IDs, addresses, numeric values).
Do not include large data like metadata or JSON.
- Emit Events at Critical Points
Actions like mint, transfer, burn, or state transitions (e.g., auction closed, order executed).
- Version Your Event Structures
If you upgrade a module, consider adding version suffix (e.g., PurchaseEventV2) for backward compatibility.
- Ensure Deterministic Ordering
Events should reflect the order of operations for easy reconstruction of history off-chain.
✅ How to Query Events Off-Chain
Use Sui’s RPC or Indexer API:
sui_getEvents or GraphQL endpoints can query by:
Event type (module + struct name)
Sender address
Transaction digest
Example:
sui_getEvents(filter: { MoveEventType: "0x2::my_project::PurchaseEvent" })
Tools like Sui Indexer, Kafka event streams, or custom indexer can subscribe to these events for analytics.
Security Consideration
Do not rely on events for on-chain logic because they are not part of state.
Only use events for off-chain analytics, notifications, and dashboards.
Sabes la respuesta?
Inicie sesión y compártalo.
Move is an executable bytecode language used to implement custom transactions and smart contracts.
Gana tu parte de 1000 Sui
Gana puntos de reputación y obtén recompensas por ayudar a crecer a la comunidad de Sui.