Hello Gno

By sborrazas on 2024-06-22

2024-06-22: This post is a draft and there is incorrect information.

Yesterday at Gophercon EU I learned about the Gno project. This blog post offers a quick dive into the project without going too deep.

I’m going to write my take on the project and how to build a very basic app (a counter). I will write everything with my own words in the hope that it will help to grasp the concepts better. You can just go to https://gno.land/ to get the precise and correct information.

Gno is many things:

All these things have different names, but those are the main concepts. This platform/ecosystem is a new paradigm because by storing your code and data in a decentralized way you don’t need to deal with a database or infra anymore (but you will have to start thinking about gas fees, and your users need a wallet to call endpoints).

Enough introduction! Just follow the steps below to get a familiar with the concepts. At the end of the post I will share more details.

Building and deploying a counter app from scratch

To deploy and interact with the app in your local development environment:

  1. Write down the app code
  2. Create a wallet (in gno they call it key). You need a wallet with some balance to deploy and perform actions, so let’s first create the wallet.
  3. Start development server and add some funds to the wallet
  4. Deploy app
  5. Increment and Decrement the counter

Step 1: Write the app

The app it’s a few lines of code:

# For this guide we assume the app source is at ~/go/src/gno-tutorial
# feel free to put the code somewhere else.
# mkdir -p ~/go/src/github.com/gno-tutorial/r/counter/
# cd ~/go/src/github.com/gno-tutorial/r/counter/
# touch counter.gno
# vim counter.gno

package counter

import (
    "gno.land/p/demo/ufmt"
)

var count int

func Increment() {
    count++
}

func Decrement() {
    count--
}

func Render(_ string) string {
    return ufmt.Sprintf("Count: %d", count)
}

Step 2: Create wallet to pay for deployment

In Gno wallets are called “keys”. My preference is the concept of a wallet, so you will see the term key/wallet interchangeably.

Clone repo with Gno tools

# For this guide I assume the code is at ~/go/src/github.com/gnolang
# feel free to put the code somewhere else.
# mkdir -p ~/go/src/github.com/gnolang
# cd ~/go/src/github.com/gnolang
git clone https://github.com/gnolang/gno.git

Run executable to create a key which we will use for testing

cd ~/go/src/github.com/gnolang/gno/gno.land
go run ./cmd/gnokey add MyKey

# Just press enter twice times to create the key
# with no password.
# We will use this key for testing
# Run the same command again to override this key
# Enter a passphrase to encrypt your key to disk:
# <just press enter>
# Repeat the passphrase:
# <just press enter>

# * MyKey (local) - addr: g1hndc2m7qfzj2dyn2ddcxced9w3rv0vvrpfzlcj pub: 
# gpub1pgfj7ard9eg82cjtv4u4xetrwqer2dntxyfzxz3pqv0sse4stv9rmu2f6nkrz2vcml
# 8m0acldwxmpf0anwlyrnxsegnwwgclw4v, path: <nil>

# **IMPORTANT** write this mnemonic phrase in a safe place.
# It is the only way to recover your account if you ever forget your password.
# acoustic digital enact hedgehog recycle village face ketchup ceiling bind menu
# output slight tragic stove helmet furnace fun adjust train couch
# insane defense topple

Step 3: Start development server and add some funds to the wallet

Run dev server binary, and add 1000000000000000ugnot to the key we just created

cd ~/go/src/github.com/gnolang/gno/contribs/gnodev
go run ./cmd/gnodev --add-account MyKey=1000000000000000ugnot

Go to http://localhost:8888 and you should see a nice website that says Welcome to Gno.land, among other things.

Step 4: Deploy to the dev server we just started

Use the gnokey tool to deploy the app using funds from our wallet MyKey

cd ~/go/src/github.com/gnolang/gno/gno.land
go run ./cmd/gnokey maketx addpkg \
                  --pkgpath "gno.land/r/demo/counter" \
                  --pkgdir ~/go/src/github.com/gno-tutorial/r/counter \
                  --gas-fee    1000000ugnot \
                  --gas-wanted 2000000 \
                  --broadcast \
                  --chainid dev \
                  --remote localhost:26657 \
                  MyKey
# Enter password.
# <just press enter>
# OK!
# GAS WANTED: 2000000
# GAS USED:   1464550
# HEIGHT:     132
# EVENTS:     []

Go to http://localhost:8888/r/demo/counter and check out your app! You should see Count: 0 Well done!

Step 5: Increment the counter We will use gnokey again to call Increment function using the funds in MyKey. As you can guess, this is because performing this action will drain more funds from the wallet.

cd ~/go/src/github.com/gnolang/gno/gno.land
go run ./cmd/gnokey maketx call \
                  -pkgpath "gno.land/r/demo/counter" \
                  -func "Increment" \
                  -gas-fee 1000000ugnot \
                  -gas-wanted 2000000 \
                  -send "" \
                  -broadcast \
                  -chainid "dev" \
                  -remote "tcp://127.0.0.1:26657" \
                  MyKey
# Enter password.
# <just press enter>
# OK!
# GAS WANTED: 2000000
# GAS USED:   98103
# HEIGHT:     1936
# EVENTS:     []

Visit http://localhost:8888/r/demo/counter and now you will see Count: 1 🎉

Now let’s do the same but calling Decrement instead:

cd ~/go/src/github.com/gnolang/gno/gno.land
go run ./cmd/gnokey maketx call \
                  -pkgpath "gno.land/r/demo/counter" \
                  -func "Increment" \
                  -gas-fee 1000000ugnot \
                  -gas-wanted 2000000 \
                  -send "" \
                  -broadcast \
                  -chainid "dev" \
                  -remote "tcp://127.0.0.1:26657" \
                  MyKey
# Enter password.
# <just press enter>
# OK!
# GAS WANTED: 2000000
# GAS USED:   98109
# HEIGHT:     3408
# EVENTS:     []

Visit http://localhost:8888/r/demo/counter and now you will see Count: 0 🎉

You wrote, deployed, and interacted with your first Gno app in your computer. Congratulations!

To bring this app to production, and to make it more user friendly, you would deploy your code in https://gno.land and ask your users to use the Adena wallet

There many gotchas related to the Gno project:

  1. You have global variables, and when you change the value of the global variable, the value will be propagated in the network
    1. This is thanks to abstractions provided by the VM
    2. This has many implications, suddenly you don’t need a database anymore!
    3. This is running in a blockchain so there is a consensus mechanism
  2. To deploy code you have to use funds from the wallet in this blockchain.
  3. To perform actions (such as submit a comment to a blog post) your users will need a wallet and a spend some funds. Not as straightforward as calling an endpoint in the web2, but the trade-off has other benefits (spam is expensive, you don’t need accounts because you have wallet keys, decentralization, resilience, etc.)
  4. The more data you send to the block chain, the more funds you use. Sending 100kb of data it’s going to be expensive, so forget about sending images. This is the same problem of storing images in the Bitcoin blockchain. Just store a URL instead or use something like IPFS which is intended to deal with large amounts of data in a decentralized context.
  5. These are the early days of the project so many things might change, and the documentation is being worked on.
  6. They’re looking forward to contributors. They have a “good first issue” label in the bug tracker.