Revision 61a7342f2bffe99ae4547110a7c562e47e89bf53 authored by Marge Bot on 12 December 2022, 15:55:54 UTC, committed by Marge Bot on 12 December 2022, 15:55:54 UTC
Co-authored-by: Pierrick Couderc <pierrick.couderc@nomadic-labs.com> Approved-by: Thomas Letan <lthms@nomadic-labs.com> Approved-by: Emma Turner <1623821-emturner@users.noreply.gitlab.com> See merge request https://gitlab.com/tezos/tezos/-/merge_requests/7075
event.rst
Contract events
===============
Contract events provide a way for contracts to deliver event-like information to external applications.
This mechanism allows off-chain applications to react to Tezos contracts execution.
Sending events
--------------
Contract events can be emitted by invoking the Michelson instruction ``EMIT``.
``EMIT %tag ty`` pops an item of type ``ty`` off the stack and pushes an ``operation`` onto the stack.
The type ascription ``ty`` is special since annotations in ``ty`` are preserved and eventually transmitted
in the event so that indexers have a choice to present the event body with appropriate labels.
Both the ``ty`` type ascription and ``%tag`` are optional.
If ``ty`` is absent, this type is inferred from the type of the top element of the stack.
If ``%tag`` is absent, no tag is attached to the event.
To actually send out the events, most importantly, the produced ``operation``\s must be included in the list of
operations, along with ``TRANSFER_TOKEN`` operations for example, that the contract wants to effect.
Event
-----
Each successful contract execution attaches into the transaction receipt a list of contract events
arranged in the order of appearance in the resultant list of operations.
There, the events are made ready for consumption by services observing the chain.
Example
-------
Suppose a contract wants to emit events with the following type:
::
or (nat %int) (string %str)
Then, this contract may generate an event emission operation with the following instructions.
Note that the ``EMIT`` instruction will emit an event with a tag ``notify_client``.
In addition, it allows indexers to recognise the two variants as ``int`` and ``str`` and,
therefore, be able to present the values with the appropriate variant labels.
::
PUSH string "right";
RIGHT nat;
EMIT %notify_client (or (nat %int) (string %str));
Retrieving events
-----------------
Events successfully emitted can be read off directly from transaction results.
This is typically achieved by making JSON RPCs to the block service.
It will return a list of operations, each including the event entries with the information above.
Here is a sample result from a call, corresponding to the example above.
::
{
"protocol": "ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK",
"hash": "opNX59asPwNZGu2kFiHFVJzn7QwtyaExoLtxdZSm3Q3o4jDdSmo",
// ... fields elided for brevity
"contents": [
{
"kind": "transaction",
// ... fields elided for brevity
"metadata": {
// ... fields elided for brevity
"internal_operation_results": [
{
"kind": "event",
// ... fields elided for brevity
"source": "KT1M1ynE3YXkM7qLZoMppq6szMbBvxX9yQVL",
"nonce": 0,
"type": {
"prim": "or",
"args": [
{
"prim": "nat",
"annots": [
"%int"
]
},
{
"prim": "string",
"annots": [
"%str"
]
}
]
},
"tag": "notify_client",
"payload": {
"prim": "Right",
"args": [
{
"string": "right"
}
]
},
"result": {
"status": "applied",
"consumed_milligas": "1000000"
}
}
]
}
}
]
}
Note that the ``operation`` produced by ``EMIT`` does not constitute a call to any other contract.
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...