3. Evidence System

3.1 Evidence Unit Schema

An Evidence Unit is a single observation with provenance. Evidence without provenance is not admissible.

{
  "evidenceId":       "string         // Content-addressed (Keccak-256 of canonical form)",
  "type":             "EvidenceSourceType",
  "source":           "string         // Declared source (e.g., 'solana-mainnet-rpc')",
  "retrievalMethod":  "string         // How evidence was obtained",
  "anchor": {
    "block":          "number         // Block/slot number",
    "slot":           "number | null  // Solana slot (if applicable)",
    "time":           "string         // ISO 8601 timestamp"
  },
  "integrity": {
    "hash":           "string | null  // Content hash of canonical form",
    "signature":      "string | null  // Provider signature (if available)"
  },
  "canonicalForm":    "bytes          // BCE-encoded content (Section 3.4)",
  "rawResponse":      "bytes | null   // Original provider response (for audit)",
  "ref":              "string         // Reference URI for independent retrieval (see below)"
}

ref Field Specification (for independent validator retrieval):

The ref field MUST contain sufficient information for a validator to independently retrieve the same evidence from the original source. Combined with retrievalMethod and anchor, this enables trustless replay verification (Section 7.2, Step 2).

Evidence Class ref Format Example
ONCHAIN (Solana) solana://{cluster}/{method}?params={url-encoded-json} solana://mainnet/getTokenAccountsByOwner?params=["AcAddr",{"mint":"MintAddr"},{"encoding":"jsonParsed"}]
ONCHAIN (EVM) evm://{chainId}/{method}?params={url-encoded-json} evm://1/eth_call?params=[{"to":"0x...","data":"0x70a08231..."},"0xF4240"]
OFFCHAIN_PINNED https://{source-domain}/{path} https://api.dexscreener.com/latest/dex/tokens/{addr}
OFFCHAIN_EPHEMERAL social://{platform}/{post-id} social://twitter/1234567890

For ONCHAIN evidence, the anchor.block / anchor.slot field specifies the exact historical state to query. Validators reconstruct the RPC call as: RPC_CALL(ref.method, ref.params, at_block=anchor.block).

For OFFCHAIN evidence, ref is informational — the original source may no longer serve the same data. Validators fall back to operator-served or decentralized storage copies, verified by integrity hash only.

3.2 Evidence Source Type Taxonomy

EvidenceSourceType = ONCHAIN_STATE | TX | EVENT | CODE | OFFCHAIN_DECLARED

Detailed Source Registry:

Source Type Chain Description Retrieval
ACCOUNT_BALANCE Solana SPL token balance at slot getTokenAccountsByOwner
ACCOUNT_BALANCE EVM ERC-20 balance at block eth_call(balanceOf)
TOKEN_SUPPLY Solana Total supply at slot getTokenSupply
TOKEN_SUPPLY EVM Total supply at block eth_call(totalSupply)
TOKEN_METADATA Solana Metaplex metadata (name, symbol, URI) getAccountInfo
TRANSFER_EVENT Solana SPL Transfer instruction log getTransaction logs
TRANSFER_EVENT EVM ERC-20 Transfer event log eth_getLogs
POOL_RESERVES Solana AMM pool state (reserves, sqrt_price) getAccountInfo
POOL_RESERVES EVM Uniswap/DEX pool reserves eth_call(getReserves)
PROGRAM_DATA Solana Account data / IDL-decoded state getAccountInfo
CONTRACT_CODE EVM Contract bytecode at block eth_getCode
TX_RECEIPT All Full transaction with status and logs getTransaction
SOCIAL_POST Off-chain Twitter/X post with engagement metrics API or scrape
SOCIAL_ENGAGEMENT Off-chain Aggregated social metrics API
DEX_SCREENER_DATA Off-chain Market data from DexScreener API / scrape

3.3 Off-Chain Evidence Lifecycle

Off-chain evidence (SOCIAL_POST, SOCIAL_ENGAGEMENT, DEX_SCREENER_DATA) is fundamentally different from on-chain evidence: it is mutable at source, ephemeral, and cannot be independently re-fetched at a later time. Tweets get deleted, engagement metrics fluctuate, DexScreener data changes. This creates a tension with replay reproducibility that the protocol resolves through mandatory snapshot-and-store semantics.

Snapshot-at-Collection Rule:

For all OFFCHAIN_DECLARED evidence types:

  1. The canonicalForm is captured once at evaluation time and becomes the immutable snapshot. It represents the state of the off-chain source at the moment of collection, not at any later time.
  2. The rawResponse field is mandatory (not optional as for on-chain evidence). The raw API response or page content MUST be preserved for audit.
  3. After canonicalization, the evidenceId = Keccak-256(canonicalForm) permanently identifies this specific snapshot.
  4. The original source is not re-queried during replay. Validators use the stored canonicalForm exclusively.
  5. The anchor.time field records the ISO 8601 timestamp of when the snapshot was taken. For off-chain evidence, anchor.block is set to the nearest Solana slot at anchor.time (for temporal ordering within the evidence graph).

Mandatory Storage for Off-Chain Evidence:

Because off-chain evidence cannot be re-fetched, it MUST be promoted to decentralized storage (IPFS/Filecoin) immediately upon VO creation — not after anchoring. This is stricter than the 24-hour window for on-chain evidence (Section 8.5), because on-chain evidence can be re-derived from archive nodes as a fallback.

Evidence Class Re-fetchable? Storage Requirement Replay Source
ONCHAIN Yes (from archive RPC) Standard tiered (Section 8.5) Independent re-fetch or stored copy
OFFCHAIN_PINNED Partial (source may change) IPFS immediately on VO creation Stored copy only, hash-verified
OFFCHAIN_EPHEMERAL No (source may be deleted) IPFS immediately on VO creation + Arweave within 7 days Stored copy only, hash-verified

Impact on Replay Trust:

Validators replaying a VO with off-chain evidence MUST understand that they are verifying computational correctness (the engine processed this evidence correctly) but NOT observational correctness (the evidence accurately reflected reality at collection time). This distinction is reflected in the qualification rules (Section 6.2).

BCE Specifications for Off-Chain Evidence Types:

SOCIAL_POST:

canonicalForm = BCE_ENCODE({
    author:       string,       // username / handle
    content:      string,       // full post text (UTF-8)
    engagement: {
        likes:    u64,
        reposts:  u64,
        replies:  u64,
        views:    u64
    },
    platform:     string,       // 'twitter' | 'telegram' | etc.
    postId:       string,       // platform-specific post identifier
    publishedAt:  string,       // ISO 8601 (post creation time)
    snapshotAt:   string        // ISO 8601 (when this snapshot was taken)
})

DEX_SCREENER_DATA:

canonicalForm = BCE_ENCODE({
    pairAddress:  bytes32,      // pool/pair address
    baseToken:    bytes32,      // base token mint
    quoteToken:   bytes32,      // quote token mint
    priceUsd:     fixedpoint64, // price in USD (scale 10^8)
    volume24h:    u64,          // 24h volume in lamports
    liquidity:    u64,          // total liquidity in lamports
    txCount24h:   u64,          // 24h transaction count
    snapshotAt:   string        // ISO 8601 (when this snapshot was taken)
})

Note: snapshotAt is included in the canonical form (unlike constructionTime in graph metadata) because the exact moment of off-chain observation is semantically meaningful — the same source queried 5 minutes later may return different data.

3.4 Baseline Canonical Encoding (BCE)

Reproducibility depends on canonicalization. Different RPC providers return structurally equivalent but byte-different responses for the same on-chain state.

BCE transforms raw evidence into a provider-independent representation:

Step 1: Strip provider-specific metadata

  • Remove jsonrpc, id, provider headers
  • Remove non-deterministic fields (request timing, node version)

Step 2: Normalize type representations

  • Integers: Fixed-width encoding (u64 for Solana lamports, u256 for EVM amounts)
  • Addresses: Fixed-length bytes (32 bytes for Solana, 20 bytes for EVM)
  • Booleans: Single byte (0x00 or 0x01)
  • Strings: UTF-8 with explicit length prefix
  • Null: Distinguished null byte (0xFF)

Step 3: Order fields deterministically

  • All object fields sorted lexicographically by key (UTF-8 byte order)
  • Arrays maintain original index order

Step 4: Serialize to deterministic binary

  • Use a canonical binary format (similar to borsh or CBOR canonical mode)
  • No optional padding, no alignment bytes

Step 5: Compute content hash

  • evidenceId = Keccak-256(canonicalForm)

BCE Specification per Evidence Type:

ACCOUNT_BALANCE:

canonicalForm = BCE_ENCODE({
    account:  bytes32,      // account address (fixed 32 or 20 bytes)
    mint:     bytes32,      // token mint
    balance:  u64,          // raw integer (lamports / wei)
    slot:     u64           // block/slot number
})

POOL_RESERVES:

canonicalForm = BCE_ENCODE({
    pool:       bytes32,    // pool address
    tokenA:     bytes32,    // token A mint
    tokenB:     bytes32,    // token B mint
    reserveA:   u128,       // reserve of token A
    reserveB:   u128,       // reserve of token B
    slot:       u64         // block/slot number
})

Cross-Provider Reconciliation

When evidence is retrieved from multiple providers for the same anchor point, the system MUST:

  1. Canonicalize each response independently
  2. Compare content hashes
  3. If hashes match, evidence is confirmed
  4. If hashes differ, flag as PROVIDER_DIVERGENCE and require manual resolution or majority consensus among 3+ providers

3.5 Provenance Requirements

Every evidence unit MUST satisfy:

  • Source reference: A declared source that an independent party can query
  • Retrieval method: Sufficient detail to reproduce the same query
  • Temporal anchor: A specific block/slot that the data is pinned to
  • Integrity guarantee: Content hash of canonical form

Additional requirements for OFFCHAIN_DECLARED evidence:

  • Raw response: rawResponse field is mandatory (not optional). The complete API response or page content MUST be stored.
  • Snapshot timestamp: anchor.time records the exact collection moment; canonicalForm includes a snapshotAt field.
  • Staleness limit: Off-chain evidence is inadmissible if anchor.time differs from the VO's evaluation start time by more than 5 minutes. This bounds the window in which the off-chain source could have changed between snapshot and evaluation.
  • Source liveness: At evaluation time, the system MUST verify the source was accessible (HTTP 200 or equivalent). If the source returns an error, the evidence unit is recorded with rawResponse containing the error and is inadmissible.

Evidence failing any of these requirements is inadmissible. Claims depending on inadmissible evidence cannot cross the line.

results matching ""

    No results matching ""