Please note that zkApp programmability is not yet available on Mina Mainnet, but zkApps can now be deployed to Berkeley Testnet.
Events
Events are public arbitrary information that can be passed along with a transaction. Say, your zkApp allows users to publish a message -- those messages could be events!
Another use case for events are zkApps which keep some large internal state, and only store a commitment to that internal state on-chain. For example, a Merkle tree where only the root is stored in on-chain state. Events enable to attach the full information of state changes in transactions. In the Merkle tree example, this could mean sending any Merkle leaves that are changed by the transaction as events. This means that an observer of these transactions can follow along and keep track of the full Merkle tree on their side.
To use events, you have to declare an events
field at the top level of your smart contract. It contains the names and types of your events. Here's an example:
class MyContract extends SmartContract {
events = {
'add-merkle-leaf': Field,
'update-merkle-leaf': Field,
};
}
In this example, we declare events called "add-merkle-leaf"
and "update-merkle-leaf"
, both with a type of Field
. Instead of Field
, you can also use other built-in SnarkyJS types as well as any Struct
. (In fact, a custom Struct
is probably better-suited to encode leaves of a Merkle tree -- we just use Field
for simplicity here.)
After declaring your events, you can use this.emitEvent(name, event)
in any smart contract method, where event
has to have the type you declared for that name
. Example:
class MyContract extends SmartContract {
events = {
"add-merkle-leaf": Field,
"update-merkle-leaf": Field,
}
@method updateMerkleTree(leaf: Field, ...) {
this.emitEvent("update-merkle-leaf", leaf);
// ...
}
}
Some other important facts about events:
- Events are not stored on-chain. Only events from the most recent couple of transactions are retained by consensus nodes. After that, they will be discarded, but are still accessible on archive nodes. In the near future, we plan to add an API to easily fetch events from an archive node.
- You can't refer to previously emitted events in a smart contract, because there is no way of proving that the events you refer to are actually the events emitted by that contract.
This is all you need to know about events! Think of them as a convenience feature -- a light-weight way of attaching information about your smart contract execution, which would otherwise get lost. Don't treat them as fully-fledged storage which can be safely accessed in smart contracts.
Events: API reference
class SmartContract {
static events?: Record<string, any>;
emitEvent(name: string, event: any): void;
}
Events vs Actions
Events and Actions are two distinct mechanisms for logging information alongside a transaction. Events are not meant for use within proofs directly as they can't be predicated on inside proofs. Events are used to signal to UIs, but can also be used for reconstructing merkle trees as we see above. Actions, on the other hand, can be accessed within provable code via Reducers. Both Events and Actions are not stored in the ledger and only exist on the transaction.