The DotGrid renderer and validator function by function: how Squeek images and metadata are rendered and verified onchain, with errors, limits and ABIs.
tokenURI supplies keccak256(abi.encode(collectionSeed, artSeed)) as the seed.These contracts may change before mainnet. Pin the ABI you use and re-check the deployment before relying on it.
The renderer derives each token's traits and image from a DotGrid page, the collection seed and the token ID. The page is a 44-byte header and ten ordered sections, stored as contract code in a page root and its chunks. The page validator checks a page's full structure. Neither holds state or emits events.
The Sepolia SqueekNFT runs both; their addresses and runtime hashes are under Deployments. Confirm them onchain from SqueekNFT's renderer() and the renderer's pageValidator() at the block you verify.
Sepolia addresses (release core-sepolia-20261103):
0x50888Ea2469Cc4E619bfcBdc4A7E7d58d4Ddd1650xA605e7a53bdE1bbA13bD6109A55B9C0D8Ea90ad7tokenURIfunction tokenURI(address page, bytes32 seed, uint256 tokenId) external view returns (string);
Reads and fully validates page, then returns base64 JSON metadata with an embedded SVG for tokenId.
| Name | Type | Unit | Meaning |
|---|---|---|---|
page | address | - | Page root address |
seed | bytes32 | - | Nonzero seed; for Squeeks after reveal, keccak256(abi.encode(collectionSeed, artSeed)) from SqueekNFT collectionSeed() and revealState() |
tokenId | uint256 | token ID | 1..2^192−1; the renderer does not check that the NFT exists |
Reverts with DotGridInvalid(code) for any page or input failure.
tokenURIForPinnedPageReturns the same metadata as tokenURI, but skips full validation when the page root's runtime hash equals codehash; SqueekNFT uses it after validating the page at construction. A codehash establishes no trust on its own, so validate that exact root first. Reverts with DotGridInvalid(132) on a mismatch.
renderSVGfunction renderSVG(address page, bytes32 seed, uint256 tokenId) external view returns (string);
function renderSVGForPinnedPage(address page, bytes32 codehash, bytes32 seed, uint256 tokenId) external view returns (string);
The SVG alone, strict or pinned.
validatePagefunction validatePage(address page) external view returns (bytes32 pageHash, bytes32 assetSetHash);
Strict read plus full validation. Returns the logical page hash and the asset-set hash, which SqueekNFT stores as sceneHash() and assetSetHash().
function rendererId() external pure returns (bytes32);
function rendererVersion() external pure returns (string);
function pageValidator() external view returns (address);
rendererId() is keccak256("sqk.dotgrid-renderer.v1") and rendererVersion() is sqk.dotgrid-renderer.v1. pageValidator() is the validator the renderer created; its code is not covered by the renderer's runtime hash, so pin it separately.
validatefunction validate(bytes page) external pure returns (Layout layout);
On the page validator: validates raw logical page bytes and returns the section directory. Most integrators call the renderer's validatePage instead.
| Field | Meaning |
|---|---|
name, description | Page-defined text with a token-specific title |
image | data:image/svg+xml;base64, embedded SVG |
attributes | Deterministically selected trait names and values |
properties.renderer, rendererId | Renderer version and identity |
properties.pageHash, assetSetHash | Logical page and renderer-bound asset identity |
properties.traitWord, resolvedFieldHash | Derivation and resolved-field evidence |
properties.emitters | Active emitter count in the resolved result |
The asset-set hash binds page and renderer: keccak256(ASSET_SET_DOMAIN || RENDERER_ID || pageHash), with domain keccak256("sqk.dotgrid-asset-set.v1"). It differs from the root codehash and the page hash.
The renderer and validator emit no events. SqueekNFT's BatchMetadataUpdate, emitted by announceReveal, announces when readers should refresh metadata.
Read every value at one Ethereum block and compare it with the deployment record. A matching hash confirms that the onchain bytes match that record.
renderer(), art(), artCodehash(), sceneHash(), assetSetHash() and collectionSeed(). art is the page root address.keccak256 of the renderer's runtime code with the expected hash, and rendererId() with keccak256("sqk.dotgrid-renderer.v1").pageValidator() and compare its runtime hash separately.artCodehash(); the root commits to its chunk hashes.validatePage(art) and require it to return sceneHash() and assetSetHash().revealState() to report revealed, then render an existing ID through SqueekNFT. Its seed is keccak256(abi.encode(collectionSeed, artSeed)).| Identity | What it proves |
|---|---|
| Renderer runtime hash | Exact rendering code |
| Validator runtime hash | Exact page-validation code |
| Root codehash | Root code, including its chunk hashes |
Page hash (sceneHash) | Logical page bytes |
| Asset-set hash | Renderer identity and page together |
Collection seed, reveal artSeed and token ID | The inputs that reproduce the same traits and image |
| Resource | Maximum or requirement |
|---|---|
| Token ID | 1..2^192−1 |
| Seed | Nonzero bytes32 |
| Page format | Magic 0x44475047, format 1 |
| Logical page / chunks | 49,152 bytes / 3 chunks |
| Runtime | 24,576 bytes per contract |
| Canvas / coordinates | 4,096 pixels / 64 units per pixel |
| Emitters | 2,048 |
| Trait categories / options | 16 / 64 |
| Palettes / glyphs / glyph path | 64 / 64 / 1,024 bytes |
| Optics / passes | 16 / 4 |
| Arrays / sets / lookup tables / tables | 8 / 64 / 64 / 1,024 |
| Resolve cost | 6,000,000 under the format's cost accounting |
| SVG / JSON / URI output | 131,072 / 196,608 / 262,144 bytes |