Skip to main content

GCR Structure

The following schema shows the internal database structure of the GCR. The GCR is comprised of several native data tables and a metatable. The main ones are described below.
GCR Structure

gcr_main

This is the primary table where the essential properties of a Demos account within the network are stored. Each account is keyed by its pubkey and holds its nonce and balance (see the balance column note below). Cross-context properties — tracked web3/social identities, points, and referral info — are stored in optimized JSONB columns (identities, points, referralInfo), allowing for efficient data management and lower overhead.

Account structure (gcr_main columns)

A Demos account is a single gcr_main row with the following columns (from src/model/entities/GCRv2/GCR_Main.ts):
ColumnTypeDescription
pubkeytext (primary key)The account’s public key — its network address.
nonceintegerMonotonic transaction counter for replay protection.
balancenumeric(38,0)bigintAccount balance in the active denomination (DEM pre-fork, OS post-fork). See the balance column note below.
identitiesjsonb (StoredIdentities)Cross-context identities — xm (web3 wallets), web2 (social accounts), pqc (post-quantum keys), ud (Unstoppable Domains). See Cross-Context Identities.
pointsjsonbReputation points: totalPoints, a per-source breakdown, and lastUpdated. See Points System.
referralInfojsonbreferralCode, referredBy, referrals[], totalReferrals. See Referral System.
flaggedbooleanWhether the account is flagged (e.g. suspected bot / no-activity heuristics).
flaggedReasontextReason enum: twitter_bot, evm_no_tx, solana_no_tx, web3_no_tx, only_evm_no_tx, manualFlag, referrerFlagged, or "".
reviewedbooleanWhether the flag has been manually reviewed.
createdAt / updatedAttimestampRow lifecycle timestamps.

gcr_subnets_txs

This table is responsible for holding and indexing all the transactions that happens in a Subnet. Note that tx_data contains the encrypted data for that specific Subnet’s tx and can only be decrypted by partecipants of the Subnet itself. See how-are-l2ps-transactions-handled.md for more informations.

gcr_assigned_txs

This table records which transactions have been assigned to which GCR account (pubkeytx_hash, with the block_number they were applied in). It replaces the assignedTxs JSONB array that previously lived on gcr_main, eliminating the write-amplification of appending to a growing JSONB column on every block.

gcr_hashes

This table is separate from the GCR data. As a metadata table, it stores the combined hashes of the GCR’s native tables to generate a GCR Status hash. This is crucial for verifying the consistency of GCR statuses during synchronization and consensus processes.

gcr_main — balance column type

The newer gcr_main table stores per-account balances directly. The balance column is numeric(38, 0) — arbitrary precision, integer-only — widened from the original bigint to accommodate the osDenomination fork: post-fork balances are 10⁹× their pre-fork values (UPDATE gcr_main SET balance = balance * 1000000000 would otherwise overflow signed 64-bit on production seed magnitudes). At the application boundary the column is read as a TypeScript bigint via the bigintNumericTransformer (src/model/entities/transformers.ts). Existing call sites that worked with the previous bigint column continue to work unchanged. Raw entityManager.query(...) callers must wrap the value in BigInt(row.balance) — this was already the convention because the pg driver also returns bigint columns as strings. The numeric(38, 0) zero-scale constraint enforces integer-only writes at the column level, comfortably covering the 10²⁷ OS magnitude ceiling.

Unimplemented GCR edit types

GCR mutations are applied by edit type in src/libs/blockchain/gcr/handleGCR.ts. A few edit types are recognized by the dispatcher but are not yet implemented — they are no-ops on the apply path and should not be relied on:
  • escrow — logs not yet implemented and applies nothing. The SDK exposes an escrow module, but escrow transactions are not settled by the node on current networks.
  • smartContract — Demos-native contract edits are not yet wired (not yet implemented).
  • assign and subnetsTx — return "Not implemented".
Integrators should treat these as forward-looking and not assume on-chain effect until the apply path lands.