Asset Management

Understanding how Ingot manages tokens, NFTs, and other digital assets

Asset Management

Overview

Ingot treats assets as "objects" that can be combined, updated, and transferred. The protocol supports fungible tokens, semi-fungible tokens, NFTs, and custom asset types through a flexible asset list system.

Asset List Specification

Assets are represented in payloads using the TLV_ASSET_LIST (type = 0x0101) TLV entry.

Structure

Each asset entry contains:

asset_type  : u8        // 0=fungible, 1=semi-fungible, 2=nft, 3=custom
asset_id    : [32]      // BLAKE3 identifier or upstream asset ID
amount      : u128le    // For NFT use 1; semi use shares; fungible use quantity
meta_tlv    : TLV[]     // Bounded extensions (e.g., display/URI, etc.)

Asset Types

  • Fungible (0): Interchangeable tokens (e.g., BRC-20 compatible tokens)
  • Semi-Fungible (1): Partially interchangeable assets (e.g., shares, batches)
  • NFT (2): Unique, non-fungible assets (e.g., ERC-721 compatible NFTs)
  • Custom (3): Application-specific asset types

Limits

  • Maximum 256 asset items per list
  • Single ASSET_LIST TLV total size โ‰ค 48 KiB
  • Exceeding limits โ†’ indexer rejects parsing

Asset Merging

Ingot supports merging multiple assets into a single output:

  • Merging Assets: Bundle multiple items (like tokens from different inputs) into one output
  • Balance Conservation: L2 validation ensures input assets = output assets per token type
  • Asset List: Explicit asset inventory in payload (TLV format)
  • Unique Identification: Each asset instance is uniquely tied to its transaction position (outpoint)

Merging Example

When transferring assets, you can combine multiple asset types:

Input 1: 100 TOKEN_A
Input 2: 50 TOKEN_B
Output: 100 TOKEN_A + 50 TOKEN_B (merged in single Pay2Ingot output)

Asset Merkle Roots

For large asset collections or privacy-sensitive scenarios, use Merkle trees:

TLV_ASSET_MERKLE_ROOT (type = 0x0102)

Structure:

root : [32]     // BLAKE3-256 Merkle root

Purpose:

  • When asset count is large, only place Merkle root in payload
  • Specific asset entries can be selectively revealed as leaves in witness
  • Provides "partial visibility" capability
  • Enables privacy-preserving asset transfers

Witness: Asset Merkle Proof

WITNESS_ASSET_PROOF structure:

leaf_bytes   : TLV[]     // TLV encoding identical to ASSET_LIST unit entry
merkle_path  : [depth]   // Depth โ‰ค 8, each step 32B hash

Validation Flow:

  1. Indexer calculates leaf hash: leaf_hash = blake3(leaf_bytes)
  2. Reconstruct Merkle root along merkle_path
  3. Verify reconstructed root equals ASSET_MERKLE_ROOT in payload
  4. Match success โ†’ leaf considered valid reveal
  5. Match failure โ†’ indexer rejects this leaf

Standard Schema Templates

Ingot provides production-ready standard schema templates:

Token Schemas

  • brc20_compatible.json: BRC-20 compatible tokens (simple, community-friendly)
  • trc721_advanced.json: TRC-721 advanced tokens (TLV format, governance, asset conservation)

NFT Schemas

  • erc721_compatible.json: ERC-721 compatible NFTs
  • music.json: Music NFTs (audio files, lyrics, copyright)

Inscription Schemas

  • text.json: Text inscriptions (plain text, Markdown, code)
  • image.json: Image inscriptions (SVG, PNG, JPEG, GIF, WebP)

DAO Schemas

  • proposal.json: DAO proposals (parameter modifications, fund allocation, code upgrades)
  • vote.json: DAO voting (weighted voting, delegation, rationale)

Application Schemas

  • social_post.json: Decentralized social media posts
  • identity.json: Decentralized identity (W3C DID standard)

Asset Operations

Mint

Creates the first instance of an asset:

  • No parent_instance_id required
  • Does not spend parent tip
  • Generates first tip for the artifact

Transfer

Changes ownership of an asset:

  • Requires ALLOW_MUTABLE=1 flag
  • Must spend current tip
  • Creates new instance with updated ownership
  • Allows HASH_PAYLOAD unchanged (only ownership/lock changes)

Attach

Appends auxiliary data to an asset:

  • Requires ALLOW_MUTABLE=1 flag
  • Must spend current tip
  • References parent tip
  • Adds new data without changing core asset properties

Mutate

Modifies mutable fields of an asset:

  • Requires ALLOW_MUTABLE=1 flag
  • Must spend current tip
  • Changes object mutable fields
  • Maintains asset continuity through artifact_id

Bundle

Aggregates multiple artifact_id into a composite object:

  • Requires ALLOW_MUTABLE=1 flag
  • Must spend current tip
  • Forms composite object from multiple artifacts
  • Enables complex asset compositions

Asset Conservation Rules

L2 indexer validates asset conservation:

  • Input Validation: Sum of input assets per asset_id
  • Output Validation: Sum of output assets per asset_id
  • Conservation: Input assets = Output assets (per token type)
  • Violation: Indexer marks as invalid, doesn't become active tip

Partial Visibility

Indexers support partial asset disclosure:

  • Merkle Proofs: Verify specific assets without downloading complete asset lists
  • Selective Reveals: Only relevant assets are disclosed in witness
  • Privacy-Preserving: Unrevealed assets remain hidden
  • Verification: Indexers can verify partial asset reveals through Merkle proofs

Time Locks

Assets can be locked with time-based restrictions:

  • Time Locks: Delay access to assets via ScriptHash locks
  • Vesting Schedules: Assets locked until specific dates or conditions
  • Use Cases: Useful for vesting schedules, timed releases, escrow services
  • Implementation: Via ScriptHash lock type + VM scripts (OP_CHECKLOCKTIMEVERIFY/OP_CHECKSEQUENCEVERIFY)

Unique Identification

Each asset instance is uniquely identified:

  • artifact_id: blake3("Ingot/artifact" || SCHEMA_ID || HASH_PAYLOAD)

    • Cross-version identifier for the same object
    • Used for deduplication and reference
  • instance_id: blake3("Ingot/instance" || artifact_id || outpoint_bytes)

    • Identifies this UTXO instance (a specific version of the same artifact)
    • Where outpoint_bytes = txid[32] || u32le(vout)
    • Uniqueness guaranteed by UTXO model

Previous: oUTXO Model | Next: Locking Mechanisms