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

lastwords/v0 package

Overview

Package lastwords is one string, on chain, forever.

There is a single message slot. Pay more than the last writer paid and the slot is yours; when the clock finally runs out, whatever is in it stays there permanently. The artefact at the end is the point, so the game is a bidding war over an epitaph rather than over a prize.

The three rules exist because the obvious version of this game does not end and does not pay:

  1. THE CLOCK TERMINATES. Every write pushes the deadline a fifth of the way to a hard end fixed when the slot opened, and no write can push it past that. A constant extension per action has no end: the pot grows faster than the price of the next write, so there is always a rational next write and the game runs until everyone is bored or broke.
  2. THE LAST WRITER DOES NOT TAKE THE POT. They take the slot, which is what they were bidding for. The pot is split among everyone ELSE who wrote, pro rata to what they paid. Winner-takes-all makes the second-to-last writer the mark and everyone knows it, which is why nobody joins.
  3. HALF OF EVERY PAYMENT GOES TO THE WRITER BEING DISPLACED, immediately. A zero-sum game minus gas has no reason for a second player. Overwriting somebody pays them, so being overwritten early is not a loss.

Nothing is ever pushed: payouts are credited to an internal ledger and swept by Withdraw. A realm that pays inside a loop over its roster is a gas bomb that eventually bricks, and the bigger the game gets the more certain that is.

The pieces are libraries, and the realm is the wiring: p/moul/x/games/clock(/p/moul/x/games/clock/v0) owns the deadline and its guards, p/moul/x/games/prorata(/p/moul/x/games/prorata/v0) owns the split, and p/moul/x/daily/pullpayment(/p/moul/x/daily/pullpayment/v0) owns the credit ledger.

Functions

Deadline

func Deadline() int64

Deadline returns the height the slot closes at.

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/games/lastwords/v0.Deadline()"

Result

Message

func Message() string

Message returns the slot's current contents, raw. Render is what escapes it.

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/games/lastwords/v0.Message()"

Result

Owed

func Owed(addr address) int64

Owed returns what an address can Withdraw right now.

Param

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/games/lastwords/v0.Owed()"

Result

Pot

func Pot() int64

Pot returns what settlement will split.

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/games/lastwords/v0.Pot()"

Result

Price

func Price(msg string) int64

Price returns what msg costs to write right now, in ugnot: a base, plus a charge per byte, and always at least one ugnot more than the current holder paid. Query it before sending; an underpaying write is refused, not refunded.

Param

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/games/lastwords/v0.Price()"

Result

Render

func Render(path string) string

Render shows the slot, the clock and the money. The message is caller-typed text, so it goes through ui.Inline: a stored string that renders as markdown is a phishing link on a page nobody can edit, and this realm's whole product is a string somebody else wrote.

Param

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/games/lastwords/v0.Render()"

Result

Settle

func Settle(cur realm)

Settle closes the game once the clock has run out, splitting the pot among every writer EXCEPT the one holding the slot, pro rata to what each paid.

Anyone may call it: leaving settlement to an interested party is how a pot stays unclaimed. It moves no coins, it credits the ledger; Withdraw is what pays. If the holder is the only writer there is nobody else to split with, so the pot returns to them.

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/moul/x/games/lastwords/v0" -func "Settle" -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/moul/x/games/lastwords/v0" -func "Settle" -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
  

Withdraw

func Withdraw(cur realm) int64

Withdraw pays the caller everything credited to them and returns the amount. Dividends are claimable while the game runs; settlement shares only after Settle.

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/moul/x/games/lastwords/v0" -func "Withdraw" -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/moul/x/games/lastwords/v0" -func "Withdraw" -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
  

Write

func Write(cur realm, msg string)

Write puts msg in the slot and makes the caller its holder. The caller must send at least Price(msg) ugnot with the transaction.

Half of the payment is credited to the writer being displaced and the rest joins the pot. The deadline is pushed a fifth of the way toward the hard end, never past it, and never to less than Floor from now.

Only a direct user transaction may write, so the payment envelope cannot be spoofed by an ephemeral MsgRun realm.

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/moul/x/games/lastwords/v0" -func "Write" -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/moul/x/games/lastwords/v0" -func "Write" -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