Transaction
4AA1D5EFA7CA85…C647465B2612
Block 26,339 · index 0 · indexed
Summary
- Hash
- 4AA1D5EFA7CA85499165B55AED273AEA75C8127C116FC57ED820C647465B2612
- Block
- 26,339
- Size
- 4775 bytes
- Gas used
- 9,088,405 / 10,906,146
- Fee
- 1000000ugnot
- Memo
- gnopublish
- Status
- success
Messages
Arguments · 9
- #1importdemo
- #2README.md
- #3# `gno.land/r/moul/demo/importdemo/v0` A minimal realm that imports and composes packages from **another namespace** — that is the whole point of the demo. It builds a small thread of posts and renders it as Markdown. ``` /r/moul/demo/importdemo/v0 → the demo thread ``` Uses [`p/nt/avl/v0`](https://gno.land/p/nt/avl/v0) for ordered storage and [`p/nt/ufmt/v0`](https://gno.land/p/nt/ufmt/v0) for formatting. Both are published on every chain we target. Stateless: `Render` rebuilds the thread on every call, so its output depends only on the code. ### Only depend on what the chain actually serves An earlier cut of this demo imported `gno.land/p/archive/dom`, which is published on **no** chain we target. It type-checked locally and passed CI — the package was vendored — but could never be deployed; `addpkg` failed with: ``` could not import gno.land/p/archive/dom (unknown import path "gno.land/p/archive/dom") ``` That is the trap this demo now documents: a vendored dependency makes the build green regardless of whether any chain can resolve it. <!-- BEGIN GNOCONTRACTS FOOTER (generated by `make readmes`; do not edit below) --> --- Part of **[moul/gno-contracts](https://github.com/moul/gno-contracts)** — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage. **Dependency graph:**  > ⚠️ **Disclaimer:** provided as-is, without warranty; not security-audited. Full disclaimer: [DISCLAIMER](https://github.com/moul/gno-contracts/blob/main/DISCLAIMER.md). <!-- END GNOCONTRACTS FOOTER -->
- #4contract.gno
- #5// Package importdemo shows a realm importing and composing packages from // ANOTHER namespace — the whole point of the demo. // // v2 imported gno.land/p/archive/dom, which is published on no chain we target // (absent on both sapphire and pearl), so it type-checked locally but could // never be deployed: `addpkg` failed with // `could not import gno.land/p/archive/dom (unknown import path)`. v2 is // archived (`ignore = true`); this version rebuilds the same thread-of-posts // idea on foreign packages that are actually on chain — `p/nt/avl/v0` for // ordered storage and `p/nt/ufmt/v0` for formatting. // // Deliberately keeps no realm state: Render builds the thread on each call, so // output depends only on the code and the demo is reproducible. package importdemo import ( "strconv" "strings" "gno.land/p/nt/avl/v0" "gno.land/p/nt/ufmt/v0" ) // thread is a titled list of posts, kept in an avl.Tree so iteration is ordered // by key rather than by insertion — the same guarantee the realm needs for a // stable Render. type thread struct { name string posts *avl.Tree // zero-padded index -> *post n int } type post struct { title string body string } func newThread(name string) *thread { return &thread{name: name, posts: avl.NewTree()} } // addPost appends a post. The key is zero-padded so avl's lexicographic order // matches insertion order past 9 entries ("10" would otherwise sort before "9"). func (t *thread) addPost(title, body string) { t.posts.Set(padIdx(t.n), &post{title: title, body: body}) t.n++ } // padIdx renders i as a fixed-width, zero-padded key. // // Done by hand on purpose: gno's ufmt supports NO width or padding flags, so // ufmt.Sprintf("%03d", 7) yields "7", not "007" — silently, with no error. Keys // built that way sort as "0","1","10","11","2", which quietly reorders every // thread past nine posts (TestOrderSurvivesPastNinePosts covers exactly this). func padIdx(i int) string { s := strconv.Itoa(i) for len(s) < 3 { s = "0" + s } return s } // String renders the thread as Markdown. func (t *thread) String() string { var b strings.Builder b.WriteString(ufmt.Sprintf("# [thread] %s\n\n", t.name)) t.posts.Iterate("", "", func(_ string, v any) bool { p := v.(*post) b.WriteString(ufmt.Sprintf("## %s\n%s\n", p.title, p.body)) return false }) return b.String() } // Render renders the demo thread for gnoweb. func Render(path string) string { t := newThread("Hello!") t.addPost("Foo", "foo foo foo") t.addPost("Bar", "bar bar bar") return t.String() }
- #6gnomod.toml
- #7module = "gno.land/r/moul/demo/importdemo/v0" gno = "0.9"
- #8/gno.MemPackageType
- #9 MPUserProd
Result log
msg:0,success:true,log:,events:[]