Skip to main content

Events

· 3 min read
Benoit Rognier
info

Edit : from version 1.3.5, the event sink mechansim is now replaced by native protocol's events from Kathmandu.

We present the new instruction emit to emit an event, in a similar an event is emitted in languages like solidity.

This feature was suggested by Nomadic Labs.

An event is declared with the event keyword, similarly to a record:

event HighestBidIncreased {
bidder : address;
amount : tez
}

The emit instruction is then used in an entrypoint as illustrated below:

entry bid() {
/* ... */
if transferred > highestbid then begin
highestbid := transferred;
emit<HighestBidIncreased>({ source; transferred })
end
}

Event sink deprecated

The emition of an event generates a call to a contract called event sink. This contract provides a single entrypoint named event which takes an argument typed bytes.

The code of the event sink contract is then:

archetype event_sink

entry %event(arg : bytes) {}

The event sink is deployed at the address KT1AHVF5m8XaWPQCGgfAsZ9eSJJZ7WVGV2hE on the mainnet, and at KT1ReVgfaUqHzWWiNRfPXQxf7TaBLVbxrztwon Ithacanet.

Event

The emit instruction builds the event argument as a triplet of:

  • the event name
  • the event annotated Michelson type
  • packed value of the event data

In the example of the HighestBidIncreased presented above, the following emit instruction:

emit<HighestBidIncreased>({ source; transferred })

is equivalent to:

const e = pack((
"HighestBidIncreased",
"pair (address %bidder) (tez %amount)",
pack({
bidder = source;
amount = transferred
})
});
const event_sink = KT1AHVF5m8XaWPQCGgfAsZ9eSJJZ7WVGV2hE;
transfer 0tz to event_sink call event<bytes>(e)

Retrieve events

A Typescript library, called the crank, is available to retrieve event data from a DApp.

The crank receives events from contracts and executes event handler functions.

For example, the handleHBI function below is executed when a HighestBidIncreased event is emitted by the contract:

import { startCrank } from '@completium/event-well-crank'
import {
HighestBidIncreased,
register_HighestBidIncreased } from './bid-bindings.ts'

const contract = "KT1..." // address of the emitter contract

const handleHBI = (hbi : HighestBidIncreased) => {
// ...
console.log(`${hbi.bidder} is now the highest bid bidder.`)
}

// register Handler
register_HighestBidIncreased(contract, handleHBI);

// Start crank
await startCrank();

The HighestBidIncreased type and register_HighestBidIncreased function are bindings code generated by completium CLI:

$ completium-cli generate bindings-ts bid.arl > bid-bindings.ts

DApp example

The Bulb DApp example is available here.

The bulb is switched on/off by receiving events from the bulb contract. The contract is designed as a simplistic state machine with On and Off states. Two events SwitchedOn and SwitchedOff are defined and emitted respectively by switchOn and switchOff entrypoints:

archetype bulb

states = | On | Off

event SwitchedOn {}

event SwitchedOff {}

transition switchOn() {
from Off to On
with effect { emit<SwitchedOn>({}) }
}

transition switchOff() {
from On to Off
with effect { emit<SwitchedOff>({}) }
}

A live bulb demo is available here.