0x1::EventThe Event module defines an EventHandleGenerator that is used to create
EventHandles with unique GUIDs. It contains a counter for the number
of EventHandles it generates. An EventHandle is used to count the number of
events emitted to a handle and emit events to the event store.
EventHandleGeneratorEventHandlepublish_generatorfresh_guidnew_event_handleemit_eventwrite_to_event_storedestroy_handleuse 0x1::BCS;
use 0x1::Errors;
use 0x1::Signer;
use 0x1::Vector;
EventHandleGeneratorA resource representing the counter used to generate uniqueness under each account. There won’t be destructor for this resource to guarantee the uniqueness of the generated handle.
struct EventHandleGenerator has key
counter: u64
addr: address
EventHandleA handle for an event such that:
struct EventHandle<T: drop, store> has store
counter: u64
guid: vector<u8>
The event generator resource was in an invalid state
const EEVENT_GENERATOR: u64 = 0;
publish_generatorPublishs a new event handle generator.
public fun publish_generator(account: &signer)
public fun publish_generator(account: &signer) {
let addr = Signer::address_of(account);
assert!(!exists<EventHandleGenerator>(addr), Errors::already_published(EEVENT_GENERATOR));
move_to(account, EventHandleGenerator{ counter: 0, addr })
}
fresh_guidDerive a fresh unique id by using sender’s EventHandleGenerator. The generated vector
fun fresh_guid(counter: &mut Event::EventHandleGenerator): vector<u8>
fun fresh_guid(counter: &mut EventHandleGenerator): vector<u8> {
let sender_bytes = BCS::to_bytes(&counter.addr);
let count_bytes = BCS::to_bytes(&counter.counter);
counter.counter = counter.counter + 1;
// EventHandleGenerator goes first just in case we want to extend address in the future.
Vector::append(&mut count_bytes, sender_bytes);
count_bytes
}
new_event_handleUse EventHandleGenerator to generate a unique event handle for sig
public fun new_event_handle<T: drop, store>(account: &signer): Event::EventHandle<T>
public fun new_event_handle<T: drop + store>(account: &signer): EventHandle<T>
acquires EventHandleGenerator {
let addr = Signer::address_of(account);
assert!(exists<EventHandleGenerator>(addr), Errors::not_published(EEVENT_GENERATOR));
EventHandle<T> {
counter: 0,
guid: fresh_guid(borrow_global_mut<EventHandleGenerator>(addr))
}
}
emit_eventEmit an event with payload msg by using handle_ref’s key and counter.
public fun emit_event<T: drop, store>(handle_ref: &mut Event::EventHandle<T>, msg: T)
public fun emit_event<T: drop + store>(handle_ref: &mut EventHandle<T>, msg: T) {
let guid = *&handle_ref.guid;
write_to_event_store<T>(guid, handle_ref.counter, msg);
handle_ref.counter = handle_ref.counter + 1;
}
write_to_event_storeNative procedure that writes to the actual event stream in Event store This will replace the “native” portion of EmitEvent bytecode
fun write_to_event_store<T: drop, store>(guid: vector<u8>, count: u64, msg: T)
native fun write_to_event_store<T: drop + store>(guid: vector<u8>, count: u64, msg: T);
destroy_handleDestroy a unique handle.
public fun destroy_handle<T: drop, store>(handle: Event::EventHandle<T>)
public fun destroy_handle<T: drop + store>(handle: EventHandle<T>) {
EventHandle<T> { counter: _, guid: _ } = handle;
}
Functions of the event module are mocked out using the intrinsic pragma. They are implemented in the prover’s prelude.
pragma intrinsic = true;