Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

arena/v0 package

Overview

v0 - Unaudited: This is an initial version that has not yet been formally audited. Use in production at your own risk.

Package arena holds the paid games of gnofly, a multiplayer plane game. A player pays an entry price in ugnot to join a game, the realm keeps the stakes until the game is over, then credits them by a rule it applies itself. Winners take what they are owed with Claim.

Games are created off chain, by the game server at a player's request, and described by a spec (see spec.gno): mode, entry price, seats, lives, game time and kill target. The realm only stores a game once someone paid for it, and forgets it when it is over or its lobby empties: no game nobody played is ever left on chain.

Four kinds of callers write to it:

  • players enter a game with their stake attached, the first one handing the realm its spec, and may leave again until it starts (Enter, Leave);
  • referees, the game servers, start a game with the players of its lobby, and report who died by whose hand when it is over (StartRound, SettleRound, CancelRound);
  • anyone can send the stakes of a game back to its players once the referee is long overdue, and close a lobby whose game never started an hour after it was created (RefundRound, ExpireLobby);
  • the admins of the game realm set the refund delay (SetRefundDelay).

The realm keeps no roles of its own: the owner, the admins, the referees and the treasury are those of gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/game/v0, asked at the time of each call.

The referee is trusted for facts only: who died, and by whom. What these facts are worth is decided by a rule of gno.land/p/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/payout/v0, picked by the mode of the game, and the realm checks what the rule returns before it sends anything.

Money

The realm owes exactly the stakes of its lobbies and of its running games, and the winnings not claimed yet, and counts them in one number, see Escrowed. Every coin that leaves goes to a player of the game it came from, or to the treasury of the game realm:

Example
1Enter        +stake   the envelope of the call stays in the realm
2Leave        -stake   back to the player
3ExpireLobby  -stakes  back to the players of the lobby
4StartRound    0       stakes move from the lobby to the game
5SettleRound  -fee     the fee leaves, the rest is credited to the winners
6Claim        -owed    everything credited to the caller, every game at once
7CancelRound  -pot     back to the players of the game
8RefundRound  -pot     back to the players of the game

A game is closed by exactly one of SettleRound, CancelRound and RefundRound, once.

What a settlement does not pay to the players is the house's cut, a fee of 5% sent to the treasury of the game realm, rounding included.

Reads are plain functions meant for vm/qeval. The ones ending in JSON return a single string holding a JSON document. Render exposes the same data as markdown for gnoweb.

Functions

ArenaJSON

func ArenaJSON(id string) string

ArenaJSON returns one arena in the shape of ArenasJSON, or null.

Param

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0.ArenaJSON()"

Result

ArenasJSON

func ArenasJSON() string

ArenasJSON returns every arena someone paid into and whose game is not over, as a JSON array sorted by id:

Example
1[
2  { "id": "3f2a...", "mode": "deathmatch", "stake": 10000000,
3    "minSeats": 2, "maxSeats": 8, "lives": 3, "seconds": 900, "killTarget": 5,
4    "creator": "g1...", "created": 1790950000, "nonce": "k3x9",
5    "lobby": [ { "address": "g1...", "ticket": "9f86d0...00a08" } ],
6    "round": { "startedAt": 1790950300, "players": [ "g1...", "g1..." ] } }
7]

The output has no whitespace. "round" is null until the game starts. The fields from "mode" to "nonce" are the arena's spec: the game server rebuilds the spec string, and so the id, from them.

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0.ArenasJSON()"

Result

CancelRound

func CancelRound(cur realm, id string)

CancelRound closes the game of an arena without a result: every player gets their stake back in full. Referee only.

The game server uses it for a game it cannot referee, for example one it finds running when it starts.

Param

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0" -func "CancelRound" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "gnoland-1" -remote "https://rpc.gno.land" ADDRESSgnokey query -remote "https://rpc.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0" -func "CancelRound" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "gnoland-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.gno.land" call.tx
  

Claim

func Claim(cur realm) int64

Claim sends the caller everything the realm owes them from settled games, and returns the amount in ugnot. It panics when there is nothing to claim.

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0" -func "Claim" -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "gnoland-1" -remote "https://rpc.gno.land" ADDRESSgnokey query -remote "https://rpc.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0" -func "Claim" -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "gnoland-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.gno.land" call.tx
  

Claimable

func Claimable(addr address) int64

Claimable returns what a player can claim, in ugnot.

Param

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0.Claimable()"

Result

ClaimsJSON

func ClaimsJSON(addr address) string

ClaimsJSON returns what a player can claim, game by game, oldest first:

Example
1{ "address": "g1...", "total": 19000000, "games": [ { "id": "...", "amount": 19000000 } ] }

The output has no whitespace. An address with nothing to claim returns the same shape with a zero total and no game.

Param

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0.ClaimsJSON()"

Result

EarningsJSON

func EarningsJSON() string

EarningsJSON returns the top winners as a JSON array, best first, at most 10 entries:

Example
1[ { "address": "g1...", "won": 19000000, "rounds": 3 } ]

The output has no whitespace. "won" adds up, round after round, what the player was paid above their own stake, never less than zero for a round. "rounds" is how many settled rounds they played. With equal winnings, the player who got there first stays ahead.

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0.EarningsJSON()"

Result

Enter

func Enter(cur realm, spec string, ticket string) string

Enter puts the caller in the lobby of the arena that spec describes, and returns its id. The exact stake must be attached to the transaction (-send "<stake>ugnot") and stays in the realm until the player leaves or the game is over.

The first entry creates the arena, the next ones join it: the realm recomputes the id from the spec every time. An arena takes entries for an hour after it was created, and until its game starts.

ticket is 64 lowercase hex characters, the SHA-256 of a secret the player's client made up: the game server gives the seat to whoever shows the secret.

It must be called directly by a user (maketx call): a call relayed by another realm or by a maketx run script is refused.

Params

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0" -func "Enter" -args $'' -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "gnoland-1" -remote "https://rpc.gno.land" ADDRESSgnokey query -remote "https://rpc.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0" -func "Enter" -args $'' -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "gnoland-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.gno.land" call.tx
  

Escrowed

func Escrowed() int64

Escrowed returns what the realm owes to players, in ugnot: the stakes of every lobby and of every running round. The balance of the realm's address is never below it.

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0.Escrowed()"

Result

ExpireLobby

func ExpireLobby(cur realm, id string)

ExpireLobby closes an arena whose game never started: every player in the lobby gets their stake back, and the arena is deleted. Anyone can call it once the arena stopped taking entries, an hour after it was created.

Param

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0" -func "ExpireLobby" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "gnoland-1" -remote "https://rpc.gno.land" ADDRESSgnokey query -remote "https://rpc.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0" -func "ExpireLobby" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "gnoland-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.gno.land" call.tx
  

Leave

func Leave(cur realm, id string)

Leave takes the caller out of the lobby of an arena and sends their stake back. It works until the game starts. The last player out deletes the arena: nothing is left on chain of a game nobody played.

Param

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0" -func "Leave" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "gnoland-1" -remote "https://rpc.gno.land" ADDRESSgnokey query -remote "https://rpc.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0" -func "Leave" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "gnoland-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.gno.land" call.tx
  

PlayerJSON

func PlayerJSON(addr address) string

PlayerJSON returns one player's totals as a JSON object:

Example
1{ "address": "g1...", "won": 19000000, "rounds": 3 }

The output has no whitespace. An unknown address returns the same shape with zero won and zero rounds.

Param

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0.PlayerJSON()"

Result

RefundDelay

func RefundDelay() int64

RefundDelay returns the refund delay, in seconds.

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0.RefundDelay()"

Result

RefundRound

func RefundRound(cur realm, id string)

RefundRound closes the game of an arena without a result, like CancelRound, and can be called by anyone, once

Example
1startedAt + seconds + RefundDelay()

has passed on the block clock. It is the players' way out when the referee never settles: no stake depends on a server staying up.

Param

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0" -func "RefundRound" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "gnoland-1" -remote "https://rpc.gno.land" ADDRESSgnokey query -remote "https://rpc.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0" -func "RefundRound" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "gnoland-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.gno.land" call.tx
  

Render

func Render(path string) string

Render returns the state of the arenas as markdown, for gnoweb:

Example
1""            the open arenas and the last games played
2"arena/<id>"  one arena: its rules, lobby and game, or its result
3"earnings"    the top winners

Everything printed here was validated against a narrow charset when it was written (see spec.gno and validate.gno), or is an address the chain gave the realm. The only caller-supplied value, the id of an arena page, is printed only if it is a valid id. Nothing needs markdown escaping.

Param

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0.Render()"

Result

ResultJSON

func ResultJSON(id string) string

ResultJSON returns the result of one closed game in the shape of ResultsJSON, or null when the realm does not have it (still running, or too old).

Param

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0.ResultJSON()"

Result

ResultsJSON

func ResultsJSON() string

ResultsJSON returns the last closed games, newest first, at most 50:

Example
1[ { "id": "3f2a...", "mode": "deathmatch", "stake": 10000000,
2    "outcome": "settled", "players": 2, "pot": 20000000, "fee": 500000,
3    "closedAt": 1790951000,
4    "payouts": [ { "address": "g1...", "amount": 19500000 } ] } ]

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0.ResultsJSON()"

Result

SetRefundDelay

func SetRefundDelay(cur realm, seconds int64)

SetRefundDelay sets how long after a game's time limit anyone may refund it. Admin only.

Param

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0" -func "SetRefundDelay" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "gnoland-1" -remote "https://rpc.gno.land" ADDRESSgnokey query -remote "https://rpc.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0" -func "SetRefundDelay" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "gnoland-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.gno.land" call.tx
  

SettleRound

func SettleRound(cur realm, id string, deaths string)

SettleRound closes the game of an arena: it applies the rule of its mode to what happened, pays the players, and pays the fee to the treasury. Referee only.

deaths is "victim:killer" entries separated by ";", in the order they happened, "victim:" when nobody shot the victim down, and the empty string when nobody died. A player dies at most as often as the arena has lives.

The referee is trusted for these facts and for nothing else. The rule refuses a victim or a killer who is not a player of the round, and decides the amounts. The realm then checks them (see settle) before it pays.

Params

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0" -func "SettleRound" -args $'' -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "gnoland-1" -remote "https://rpc.gno.land" ADDRESSgnokey query -remote "https://rpc.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0" -func "SettleRound" -args $'' -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "gnoland-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.gno.land" call.tx
  

StartRound

func StartRound(cur realm, id string) int64

StartRound starts the game of an arena with every player of its lobby. Referee only. The lobby must hold at least minSeats players; it holds at most maxSeats, Enter sees to that. No coin moves: the stakes that were owed to the lobby are now owed to the round. It returns how many play.

Param

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0" -func "StartRound" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "gnoland-1" -remote "https://rpc.gno.land" ADDRESSgnokey query -remote "https://rpc.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0" -func "StartRound" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "gnoland-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.gno.land" call.tx
  

Version

func Version() int64

Version returns a counter that bumps on every admin write: the refund delay. Player and referee actions do not bump it.

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/g1t2kg2vtr3fukg43eujkn6x53gfdyakhngt4sfd/gnofly/arena/v0.Version()"

Result