Pure package detail
grc721
gno.land/p/nym-helox118/grc721
Indexed deployment identity with independently loaded latest RPC source. Functions and Render are realm-only RPC capabilities.
Indexed deployment
Identity
- Package path
- gno.land/p/nym-helox118/grc721
- Block
- 29234
- Deployed (UTC)
- Transaction
- WvI3JaOGQdU0Y+qqS8KEhCaLDXFy1hFl8ZSjdMZ/BYI=
Latest RPC state
Source
package grc721
import (
"chain"
)
// CallerTeller resolves the acting account at each write as rlm.Previous() —
// the realm that crossed into the realm holding the teller.
//
// SECURITY: this accessor hangs off *PrivateLedger, not *Token, and that is
// load-bearing. A frame-relative teller acts as whoever crossed into its
// holder, so it is only meaningful inside the token's own realm, where the
// wrappers act for a caller who knowingly invoked the collection. Anywhere
// else it is a confused deputy: a realm a user merely calls could move that
// user's tokens. The *Token pointer is published — exported vars, the
// collection facade, grc721reg — while the ledger is not, since NewToken hands
// it to the creating realm and nowhere else. So a foreign realm cannot mint
// one.
//
// Construction privacy alone is not enough: a realm may legally build a teller
// and then export the VALUE. The write methods therefore also verify that the
// invoking realm is the token's own (see guardHome), which leaves a leaked
// teller inert everywhere but home.
func (led *PrivateLedger) CallerTeller() Teller {
if led == nil {
panic("Ledger cannot be nil")
}
return &fnTeller{
accountFn: func(_ int, rlm realm) address {
return rlm.Previous().Address()
},
homeGuard: true,
Token: led.token,
}
}
// Write methods return ErrReadonly.
func (tok *Token) ReadonlyTeller() Teller {
if tok == nil {
panic("Token cannot be nil")
}
return &fnTeller{
accountFn: nil,
Token: tok,
}
}
// Permanently acts as the calling realm (verified via IsCurrent).
func (tok *Token) RealmTeller(_ int, rlm realm) Teller {
if tok == nil {
panic("Token cannot be nil")
}
if !rlm.IsCurrent() {
panic(ErrSpoofedRealm)
}
caller := rlm.Address()
return &fnTeller{
accountFn: func(_ int, _ realm) address {
return caller
},
Token: tok,
}
}
// Like RealmTeller but acts as a sub-account derived from slug.
func (tok *Token) RealmSubTeller(_ int, rlm realm, slug string) Teller {
if tok == nil {
panic("Token cannot be nil")
}
if !rlm.IsCurrent() {
panic(ErrSpoofedRealm)
}
account := accountSlugAddr(rlm.Address(), slug)
return &fnTeller{
accountFn: func(_ int, _ realm) address {
return account
},
Token: tok,
}
}
// Admin-grade: issuer-only (holds the PrivateLedger). Panics on invalid addr to close the empty-sentinel hole.
func (led *PrivateLedger) ImpersonateTeller(addr address) Teller {
if led == nil {
panic("Ledger cannot be nil")
}
if !addr.IsValid() {
panic(ErrInvalidAddress)
}
return &fnTeller{
accountFn: func(_ int, _ realm) address {
return addr
},
Token: led.token,
}
}
// guardHome confines a frame-relative teller to the token's own realm.
// Construction privacy stops a foreign realm from minting one; this stops a
// minted one from travelling, which is what happens when a realm legally builds
// a teller and then exports the value.
//
// The check is on the invoking realm's path alone — deliberately NOT on whether
// the resolved actor is an end user. Keying on the actor only blocks the case
// where the debited party is the signing user, and leaves two doors open: a
// realm can be charged by a realm it calls, and TransferFrom resolves the
// *spender* from the frame, so a realm reached from an honest hub spends that
// hub's approvals against any owner who granted one. Both are the same defect
// as the original one level up — frame-relative resolution means whoever you
// call can act as you — and neither is reachable once the teller only works at
// home.
//
// The host is compared after stripping any ":subpath" synthesized by realm.Sub,
// so the token's own sub-realms are not falsely rejected.
//
// A foreign realm that needs to move a user's tokens uses the ordinary route:
// the owner Approves it, and it spends as itself through RealmTeller, which is
// eagerly bound to its own address and approval-gated.
//
// The leading int keeps this a plain method.
func (ft *fnTeller) guardHome(_ int, rlm realm) error {
if !ft.homeGuard {
return nil
}
host, _, _ := chain.SplitPkgSubPath(rlm.PkgPath())
if host != ft.Token.origRealm {
return ErrForeignCallerTeller
}
return nil
}
func (ft *fnTeller) Approve(_ int, rlm realm, to address, tid TokenID) error {
if ft.accountFn == nil {
return ErrReadonly
}
if !rlm.IsCurrent() {
return ErrSpoofedRealm
}
if err := ft.guardHome(0, rlm); err != nil {
return err
}
caller := ft.accountFn(0, rlm)
return ft.Token.ledger.Approve(caller, to, tid)
}
func (ft *fnTeller) SetApprovalForAll(_ int, rlm realm, operator address, approved bool) error {
if ft.accountFn == nil {
return ErrReadonly
}
if !rlm.IsCurrent() {
return ErrSpoofedRealm
}
if err := ft.guardHome(0, rlm); err != nil {
return err
}
caller := ft.accountFn(0, rlm)
return ft.Token.ledger.SetApprovalForAll(caller, operator, approved)
}
func (ft *fnTeller) TransferFrom(_ int, rlm realm, from, to address, tid TokenID) error {
if ft.accountFn == nil {
return ErrReadonly
}
if !rlm.IsCurrent() {
return ErrSpoofedRealm
}
if err := ft.guardHome(0, rlm); err != nil {
return err
}
spender := ft.accountFn(0, rlm)
return ft.Token.ledger.TransferFrom(spender, from, to, tid)
}
func accountSlugAddr(addr address, slug string) address {
if slug == "" {
return addr
}
key := addr.String() + "/" + slug
return chain.PackageAddress(key)
}
The verified vm/qfuncs operation accepts realm paths only.
Pure packages expose source files but do not have Realm Render.