Documentation

English
  • English
  • Russian
Welcome

Advanced Concepts

Build onto what you already learned regarding zkApps and SnarkyJS

This page explores additional topics that require some familiarity with building zkApps, SnarkyJS, and crytography.

Events

Events are 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 CircuitValue. (In fact, a custom CircuitValue 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;
}