Friedger | Blog
December 19, 2023
8 min read

Synthetic Events in Stacks

Synthetic Events in Stacks

Most blockchains have a way to inform users about events that happened in a smart contract. Some events are emitted by default, others are defined explicitly by code in the contract.

In Stacks, all changes involving a fungible or non-fungible token create events. For example, transferring the SIP-10 token ALEX emits a transfer event of the underlying native token SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.age000-governance-token::alex

The node api shows these events like this:

Printing Events

Developers can define events by using the print function in smart contracts. For example, in a transfer of a SIP-10 tokens the memo is printed after the underlying native token was transferred. This allows exchanges to use the memos to associate tokens to user accounts. The print function does not do anything else and returns the argument as is. Here is a snippet from the transfer function of a token:

(try! (ft-transfer? abc amount sender recipient))
(print memo)

There can be more complex events like notifications when meta data of tokens or nfts are updated (SIP-19). They look like this:

(print { notification: "token-metadata-update", payload: { token-class: "nft", contract-id: (as-contract tx-sender) }})

Or events when buying an nft on a non-custodial marketplace:

(print {a: "buy-in-ustx", id: id})

Synthetic Events

Apart from token events and print events, there is a third class of events: so-called synthetic events. These events are created by the stacks node if certain smart contract functions are called even though there are no print calls in the function.

Currently, there are only synthetic events for the stacking contract pox-3, pox-2, pox. If a user stack stx tokens, joins a stacking pool or the pool operator manages the stacking pool, then a the stack node creates an event, a synthetic event because there is no print call in the whole pox contract. By the way, these events are stored in a separate table of the stacks blockchain api for easy consumption and calculations of the current stacking state of users.

The reason for using synthetic events is that these events can be adjusted without a hard fork.

There is a discussion whether this concept can be generalised so that more synthetic events can be created for more smart contracts that are deployed. Currently, there is a big burden on developers to add all events (via print) in advance to a contract without knowing all use cases. If a new use case comes up that would require a new event, then the contract needs to be upgraded to a new version. Synthetic events could help. However, this needs to be implemented in the Stacks node directly. Currently, the main focus of the core team is on the upcoming Stacks 3.0/Nakamoto hard fork. Therefore, we won’t see generalised synthetic events in the near future. Join the discussion on github.com/stacks-network/stacks-core.

Note: during the research for this post, I was looking for events that are emitted when stacked STX are auto-unlocked in case that a stacker did not meet the minimum stacked STX for at least 1 stacking slot. Until now, I haven’t found an answer whether these events are created or not.