ContentsBrowse sections
Gno presents a smart-contract language it describes as “~99% identical to Go.” Familiar syntax and package structure carry into a system whose programs must be deterministic, metered, persistent and reproduced by every validator. The compatibility question concerns which accepted programs, semantics, standard library and tools carry over with them.
In its language overview, Gno places that figure beside two more specific propositions: Go programmers should face a “minimal learning curve,” and GnoVM interprets an abstract syntax tree rather than bytecode. Those claims live at different layers. Familiarity concerns what an author recognizes, compatibility what programs mean, execution identity what every validator reproduces. Treating them as one promise would collapse three different tests.
Ethereum, CosmWasm, Move, and Starknet bind execution to bytecode or a restricted intermediate representation. Gno commits source and performs type checking, preprocessing and package initialization inside consensus when a package is activated. Admission policy matters: the examined October release can park source in an inert state without type checking or execution at submission. Its evaluator also enforces source-resolved packages, persistent typed objects, realm authority, and storage bonds. Source-native composition therefore places language machinery inside consensus while leaving submission and activation as distinct transitions.
July source records identify revisions, paths, lines and Git objects. Comparisons with v1.5.1 place later repairs and tests beside the mechanisms they concern. The October source and network observations separately identify what was built locally and what a current endpoint reported.
Testing Gno’s “~99% Identical to Go” Claim
A reproducible “~99% identical to Go” result requires a named program suite, weighting rule, Gno release, and procedure. The public documentation supplies no such calculation. The figure works as an orientation to familiar syntax and package structure rather than as a measured compatibility result.
Compatibility reaches across accepted programs, runtime semantics, failure modes, standard-library coverage, tools, execution cost, and authority. Each dimension produces a different denominator. Familiarity lowers the cost of reading Gno code while leaving those deeper boundaries to be tested separately.
Gno’s documentation names Go 1.17 as the target language specification. The implementation crosses later boundaries for specific reasons. In the July source analysis, the pinned parser Makefile source copies GOROOT/src/go/parser, applies gno.patch, and commits the generated code for ordinary validator builds. The TypeCheckMemPackage source configures Go’s go/types for Go 1.18 because Gno’s injected built-ins use any and type parameters. The interpreter separately adopts Go 1.22’s per-iteration loop-variable rule. A source comment supplies the compact description: Gno “matches no single Go version.”
These Go-version numbers describe different layers of a deliberately constrained consensus language. The declared surface excludes generics, goroutines, channels, and select; the chain adds concepts that Go lacks, including realms, explicit crossings, persistent object identity, gas, and storage authority. The project’s compatibility reference is correspondingly granular. It classifies standard-library packages as full, partial, test-only, future, undecided, non-deterministic, Go-specific, or dependent on generics.
Gno is more precisely described as a Go-derived smart-contract language, readable to Go developers and governed at runtime by Gno-specific semantics. October release source preserves the mixed-version type-check gate; the CLI fixtures below test a narrow part of the accepted-program boundary.
What Gno Gains by Keeping Source
An import such as gno.land/p/demo/avl names a source package stored in consensus state: the data every validator commits to and must reproduce. Another application can import that package by path, and the chain can serve its implementation directly.
In the July deployment path, MsgAddPackage accepts a MemPackage containing .gno source and package metadata. The package-admission source validates that material and charges gas for its source. TypeCheckMemPackage Go-parses and type-checks the files while resolving imports. The RunMemPackage source parses them into Gno nodes, preprocesses declarations, executes package initialization, persists package values, types, nodes, and surviving objects, and stores the source package.
Inert Submission and Activation
In the examined release, a configurable policy separates submission from activation. The submission-policy definitions distinguish permissionless, permissioned and inert modes. The inert branch stores submitted packages without type checking or execution at that step. They become callable only through a later enabling operation. The branch charges the submitter for deferred front-end work and treats genesis separately from replayed transactions.
Source can be present in committed state before it becomes active, and admission policy can allocate authority over activation. A package’s readable bytes alone therefore do not establish that ordinary calls can execute it. The relevant question includes its state, the configured policy and the enabling transition. This review establishes that the release implements those modes; it does not establish which policy a named live deployment uses.
Type checking and package loading use the production MemPackage blob. Query paths can reconstruct the full package by adding any #allbutprod sibling that contains test or file-test material. The MemPackage store source shows both blobs written through IAVL, the immutable AVL-tree key-value store backing committed state.
An ordinary MsgCall later loads persisted package, node, and value structures and parses only a synthesized call expression. Preprocessed Gno nodes, types and values persist, and the exact .gno files are part of the chain-committed program record. These structures are distinct from the transient go/types type-check cache discussed below. The package path supplies the addressable identity, while behavior also depends on the persisted Gno structures, state, and evaluator version.
Stateful /r/ packages, called realms, extend the idea from readable code to durable objects. A realm has persistent state and an authority identity. At the end of a transaction, GnoVM follows changed object references, assigns persistent identities, saves reachable state, removes objects with no remaining references, and attributes the byte difference to a realm. Imports remain familiar while persistence adds realm ownership to the object graph.
The design yields inspectable programs, readable dependency paths, and typed persistent state. Each property depends on a wider execution boundary. Peer systems usually bind execution after source has been transformed.
Where Peer Systems Draw the Execution Boundary
Every smart-contract system needs a smaller execution contract than the host environment used to author code. Files, clocks, networks, concurrency, native libraries, and allocation without protocol gas are useful in ordinary programs and hazardous in replicated execution. The design question is where to constrain them and which artifact every validator agrees to execute.
Ethereum uses Solidity and Vyper for authoring and EVM bytecode for execution. Contract accounts hold the compiled bytes, and validators implement the EVM instruction set. Ethereum’s EVM documentation defines the deployed artifact; its verification guide explains the tradeoff. Readable source, compiler version, optimizer settings, and deployed bytecode must be matched after deployment.
CosmWasm’s officially supported contract stack uses Rust for authoring and WebAssembly for execution. Developers compile for wasm32-unknown-unknown, optimize the module, and upload the resulting binary. Rust parsing and type checking stay outside consensus; bytecode-level validation stays in the chain path. The build guide treats optimized Wasm as the deployable artifact, and the VM compatibility source constrains its structure, imports, exports, memory, limits, and capabilities.
Move carries more of its safety model into typed bytecode. The July-reviewed Aptos build documentation places .mv modules beside separate .mvsm source maps and .move source files. The foundational Move design checks submitted bytecode for structural, type, reference, resource, semantic, and linking safety before interpretation. Move as deployed keeps verification inside consensus while the source compiler stays outside the trusted computing base and transaction critical path. The Aptos compilation guide and foundational Move paper describe that division.
Starknet preserves provability at its intermediate boundary. Cairo source compiles into Sierra, the declared contract representation. The declaring party obtains a CASM compilation and supplies its compiled-class hash, and once the declaration enters a block, the class trie maps the Sierra class hash to that lower-level hash. The July-reviewed state documentation describes proving Sierra-to-CASM compilation inside the Starknet OS as future work. Starknet’s Sierra documentation explains how failed transactions remain provable and gas requirements become explicit before lower-level execution.
-
Ethereum EVMAuthor Solidity / Vyper Transform Compile outside consensus Consensus begins Protocol input EVM bytecode Decode Transaction and instruction stream Execute EVM instruction set
-
CosmWasm Wasm VMAuthor Rust Transform Compile and optimize outside consensus Consensus begins Protocol input Wasm module Validate Imports, exports, memory, limits, capabilities Execute CosmWasm VM
-
Aptos Move VMAuthor Move Transform Compile outside consensus Consensus begins Protocol input Move bytecode
.mvVerify Structure, types, references, resources, semantic checks, linking Execute Interpret verified module -
Starknet Cairo VMAuthor Cairo Transform Compile source to Sierra and Sierra to CASM outside consensus Consensus begins Protocol input Sierra class hash + compiled-class hash Bind Class trie maps Sierra hash to CASM hash Execute Cairo VM over CASM
-
Gno GnoVMAuthor Gno source Consensus begins Protocol input
.gnosource package Front end Parse and type-check Prepare Preprocess and initialize Persist Nodes, types, values, objects; later calls interpreted
These systems still perform consensus-time analysis over an artifact below the full source language. The EVM executes an untyped instruction stream, CosmWasm validates a restricted Wasm module, and Move verifies typed bytecode. Starknet commits the association between a Sierra class hash and a supplied compiled-class hash, then executes the CASM form. July-reviewed documentation assigns proof of Sierra-to-CASM compilation inside the Starknet OS to future work. The human-language parser and source compiler remain outside consensus; artifact decoding, validation, linking, and protocol binding remain inside.
A stable executable format keeps high-level source parsing, source-package resolution, compiler diagnostics, and optimizer evolution outside the consensus critical path. A smaller instruction vocabulary narrows what the protocol must hash, meter, specify, and test. Nodes may interpret, cache, JIT, or AOT-compile the committed artifact only when those strategies preserve consensus results and metering. Bytecode and IR guarantee none of those properties by themselves.
Execution identity in these systems is bound to the lower-level artifact. Human source can be published alongside it. Establishing correspondence requires reproducible compilation, metadata, or a verification service.
Gno chooses a wider boundary. Its language overview treats direct interpretation of the parsed syntax tree as a defining feature. Exact .gno files enter the chain-committed program record, and front-end work for activation runs inside the state transition. Human-readable imports and direct source retrieval become consensus-visible features.
That wider boundary carries a structural cost. A source-language front end evolves across releases, processes adversarial input before contract initialization, and must preserve old semantics once persistent state depends on them. Parser behavior, host-checker configuration, preprocessing limits, dependency caches, gas prices, object persistence, and migration rules all enter the protocol surface. Gno accepts that larger surface to gain source-native composition.
GnoVM Cache State and the Block 352,922 Halt
The architectural tradeoff became visible at block 352,922, when validators processed the same package source with divergent evaluator cache states.
Cache State and Divergent Gas
A maintainer analysis in the project’s change record describes the failure. TypeCheckMemPackage inserted packages reached as dependencies into the permanent cache. Root type-check calls left their packages outside that cache. The production genesis path also routed initialization through a per-transaction cache that was later discarded. Restart initialization populated dependency entries while leaving twenty-two root or “leaf” standard libraries absent, including time, regexp, and math/rand.
MsgAddPackage
Same package source; different consensus-metered store reads
- Initialization uses a per-transaction cache.
- The transaction ends and that cache is discarded.
- Metered work
- ≈ 7.0M gascold profile
- Dependency entries populate during restart.
- Twenty-two root or leaf libraries remain absent.
- Metered work
- ≈ 2.1M gaswarm profile
Reported cause Maintainers associate the divergent gas profiles with the halt after block 352,922.
Repair Populate every initialization path, compare cold and warm gas in regression tests, then release v1.1.0.
Public block timestamps place block 352,923 more than 78 hours after its predecessor. The causal account comes from the maintainers, and an independent outage trace is unavailable.
Deterministic Admission Beyond the Cache
The incident exposes a broader requirement: evaluator state must be normalized wherever it can affect consensus. In the examined source, types.Config.GoVersion is set to Go 1.18. This selects the requested language version for go/types while leaving host implementation details to the bundled toolchain.
Other admission choices narrow the consensus result. ErrTypeCheck wraps variable parser and type-checker diagnostics in a stable coarse cause for the consensus-hashed result while retaining detailed text outside that cause. The keeper sorts realm-state changes before applying them and charges a fixed rate per .gno byte before type checking and preprocessing.
The boundary moved across releases. At v1.0.0 and v1.1.0, the channel fixture cleared conversion and failed during Gno execution. A follow-up change moved channel rejection ahead of execution two days after v1.1.0.
The July command-line interface (CLI) fixtures mark a separate boundary. A supported program printed ok, while goroutine and channel inputs returned “not permitted” without a host stack trace. A generic program, valid in modern Go but outside Gno’s declared surface, reached preprocessing through gno run and produced a recovered host panic with a Go stack trace. That command bypasses TypeCheckMemPackage, so this fixture covers the CLI path. The deployment path requires separate evidence because GoVersion: go1.18 permits generic syntax and an open proposal adds an explicit rejection before go/types. The finding is confined to CLI containment, and live-network behavior requires separate evidence.
The release retains the go1.18 type-check setting and the comment that Gno matches no single Go version. Four local CLI fixtures sharpen the result. The supported program printed valid-gno-path. Goroutine and channel fixtures exited with the respective “not permitted” diagnostics. The unsupported generic fixture exited with a recovered host panic and stack trace during preprocessing, including name T not defined in fileset.
For this unsupported input, the CLI reports a recovered host panic and stack trace rather than an ordinary diagnostic. It does not establish that a supported Gno program is incorrect, or that a transaction on the public network reaches the same path. The command does not exercise the complete chain package-admission route. No hostile package was submitted to a live network.
The release’s build-tag regression tests expose another admission boundary. A Go build tag supplied in a package or its import cannot raise the pinned language version. Tests reject newer syntax despite such a tag, while accepting an older-language body tagged with a hypothetical later Go version. Both test functions passed independently. The rule keeps a submitter’s comment from selecting a different type-checking language; broader host-toolchain equivalence still requires a replay comparison.
GnoVM Work Dimensions That Gas Must Bound
Accepted code runs inside GnoVM’s AST-directed stack interpreter. The Machine.Run source repeatedly pops internal operations through runOnce until OpHalt. Supported paths charge gas through flat incrCPU costs, operation-specific slopes, native-call tables, and allocation or storage meters. Gas is intended to bound validator effort. The remaining question is whether every relevant work dimension is priced and bounded. Performance requires separate benchmarks.
The examined gas table combines base costs with slopes for allocation, traversal, comparison, and large-number operations. Several paths, including realm crossing and some native calls, still carry values described as arbitrary or incompletely benchmarked. Package submission charges 1,250 gas per source byte, calibrated on realistic packages. The source notes that imported-dependency rechecking was excluded and that host-machine calibration remains uncertain.
Source length also failed to express one preprocessing cost. A tiny chained constant expression could create rapidly expanding intermediate values, so the VM added a separate allocation cap, captured by the allocation regression source. The July account of open PR 5826 described a deterministic 100,000-node type-expansion budget and explicit pre-go/types rejection of generic and interface-type-set fan-out. Its October proposal has changed, as discussed below; the July budget must not be presented as its current design. In the examined source, the 1,250-gas-per-source-byte charge meters input length. Potentially exponential work in go/types’ native validType traversal occupies a separate cost dimension and needs its own bound.
PR 5826 also remains open, but its current description proposes charging a structural type-expansion cost and rejecting selected syntax before go/types, rather than the old fixed node budget. Its timings and unguarded stress result are the contributor’s reported evidence here. This review did not repeat that resource-exhaustion experiment or treat the proposal as merged. The substantive question survives the revision: source length, type expansion and evaluator work are distinct quantities, so a linear byte charge cannot by itself demonstrate a bound on every front-end path.
Source size, allocation growth, structural type expansion, opcode work, and storage access are different costs. A robust evaluator needs an effective bound for each.
Gno Realm Authority Inside a Method Call
A Gno-specific security boundary appears in an ordinary method call.
Borrowed Realm Authority
A realm is a stateful /r/ package. A /p/ package is reusable library code without persistent realm state of its own. When an object is allocated, the VM attaches a PkgID: a runtime ownership stamp rather than a user identity or cryptographic key. If the object survives transaction finalization, that stamp helps determine which realm owns the bytes and which active authority may modify them.
The VM tracks two related contexts. Realm-context records who is acting and advances through an explicit cross(rlm) call. Realm-storage-context, held in m.Realm, carries the active write authority. It determines whose ownership stamp new persistent state receives and whose state the current frame may principally modify. The two contexts usually travel together. An implicit borrow can separate them.
The ordered borrow rules are where Gno departs sharply from Go. A realm-declared function can borrow the declaring realm’s authority. Called on an object stamped by another realm, a /p/ method can borrow the receiver’s storage authority. A /p/ closure can carry the authority of the realm in which it was created. The three branches appear together in the Machine.PushFrameCall source. These rules let a stateless library update a data structure owned by its caller without acquiring persistent state of its own. They also give an ordinary-looking call more authority than its syntax reveals.
Write Authority Laundering
The project’s security-guide source describes one composition risk as “write authority laundering.” The repository’s filetest source supplies the executable case.
A victim realm owns an object whose type comes from a /p/ library. Calling a library method on that realm-stamped receiver lends the method the victim’s storage authority. That method then invokes an attacker-supplied top-level /p/ function. A top-level package function inherits the current authority context, so the callback retains the storage context already active inside Apply. It can write through the victim’s exposed mutable shape.
In the filetest, the victim-stamped object’s Apply method receives an attacker package’s EvilWrite callback. The expected value changes from embed-orig to pwnd-via-apply.
Evidence limit A live exploit also requires an API that exposes mutable data and the relevant callback shape.
The guide names patterns that deserve review, including iteration and builder callbacks, and recommends private sensitive fields, restricted callback types, careful pointer exposure, and explicit realm-transition checks.
The release also preserves the authority composition described above. All 67 selected realm-laundering fixture cases passed, covering blocked writes, independent value copies and calls that retain borrowed receiver authority. The stored-method case still produces pwnd-via-apply through the library callback. Agreement with these expected outcomes identifies the tested authority rules; it does not classify every permitted composition as a defect.
These authority rules are Gno-specific. Authority follows the object, the function form, and the path into the call.
Gno Storage Deposits and Long-Lived State
Every persistent byte becomes work the network must carry into future blocks. Gno prices part of that obligation with a refundable storage bond.
The VMKeeper.processStorageDeposit source gathers realm-state byte changes, sorts realm paths for deterministic application, and locks the configured amount in ugnot, the base denomination of GNOT, when measured state grows. When state shrinks, value is released according to the realm’s historical deposit-to-storage ratio, so later price changes preserve the valuation attached to old bytes.
The refund recipient depends on token restrictions. Unrestricted ugnot goes to the caller who triggers the cleanup. Restricted ugnot goes to StorageFeeCollector, and the event records RefundWithheld. Realm design therefore determines who may allocate persistent bytes, who supplies the bond, and who can cause its release.
Parameter Validation and Execution
At the July revision, configuration validation accepts a wider form than the execution path handles. The Params.Validate source accepts StoragePrice and DefaultDeposit through plural ParseCoins. The execution paths later use singular MustParseCoin, take the configured amount, and perform transfers in ugnot. A value of 100foo passes validation while its amount is charged in ugnot. A governance-set multi-coin value can pass validation and later panic on the execution path that consumes it.
The release’s parameter validator now requires both DefaultDeposit and StoragePrice to contain exactly one coin denominated in ugnot. The release regression test rejects multi-coin sets and wrong denominations. That test passed independently in this review. The July mismatch concerns the old revision; the examined release repairs it.
Package Data Outside the Storage Bond
The bond covers a subset of consensus state. Raw production and test MemPackage blobs are stored under separate keys in the same committed store, outside realm logical byte-difference accounting. An open draft, at its July 26 snapshot, proposes moving test-only package data outside the application hash and treats the change as consensus-breaking. Readable source therefore has a state footprint beyond the storage bond’s measurement boundary.
The broader accounting distinction persists. In the examined release, production and test package blobs still enter the committed store through separate keys. PR 5971 remains an open draft proposing a different treatment of test material. An open proposal is evidence of a design under discussion, not an implemented change to the current state boundary. The storage bond’s realm accounting and the complete consensus footprint still need to be distinguished.
Legacy State and Deposit Coverage
Realms that predate chain-parameter byte accounting lack a metadata baseline for their legacy parameter state. Deleting those old bytes first yields zero refund. If a realm first creates newly charged state and later deletes legacy state, current accounting can unlock existing post-feature deposits against unfunded legacy bytes. The mixed-history deposit test source constructs that sequence and asserts the coverage shortfall.
The case is bounded by the legacy bytes and deposits of an affected realm. This boundary belongs to migration history. A network that activates the mechanism at genesis starts with a baseline, while pre-feature realms carry state the later accounting rule never priced.
Gno Runtime Upgrades and State Continuity
Gno’s source-native applications turn every runtime release into a question about history. A package remains useful only while later parsers, type checkers, realm rules, storage encodings, and libraries can still give its state an executable meaning or supply a deliberate migration.
The Topaz testnet release reports a direct experiment. The initial plan called for replaying gnoland1 and roughly 1.26 million Test13 transactions into a new genesis. That prototype approached three gigabytes and took about two hours on a fast machine. Language and API drift mattered more: a newer package-path rule rejected GnoSwap deployments, and the missing dependencies cascaded into roughly 1.2 million failed calls. Changes to AVL and runtime APIs broke further packages.
The team launched Topaz with curated packages and fresh state, leaving Test13 balances, realms, and names in the prior lineage. For a testnet, that was a documented engineering choice: a new state lineage replaced a replay full of compatibility patches.
The episode separates readable history from executable continuity. The archive preserves source and transaction attempts, while execution outcomes and distinct user identities remain unresolved, and reproducing their effects requires the old evaluator or a verified transformation into the new one. Because persistent state must remain meaningful under later evaluators, language compatibility directly governs state continuity.
Topaz Release Artifacts and Deployed Runtime Identity
The Topaz release links source and artifacts. It names a source revision, publishes binaries and checksums, and supplies a genesis-file digest. The inspected Darwin arm64 and Linux amd64 binaries embed the same revision. Establishing build reproducibility would require a bit-for-bit rebuild.
The release uses a lightweight, unsigned tag. Its checksums identify the downloaded bytes, while producer identity and the running process remain unresolved.
One build claim conflicts with the inspected artifacts. The release page says CGO_ENABLED=0. Both binaries report CGO_ENABLED=1 in their embedded metadata, and the Linux artifact is dynamically linked. CGO is the Go build mode that permits native C linkage, so the discrepancy concerns the build recipe rather than the named source revision.
Genesis introduces a related trust boundary. Startup instructions in the validator-guide source require --skip-genesis-sig-verification. The release README source explains that some transactions contain placeholder or intentionally invalidated signatures and that the names.Enable caller was patched after signing. The published digest lets validators check that they share the final genesis bytes. That startup flag makes the file the trusted input for initial state.
On 25 July, the public Topaz testnet endpoint self-reported a direct child of the release revision that adds a remote procedure call (RPC) idle-timeout setting. Artifact custody for that child build remains unresolved, as does the identity of the installed binary. The separately queried July Gno Betanet endpoint left its application and software build fields empty. These dated observations are not a current deployment inventory.
-
Source
Release-named source revision
The release names a source revision; both inspected binaries embed the same revision.
-
Build
Published build claim and artifact metadata disagree
- Release claim
CGO_ENABLED=0- Inspected binaries
CGO_ENABLED=1; Linux dynamically linked
-
Artifact
Published binaries + checksums
The manifest identifies downloaded bytes; producer identity and the running process remain unresolved.
-
Unverified transition
Artifact → operator deployment
The binding between a published digest and the operator’s installed binary remains unresolved.
-
Observed process
Endpoint-reported child revision
The endpoint names a child revision whose artifact digest is absent from the published release record.
- Published genesis digestshared final bytes
--skip-genesis-sig-verificationgenesis transaction signature verification bypassed- Trusted initial-state inputthe final file becomes authoritative
The digest identifies the file validators share. The startup flag makes that file authoritative without verifying its embedded transaction signatures.
Binding a public process to reviewed source requires specified build inputs, reproducible artifact identity, and evidence of the operator’s deployed binary. The Topaz record reaches identifiable release artifacts, while the observed process sits beyond that binding. Gno’s package-source model begins another identity chain inside the process. End-to-end verification requires both.
October Source and Network Observations
The latest-release response retrieved during this review names v1.5.1, published on 13 October. Its source revision is 07e44776c26187830b7dcbd2454991b5a1960378. The review obtained that immutable source archive, checked all 9,125 file blobs against the untruncated Git tree and independently built the local command-line tool. The parser and GnoVM package suites passed. Current master was captured separately from the release and was not substituted for its source. Those checks establish source custody and behaviour on selected local paths; they do not reproduce a published release binary or identify a network operator’s installed executable.
Current Network Observation
The current rpc.gno.land/status response names network gnoland-1, reports build version v1.5.1, height 882,363 and catching_up: false. Its application/software fields remain blank. The separately acquired abci_info response is not pinned to the same block. These observations identify what one endpoint reported at acquisition time. They do not bind its process to the source archive, local build or published artifact.
Source retrieval supplies a separate observation. The responding chain endpoint returned gnoblog.gno, its test file and gnomod.toml from gno.land/r/gnoland/blog. All three match the release examples byte for byte. The query responses supply neither a state proof nor a usable height. They demonstrate retrieval of production and test source through the public interface, without assigning those files to an independently verified atomic state or identifying the evaluator serving them.
Both attempts at the old Topaz hostname failed DNS resolution. That is a failed observation route, not proof that every Topaz node has stopped or that its history disappeared. The July Topaz release, genesis and artifact findings remain dated evidence. A new network/version label supplies no migration account connecting all old balances, packages and identities to the current state.
The current endpoint observations leave a specific gap between retrieved source and the process serving it. Byte-identical package files show direct source retrieval. They do not identify the evaluator, establish the configured admission policy or connect every historical state lineage to the running network.
Public Claims and Evidence
The Go comparison holds at the source layer: familiarity lowers the cost of reading and organizing Gno code. The execution contract extends through the custom evaluator, realm rules, persistent objects, gas schedule and migration policy.
Determinism depends on cache discipline, stable errors, metering, ordered state transitions, migration policy, and regression tests. The block 352,922 halt and its repair make that maintenance burden concrete. A supportable public claim should name the release, test boundary, and remaining type-check or preprocessing work.
On-chain source makes a deployed package directly inspectable without a voluntary address-to-source verification service. The parser, interpreter, compiled node, operator deployment, and interface still determine what that package becomes in use. Source-to-build evidence and deployed artifact identity would make the boundary traceable.
Storage deposits carry the clearest implemented GNOT utility in the examined source: measured realm-state growth locks ugnot, and eligible state release unlocks it according to the historical bond. Network-level attribution requires a named deployment and identified binary.
At block 352,922, validators could inspect the same source while their cache histories changed consensus-metered work. Realm authority, storage accounting and runtime migration extend the execution question to calls, persistent bytes and later releases. A source-native system lets an evaluator begin with the program’s readable text; establishing what runs also requires the evaluator, state and deployment identity.
Scope of Inference
Detailed source records and historical release comparisons use the immutable July snapshot. In October, the review separately pins v1.5.1 and repeats the parser/GnoVM suites, four CLI fixtures and the storage-money validator regression. The additional checks comprise 67 authority fixture cases, root/import build-tag tests and three chain-served package comparisons.
July fixtures covered authority laundering, preprocessing allocation, mixed-history storage deposits and CLI programs in supported, goroutine, channel and generic forms. The October outputs are recorded separately. Code citations open records containing the exact revision, path, lines, and content identity. Documentation, releases, and endpoints are dated separately. These tests establish behaviour on the examined paths, while live exploitation and deployed-binary identity require deployment evidence.
Further Tests
A measured compatibility claim needs a declared program suite, weighting rule, release and procedure. The remaining deployment question needs a different test: a reproducible build and evidence of the binary installed by an operator. A node’s version string supplies neither. Independently reconstructing the block 352,922 outage and replaying the same state across host environments would also test the maintainers' cache explanation and the evaluator’s consistency.
Later implementations must be assessed on their own paths. The repaired parameter validator already changes which findings apply to the October release. The distinction between source length and type-expansion work remains open to a resource-bound experiment; an unmerged proposal or a successful ordinary fixture cannot settle it.
References
Gno Language, Runtime, and Network
Gno Project. 2026. Gno language and runtime source. Repository snapshot.
Gno Project. 2026. “Go – Gno Compatibility.” Documentation. Source edition.
Gno Project. 2026. “What Is Gno?” Documentation. Source edition.
Gno Project. 2026. “Gno Interrealm Specification” and “Gno Security Guide for Realm Authors.” Inter-realm source record and security-guide source record.
Gno Project. 2026. Parser import workflow and Yaegi-derived file-test lineage. Parser source record and test-provenance source record.
Gno Project. 2026. GnoVM interpreter, realm, ownership, type-check, and store paths. Source.
Gno Project. 2026. VM keeper, gas, parameter-accounting, and storage-deposit paths. Package-admission source record, storage-deposit source record, and parameter-validation source record.
Gno Project. 2026. “Make cold stdlib load populate typeCheckCache.” Pull request 5400.
Gno Project. 2026. “Bound type-expansion fan-out before go/types validType.” Pull request 5826.
Gno Project. 2026. “Store test MemPackage blob outside consensus state.” Draft pull request 5971, July 26 snapshot.
Gno Project. 2026. “Topaz.” Published July 17. Release.
Gno Project. 2026. v1.5.1, published 13 October, and immutable release source 07e44776c26187830b7dcbd2454991b5a1960378. Release and source. Retrieved 18 October UTC during the 17 October Toronto review.
Gno Project. 2026. PR 5826 and draft PR 5971, current open descriptions retrieved 18 October UTC. Proposal evidence is distinct from release implementation. Type-expansion proposal and Package-store proposal.
Code Records
Gno Project. 2026. TypeCheckMemPackage; gnolang/gno@d14a037; gnovm/pkg/gnolang/gotypecheck.go, lines 159–190; Git blob 4a31fd943cfc4103ce7dc0b31f9f468e3b575411. Source.
Gno Project. 2026. VMKeeper.AddPackage; gnolang/gno@d14a037; gno.land/pkg/sdk/vm/keeper.go, lines 616–818; Git blob c757c06a255512fcae4ef019c66db17f9b820d7f. Source.
Gno Project. 2026. RunMemPackage; gnolang/gno@d14a037; gnovm/pkg/gnolang/machine.go, lines 369–459; Git blob f5d8a28c7aac952203091a6a2b3aae55966cf2b1. Source.
Gno Project. 2026. AddMemPackage and GetMemPackageAll; gnolang/gno@d14a037; gnovm/pkg/gnolang/store.go, lines 994–1197; Git blob c7673ea877addbdf15ee3e0d44f59e9eee1aaea1. Source.
CosmWasm. 2026. VM compatibility checks; CosmWasm/cosmwasm@4a8f975; packages/vm/src/compatibility.rs; Git blob bd702c2fe74435fd37395ec9eb2e77ff30bf2736. Source.
Gno Project. 2026. Machine.Run and runOnce; gnolang/gno@d14a037; gnovm/pkg/gnolang/machine.go, lines 1680–1760; Git blob f5d8a28c7aac952203091a6a2b3aae55966cf2b1. Source.
Gno Project. 2026. TestPreprocessAlloc_DoublingConcatBlowsUpFromTinySource; gnolang/gno@d14a037; gnovm/pkg/gnolang/preprocess_alloc_test.go, lines 277–321; Git blob 0f7d46ff2de8c011929f6982f2ab01f537e2f1af. Source.
Gno Project. 2026. “Gno Security Guide for Realm Authors”; gnolang/gno@d14a037; docs/resources/gno-security-guide.md; Git blob 8f4154b2573ac5fe4fadd5275ceaab7b4c420a96. Source.
Gno Project. 2026. VMKeeper.processStorageDeposit; gnolang/gno@d14a037; gno.land/pkg/sdk/vm/keeper.go, lines 1795–1937; Git blob c757c06a255512fcae4ef019c66db17f9b820d7f. Source.
Gno Project. 2026. Params.Validate; gnolang/gno@d14a037; gno.land/pkg/sdk/vm/params.go, lines 133–154; Git blob 6a0b092bbe58019f1664ebfa11d2c77a9896fe55. Source.
Gno Project. 2026. TestParamsDepositMixedPreFeatureCreateThenDeleteLeaks; gnolang/gno@d14a037; gno.land/pkg/sdk/vm/params_deposit_test.go, lines 143–204; Git blob 62ed0ff93fb2881b89be149c5f75fe6f838a0355. Source.
Gno Project. 2026. “Gno Interrealm Specification”; gnolang/gno@d14a037; docs/resources/gno-interrealm-v2.md; Git blob 07d36435a6b023ff839fa8033ac9d4560e3ed5c5. Source.
Gno Project. 2026. Parser import workflow; gnolang/gno@d14a037; gnovm/pkg/parser/Makefile; Git blob 1f141497f0f18969fd1cc73afc5c66d842a27c9d. Source.
Gno Project. 2026. GnoVM test provenance; gnolang/gno@d14a037; gnovm/tests/README.md; Git blob 6951a87e2f652d5d0dbfe0455c11bf84e9d4b6f1. Source.
Gno Project. 2026. Topaz validator guide; gnolang/gno@fc40526; misc/deployments/topaz.gno.land/VALIDATOR.md; Git blob f526fdffbaf0b3a1c7319868c941a58cdefa8a04. Source.
Gno Project. 2026. Topaz release README; gnolang/gno@fc40526; misc/deployments/topaz.gno.land/README.md; Git blob 33fee6c6dc9745d7fa620c2d9ddcd954e51c7d17. Source.
Comparative Execution Systems
Ethereum Foundation. 2026. “Ethereum Virtual Machine” and “Smart Contract Verification.” Accessed July 25. EVM documentation and verification guide.
CosmWasm. 2026. “Building the Contract” and VM compatibility checks. Accessed July 25. Build guide and VM source record.
Aptos Labs. 2026. “Compiling Move Packages.” Accessed July 25. Compilation guide.
Blackshear, Sam, Evan Cheng, David L. Dill, Victor Gao, Ben Maurer, Todd Nowacki, Alistair Pott, Shaz Qadeer, Rain, Dario Russi, Stephane Sezer, Tim Zakian, and Runtian Zhou. 2020. “Move: A Language With Programmable Resources.” Libra Association technical report, revised May 1, 2020. https://developers.diem.com/papers/diem-move-a-language-with-programmable-resources/2020-04-09.pdf.
Starknet. 2026. “Sierra Intermediate Representation” and protocol state. Accessed July 25. Documentation and state model.
Security Review
Oak Security. “Gno” audit reports, 2025–2026. Reports.