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 KT1ReVgfaUqHzWWiNRfPXQxf7TaBLVbxrztw
on 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.