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/p/g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt/bazaar/grc721/v0

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v0
Namespace
g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt / bazaar / grc721
Files
4 (gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt/bazaar/grc721/v0
gno
0.9

Files (4)

  • gnomod.tomltoml
  • tellers.gnogno
  • token.gnogno
  • types.gnogno
tellers.gnogno
1package grc72123import (4	"chain"5)67// CallerTeller resolves the acting account at each write as rlm.Previous() —8// the realm that crossed into the realm holding the teller.9//10// SECURITY: this accessor hangs off *PrivateLedger, not *Token, and that is11// load-bearing. A frame-relative teller acts as whoever crossed into its12// holder, so it is only meaningful inside the token's own realm, where the13// wrappers act for a caller who knowingly invoked the collection. Anywhere14// else it is a confused deputy: a realm a user merely calls could move that15// user's tokens. The *Token pointer is published — exported vars, the16// collection facade, grc721reg — while the ledger is not, since NewToken hands17// it to the creating realm and nowhere else. So a foreign realm cannot mint18// one.19//20// Construction privacy alone is not enough: a realm may legally build a teller21// and then export the VALUE. The write methods therefore also verify that the22// invoking realm is the token's own (see guardHome), which leaves a leaked23// teller inert everywhere but home.24func (led *PrivateLedger) CallerTeller() Teller {25	if led == nil {26		panic("Ledger cannot be nil")27	}2829	return &fnTeller{30		accountFn: func(_ int, rlm realm) address {31			return rlm.Previous().Address()32		},33		homeGuard: true,34		Token:     led.token,35	}36}3738// Write methods return ErrReadonly.39func (tok *Token) ReadonlyTeller() Teller {40	if tok == nil {41		panic("Token cannot be nil")42	}4344	return &fnTeller{45		accountFn: nil,46		Token:     tok,47	}48}4950// Permanently acts as the calling realm (verified via IsCurrent).51func (tok *Token) RealmTeller(_ int, rlm realm) Teller {52	if tok == nil {53		panic("Token cannot be nil")54	}5556	if !rlm.IsCurrent() {57		panic(ErrSpoofedRealm)58	}5960	caller := rlm.Address()6162	return &fnTeller{63		accountFn: func(_ int, _ realm) address {64			return caller65		},66		Token: tok,67	}68}6970// Like RealmTeller but acts as a sub-account derived from slug.71func (tok *Token) RealmSubTeller(_ int, rlm realm, slug string) Teller {72	if tok == nil {73		panic("Token cannot be nil")74	}7576	if !rlm.IsCurrent() {77		panic(ErrSpoofedRealm)78	}7980	account := accountSlugAddr(rlm.Address(), slug)8182	return &fnTeller{83		accountFn: func(_ int, _ realm) address {84			return account85		},86		Token: tok,87	}88}8990// Admin-grade: issuer-only (holds the PrivateLedger). Panics on invalid addr to close the empty-sentinel hole.91func (led *PrivateLedger) ImpersonateTeller(addr address) Teller {92	if led == nil {93		panic("Ledger cannot be nil")94	}9596	if !addr.IsValid() {97		panic(ErrInvalidAddress)98	}99100	return &fnTeller{101		accountFn: func(_ int, _ realm) address {102			return addr103		},104		Token: led.token,105	}106}107108// guardHome confines a frame-relative teller to the token's own realm.109// Construction privacy stops a foreign realm from minting one; this stops a110// minted one from travelling, which is what happens when a realm legally builds111// a teller and then exports the value.112//113// The check is on the invoking realm's path alone — deliberately NOT on whether114// the resolved actor is an end user. Keying on the actor only blocks the case115// where the debited party is the signing user, and leaves two doors open: a116// realm can be charged by a realm it calls, and TransferFrom resolves the117// *spender* from the frame, so a realm reached from an honest hub spends that118// hub's approvals against any owner who granted one. Both are the same defect119// as the original one level up — frame-relative resolution means whoever you120// call can act as you — and neither is reachable once the teller only works at121// home.122//123// The host is compared after stripping any "#subpath" synthesized by realm.Sub,124// so the token's own sub-realms are not falsely rejected.125//126// A foreign realm that needs to move a user's tokens uses the ordinary route:127// the owner Approves it, and it spends as itself through RealmTeller, which is128// eagerly bound to its own address and approval-gated.129//130// The leading int keeps this a plain method.131func (ft *fnTeller) guardHome(_ int, rlm realm) error {132	if !ft.homeGuard {133		return nil134	}135136	host, _, _ := splitPkgSubPath(rlm.PkgPath())137	if host != ft.Token.origRealm {138		return ErrForeignCallerTeller139	}140141	return nil142}143144func (ft *fnTeller) Approve(_ int, rlm realm, to address, tid TokenID) error {145	if ft.accountFn == nil {146		return ErrReadonly147	}148149	if !rlm.IsCurrent() {150		return ErrSpoofedRealm151	}152153	if err := ft.guardHome(0, rlm); err != nil {154		return err155	}156157	caller := ft.accountFn(0, rlm)158159	return ft.Token.ledger.Approve(caller, to, tid)160}161162func (ft *fnTeller) SetApprovalForAll(_ int, rlm realm, operator address, approved bool) error {163	if ft.accountFn == nil {164		return ErrReadonly165	}166167	if !rlm.IsCurrent() {168		return ErrSpoofedRealm169	}170171	if err := ft.guardHome(0, rlm); err != nil {172		return err173	}174175	caller := ft.accountFn(0, rlm)176177	return ft.Token.ledger.SetApprovalForAll(caller, operator, approved)178}179180func (ft *fnTeller) TransferFrom(_ int, rlm realm, from, to address, tid TokenID) error {181	if ft.accountFn == nil {182		return ErrReadonly183	}184185	if !rlm.IsCurrent() {186		return ErrSpoofedRealm187	}188189	if err := ft.guardHome(0, rlm); err != nil {190		return err191	}192193	spender := ft.accountFn(0, rlm)194195	return ft.Token.ledger.TransferFrom(spender, from, to, tid)196}197198func accountSlugAddr(addr address, slug string) address {199	if slug == "" {200		return addr201	}202203	key := addr.String() + "/" + slug204205	return chain.PackageAddress(key)206}207

Functions

not supported for pure packages by the node (vm/qfuncs)

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