Skip to main content

Events

· 3 min read
Benoit Rognier

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

This feater was suggested by Nomadic Labs. Thank you to Bruno Bernardo for the event well mechanism.

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 well

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

The code of the event well contract is then:

archetype event_well

entry %event(arg : bytes) {}

The event well 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_well = KT1AHVF5m8XaWPQCGgfAsZ9eSJJZ7WVGV2hE;
transfer 0tz to event_well 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.