Event
s are objects that contain information about the execution of the application. They are mainly used by service providers like block explorers and wallet to track the execution of various messages and index transactions. {synopsis}
- Anatomy of an SDK application {prereq}
Events are implemented in the Cosmos SDK as an alias of the ABCI Event
type and
take the form of: {eventType}.{eventAttribute}={value}
.
Events contain:
- A
type
, which is meant to categorize an event at a high-level (e.g. by module or action). - A list of
attributes
, which are key-value pairs that give more information about the categorizedevent
. +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/events.go#L51-L56
Events are returned to the underlying consensus engine in the response of the following ABCI messages:
Events, the type
and attributes
, are defined on a per-module basis in the module's
/types/events.go
file, and triggered from the module's handler
via the EventManager
. In addition, each module documents its events under
spec/xx_events.md
.
In Cosmos SDK applications, events are managed by an abstraction called the EventManager
.
Internally, the EventManager
tracks a list of Events
for the entire execution flow of a
transaction or BeginBlock
/EndBlock
.
The EventManager
comes with a set of useful methods to manage events. Among them, the one that is
used the most by module and application developers is the EmitEvent
method, which tracks
an event
in the EventManager
.
Module developers should handle event emission via the EventManager#EmitEvent
in each message
Handler
and in each BeginBlock
/EndBlock
handler. The EventManager
is accessed via
the Context
, where event emission generally follows this pattern:
ctx.EventManager().EmitEvent(
sdk.NewEvent(eventType, sdk.NewAttribute(attributeKey, attributeValue)),
)
Module's handler
function should also set a new EventManager
to the context
to isolate emitted events per message
:
func NewHandler(keeper Keeper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
ctx = ctx.WithEventManager(sdk.NewEventManager())
switch msg := msg.(type) {
See the Handler
concept doc for a more detailed
view on how to typically implement Events
and use the EventManager
in modules.
It is possible to subscribe to Events
via Tendermint's Websocket.
This is done by calling the subscribe
RPC method via Websocket:
{
"jsonrpc": "2.0",
"method": "subscribe",
"id": "0",
"params": {
"query": "tm.event='eventCategory' AND eventType.eventAttribute='attributeValue'"
}
}
The main eventCategory
you can subscribe to are:
NewBlock
: Containsevents
triggered duringBeginBlock
andEndBlock
.Tx
: Containsevents
triggered duringDeliverTx
(i.e. transaction processing).ValidatorSetUpdates
: Contains validator set updates for the block.
These events are triggered from the state
package after a block is committed. You can get the
full list of event
categories here.
The type
and attribute
value of the query
allow you to filter the specific event
you are looking for. For example, a transfer
transaction triggers an event
of type Transfer
and has Recipient
and Sender
as attributes
(as defined in the events
file of the bank
module). Subscribing to this event
would be done like so:
{
"jsonrpc": "2.0",
"method": "subscribe",
"id": "0",
"params": {
"query": "tm.event='Tx' AND transfer.sender='senderAddress'"
}
}
where senderAddress
is an address following the AccAddress
format.
Learn about SDK telemetry {hide}