A journey into Gno.land

the evolution of smart contract -- Eth Seoul

3 June 2023

Manfred Touron

VP Eng., Gno.land

History of Smart Contracts

2

1994, the inception of smart contracts

3

2009, smart contracts meet blockchain

4

2015, the dawn of complex smart contracts

5

2019, the rise of WASM smart contracts

6

quick recap

7

Gno.land

8

Gno: a new era in smart contracting

9

Why Go?

10

Go, but why Gno?

11

Gno: intuitive VM

EVM

  1. program code (Solidity) ->
  2. EVM bytecode (new low-level construct) ->
  3. EVM implementation (C++/Go/Python/Rust)

GnoVM, everything is Go

  1. program code (Go) ->
  2. Go AST (if, else, func, struct, etc) ->
  3. GnoVM implementation (Go)
12

Gno: auto-persistence

// realm package gno.land/r/manfred/demo

var x int

func Incr() {
    x += 1
}
13

Gno vs Solidity

// contract 0x503b6dd2fc5b285cdfef...
// address, code, obfuscated.
pragma solidity ^0.8.17;

contract Primitives {
    uint x = 0;

    function incr() public {
        x += 1;
    }
}
14

Gno vs Rust/WASM

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
    deps: DepsMut,
    _env: Env,
    info: MessageInfo,
    msg: ExecuteMsg,
) -> Result<Response, ContractError> {
    match msg {
        ExecuteMsg::Increment {} => increment(deps),
    }
}

pub fn increment(deps: DepsMut) -> Result<Response, ContractError> {
    STATE.update(deps.storage, |mut state| -> Result<_, ContractError> {
        state.count += 1;
        Ok(state)
    })?;

    Ok(Response::new().add_attribute("method", "increment"))
}
15

Gno vs Go/CosmWasm

func executeEnqueue(deps *std.Deps, _ types.Env, _ types.MessageInfo, enqueue *Enqueue) (*types.Response, error) {
    iter := deps.Storage.Range(nil, nil, std.Descending)
    nextKey := []byte{FirstKey}
    dbKey, _, err := iter.Next()
    if err == nil {
        nextKey[0] = dbKey[0] + 1
    }
    value, err := (Item{Value: enqueue.Value}).MarshalJSON()
    if err != nil {
        return nil, err
    }
    deps.Storage.Set(nextKey, value)
    return &types.Response{}, nil
}
16

Gno vs CosmosSDK

// cli/cli.go, msg.go, handler.go, >keeper.go<
//  * keeper/handler pattern, "ctx", binary codec, determinism
import (
    "github.com/gnolang/gno/pkgs/sdk"
)

type Keeper struct{ storeKey storetypes.StoreKey } // expected to be prefix store.

func (k *Keeper) Incr(sdk.Context) {
    store := ctx.KVStore(k.storeKey)
    bz := store.Get("x")
    if bz == nil {
        panic("XXX")
    }
    x, err := strconv.Atoi(bz)
    if err != nil {
        panic("XXX")
    }
    x += 1 // all we wanted
    bz = strconv.Itoa(x)
    store.Set("x", bz)
}
17

Gno vs Go

package counter

import (
    "io/ioutil"
    "strconv"
)

func IncrementCounter() (int, error) {
    counterBytes, err := ioutil.ReadFile("counter.txt")
    if err != nil {
        return 0, err
    }
    counter, err := strconv.Atoi(string(counterBytes))
    if err != nil {
        return 0, err
    }
    counter += 1
    err = ioutil.WriteFile("counter.txt", []byte(strconv.Itoa(counter)), 0644)
    if err != nil {
        return 0, err
    }
    return counter, nil
}
18

Gno: auto-merkleization

// user-defined data-structures
// gno.land/p/demo/avl/node.gno

type Node struct {
    key       string
    value     interface{}
    height    int8
    size      int
    leftNode  *Node
    rightNode *Node
}
19

Gno: imports, as simple as in web2

// gno.land/r/moul/basics/import/v1/contract.gno

import (
    "gno.land/p/demo/avl"
    "gno.land/p/demo/dom"
)

func Render(path string) string {
    thread := dom.Plot{Name: "Hello!"}
    thread.AddPost("Foo", "foo foo foo")
    thread.AddPost("Bar", "bar bar bar")
    return thread.String()
}
20

Gno GRC721 example

package grc721

type IGRC721 interface {
    BalanceOf(owner std.Address) (uint64, error)
    OwnerOf(tid TokenID) (std.Address, error)
    SafeTransferFrom(from, to std.Address, tid TokenID) error
    TransferFrom(from, to std.Address, tid TokenID) error
    Approve(approved std.Address, tid TokenID) error
    SetApprovalForAll(operator std.Address, approved bool) error
    GetApproved(tid TokenID) (std.Address, error)
    IsApprovedForAll(owner, operator std.Address) bool
}
21

Gno: a well-known, new language

22

Gno: not only for DeFi

// from gno.land/r/demo/boards/post.gno

// A Post is a "thread" or a "reply" depending on context.
// A thread is a Post of a Board that holds other replies.
type Post struct {
    board       *Board
    id          PostID
    creator     std.Address
    title       string // optional
    body        string
    replies     avl.Tree // Post.id -> *Post
    repliesAll  avl.Tree // Post.id -> *Post (all replies, for top-level posts)
    reposts     avl.Tree // Board.id -> Post.id
    threadID    PostID   // original Post.id
    parentID    PostID   // parent Post.id (if reply or repost)
    repostBoard BoardID  // original Board.id (if repost)
    createdAt   time.Time
    updatedAt   time.Time
}
23

Gno.land: your GitHub for contracts

24

Gno: interchain & scalability

25

Gno.land: proof of contributions, governance

26

Action Items

27

Thank you

Manfred Touron

VP Eng., Gno.land

Use the left and right arrow keys or click the left and right edges of the page to navigate between slides.
(Press 'H' or navigate to hide this message.)