Skip to main content

Module sui::event

Events module. Defines the sui::event::emit function which creates and sends a custom MoveEvent as a part of the effects certificate of the transaction.

Every MoveEvent has the following properties:

  • sender
  • type signature (T)
  • event data (the value of T)
  • timestamp (local to a node)
  • transaction digest

Example:

module my::marketplace {
use sui::event;
/* ... */
struct ItemPurchased has copy, drop {
item_id: ID, buyer: address
}
entry fun buy(/* .... */) {
/* ... */
event::emit(ItemPurchased { item_id: ..., buyer: .... })
}
}
use std::address;
use std::ascii;
use std::bcs;
use std::option;
use std::string;
use std::type_name;
use std::vector;
use sui::accumulator;
use sui::address;
use sui::dynamic_field;
use sui::hash;
use sui::hex;
use sui::object;
use sui::transfer;
use sui::tx_context;

Struct EventStreamHead

public struct EventStreamHead has store
Click to open
Fields
root: vector<u8>
Merkle root for all events in the current checkpoint.
prev: vector<u8>
Hash of the previous version of the head object.

Struct EventStream

public struct EventStream has store
Click to open
Fields

Struct EventStreamCap

public struct EventStreamCap has key, store
Click to open
Fields
id: sui::object::UID
stream_id: address

Constants

const ENotSystemAddress: u64 = 0;

Function emit

Emit a custom Move event, sending the data offchain.

Used for creating custom indexes and tracking onchain activity in a way that suits a specific application the most.

The type T is the main way to index the event, and can contain phantom parameters, eg emit(MyEvent<phantom T>).

public fun emit<T: copy, drop>(event: T)
Click to open
Implementation
public native fun emit<T: copy + drop>(event: T);

Function update_head

entry fun update_head(accumulator_root: &mut sui::accumulator::Accumulator, stream_id: address, new_root: vector<u8>, ctx: &sui::tx_context::TxContext)
Click to open
Implementation
entry fun update_head(accumulator_root: &mut accumulator::Accumulator, stream_id: address, new_root: vector<u8>, ctx: &TxContext) {
    assert!(ctx.sender() == @0x0, ENotSystemAddress);
    let name = accumulator::get_accumulator_field_name<EventStreamHead>(stream_id);
    let accumulator_root_id = accumulator_root.id();
    if (dynamic_field::exists_with_type<accumulator::Key, EventStreamHead>(accumulator_root_id, name)) {
        let head: &mut EventStreamHead = dynamic_field::borrow_mut(accumulator_root_id, name);
        let prev_bytes = bcs::to_bytes(head);
        let prev = hash::blake2b256(&prev_bytes);
        head.prev = prev;
        head.root = new_root;
    } else {
        let head = EventStreamHead {
            root: new_root,
            prev: address::to_bytes(address::from_u256(0)),
        };
        dynamic_field::add(accumulator_root_id, name, head);
    };
}

Function new_event_stream

public fun new_event_stream(ctx: &mut sui::tx_context::TxContext): sui::event::EventStream
Click to open
Implementation
public fun new_event_stream(ctx: &mut TxContext): EventStream {
    EventStream {
        name: object::new(ctx),
    }
}

Function destroy_stream

public fun destroy_stream(stream: sui::event::EventStream)
Click to open
Implementation
public fun destroy_stream(stream: EventStream) {
    let EventStream { name } = stream;
    name.delete();
}

Function get_cap

public fun get_cap(stream: &sui::event::EventStream, ctx: &mut sui::tx_context::TxContext): sui::event::EventStreamCap
Click to open
Implementation
public fun get_cap(stream: &EventStream, ctx: &mut TxContext): EventStreamCap {
    EventStreamCap {
        id: object::new(ctx),
        stream_id: stream.name.to_address(),
    }
}

Function default_event_stream_cap

public fun default_event_stream_cap<T: copy, drop>(ctx: &mut sui::tx_context::TxContext): sui::event::EventStreamCap
Click to open
Implementation
public fun default_event_stream_cap<T: copy + drop>(ctx: &mut TxContext): EventStreamCap {
    EventStreamCap {
        id: object::new(ctx),
        stream_id: type_name::get_original_package_id<T>(),
    }
}

Function destroy_cap

public fun destroy_cap(cap: sui::event::EventStreamCap)
Click to open
Implementation
public fun destroy_cap(cap: EventStreamCap) {
    let EventStreamCap { id, .. } = cap;
    id.delete();
}

Function emit_authenticated

public fun emit_authenticated<T: copy, drop>(cap: &sui::event::EventStreamCap, event: T)
Click to open
Implementation
public fun emit_authenticated<T: copy + drop>(cap: &EventStreamCap, event: T) {
    let accumulator_addr = accumulator::get_accumulator_field_address<EventStreamHead>(cap.stream_id);
    emit_authenticated_impl<EventStreamHead, T>(accumulator_addr, cap.stream_id, event);
}

Function emit_authenticated_impl

TODO: needs verifier rule like emit to ensure it is only called in package that defines T Like emit, but also adds an on-chain committment to the event to the stream stream.

fun emit_authenticated_impl<StreamHeadT, T: copy, drop>(accumulator_id: address, stream: address, event: T)
Click to open
Implementation
native fun emit_authenticated_impl<StreamHeadT, T: copy + drop>(accumulator_id: address, stream: address, event: T);