Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

statements state

Back to all declarations

RealmPath

untyped string

RealmPath is this realm's own path, used to build Render links.

Value

"/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/statements"

BooksPath

untyped string

BooksPath is the ledger realm every figure here is derived from. It is taken BY VALUE from that realm's own exported constant rather than typed out again, so this is the compile-time pin itself and not a second copy of it that could drift. A reader checking which ledger a statement describes is reading the import, not a string in a doc comment.

Value

"/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/books"

PublicationsAreUncapped

untyped bool

PublicationsAreUncapped records a decision by its absence, because every other realm in this portfolio caps its per-owner state and a reader will look for the cap here. There is none, and the three reasons are: - \*\*No shared resource is consumed.\*\* Keys are per owner, like r/books' books. An owner can fill their own publication history and nobody else's, and the cost of doing so is gas plus a storage deposit each time. That is the same griefing argument r/books makes for its per-owner caps, and here it is sufficient on its own. - \*\*Nothing iterates them.\*\* Render reads the newest [RenderPublicationLimit](#RenderPublicationLimit) by sequence number, by direct key lookup, so page cost does not grow with the count. No accessor walks a publisher's history. - \*\*There is no engine cap to mirror.\*\* r/books caps because p/journal caps and the interaction of its ceiling with RederiveFromJournal is unmeasured. No such ceiling exists above this realm. A cap added only so a test could reach it would be worse than none.

Value

true

RenderPublicationLimit

untyped bigint

RenderPublicationLimit caps how many of a publisher's statements one Render call lists. Publications are unbounded (see [PublicationsAreUncapped](#PublicationsAreUncapped)), so this is what keeps a publisher's page cost flat.

Value

(20 <untyped> bigint)

RenderAbnormalLimit

untyped bigint

RenderAbnormalLimit caps how many census rows one Render call emits. A chart may hold books.MaxAccountsPerBook accounts and in a pathological book every one of them is abnormal.

Value

(25 <untyped> bigint)

record

type

record is one frozen statement. It stores the [stmt.Statement](/gno.land/p/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/statements#Statement) whole rather than copying its ten fields into a parallel struct: a second field set is a second place for the two to disagree, and every field here is a value or a slice this realm allocated. There is deliberately no seq field. One was written here and read nowhere — found by the sabotage harness, which could not make dropping the assignment fail any test. A stored copy of the sequence would be a second place for the key and the record to disagree, and the key already carries it: every read path reaches a record by constructing pubKey(owner, seq) from a seq it already holds, so a field would only ever be checked against its own source.

Value

statements.record

published

*v0.Tree

published maps "\<owner>|\<padded seq>" to \*record. The pointer never leaves this file. Every accessor copies scalars out, so no caller receives a handle onto stored state — the same discipline r/books applies to its \*journal.Book.

Open
OID
03d65d…b668:4
published details

Inspect pointer

counts

*v0.Tree

counts maps an owner's address string to how many statements they have published. It is the sequence allocator as well as the count.

Open
OID
03d65d…b668:7
counts details

Inspect pointer

pubCount

int

pubCount is the global total, maintained alongside the tree so the index page never iterates. It is a count and nothing more; see the package doc on why there is no way to enumerate publishers.

Value

2

refuseCoins

func()

refuseCoins panics if a user call arrives carrying coins. Adopted verbatim from r/books, which faces the identical slot: no withdrawal path, so accepted coins are stranded permanently. The guard is on IsUserCall rather than IsUser deliberately, and the reason is NOT the one the canonical payment-guard advice gives. That advice is about a realm that ACCEPTS payment, where IsUser is dangerously broad because the MsgRun ephemeral can consume the envelope before forwarding control and the receipt invariant no longer holds. This guard REFUSES, so the broader predicate would refuse MORE, and "more conservative" is the wrong frame. The real reason is that OriginSend is a fact about the TRANSACTION, not about this realm. It is a faithful receipt only on the direct MsgCall path, where the envelope's destination is this realm. On a MsgRun path the envelope can be non-empty while nothing arrives here — coins sent to the ephemeral flow back to the user — so pairing it with IsUser buys no protection and adds a FALSE REFUSAL mode: a panic on a call that brought this realm nothing. IsUserCall is the narrowest predicate covering the only path on which a non-empty envelope means coins actually credited to this address. The residual is stated rather than guarded: coins can still reach this realm's address through an intermediary's explicit banker send, which no predicate here can see. What makes that survivable is not this guard but the absence of any consumption path — nothing in this realm can spend what arrives, so a stranded balance is inert rather than exploitable. An earlier version of this comment said "OriginSend is only meaningful for a direct MsgCall", which is false as written — it is readable on every path and merely stops being a receipt. An independent audit caught it. The predicate was right and the stated reason was not, which is the worse of the two failures: the predicate is re-derivable from the references and a confident wrong sentence is what stops a maintainer re-deriving it. Onyx's VM tightens IsUserCall, so this is exactly the comment that gets consulted after the semantics have moved underneath it.

Open
OID
03d65d…b668:10
refuseCoins details

Inspect func

parseKind

func(s string) journal.Kind

parseKind turns one of [r/books](/r/books)' five kind words back into a [journal.Kind](/gno.land/p/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/journal#Kind), and PANICS on anything else. This is the ugly seam and it is named rather than hidden. r/books returns an account's kind as \`journal.Kind.String()\` — a presentation format that has become an API across a realm boundary — and no Kind parser exists anywhere in this portfolio (measured in DISCOVERY.md § 7, step 2c: zero hits for ParseKind, parseKind and kindFromString; r/books' own kindFromCode maps a code PREFIX to a kind and is unexported). It panics rather than returning a zero Kind, and the reason is specific: the zero Kind is reported CREDIT-NORMAL by [journal.Kind.IsDebitNormal](/gno.land/p/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/journal#Kind.IsDebitNormal), so a silently-unparsed word would not drop the row — it would file it under claims and produce a statement that balances and misstates. p/statements' Derive would catch it as ErrInvalidKind, and relying on that would make this realm's error message point at the wrong layer. The round trip is pinned in the suite over all five kinds rather than assumed, because the contract is another realm's String method.

Open
OID
03d65d…b668:12
parseKind details

Inspect func

chartOf

func(owner .uverse.address) []journal.Account

chartOf reads an owner's whole chart out of [r/books](/r/books) as journal.Account rows, ready for [stmt.Derive](/gno.land/p/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/statements#Derive). ### One walk, not a paging loop {#hdr-One_walk__not_a_paging_loop} books.Codes takes a \`from\` and a \`limit\`, so the obvious shape is a paging loop — and DISCOVERY.md § 6.4 planned one, costing ceil(n/limit) full chart walks because that iterator has no seek and honours \`from\` by skipping. This asks for the whole chart in ONE call instead, with limit at r/books' own account cap, which is exactly one walk and is strictly cheaper than any paging of it. The cap is read from that realm's exported constant, so the request can never be short of what a book may hold. Dropping the loop also drops its hazard. books.Codes' \`from\` is INCLUSIVE — paging re-reads the last code received — so every paging caller owes itself a boundary dedup, and a missed one double-counts one account per page boundary. A double-counted balance is the defect this product is least able to detect: the statement would still balance. ### The agreement check is not decoration {#hdr-The_agreement_check_is_not_decoration} books.Accounts and books.Codes are two reads, taken at one instant but through different code paths. If they disagree this refuses rather than publishing over a truncated chart, because a chart missing rows yields a statement that is wrong in a way no identity here can see. ### Taint {#hdr-Taint} The \[]string books.Codes returns was allocated under that realm and reaches here readonly-tainted. Nothing below mutates it or stores it: the codes are read out by value, and the rows are allocated here.

Open
OID
03d65d…b668:13
chartOf details

Inspect func

deriveLive

func(owner .uverse.address) statements.Statement

deriveLive reads the owner's chart now and classifies it. Every live figure in this realm goes through here, so there is one path from the ledger to a statement and no accessor can derive differently from Publish. MustDerive, not Derive: on the mutating path an error return does not revert a Gno transaction and only a panic does.

Open
OID
03d65d…b668:14
deriveLive details

Inspect func

Publish

func() int64

Publish freezes the caller's own statement at the current height and returns its sequence number, which starts at 1 for each publisher. The owner is cur.Previous().Address() and there is no owner parameter, so authorization is structural rather than a check: there is no address for a caller to forge and no way to publish a statement about somebody else's book. A realm that calls in publishes over its own book for free, which arrives as a property of that rule rather than as a feature — the same way it does in r/books. An EMPTY CHART IS REFUSED, and this is a deliberate divergence from p/statements, whose doc calls zero rows "a legitimate statement of nothing". It is legitimate for a pure function and not worth a storage deposit here: a frozen row of zeros at a permanent path reads as a statement rather than as an absence, and the publisher has paid to say nothing. Everything that can refuse does so before this realm writes anything.

Open
OID
03d65d…b668:15
Publish details

Inspect func

Count

func(owner .uverse.address) int

Count is how many statements an owner has published. Zero for an address that has never published, which is not an error.

Open
OID
03d65d…b668:16
Count details

Inspect func

Latest

func(owner .uverse.address) (int64, bool)

Latest is an owner's highest sequence number, and whether they have published at all. The second result matters: sequence numbers start at 1, so a zero first result means "never published" and never "statement 0".

Open
OID
03d65d…b668:17
Latest details

Inspect func

Total

func() int

Total is how many statements exist across every publisher. It is a count and nothing more; see the package doc on why there is no enumeration and no cross-owner figure.

Open
OID
03d65d…b668:18
Total details

Inspect func

Has

func(owner .uverse.address, seq int64) bool

Has reports whether a publication exists, so a reader can distinguish it from the panics every accessor below raises for an unknown one.

Open
OID
03d65d…b668:19
Has details

Inspect func

PublishedAt

func(owner .uverse.address, seq int64) int64

PublishedAt is the chain height a statement was frozen at.

Open
OID
03d65d…b668:20
PublishedAt details

Inspect func

Rows

func(owner .uverse.address, seq int64) int

Rows is how many accounts the statement classified.

Open
OID
03d65d…b668:21
Rows details

Inspect func

BalanceSheet

func(owner .uverse.address, seq int64) (assets int64, liabilities int64, equity int64, cumulativeNet int64, claims int64)

BalanceSheet returns a frozen statement's balance sheet. cumulativeNet appears here as an EXPLICIT RECONCILING LINE because nothing in this stack closes a nominal account into equity. claims is liabilities + equity + cumulativeNet, so a reader who checks assets against liabilities + equity alone and finds it short by exactly cumulativeNet is not looking at a bug. assets and claims are both returned and their equality is deliberately not offered as a verdict; see the package doc.

Open
OID
03d65d…b668:22
BalanceSheet details

Inspect func

IncomeStatement

func(owner .uverse.address, seq int64) (cumulativeRevenue int64, cumulativeExpenses int64, cumulativeNet int64)

IncomeStatement returns a frozen statement's income statement. Every figure is CUMULATIVE SINCE THE BOOK'S FIRST POSTING, not a period figure; see the package doc.

Open
OID
03d65d…b668:23
IncomeStatement details

Inspect func

SectionTotal

func(owner .uverse.address, seq int64, section string) int64

SectionTotal returns the figure presented for one section: "assets", "claims" or "performance". The performance total is the income statement's bottom line, not the sum of its two components.

Open
OID
03d65d…b668:24
SectionTotal details

Inspect func

AbnormalCount

func(owner .uverse.address, seq int64) int

AbnormalCount is how many accounts in a frozen statement carry a balance running against their kind. ### What the census catches, and what it cannot {#hdr-What_the_census_catches__and_what_it_cannot} This is the only partial answer in this portfolio to p/journal's consumer obligation 7 — a kind set wrongly when an account was opened is undetectable in that package and undetectable anywhere else in it. The answer is sound and incomplete, and the incompleteness is exact: - It CATCHES a misclassification that crosses the debit/credit-normal boundary and whose account has a non-zero balance. An account named "Accounts payable" but coded 1200 is an asset in r/books' scheme, accumulates credits, and reads negative here. - It CANNOT CATCH a misclassification that stays on the same side: liability to equity to revenue, or asset to expense. Both subtotals move, no balance goes negative, and nothing in this portfolio detects it. Obligation 7 is NARROWED, NOT CLOSED. - It has a FALSE-POSITIVE MODE that is not a defect. A genuine contra account — accumulated depreciation under assets, a sales return under revenue — is legitimately abnormal-signed. r/books' code-prefix scheme has no contra range, so such an account is indistinguishable here from a miscoded one. So a non-zero count is A FINDING TO READ, never a verdict, and a zero count is not a clean bill of health.

Open
OID
03d65d…b668:25
AbnormalCount details

Inspect func

AbnormalIn

func(owner .uverse.address, seq int64, section string) int

AbnormalIn counts the abnormal accounts presented in one section: "assets", "claims" or "performance".

Open
OID
03d65d…b668:26
AbnormalIn details

Inspect func

AbnormalAt

func(owner .uverse.address, seq int64, i int) (code string, name string, kind string, section string, balance int64)

AbnormalAt returns one census row by its zero-based index. Rows are in ascending account-code order, which p/statements enforces as a precondition on its input rather than relying on this realm to sort. section is the row's statement section, derived from its kind through the same mapping the totals were built from.

Open
OID
03d65d…b668:27
AbnormalAt details

Inspect func

CurrentBalanceSheet

func(owner .uverse.address) (assets int64, liabilities int64, equity int64, cumulativeNet int64, claims int64)

CurrentBalanceSheet derives the owner's balance sheet from their chart NOW, publishing nothing. It exists so that a false [Verify](#Verify) is diagnosable: a reader can see which figure moved instead of only that one did. Each of the three Current accessors re-reads the chart, so asking for all of them is three walks. [Verify](#Verify) is the single-call form.

Open
OID
03d65d…b668:28
CurrentBalanceSheet details

Inspect func

CurrentIncomeStatement

func(owner .uverse.address) (cumulativeRevenue int64, cumulativeExpenses int64, cumulativeNet int64)

CurrentIncomeStatement derives the owner's income statement from their chart now. Cumulative since inception; see the package doc.

Open
OID
03d65d…b668:29
CurrentIncomeStatement details

Inspect func

CurrentAbnormalCount

func(owner .uverse.address) int

CurrentAbnormalCount runs the census over the owner's chart now. Its reach is exactly [AbnormalCount](#AbnormalCount)'s.

Open
OID
03d65d…b668:30
CurrentAbnormalCount details

Inspect func

CurrentRows

func(owner .uverse.address) int

CurrentRows is how many accounts the owner's chart holds right now, as this realm reads it. It agrees with books.Accounts by construction — chartOf refuses when they disagree — and is exposed so a reader comparing a frozen statement's Rows against the live chart does not have to call two realms.

Open
OID
03d65d…b668:31
CurrentRows details

Inspect func

Verify

func(owner .uverse.address, seq int64) bool

Verify re-derives the owner's chart now and reports whether every figure in a frozen statement still holds, including the census rows. ### Read the ceiling before quoting this {#hdr-Read_the_ceiling_before_quoting_this} A true result means THE FROZEN FIGURES STILL HOLD. It does NOT mean the chart is untouched, and the gap is demonstrable rather than theoretical: a posting that moves an amount between two asset accounts leaves Assets, Claims, the net, the row count and the census all identical, and this still reads true. The suite pins that case. A false result is a real difference and nothing more: the owner has posted since, which is the normal life of a book. It is not evidence of misconduct, and this realm offers no mechanism that treats it as such. What proves the chart's own history is r/books' append-only journal, where a wrong entry is corrected by a visible reversal rather than an edit.

Open
OID
03d65d…b668:32
Verify details

Inspect func

Height

func() int64

Height is the chain height this realm stamps publications with. Exposed so a caller can predict what Publish will record.

Open
OID
03d65d…b668:33
Height details

Inspect func

Ledger

func() string

Ledger is the path of the realm every figure here is derived from. The constant is [BooksPath](#BooksPath); this is the accessor for a caller that cannot read a constant off a package.

Open
OID
03d65d…b668:34
Ledger details

Inspect func

pubKey

func(owner string, seq int64) string

pubKey is owner|paddedSeq. The sequence is left-padded to 19 digits — the width of MaxInt64 — so that lexicographic order over an owner's prefix is numeric order over their statements. An unpadded decimal would sort "10" before "9". The convention is r/invoices' invKey, adopted rather than re-derived.

Open
OID
03d65d…b668:35
pubKey details

Inspect func

ownerCount

func(owner string) int

ownerCount reads a publisher's count, treating an absent key as zero. avl.Tree.Get returns ONE value and cannot distinguish an absent key from a nil-valued one, so the two-value type assertion carries the existence answer in one traversal. Only this file ever Sets, and it only ever Sets an int.

Open
OID
03d65d…b668:36
ownerCount details

Inspect func

mustRecord

func(owner .uverse.address, seq int64) *statements.record
Open
OID
03d65d…b668:37
mustRecord details

Inspect func

parseSection

func(section string) statements.Section

parseSection turns a section word into a [stmt.Section](/gno.land/p/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/statements#Section) and panics on anything else. The three words are that type's own String output, so the round trip is exact; the suite pins it rather than trusting this to stay true of another package's method.

Open
OID
03d65d…b668:38
parseSection details

Inspect func

Render

func(path string) string

Render serves the index at "", a publisher's page at "\<address>", and one statement at "\<address>/\<seq>". Every caller-supplied string — an account's code and name, both of them an owner's free text in r/books — goes through \[cell]. Free text reaching Render unescaped is the one injection-shaped surface a realm with no custody still has, and here the bytes come from a THIRD realm's state, which does not make them safer.

Open
OID
03d65d…b668:39
Render details

Inspect func

cell

func(s string) string

cell prepares caller-supplied text for a GFM table cell, truncating it for display first. It is r/books' helper of the same name, adopted verbatim, because the slot is identical and the text is literally the same bytes one realm further on. TableCell rather than InlineText: these bytes land between two \`|\` delimiters and InlineText does not escape the pipe — deliberately, per the sanitizer's own doc, so that TableCell can escape it without double-escaping. r/books shipped InlineText in this slot first and an adversarial audit found it. The account CODE needs this as much as the name does. A GFM row is split before inline parsing runs, so a \`|\` inside a backtick span is not protected by the backticks, and r/books' kindFromCode constrains only the code's first character. TRUNCATE BEFORE ESCAPING, and on a RUNE boundary. Escaping first and cutting afterwards can slice a \`\\|\` in half and leave a cell ending in a bare backslash; cutting on a byte boundary can split a multi-byte rune and emit invalid UTF-8. By the time the sanitizer sees the string the damage is upstream of it.

Open
OID
03d65d…b668:41
cell details

Inspect func

renderPublisher

func(owner .uverse.address) string
Open
OID
03d65d…b668:42
renderPublisher details

Inspect func

renderStatement

func(owner .uverse.address, seq int64) string
Open
OID
03d65d…b668:43
renderStatement details

Inspect func
RealmPath : untyped string ="/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/statements"
BooksPath : untyped string ="/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/books"
PublicationsAreUncapped : untyped bool =true
RenderPublicationLimit : untyped bigint =(20 <untyped> bigint)
RenderAbnormalLimit : untyped bigint =(25 <untyped> bigint)
record : type =statements.record
published : *v0.Tree Inspect
counts : *v0.Tree Inspect
pubCount : int =2
refuseCoins : func() Inspect
parseKind : func(s string) journal.Kind Inspect
chartOf : func(owner .uverse.address) []journal.Account Inspect
deriveLive : func(owner .uverse.address) statements.Statement Inspect
Publish : func() int64 Inspect
Count : func(owner .uverse.address) int Inspect
Latest : func(owner .uverse.address) (int64, bool) Inspect
Total : func() int Inspect
Has : func(owner .uverse.address, seq int64) bool Inspect
PublishedAt : func(owner .uverse.address, seq int64) int64 Inspect
Rows : func(owner .uverse.address, seq int64) int Inspect
BalanceSheet : func(owner .uverse.address, seq int64) (assets int64, liabilities int64, equity int64, cumulativeNet int64, claims int64) Inspect
IncomeStatement : func(owner .uverse.address, seq int64) (cumulativeRevenue int64, cumulativeExpenses int64, cumulativeNet int64) Inspect
SectionTotal : func(owner .uverse.address, seq int64, section string) int64 Inspect
AbnormalCount : func(owner .uverse.address, seq int64) int Inspect
AbnormalIn : func(owner .uverse.address, seq int64, section string) int Inspect
AbnormalAt : func(owner .uverse.address, seq int64, i int) (code string, name string, kind string, section string, balance int64) Inspect
CurrentBalanceSheet : func(owner .uverse.address) (assets int64, liabilities int64, equity int64, cumulativeNet int64, claims int64) Inspect
CurrentIncomeStatement : func(owner .uverse.address) (cumulativeRevenue int64, cumulativeExpenses int64, cumulativeNet int64) Inspect
CurrentAbnormalCount : func(owner .uverse.address) int Inspect
CurrentRows : func(owner .uverse.address) int Inspect
Verify : func(owner .uverse.address, seq int64) bool Inspect
Height : func() int64 Inspect
Ledger : func() string Inspect
pubKey : func(owner string, seq int64) string Inspect
ownerCount : func(owner string) int Inspect
mustRecord : func(owner .uverse.address, seq int64) *statements.record Inspect
parseSection : func(section string) statements.Section Inspect
Render : func(path string) string Inspect
renderIndex : func() string Inspect
cell : func(s string) string Inspect
renderPublisher : func(owner .uverse.address) string Inspect
renderStatement : func(owner .uverse.address, seq int64) string Inspect