Move.

Publication

Partagez vos connaissances.

Satoshi .
Sep 01, 2025
Questions et Réponses avec des Experts

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
2
4
Partager
Commentaires
.

Réponses

4
290697tz.
Sep 3 2025, 02:01

In 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

  1. 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::lending::LoanIssued" }


Best Practices for Structured Logging

  1. Use strongly typed events

Define clear structs with field names (instead of unstructured strings).

This makes off-chain parsing consistent.

  1. 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.

  1. Keep event payloads small

Gas costs scale with payload size.

Log identifiers (object IDs, addresses, amounts) instead of duplicating full state.

  1. Name events by action

Use verbs like LoanIssued, DepositMade, AuctionClosed.

Makes it easier for indexers and dashboards to track.

  1. 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.

4
Meilleure réponse
Commentaires
.
NakaMoto. SUI.
Sep 1 2025, 13:41

How to Emit Events in Sui Move

  1. 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

  1. Use Strongly Typed Structs

Avoid raw strings or arbitrary maps.

Define fields explicitly for predictable indexing.

  1. Keep Events Lightweight

Emit only essential information (IDs, addresses, numeric values).

Do not include large data like metadata or JSON.

  1. Emit Events at Critical Points

Actions like mint, transfer, burn, or state transitions (e.g., auction closed, order executed).

  1. Version Your Event Structures

If you upgrade a module, consider adding version suffix (e.g., PurchaseEventV2) for backward compatibility.

  1. 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.

3
Commentaires
.
acher.
Sep 1 2025, 13:15

When you’re building on Sui, events are the main way to expose structured data for off-chain analytics, dashboards, or marketplace activity tracking. Unlike state changes, which can be heavy and expensive to index, events are lightweight, append-only logs that off-chain indexers can subscribe to.

To emit an event in Move, you define a struct that represents the shape of your event and mark it with the drop ability (so it doesn’t need to persist on-chain). Then you call event::emit<T>() to publish it during execution. A simple pattern looks like this:

module myapp::analytics {
    use sui::event;
    use sui::tx_context::TxContext;

    struct TransferEvent has drop {
        sender: address,
        recipient: address,
        amount: u64,
    }

    public entry fun transfer(recipient: address, amount: u64, ctx: &mut TxContext) {
        let sender = tx_context::sender(ctx);
        // perform your logic here (debit/credit balances)
        
        // emit the event for off-chain indexing
        event::emit(TransferEvent { sender, recipient, amount });
    }
}

Best practices for structured logging in Sui:

  • Keep event fields flat and primitive (address, u64, vector<u8>) so off-chain indexers can easily parse them.
  • Emit one event per action instead of batching complex data into a single event. This makes filtering and aggregation easier.
  • Use consistent naming across modules so different apps can reuse analytics tools (e.g., always call it TransferEvent or MintEvent).
  • If your app evolves, consider versioning your events (e.g., V1, V2) instead of breaking old indexers.

Events don’t persist state on-chain, but they create a reliable stream of business actions (mints, sales, swaps, staking) that off-chain services can index into databases or analytics pipelines. For example, a marketplace can build a leaderboard of top traders by indexing SaleEvents.

1
Commentaires
.
Big Mike.
Sep 4 2025, 00:58

When I design analytics in Sui Move, I rely on the event system because it provides a lightweight and efficient way to expose structured data to off-chain indexers. To emit events, I first define a custom struct that represents the event payload, and I ensure it derives the drop ability since the event will only exist ephemerally on-chain. For example:

module my_dapp::analytics {

    use sui::event;

    struct UserAction has drop {
        user: address,
        action: vector<u8>,
        timestamp: u64,
    }

    public fun emit_user_action(user: address, action: vector<u8>, timestamp: u64) {
        let e = UserAction { user, action, timestamp };
        event::emit(e);
    }
}

I make sure to keep my event structs flat and serializable — avoiding deep nesting or unnecessary complexity — because this makes indexing and querying simpler off-chain.

For structured logging, I follow two patterns:

  1. Consistency in field names and types: I standardize naming across modules so my indexer can aggregate analytics without extra transformations.
  2. Granularity of events: Instead of emitting overly generic events, I design event types around meaningful business actions (e.g., UserAction, AssetTransferred, RewardClaimed).

By following these practices, I can expose precise, structured logs to off-chain systems, making it easier to build dashboards, run analytics pipelines, and trace user behavior in real time.

0
Commentaires
.

Connaissez-vous la réponse ?

Veuillez vous connecter et la partager.

Move is an executable bytecode language used to implement custom transactions and smart contracts.

271Publications618Réponses
Sui.X.Peera.

Gagne ta part de 1000 Sui

Gagne des points de réputation et obtiens des récompenses pour avoir aidé la communauté Sui à se développer.