PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/r/g1sw5xklxjjuv0yvuxy5f5s3l3mnj0nqq626a9wr/goldenticket

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
goldenticket
Namespace
g1sw5xklxjjuv0yvuxy5f5s3l3mnj0nqq626a9wr
Files
3 (gnomod.toml)
Exported functions
8
Module
gno.land/r/g1sw5xklxjjuv0yvuxy5f5s3l3mnj0nqq626a9wr/goldenticket
gno
0.9

Files (3)

  • gnomod.tomltoml
  • goldenticket.gnogno
  • goldenticket_test.gnogno
goldenticket.gnogno
1// Package goldenticket is a 1/1 GRC721 NFT: one golden ticket, minted to the2// publisher when the package is added. It exists to check that a gno.land3// collection shows in the Adena wallet before gnofly's planes go to mainnet,4// so it is built the way the planes are:5//6//   - the collection is a gno.land/p/nt/grc721/v0 token made with NewToken,7//     whose NewToken and Transfer events Adena finds on its indexer;8//   - the read functions take a grc721.TokenID and return (value, error), as9//     Adena calls them: OwnerOf("1"), BalanceOf("g1..."), TokenURI("1") as10//     the <img src>, TokenMetadata("1") as JSON with camelCase traitType.11//12// Transfer moves the ticket, so it can reach any Adena account.13package goldenticket1415import (16	"errors"17	"strings"1819	"gno.land/p/nt/grc721/v0"20)2122const (23	tokenName   = "Golden Ticket"24	tokenSymbol = "GOLD"25	ticket      = grc721.TokenID("1")2627	// An https PNG, as the planes' images are: the SuperGnome of gnofly, from28	// the Blob store that serves the collection. Adena loads https: and data:29	// images only.30	image = "https://xjfvwq1pdzcznycc.public.blob.vercel-storage.com/planes/777.png"3132	errNoTicket = "goldenticket: there is one ticket, id 1"33	errNotOwner = "goldenticket: caller does not hold the ticket"34	errBadOwner = "goldenticket: invalid recipient address"35)3637var (38	// Token is the collection, read-only: Token.OwnerOf("1"), Token.BalanceOf.39	Token  *grc721.Token40	ledger *grc721.PrivateLedger41)4243// init runs once, when the package is added to the chain. This is the only44// moment cur.Previous() is the publisher, who receives the ticket.45//46// Under `gno test` there is no publisher and the address is empty. The tests47// call bootstrap themselves with a real address.48func init(cur realm) {49	bootstrap(cur.Previous().Address(), cur)50}5152// bootstrap creates the collection and mints the ticket to holder; with no53// valid holder, under `gno test`, it mints nothing.54func bootstrap(holder address, rlm realm) {55	Token, ledger = grc721.NewToken(tokenName, tokenSymbol, 0, rlm)56	if !holder.IsValid() {57		return58	}59	if err := ledger.Mint(holder, ticket); err != nil {60		panic(err)61	}62}6364// Name and Symbol, as GRC721 tokens have them. Adena reads both from the65// NewToken event.66func Name() string   { return tokenName }67func Symbol() string { return tokenSymbol }6869// OwnerOf returns who holds the ticket, or an error for any other id.70func OwnerOf(tid grc721.TokenID) (address, error) {71	if tid != ticket {72		return "", errors.New(errNoTicket)73	}74	return Token.OwnerOf(tid)75}7677// BalanceOf returns 1 for the holder of the ticket, 0 for everyone else.78func BalanceOf(addr address) (int64, error) {79	return Token.BalanceOf(addr)80}8182// TokenURI returns the image of the ticket: what Adena shows.83func TokenURI(tid grc721.TokenID) (string, error) {84	if _, err := OwnerOf(tid); err != nil {85		return "", err86	}87	return image, nil88}8990// TokenMetadata returns the metadata of the ticket as JSON, with the keys91// Adena reads.92func TokenMetadata(tid grc721.TokenID) (string, error) {93	if _, err := OwnerOf(tid); err != nil {94		return "", err95	}96	return `{"name":"` + tokenName + ` #1","description":"A 1/1 on gno.land, minted to check that collections show in Adena.",` +97		`"image":"` + image + `","attributes":[{"traitType":"edition","value":"1 of 1"},{"traitType":"metal","value":"gold"}]}`, nil98}99100// Transfer gives the ticket to someone else. Only its holder can, by a101// direct call (maketx call or Adena), not through another realm.102func Transfer(cur realm, to address) {103	caller := cur.Previous()104	if !caller.IsUserCall() {105		panic(errNotOwner)106	}107	if !to.IsValid() {108		panic(errBadOwner)109	}110	holder, err := Token.OwnerOf(ticket)111	if err != nil || holder != caller.Address() {112		panic(errNotOwner)113	}114	if err := ledger.TransferFrom(holder, holder, to, ticket); err != nil {115		panic(err)116	}117}118119// Render shows the ticket and who holds it.120func Render(_ string) string {121	var b strings.Builder122	b.WriteString("# " + tokenName + "\n\n")123	b.WriteString("A 1/1 GRC721 on gno.land, minted to check that collections show in Adena.\n\n")124	b.WriteString("![" + tokenName + "](" + image + ")\n\n")125	holder, err := Token.OwnerOf(ticket)126	if err != nil {127		b.WriteString("Not minted.\n")128		return b.String()129	}130	b.WriteString("Held by `" + holder.String() + "`.\n")131	return b.String()132}133

Functions

  • BalanceOf(addr string) (int64, interface {Error func() string})

  • Name() string

  • OwnerOf(tid string) (string, interface {Error func() string})

  • Render(string) string

  • Symbol() string

  • TokenMetadata(tid string) (string, interface {Error func() string})

  • TokenURI(tid string) (string, interface {Error func() string})

  • Transfer(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, to string)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

Rendered

RenderedRawgnoweb ↗

vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.