DocsTechnicalInscription Format

Technical

Inscription Format

The complete data model for MON-20 inscriptions — on-chain encoding, off-chain indexing, and derived state structures.

On-chain encoding

An inscription payload is a UTF-8 JSON string. It is passed as the payload argument to inscribe(string), which ABI-encodes it as a calldata string — a length-prefixed byte array appended to the function selector.

The contract emits the payload verbatim in the Inscribed event. This means the exact bytes you submitted — whitespace, key ordering, any extra fields — are stored permanently in the event log. The indexer re-parses the JSON from the event.

Extra unknown fields in the JSON are ignored by the indexer but preserved in the event log. For example, adding a "note" field won't break validation — but it has no effect on balances.

Canonical JSON format

While the protocol accepts any valid JSON (with required fields present), the recommended canonical format uses minimal whitespace and lowercase keys. This minimizes calldata size and therefore gas cost.

canonical-deploy.json
{"p":"mon-20","op":"deploy","tick":"moni","max":"21000000","lim":"5000"}
canonical-mint.json
{"p":"mon-20","op":"mint","tick":"moni","amt":"5000"}
canonical-transfer.json
{"p":"mon-20","op":"transfer","tick":"moni","amt":"500","to":"0xAbCd..."}

The Monadinals UI automatically generates canonical-format payloads. If you are constructing inscriptions manually, compact JSON is recommended to reduce gas cost.

Indexed state: Ticker registry

When the indexer processes a valid deploy inscription, it writes a record to the ticker registry. This record is immutable once written.

FieldTypeDescriptionRequired
tickstringLowercase ticker symbol. Primary key.YES
deployeraddressThe msg.sender of the deploy inscription.YES
max_supplyuint256Maximum total supply from the max field.YES
mint_limituint256Per-mint cap from the lim field.YES
decimalsuint8Decimal precision from the dec field (default 18).YES
minted_supplyuint256Running total of all confirmed minted amounts.YES
deploy_blockuint256Block number of the deploy inscription.YES
deploy_tx_indexuint256Transaction index within the deploy block.YES

Indexed state: Balance ledger

The balance ledger maps (address, tick) pairs to derived token balances. Every valid mint and transfer mutates this ledger.

FieldTypeDescriptionRequired
addressaddressHolder's EVM address. Composite primary key with tick.YES
tickstringToken ticker. Composite primary key with address.YES
balanceuint256Current derived balance. Increases on mint, decreases on outbound transfer, increases on inbound transfer.YES

No negative balances

The indexer never permits a balance to go negative. A transfer with amt exceeding the sender's balance is silently dropped. The ledger is guaranteed to only contain non-negative values.

Indexed state: Inscription log

The indexer stores a complete log of all processed inscriptions — including invalid ones that were ignored. This powers the Explorer and allows reconstruction of derived state from scratch.

FieldTypeDescriptionRequired
iduint256Sequential inscription ID assigned by the indexer.YES
fromaddressOriginating address (msg.sender from the event).YES
opstringOperation type: deploy, mint, or transfer.YES
tickstringTarget ticker symbol.YES
payloadstringRaw JSON payload as emitted in the event.YES
block_numberuint256Block number of the inscription.YES
tx_indexuint256Transaction index within the block. Used for canonical ordering.YES
tx_hashbytes32Transaction hash for on-chain verification.YES
validbooleanWhether the indexer accepted this inscription. Invalid inscriptions are still stored for auditability.YES
timestampuint256block.timestamp from the event.YES

State reconstruction

Because all state is derived from events, the indexer can be fully rebuilt from scratch at any time by:

  1. 1Querying all Inscribed events from the contract address, ordered by block number and transaction index
  2. 2Replaying each event through the MON-20 validation and state-mutation logic in order
  3. 3Arriving at the same ticker registry, balance ledger, and inscription log as any other correctly-implemented indexer

Trustless verification

Any developer can run their own indexer against the Monad node to independently verify balances. The on-chain event log is the canonical source of truth — the Monadinals team's indexer is just one implementation of the derivation rules.