Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: refactor package & realm concept pages #1469

Closed
wants to merge 45 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
92c0dff
wip save
leohhhn Dec 19, 2023
3eda27c
Merge branch 'master' into docs/pkg-path
leohhhn Dec 19, 2023
f4d2f21
Merge branch 'master' into docs/pkg-path
leohhhn Jan 10, 2024
9c9340a
Merge branch 'master' into docs/pkg-path
leohhhn Jan 10, 2024
5b0fbd3
Merge branch 'master' into docs/pkg-path
leohhhn Jan 17, 2024
d6d7700
add coins link
leohhhn Jan 18, 2024
53620d3
Merge branch 'master' into docs/pkg-path
leohhhn Jan 24, 2024
a38a32d
update realm page
leohhhn Jan 24, 2024
d2f0acf
update realm concept page
leohhhn Jan 24, 2024
70e4d47
fix typo
leohhhn Jan 24, 2024
cbdd6c4
Merge branch 'master' into docs/pkg-path
leohhhn Jan 25, 2024
dcc0721
Merge branch 'master' into docs/pkg-path
leohhhn Mar 26, 2024
2181061
Merge branch 'master' into docs/pkg-path
leohhhn Apr 3, 2024
2f057f7
refactor realm page
leohhhn Apr 3, 2024
ad4b55d
save
leohhhn Apr 3, 2024
76d953b
fixup signature
leohhhn Apr 3, 2024
641ef59
fix capitalization
leohhhn Apr 3, 2024
7eb6cfe
start working w realms section, update chain reference
leohhhn Apr 3, 2024
2105a75
save
leohhhn Apr 3, 2024
c82f622
add diagrams to realm page
leohhhn Apr 3, 2024
a778d9b
add more sections
leohhhn Apr 3, 2024
51adc98
render section
leohhhn Apr 3, 2024
f8817e1
add state persistence parag
leohhhn Apr 3, 2024
ab7f8b3
save
leohhhn Apr 3, 2024
899a387
finish package page
leohhhn Apr 4, 2024
d0848d4
remove coins section in realms
leohhhn Apr 4, 2024
dca0947
revert accidental change to seqid
leohhhn Apr 4, 2024
00e5469
typo
leohhhn Apr 4, 2024
e791bd8
replace interface with any
leohhhn Apr 4, 2024
9fa722c
inline
leohhhn Apr 4, 2024
b633dbc
remove "leftover"
leohhhn Apr 4, 2024
3a857ad
phrasing
leohhhn Apr 4, 2024
a2efdc7
rephrasing
leohhhn Apr 4, 2024
28e23d4
remove breaking change line
leohhhn Apr 5, 2024
306afca
add abci query mention
leohhhn Apr 8, 2024
3fe4c65
add IsUser ref
leohhhn Apr 8, 2024
674e80c
fix prevrealm ref
leohhhn Apr 8, 2024
74024b9
Merge branch 'master' into docs/pkg-path
leohhhn Jun 5, 2024
640a793
Merge branch 'master' into docs/pkg-path
leohhhn Jun 25, 2024
ff79db9
Merge branch 'master' into docs/pkg-path
leohhhn Jun 26, 2024
a0993ca
Merge branch 'master' into docs/pkg-path
leohhhn Sep 11, 2024
9f1c9bb
minor fixups
leohhhn Sep 11, 2024
4a77688
make build
leohhhn Sep 11, 2024
edb9c42
fix links
leohhhn Sep 11, 2024
ee62df0
pure pacakges
leohhhn Sep 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 82 additions & 84 deletions docs/concepts/packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,112 +2,110 @@
id: packages
---

# Packages
# Pure Packages

Packages aim to encompass functionalities that are more closely aligned with the characteristics and capabilities of realms, as opposed to standard libraries. As opposed to realms, they are stateless.
In gno.land, pure packages are Gno code that is meant to be reused by other Gno code,
be it by other pure packages or realms. Here are some defining features of packages:
- Pure packages are stored on-chain under the `"gno.land/p/"` path, and can be
written & deployed on-chain by anyone, permissionlessly
- Pure packages are meant to be imported by other packages & realms
- Pure packages do not persist state - packages can have global variables & constants,
but any attempt to change their values will be discarded,
- Documentation for pure packages should be contained within package code itself,
in the form of comments, following the [Go doc standard](https://tip.golang.org/doc/comment).

The full list of pre-deployed available packages can be found under the [demo package](https://github.com/gnolang/gno/tree/master/examples/gno.land/p/demo). Below are some of the most commonly used packages.
To learn how to write a pure package,
see [How to write a simple Gno Library](../how-to-guides/simple-library.md).

## `avl`
## Commonly used `p/` packages

In Go, the classic key/value data type is represented by the `map` construct. However, while Gno also supports the use of `map`, it is not a viable option as it lacks determinism due to its non-sequential nature.

To address this issue, Gno implements the [AVL Tree](https://en.wikipedia.org/wiki/AVL_tree) (Adelson-Velsky-Landis Tree) as a solution. The AVL Tree is a self-balancing binary search tree.
To better understand how packages work, let's look at a few commonly
used ones. Some of the most commonly used packages live in the
[`examples`](https://github.com/gnolang/gno/tree/master/examples/)
folder on the monorepo, and under the `"gno.land/p/demo"` on-chain path.

The `avl` package comprises a set of functions that can manipulate the leaves and nodes of the AVL Tree.
### Package `avl`

## `grc20`
Deployed under `gno.land/p/demo/avl`, the AVL package provides a tree structure
for storing data. Currently, the AVL package is used to replace the functionality
of the native `map` in Gno, as maps are not fully deterministic and thus do not
work as expected in the language. Here is how using the AVL package from your
realm might look like:

Gno includes an implementation of the `erc20` fungible token standard referred to as `grc20`. The interfaces of `grc20` are as follows:

[embedmd]:# (../assets/explanation/packages/pkg-1.gno go)
```go
func TotalSupply() uint64
func BalanceOf(account std.Address) uint64
func Transfer(to std.Address, amount uint64)
func Approve(spender std.Address, amount uint64)
func TransferFrom(from, to std.Address, amount uint64)
func Allowance(owner, spender std.Address) uint64
```
package myrealm

The role of each function is as follows:
import (
"gno.land/p/demo/avl"
)

* `TotalSupply`: Returns the total supply of the token.
* `BalanceOf`: Returns the balance of tokens of an account.
* `Transfer`: Transfers specific `amount` of tokens from the `caller` of the function to the `to` address.
* `Approve`: Grants the `spender`(also referred to as `operator`) with the ability to send specific `amount` of the `caller`'s (also referred to as `owner`) tokens on behalf of the `caller`.
* `TransferFrom`: Can be called by the `operator` to send specific `amount` of `owner`'s tokens from the `owner`'s address to the `to` address.
* `Allowance`: Returns the number of tokens approved to the `spender` by the `owner`.
// This AVL tree will be persisted after transaction calls
var tree *avl.Tree

Two types of contracts exist in`grc20`:
func Set(key string, value int) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function seems useless, since it's just calling tree.Set

Copy link
Contributor Author

@leohhhn leohhhn Apr 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an example realm and the point of the function is to just expose the Set function from the AVL package to the user. It wasn't meant for anything else. What would you suggest putting here instead?

// tree.Set takes in a string key, and a value that can be of any type
tree.Set(key, value)
}

1. `Banker`
- Implements the token factory with `Helper` functions.
- The underlying struct should not be exposed to users. However, it can return a typecasted `Token` object using the `Token()` method.
2. `Token`
- Implements the `GRC20` interface.
- The underlying struct can be exposed to users. Created with the `Token()` method of `Banker`.
func Get(key string) int {
// tree.Get returns the value at given key in its raw form,
// and a bool to signify the existence of the key-value pair
rawValue, exists := tree.Get(key)
if !exists {
panic("value at given key does not exist")
}

// rawValue needs to be converted into the proper type before returning it
return rawValue.(int)
}
```

## `grc721`
### Package `ufmt`

Gno includes an implementation of the `erc721` non-fungible token standard referred to as `grc721`. The interfaces of `grc721` are as follows:
Deployed under `gno.land/p/demo/ufmt`, the `ufmt` package is a minimal version of
the `fmt` package. From [`ufmt.gno`](https://gno.land/p/demo/ufmt/ufmt.gno):

[embedmd]:# (../assets/explanation/packages/pkg-2.gno go)
```go
// functions that work similarly to those of grc20
func BalanceOf(owner std.Address) (uint64, error)
func Approve(approved std.Address, tid TokenID) error
func TransferFrom(from, to std.Address, tid TokenID) error

// functions unique to grc721
func OwnerOf(tid TokenID) (std.Address, error)
func SafeTransferFrom(from, to std.Address, tid TokenID) error
func SetApprovalForAll(operator std.Address, approved bool) error
func GetApproved(tid TokenID) (std.Address, error)
func IsApprovedForAll(owner, operator std.Address) bool
// Package ufmt provides utility functions for formatting strings, similarly
// to the Go package "fmt", of which only a subset is currently supported
// (hence the name µfmt - micro fmt).
package ufmt
```

`grc721` contains a new set of functions:
View the package on-chain [here](https://gno.land/p/demo/ufmt), or on GitHub,
[here](https://github.com/gnolang/gno/tree/master/examples/gno.land/p/demo/ufmt).

* `OwnerOf`: Returns the `owner`'s address of a token specified by its `TokenID`.
* `SafeTransferFrom`: Equivalent to the `TransferFrom` function of `grc20`.
* The `Safe` prefix indicates that the function runs a check to ensure that the `to` address is a valid address that can receive tokens.
* As you can see from the [code](https://github.com/gnolang/gno/blob/master/examples/gno.land/p/demo/grc/grc721/basic_nft.gno#L341), the concept of `Safe` has yet to be implemented.
* `SetApprovalForAll`: Approves all tokens owned by the `owner` to an `operator`.
* You may not set multiple `operator`s.
* `GetApproved`: Returns the `address` of the `operator` for a token, specified with its `ID`.
* `IsApprovedForAll`: Returns if all NFTs of the `owner` have been approved to the `operator`.
### Package `seqid`

## `testutils`
Deployed under `gno.land/p/demo/seqid`, the `seqid` package provides a simple
way to have sequential IDs in Gno. Its encoding scheme is based on the `cford32`
package. From [`seqid.gno`](https://gno.land/p/demo/seqid/seqid.gno):

The `testutils` package contains a set of functions that comes in handy when testing realms. The sample function below is the commonly used `TestAddress` function that generates a random address.

[embedmd]:# (../assets/explanation/packages/pkg-3.gno go)
```go
func TestAddress(name string) std.Address {
if len(name) > std.RawAddressSize {
panic("address name cannot be greater than std.AddressSize bytes")
}
addr := std.RawAddress{}
// TODO: use strings.RepeatString or similar.
// NOTE: I miss python's "".Join().
blanks := "____________________"
copy(addr[:], []byte(blanks))
copy(addr[:], []byte(name))
return std.Address(std.EncodeBech32("g", addr))
}
// Package seqid provides a simple way to have sequential IDs which will be
// ordered correctly when inserted in an AVL tree.
//
// Sample usage:
//
// var id seqid.ID
// var users avl.Tree
//
// func NewUser() {
// users.Set(id.Next().String(), &User{ ... })
// }
package seqid
```

The code takes the `name` as the input and creates a random address. Below is a list of examples where it's used in the test case of the `foo20` realm.
View the package on-chain [here](https://gno.land/p/demo/seqid), or on GitHub,
[here](https://github.com/gnolang/gno/tree/master/examples/gno.land/p/demo/seqid).

[embedmd]:# (../assets/explanation/packages/pkg-4.gno go)
```go
admin := users.AddressOrName("g1tntwtvzrkt2gex69f0pttan0fp05zmeg5yykv8")
test2 := users.AddressOrName(testutils.TestAddress("test2"))
recv := users.AddressOrName(testutils.TestAddress("recv"))
normal := users.AddressOrName(testutils.TestAddress("normal"))
owner := users.AddressOrName(testutils.TestAddress("owner"))
spender := users.AddressOrName(testutils.TestAddress("spender"))
recv2 := users.AddressOrName(testutils.TestAddress("recv2"))
mibu := users.AddressOrName(testutils.TestAddress("mint_burn"))
```
## Pure packages vs Standard Libraries

Apart from pure packages, Gno, like Go, has standard libraries. To better
understand the difference between these two concepts, let's compare a few
specific points:
- Pure packages can be written and deployed by anyone at any time, while standard
libraries require thorough battle-testing and reviews by the core team & community
before being added to the language
- Standard libraries usually provide low-level necessities for the language,
while pure packages utilize them to create a broader range of functionality
Loading
Loading