language/move-stdlib/docs/Event.md
<a name="0x1_Event"></a>
0x1::EventThe Event module defines an <code><a href="Event.md#0x1_Event_EventHandleGenerator">EventHandleGenerator</a></code> that is used to create <code><a href="Event.md#0x1_Event_EventHandle">EventHandle</a></code>s with unique GUIDs. It contains a counter for the number of <code><a href="Event.md#0x1_Event_EventHandle">EventHandle</a></code>s it generates. An <code><a href="Event.md#0x1_Event_EventHandle">EventHandle</a></code> 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_handle<a name="0x1_Event_EventHandleGenerator"></a>
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.
<pre><code><b>struct</b> <a href="Event.md#0x1_Event_EventHandleGenerator">EventHandleGenerator</a> has key </code></pre> <details> <summary>Fields</summary> <dl> <dt> <code>counter: u64</code> </dt> <dd> </dd> <dt> <code>addr: address</code> </dt> <dd> </dd> </dl> </details><a name="0x1_Event_EventHandle"></a>
EventHandleA handle for an event such that:
<a name="@Constants_0"></a>
<a name="0x1_Event_EEVENT_GENERATOR"></a>
The event generator resource was in an invalid state
<pre><code><b>const</b> <a href="Event.md#0x1_Event_EEVENT_GENERATOR">EEVENT_GENERATOR</a>: u64 = 0; </code></pre><a name="0x1_Event_publish_generator"></a>
publish_generatorPublishs a new event handle generator.
<pre><code><b>public</b> <b>fun</b> <a href="Event.md#0x1_Event_publish_generator">publish_generator</a>(account: &signer) </code></pre> <details> <summary>Implementation</summary> <pre><code><b>public</b> <b>fun</b> <a href="Event.md#0x1_Event_publish_generator">publish_generator</a>(account: &signer) { <b>let</b> addr = <a href="Signer.md#0x1_Signer_address_of">Signer::address_of</a>(account); <b>assert</b>(!<b>exists</b><<a href="Event.md#0x1_Event_EventHandleGenerator">EventHandleGenerator</a>>(addr), <a href="Errors.md#0x1_Errors_already_published">Errors::already_published</a>(<a href="Event.md#0x1_Event_EEVENT_GENERATOR">EEVENT_GENERATOR</a>)); move_to(account, <a href="Event.md#0x1_Event_EventHandleGenerator">EventHandleGenerator</a>{ counter: 0, addr }) } </code></pre> </details><a name="0x1_Event_fresh_guid"></a>
fresh_guidDerive a fresh unique id by using sender's EventHandleGenerator. The generated vector<u8> is indeed unique because it was derived from the hash(sender's EventHandleGenerator || sender_address). This module guarantees that the EventHandleGenerator is only going to be monotonically increased and there's no way to revert it or destroy it. Thus such counter is going to give distinct value for each of the new event stream under each sender. And since we hash it with the sender's address, the result is guaranteed to be globally unique.
<pre><code><b>fun</b> <a href="Event.md#0x1_Event_fresh_guid">fresh_guid</a>(counter: &<b>mut</b> <a href="Event.md#0x1_Event_EventHandleGenerator">Event::EventHandleGenerator</a>): vector<u8> </code></pre> <details> <summary>Implementation</summary> <pre><code><b>fun</b> <a href="Event.md#0x1_Event_fresh_guid">fresh_guid</a>(counter: &<b>mut</b> <a href="Event.md#0x1_Event_EventHandleGenerator">EventHandleGenerator</a>): vector<u8> { <b>let</b> sender_bytes = <a href="BCS.md#0x1_BCS_to_bytes">BCS::to_bytes</a>(&counter.addr); <b>let</b> count_bytes = <a href="BCS.md#0x1_BCS_to_bytes">BCS::to_bytes</a>(&counter.counter); counter.counter = counter.counter + 1; // <a href="Event.md#0x1_Event_EventHandleGenerator">EventHandleGenerator</a> goes first just in case we want <b>to</b> extend address in the future. <a href="Vector.md#0x1_Vector_append">Vector::append</a>(&<b>mut</b> count_bytes, sender_bytes); count_bytes } </code></pre> </details><a name="0x1_Event_new_event_handle"></a>
new_event_handleUse EventHandleGenerator to generate a unique event handle for <code>sig</code>
<pre><code><b>public</b> <b>fun</b> <a href="Event.md#0x1_Event_new_event_handle">new_event_handle</a><T: drop, store>(account: &signer): <a href="Event.md#0x1_Event_EventHandle">Event::EventHandle</a><T> </code></pre> <details> <summary>Implementation</summary> <pre><code><b>public</b> <b>fun</b> <a href="Event.md#0x1_Event_new_event_handle">new_event_handle</a><T: drop + store>(account: &signer): <a href="Event.md#0x1_Event_EventHandle">EventHandle</a><T> <b>acquires</b> <a href="Event.md#0x1_Event_EventHandleGenerator">EventHandleGenerator</a> { <b>let</b> addr = <a href="Signer.md#0x1_Signer_address_of">Signer::address_of</a>(account); <b>assert</b>(<b>exists</b><<a href="Event.md#0x1_Event_EventHandleGenerator">EventHandleGenerator</a>>(addr), <a href="Errors.md#0x1_Errors_not_published">Errors::not_published</a>(<a href="Event.md#0x1_Event_EEVENT_GENERATOR">EEVENT_GENERATOR</a>)); <a href="Event.md#0x1_Event_EventHandle">EventHandle</a><T> { counter: 0, guid: <a href="Event.md#0x1_Event_fresh_guid">fresh_guid</a>(borrow_global_mut<<a href="Event.md#0x1_Event_EventHandleGenerator">EventHandleGenerator</a>>(addr)) } } </code></pre> </details><a name="0x1_Event_emit_event"></a>
emit_eventEmit an event with payload <code>msg</code> by using <code>handle_ref</code>'s key and counter.
<pre><code><b>public</b> <b>fun</b> <a href="Event.md#0x1_Event_emit_event">emit_event</a><T: drop, store>(handle_ref: &<b>mut</b> <a href="Event.md#0x1_Event_EventHandle">Event::EventHandle</a><T>, msg: T) </code></pre> <details> <summary>Implementation</summary> <pre><code><b>public</b> <b>fun</b> <a href="Event.md#0x1_Event_emit_event">emit_event</a><T: drop + store>(handle_ref: &<b>mut</b> <a href="Event.md#0x1_Event_EventHandle">EventHandle</a><T>, msg: T) { <b>let</b> guid = *&handle_ref.guid; <a href="Event.md#0x1_Event_write_to_event_store">write_to_event_store</a><T>(guid, handle_ref.counter, msg); handle_ref.counter = handle_ref.counter + 1; } </code></pre> </details><a name="0x1_Event_write_to_event_store"></a>
write_to_event_storeNative procedure that writes to the actual event stream in Event store This will replace the "native" portion of EmitEvent bytecode
<pre><code><b>fun</b> <a href="Event.md#0x1_Event_write_to_event_store">write_to_event_store</a><T: drop, store>(guid: vector<u8>, count: u64, msg: T) </code></pre> <details> <summary>Implementation</summary> <pre><code><b>native</b> <b>fun</b> <a href="Event.md#0x1_Event_write_to_event_store">write_to_event_store</a><T: drop + store>(guid: vector<u8>, count: u64, msg: T); </code></pre> </details><a name="0x1_Event_destroy_handle"></a>
destroy_handleDestroy a unique handle.
<pre><code><b>public</b> <b>fun</b> <a href="Event.md#0x1_Event_destroy_handle">destroy_handle</a><T: drop, store>(handle: <a href="Event.md#0x1_Event_EventHandle">Event::EventHandle</a><T>) </code></pre> <details> <summary>Implementation</summary> <pre><code><b>public</b> <b>fun</b> <a href="Event.md#0x1_Event_destroy_handle">destroy_handle</a><T: drop + store>(handle: <a href="Event.md#0x1_Event_EventHandle">EventHandle</a><T>) { <a href="Event.md#0x1_Event_EventHandle">EventHandle</a><T> { counter: _, guid: _ } = handle; } </code></pre> </details><a name="@Module_Specification_1"></a>
Functions of the event module are mocked out using the intrinsic pragma. They are implemented in the prover's prelude.
<pre><code><b>pragma</b> intrinsic = <b>true</b>; </code></pre>Determines equality between the guids of two event handles. Since fields of intrinsic structs cannot be accessed, this function is provided.
<a name="0x1_Event_spec_guid_eq"></a>
<pre><code><b>fun</b> <a href="Event.md#0x1_Event_spec_guid_eq">spec_guid_eq</a><T>(h1: <a href="Event.md#0x1_Event_EventHandle">EventHandle</a><T>, h2: <a href="Event.md#0x1_Event_EventHandle">EventHandle</a><T>): bool { // The implementation currently can just <b>use</b> <b>native</b> equality since the mocked prover // representation does not have the `counter` field. h1 == h2 } </code></pre>