An open, on-chain encyclopedia. Anyone can create or edit a page, every edit is
a signed revision, and the whole history is public and tamper-evident.
A thin realm over p/moul/x/wiki/v0: the library
owns content (titles, revisions, wikilinks, categories, diffs, rendering), this
realm owns authority (who may write what) and the chain wiring (block
height, block time, the calling address, transaction links). There is no policy
in the library and no content logic here.
Writing
call
who
Edit(title, body, summary)
anyone, subject to the page's protection
Revert(title, rev, summary)
same
Comment(title, body, replyTo)
anyone not banned, whatever the protection
HideComment(title, id)
steward
Protect(title, "open"|"semi"|"locked")
steward
Move(from, to, reason)
steward
Blank(title, reason)
steward
Purge(title)
steward
AddEditor / RemoveEditor / Ban / Unban / SetCooldown
steward
1gnokey maketx call -pkgpath gno.land/r/moul/x/wiki/v0 -func Edit \
2 -args 'Gno land' -args 'gno.land is a chain that runs [[Gno]].
3[[Category:Chains]]
4' -args 'expand the intro'\
5 -gas-fee 1000000ugnot -gas-wanted 20000000 -broadcast -chainid <id> <key>
The body is markdown plus [[wikilinks]], [[Category:Name]] and a
#REDIRECT [[Target]] first line; the syntax table is in the library README.
Render is total: a malformed path returns a page, never an abort.
Authority
One ownable.Ownable steward, transferable, so the wiki can be handed to a DAO
realm without redeploying. Three protection levels: open (anyone), semi
(an explicit editor list), locked (steward only). A page that does not exist
yet is open to anyone.
Commenting ignores the protection level on purpose. Locking an article is
how a steward stops an edit war; the discussion is where that war is supposed to
move, so a locked page still takes comments. A banned address cannot comment,
and the cooldown still applies.
On anti-vandalism, the honest version: the storage deposit makes adding
bytes cost the adder, but the chain refunds released storage to whoever frees
it, at the realm's blended rate, not to whoever paid (see the library README,
"Who gets the deposit back"). So shrinking a page can pay the editor who does
it, and reverting the damage costs the good actor. That is why Blank, Purge
and HideComment are steward-gated, and why the ban list, the protection
levels and SetCooldown are not optional extras.
Blanking is the deletion a chain can honestly offer. The page stops rendering
and stops costing rent as its bodies age out, while the revision spine stays as
proof that something was there and who removed it. Purge releases the
retained bytes immediately. Neither removes the transactions that wrote the
content: on a public chain, "delete" means "stop serving", not "unhappen".
Cost
Storage deposit is 100ugnot per byte, locked while the bytes are held and
released when they are removed. A 5 KB article is therefore about 0.5 GNOT of
deposit for its current revision, plus roughly 0.02 GNOT for each revision's
permanent spine; the default retention window keeps three bodies per page. Every
page's footer shows its own held bytes and deposit, and Special:Stats shows
the wiki's.
Retention defaults to 3 rather than 1 so that a revert can reach past two bad
edits in a row, which is the common vandalism pattern. Raising it costs
linearly more deposit per page.
Seeded content
init writes four linked pages (Gno land, Gno, Tendermint2,
Help:Editing) so a fresh deploy renders a connected wiki instead of an empty
index.
Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.
Dependency graph:
🧪 Highly experimental — potentially vibe-coded. Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: DISCLAIMER.
Overview
Package wiki is an open, on-chain encyclopedia: anyone can create and edit a page, every edit is a signed revision, and the whole history is public.
It is a thin realm over gno.land/p/moul/x/wiki/v0. The library owns content (titles, revisions, wikilinks, categories, diffs, rendering); this realm owns authority (who may edit what) and the chain wiring (block height, block time, the calling address, transaction links).
The split matters for reading the code: there is no policy in the library and no content logic here.
1var( 2site*wiki.Wiki 3Ownable*ownable.Ownable 4 5// editors may write to semi-protected pages; banned may write nowhere. 6editorsaddrset.Set 7bannedaddrset.Set 8 9// cooldown is the minimum number of blocks between two writes by the same10// address, 0 to disable.11//12// The storage deposit makes ADDING bytes cost the adder, but it does not13// make removing them cost anything: the chain refunds released storage to14// the caller of the transaction that frees it, at the realm's blended15// deposit rate, not to whoever originally paid (processStorageDeposit in16// gno.land/pkg/sdk/vm/keeper.go). So replacing a long article with a short17// one can pay the editor who does it. Blank and Purge are steward-gated18// for that reason, and this cooldown plus the ban list and the protection19// levels are what is left for ordinary edits. See #140 Q2.20cooldownint6421lastEditavl.Tree// address -> the height of that address's last edit22editCountint23)
Comment appends a message to a page's discussion and returns its id. Pass replyTo = 0 for a new thread, or the id of a top-level message to reply to.
Commenting deliberately ignores the page's protection level: locking an article is how a steward stops an edit war, and the discussion is where that war is supposed to move. A banned address still cannot comment, and the cooldown still applies.
Purge drops every body this realm still holds for a page and returns the number of bytes released. Use it for content that must stop being served from realm state; it cannot remove the transactions that wrote it.
1 the front page
2Title an article
3Title/history[?offset=] its revisions, newest first
4Title/raw the current source, with its hash
5Title/rev/<id> one stored revision
6Title/diff?from=&to= a line diff between two revisions
7Title/talk[?offset=] the page's discussion
8Category:Name a category page and its members
9Special:AllPages[?ns=] the page index for a namespace
10Special:Categories every category with at least one member
11Special:RecentChanges the change feed
12Special:Backlinks?page= what links to a page
13Special:Stats size and storage cost