Skip to content

Commit

Permalink
feat(docs): emit/event docs (gnolang#2047)
Browse files Browse the repository at this point in the history
<!-- please provide a detailed description of the changes made in this
pull request. -->

## Description

This PR adds docs for emit/event. It adds reference docs, and a section
in effective Gno. More practical examples will be added to Gno By
Example.

Closes: gnolang#2003 

<details><summary>Contributors' checklist...</summary>

- [ ] Added new tests, or not needed, or not feasible
- [ ] Provided an example (e.g. screenshot) to aid review or the PR is
self-explanatory
- [ ] Updated the official documentation or not needed
- [ ] No breaking changes were made, or a `BREAKING CHANGE: xxx` message
was included in the description
- [ ] Added references to related issues and PRs
- [ ] Provided any useful hints for running manual tests
- [ ] Added new benchmarks to [generated
graphs](https://gnoland.github.io/benchmarks), if any. More info
[here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
</details>

---------

Co-authored-by: Lee ByeongJun <[email protected]>
  • Loading branch information
leohhhn and notJoon authored May 13, 2024
1 parent 98c1d64 commit 977a3f4
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 3 deletions.
67 changes: 67 additions & 0 deletions docs/concepts/effective-gno.md
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,73 @@ actual logic. This way, `privateMethod` can only be called from within the
realm, and it can use the caller's address for authentication or authorization
checks.

### Emit Gno events to make life off-chain easier

Gno provides users the ability to log specific occurrences that happened in their
on-chain apps. An `event` log is stored in the ABCI results of each block, and
these logs can be indexed, filtered, and searched by external services, allowing
them to monitor the behaviour of on-chain apps.

It is good practice to emit events when any major action in your code is
triggered. For example, good times to emit an event is after a balance transfer,
ownership change, profile created, etc. Alternatively, you can view event emission
as a way to include data for monitoring purposes, given the indexable nature of
events.

Events consist of a type and a slice of strings representing `key:value` pairs.
They are emitted with the `Emit()` function, contained in the `std` package in
the Gno standard library:

```go
package events

import (
"std"
)

var owner std.Address

func init() {
owner = std.PrevRealm().Addr()
}

func ChangeOwner(newOwner std.Address) {
caller := std.PrevRealm().Addr()

if caller != owner {
panic("access denied")
}

owner = newOwner
std.Emit("OwnershipChange", "newOwner", newOwner.String())
}

```
If `ChangeOwner()` was called in, for example, block #43, getting the `BlockResults`
of block #43 will contain the following data:

```json
{
"Events": [
{
"@type": "/tm.gnoEvent",
"type": "OwnershipChange",
"pkg_path": "gno.",
"func": "ChangeOwner",
"attrs": [
{
"key": "newOwner",
"value": "g1zzqd6phlfx0a809vhmykg5c6m44ap9756s7cjj"
}
]
}
// other events
]
}
```

Read more about events [here](./stdlibs/events.md).

### Contract-level access control

In Gno, it's a good practice to design your contract as an application with its
Expand Down
3 changes: 1 addition & 2 deletions docs/concepts/stdlibs/coin.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ The `Coins` slice can be included in a transaction made by a user addresses or a
Coins in this set are then available for access by specific types of Bankers,
which can manipulate them depending on access rights.

[//]: # (TODO ADD LINK TO Effective GNO)
Read more about coins in the [Effective Gno](https://docs.gno.land/concepts/effective-gno/#native-tokens) section.
Read more about coins in the [Effective Gno](../effective-gno.md#coins) section.

The Coin(s) API can be found in under the `std` package [reference](../../reference/stdlibs/std/coin.md).
57 changes: 57 additions & 0 deletions docs/concepts/stdlibs/events.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
id: events
---

# Gno Events

## Overview

Events in Gno are a fundamental aspect of interacting with and monitoring
on-chain applications. They serve as a bridge between the on-chain environment
and off-chain services, making it simpler for developers, analytics tools, and
monitoring services to track and respond to activities happening in Gno.land.

Gno events are pieces of data that log specific activities or changes occurring
within the state of an on-chain app. These activities are user-defined; they might
be token transfers, changes in ownership, updates in user profiles, and more.
Each event is recorded in the ABCI results of each block, ensuring that action
that happened is verifiable and accessible to off-chain services.

## Emitting Events

To emit an event, you can use the `Emit()` function from the `std` package
provided in the Gno standard library. The `Emit()` function takes in a string
representing the type of event, and an even number of arguments after representing
`key:value` pairs.

Read more about events & `Emit()` in
[Effective Gno](../effective-gno.md#emit-gno-events-to-make-life-off-chain-easier),
and the `Emit()` reference [here](../../reference/stdlibs/std/chain.md#emit).

## Data contained in a Gno Event

An event contained in an ABCI response of a block will include the following
data:

``` json
{
"@type": "/tm.gnoEvent", // TM2 type
"type": "OwnershipChange", // Type/name of event defined in Gno
"pkg_path": "gno.land/r/demo/example", // Path of the emitter
"func": "ChangeOwner", // Gno function that emitted the event
"attrs": [ // Slice of key:value pairs emitted
{
"key": "oldOwner",
"value": "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"
},
{
"key": "newOwner",
"value": "g1zzqd6phlfx0a809vhmykg5c6m44ap9756s7cjj"
}
]
}
```

You can fetch the ABCI response of a specific block by using the `/block_results`
RPC endpoint.

16 changes: 15 additions & 1 deletion docs/reference/stdlibs/std/chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,19 @@ std.AssertOriginCall()
```
---

## Emit
```go
func Emit(typ string, attrs ...string)
```
Emits a Gno event. Takes in a **string** type (event identifier), and an even number of string
arguments acting as key-value pairs to be included in the emitted event.

#### Usage
```go
std.Emit("MyEvent", "myKey1", "myValue1", "myKey2", "myValue2")
```
---

## CurrentRealmPath
```go
func CurrentRealmPath() string
Expand Down Expand Up @@ -117,7 +130,8 @@ currentRealm := std.CurrentRealm()
```go
func PrevRealm() Realm
```
Returns the previous caller realm (can be realm or EOA). If caller is am EOA, `pkgpath` will be empty.
Returns the previous caller realm (can be code or user realm). If caller is a
user realm, `pkgpath` will be empty.

#### Usage
```go
Expand Down

0 comments on commit 977a3f4

Please sign in to comment.