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/moul/x/grc20faucet/v0

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
v0
Namespace
moul / x / grc20faucet
Files
4 (README)(gnomod.toml)
Exported functions
9
Module
gno.land/r/moul/x/grc20faucet/v0
gno
0.9
This realm implements 2 recognized tokens.BLUE →RED →

Files (4)

  • README.mdmarkdown
  • gnomod.tomltoml
  • faucet.gnogno
  • faucet_test.gnogno
faucet.gnogno
1// Package grc20faucet issues two free GRC20 tokens, RED and BLUE, and gives2// them away on request.3//4// It exists so that anything needing a token to experiment on has one that is5// worthless, unlimited and shared. Both tokens are registered in6// gno.land/r/nt/grc20reg/v0, which is what lets another realm find and move7// them by key without importing this package: that indirection is the whole8// point, and it is what gno.land/r/moul/x/grc20wrapdemo/v0 wraps.9//10// Two tokens rather than one, because the interesting patterns start at two: a11// meta-token over a pair needs a pair.12package grc20faucet1314import (15	"chain/runtime"1617	"gno.land/p/nt/avl/v0"18	"gno.land/p/nt/grc20/v0"19	"gno.land/p/nt/ufmt/v0"20	"gno.land/r/nt/grc20reg/v0"21)2223// Tokens are exported so an importing realm can read them directly; the24// ledgers stay private, since they carry unrestricted mint and burn.25var (26	Red  *grc20.Token27	Blue *grc20.Token2829	redLedger  *grc20.PrivateLedger30	blueLedger *grc20.PrivateLedger3132	// RedKey and BlueKey are the grc20reg lookup keys, the way a realm that33	// does NOT import this package refers to these tokens.34	RedKey  string35	BlueKey string3637	lastClaim = avl.NewTree() // address -> block height of its last claim38)3940const (41	decimals = 44243	// ClaimAmount is minted of EACH token per claim: 100.0000 units.44	ClaimAmount = int64(1_000_000)4546	// ClaimEvery is the cooldown, in blocks, between two claims by the same47	// account. Free money with no cooldown is a spam vector, not a faucet.48	ClaimEvery = int64(100)49)5051func init(cur realm) {52	Red, redLedger = grc20.NewToken("Red Token", "RED", decimals, 0, cur)53	Blue, blueLedger = grc20.NewToken("Blue Token", "BLUE", decimals, 1, cur)54	RedKey = grc20reg.Register(cross(cur), Red, "red")55	BlueKey = grc20reg.Register(cross(cur), Blue, "blue")56}5758// Claim mints ClaimAmount of both RED and BLUE to the caller.59func Claim(cur realm) {60	who := caller(cur)61	now := runtime.ChainHeight()62	if next, ok := NextClaim(who); ok && now < next {63		panic(ufmt.Sprintf("too soon: next claim at block %d, current %d", next, now))64	}65	lastClaim.Set(who.String(), now)66	checkErr(redLedger.Mint(who, ClaimAmount))67	checkErr(blueLedger.Mint(who, ClaimAmount))68}6970// NextClaim returns the block height at which `who` may claim again, and71// whether they have ever claimed at all.72func NextClaim(who address) (int64, bool) {73	v := lastClaim.Get(who.String())74	if v == nil {75		return 0, false76	}77	return v.(int64) + ClaimEvery, true78}7980// Transfer moves the caller's own units of `symbol`.81func Transfer(cur realm, symbol string, to address, amount int64) {82	checkErr(ledgerOf(symbol).CallerTeller().Transfer(0, cur, to, amount))83}8485// Approve lets `spender` draw `amount` of `symbol` from the caller's balance.86//87// This is the call that makes every wrapper in grc20wrapdemo work: the wrapper88// realm has no authority over anybody's tokens until its address is named here.89func Approve(cur realm, symbol string, spender address, amount int64) {90	checkErr(ledgerOf(symbol).CallerTeller().Approve(0, cur, spender, amount))91}9293// TransferFrom spends an allowance the caller was granted.94func TransferFrom(cur realm, symbol string, from, to address, amount int64) {95	checkErr(ledgerOf(symbol).CallerTeller().TransferFrom(0, cur, from, to, amount))96}9798// BalanceOf returns `owner`'s balance of `symbol`.99func BalanceOf(symbol string, owner address) int64 {100	return tokenOf(symbol).BalanceOf(owner)101}102103// Allowance returns what `owner` let `spender` draw of `symbol`.104func Allowance(symbol string, owner, spender address) int64 {105	return tokenOf(symbol).Allowance(owner, spender)106}107108// TotalSupply returns how much of `symbol` has been claimed so far.109func TotalSupply(symbol string) int64 {110	return tokenOf(symbol).TotalSupply()111}112113func tokenOf(symbol string) *grc20.Token {114	switch symbol {115	case "RED":116		return Red117	case "BLUE":118		return Blue119	}120	panic("unknown symbol " + symbol + " (RED or BLUE)")121}122123func ledgerOf(symbol string) *grc20.PrivateLedger {124	switch symbol {125	case "RED":126		return redLedger127	case "BLUE":128		return blueLedger129	}130	panic("unknown symbol " + symbol + " (RED or BLUE)")131}132133// caller is the account or realm that crossed into this one.134func caller(cur realm) address {135	if !cur.IsCurrent() {136		panic("grc20faucet: stale realm token")137	}138	return cur.Previous().Address()139}140141func checkErr(err error) {142	if err != nil {143		panic(err)144	}145}146147func Render(path string) string {148	s := "# GRC20 faucet: RED and BLUE\n\n"149	s += "Two worthless tokens to experiment on. `Claim` gives you "150	s += ufmt.Sprintf("%d of each, once every %d blocks.\n\n", ClaimAmount, ClaimEvery)151152	s += "| token | symbol | decimals | supply | registry key |\n"153	s += "|---|---|---|---|---|\n"154	s += ufmt.Sprintf("| %s | RED | %d | %d | `%s` |\n",155		Red.GetName(), Red.GetDecimals(), Red.TotalSupply(), RedKey)156	s += ufmt.Sprintf("| %s | BLUE | %d | %d | `%s` |\n",157		Blue.GetName(), Blue.GetDecimals(), Blue.TotalSupply(), BlueKey)158159	s += "\n## Use it\n\n"160	s += "```\n"161	s += "gnokey maketx call -pkgpath gno.land/r/moul/x/grc20faucet/v0 -func Claim ...\n"162	s += "gnokey maketx call -pkgpath gno.land/r/moul/x/grc20faucet/v0 -func Approve \\\n"163	s += "  -args RED -args <spender> -args 1000000 ...\n"164	s += "```\n\n"165	s += "Both tokens are registered in [grc20reg](/r/nt/grc20reg/v0), so a realm can\n"166	s += "move them by key without importing this one. That is what\n"167	s += "[grc20wrapdemo](/r/moul/x/grc20wrapdemo/v0) does with them.\n"168169	if path != "" {170		s += "\n---\n\n"171		s += ufmt.Sprintf("Balance of `%s`: RED %d, BLUE %d\n",172			path, Red.BalanceOf(address(path)), Blue.BalanceOf(address(path)))173	}174	return s175}176

Functions

  • Allowance(symbol string, owner string, spender string) int64

  • Approve(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}, symbol string, spender string, amount int64)

  • BalanceOf(symbol string, owner string) int64

  • Claim(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})

  • NextClaim(who string) (int64, bool)

  • Render(path string) string

  • TotalSupply(symbol string) int64

  • 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}, symbol string, to string, amount int64)

  • TransferFrom(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}, symbol string, from string, to string, amount int64)

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.