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/daily/quotes/v0

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
v0
Namespace
moul / x / daily / quotes
Files
3 (README)(gnomod.toml)
Exported functions
2
Module
gno.land/r/moul/x/daily/quotes/v0
gno
0.9

Files (3)

  • README.mdmarkdown
  • gnomod.tomltoml
  • quotes.gnogno
quotes.gnogno
1// Package quotes is a community "Quote of the Moment" board realm.2//3// Anyone can submit a quote via the exported crossing function AddQuote.4// Each quote records its text, the address of the caller who added it, and5// the block height at submission time. Render deterministically picks a6// "featured" quote by the current block height (a stable index into the7// list), shows it as a blockquote, then lists every quote with its author8// and id below.9package quotes1011import (12	"strconv"13	"strings"1415	"chain"16	"chain/runtime"17)1819// quote is a single board entry. Author is stored as a plain string address20// (realm values are ephemeral and must never be persisted).21type quote struct {22	id     int23	text   string24	author string // bech32 address of the submitter, or "" for seeded quotes25	height int64  // block height at submission (0 for seeded quotes)26}2728// board is the persistent realm state. A plain slice is fine here: the list29// only ever grows by append and Render walks it in insertion order, which is30// deterministic.31var board []quote3233// init seeds the board so a fresh deploy renders nicely.34func init() {35	seed := []string{36		"The unexamined life is not worth living.",37		"We suffer more often in imagination than in reality.",38		"Waste no more time arguing about what a good person should be. Be one.",39		"He who is brave is free.",40	}41	for _, s := range seed {42		board = append(board, quote{43			id:     len(board),44			text:   s,45			author: "", // seeded46			height: 0,47		})48	}49}5051// AddQuote is the exported, state-mutating entry point. It follows the gno 0.952// interrealm crossing convention: the first parameter is `cur realm`. Callers53// invoke it as AddQuote(cross(cur), "...") over a MsgCall.54func AddQuote(cur realm, text string) {55	// Authentication primitive: reject a stale/forged realm value before56	// deriving any caller identity from it.57	if !cur.IsCurrent() {58		panic("spoofed realm: cur is not the live crossing frame")59	}6061	if err := validate(text); err != nil {62		panic(err)63	}6465	author := cur.Previous().Address().String()66	h := runtime.ChainHeight()6768	board = append(board, quote{69		id:     len(board),70		text:   text,71		author: author,72		height: h,73	})7475	chain.Emit("QuoteAdded",76		"id", strconv.Itoa(len(board)-1),77		"author", author,78		"height", strconv.FormatInt(h, 10),79	)80}8182// maxQuoteLen caps quote length to keep storage costs bounded and Render tidy.83const maxQuoteLen = 2808485// validate enforces basic content rules. Returns an error describing the86// problem, or nil when the text is acceptable.87func validate(text string) error {88	if len(text) == 0 {89		return errEmpty90	}91	if len(text) > maxQuoteLen {92		return errTooLong93	}94	return nil95}9697// Sentinel errors for validation. Kept as package-level vars so tests can98// compare against them directly.99var (100	errEmpty   = quoteError("quote text must not be empty")101	errTooLong = quoteError("quote text exceeds " + strconv.Itoa(maxQuoteLen) + " characters")102)103104// quoteError is a trivial string-backed error type (the VM has no host105// stdlib errors package convenience beyond this).106type quoteError string107108func (e quoteError) Error() string { return string(e) }109110// featuredIndex deterministically picks which quote is "of the moment" for a111// given block height. Pure function of (height, count) so it is fully112// deterministic and easy to test.113func featuredIndex(height int64, count int) int {114	if count <= 0 {115		return -1116	}117	// Guard against a negative height (should not happen on-chain, but keeps118	// the modulo well-defined).119	if height < 0 {120		height = -height121	}122	return int(height % int64(count))123}124125// Render produces the Markdown page shown in gnoweb. It is NOT a crossing126// function (no `cur realm` parameter) — it is a read-only view.127func Render(path string) string {128	count := len(board)129	if count == 0 {130		return "# Quote of the Moment\n\n_No quotes yet. Be the first to add one._\n"131	}132133	h := runtime.ChainHeight()134	idx := featuredIndex(h, count)135	featured := board[idx]136137	var b strings.Builder138	b.WriteString("# Quote of the Moment\n\n")139140	// Featured quote as a blockquote.141	b.WriteString("> ")142	b.WriteString(featured.text)143	b.WriteString("\n>\n> — ")144	b.WriteString(authorLabel(featured))145	b.WriteString(" (#")146	b.WriteString(strconv.Itoa(featured.id))147	b.WriteString(")\n\n")148149	b.WriteString("_Featured pick rotates with block height ")150	b.WriteString(strconv.FormatInt(h, 10))151	b.WriteString(" — index ")152	b.WriteString(strconv.Itoa(idx))153	b.WriteString(" of ")154	b.WriteString(strconv.Itoa(count))155	b.WriteString("._\n\n")156157	// Full list.158	b.WriteString("## All quotes (")159	b.WriteString(strconv.Itoa(count))160	b.WriteString(")\n\n")161	for _, q := range board {162		b.WriteString("- **#")163		b.WriteString(strconv.Itoa(q.id))164		b.WriteString("** ")165		b.WriteString(q.text)166		b.WriteString(" — _")167		b.WriteString(authorLabel(q))168		b.WriteString("_\n")169	}170171	return b.String()172}173174// authorLabel renders a human-friendly author string. Seeded quotes (empty175// author) show as the house account.176func authorLabel(q quote) string {177	if q.author == "" {178		return "the board"179	}180	return q.author181}182

Functions

  • AddQuote(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}, text string)

  • Render(path string) 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.