Skip to main content

Ghostmint Precompile

The ghostmint precompile is the bridge between the EVM smart contract layer and the Cosmos SDK native token system. It lives at a fixed address (0x0808) and allows authorized EVM contracts to mint and burn native GHOST tokens by calling into the Cosmos x/bank module through the x/ghostmint keeper.

This precompile enables the GHOST token use case of the broader Specter data protocol. When a user commits GHOST tokens into the privacy system, the tokens are burned via this precompile. When they reveal (withdraw), the tokens are minted back via this precompile. The net effect is supply-neutral: every token that enters the privacy system exits it, with the privacy protocol acting as an intermediary that breaks the on-chain link between sender and receiver.

Precompile Address

0x0000000000000000000000000000000000000808

The address 0x0808 was chosen to sit immediately after the cosmos/evm module's reserved precompile range (0x0800–0x0807). This avoids conflicts with both standard Ethereum precompiles (0x01–0x0a) and the Cosmos EVM precompiles.

ABI

The precompile exposes four functions and two events:

Functions

FunctionSignatureMutabilityGas Cost
mintNativeTomintNativeTo(address recipient, uint256 amount) returns (bool success)nonpayable50,000
burnNativeFromburnNativeFrom(address from, uint256 amount) returns (bool success)payable50,000
totalMintedtotalMinted() returns (uint256 total)view200
totalBurnedtotalBurned() returns (uint256 total)view200

Events

EventSignature
NativeMintedNativeMinted(address indexed recipient, uint256 amount)
NativeBurnedNativeBurned(address indexed from, uint256 amount)

Function Details

mintNativeTo(address recipient, uint256 amount) Mints amount of native GHOST (in aghost, the smallest unit at 18 decimals) and sends it to recipient. The mint operation goes through the x/bank module: tokens are minted to the ghostmint module account, then sent to the recipient's account. Returns true on success, reverts on failure. Emits NativeMinted.

burnNativeFrom(address from, uint256 amount) Burns amount of native GHOST from the from address. The burn operation sends tokens from the from address to the ghostmint module account, then burns them via x/bank. Returns true on success, reverts on failure. Emits NativeBurned. The payable modifier is required because the caller sends native value with the call to fund the burn.

totalMinted() Returns the cumulative total of all GHOST tokens ever minted through this precompile, stored in the module's KVStore. This is a monotonically increasing counter — it never decreases.

totalBurned() Returns the cumulative total of all GHOST tokens ever burned through this precompile, stored in the module's KVStore. Also monotonically increasing.

The difference totalMinted() - totalBurned() represents the net tokens currently "in flight" within the privacy system (committed but not yet revealed).

Gas Costs

OperationGasRationale
mintNativeTo50,000Involves two x/bank operations: mint to module + send to recipient
burnNativeFrom50,000Involves two x/bank operations: send to module + burn from module
totalMinted200Single KVStore read
totalBurned200Single KVStore read

The 50,000 gas cost for mint/burn operations reflects the underlying Cosmos SDK state changes (module account balance updates, supply tracking, event emission). These costs are fixed regardless of the amount being minted or burned.

Authorization

The precompile enforces strict caller authorization. Only addresses registered as authorized callers in the precompile's configuration can invoke mintNativeTo or burnNativeFrom. Unauthorized calls revert immediately.

In practice, the authorized callers are NativeAssetHandler contract instances — one per vault that handles native GHOST:

Authorized CallerRole
NativeAssetHandler (core)Handles mint/burn for the main BatchCommitRevealVault
NativeAssetHandler (forking)Handles mint/burn for the ForkingVault

The authorized caller list is configured at chain initialization and can be updated through governance proposals. This means adding a new vault that can mint/burn GHOST requires an on-chain governance vote — no single party can unilaterally authorize a new minter.

Authorization Flow

End-to-End Flow

The ghostmint precompile sits at a specific point in the commit/reveal pipeline. Here is the full sequence for a GHOST token commit (burn) and reveal (mint):

Commit (Burn) Flow

Reveal (Mint) Flow

Supply Invariant

The ghostmint module enforces a supply invariant that runs every block at the consensus level, independent of EVM execution:

  1. At the end of each block, the module reads the current total GHOST supply from x/bank
  2. It compares this against the LastTotalSupply stored from the previous block
  3. If the current supply exceeds the previous supply, it logs an error (since Specter is configured for zero inflation — supply should only change through balanced ghostmint mint/burn operations)
  4. It stores the current supply as LastTotalSupply for the next block's comparison

Additionally, a hard cap of 1 billion GHOST (10^27 aghost) is enforced at the keeper level. Any mint operation that would push cumulative totalMinted above this cap is rejected, regardless of what the calling contract requests.

This dual-layer protection — per-operation hard cap plus per-block invariant checking — ensures that the GHOST token supply remains auditable and predictable, even if a bug exists in the smart contract layer.

Relationship to the Data Protocol

The ghostmint precompile is specific to the GHOST token use case of the Specter data protocol. It is not involved in generic data commitments.

OperationUses ghostmint?Description
Token commit (CommitRevealVault)Yes — burns GHOSTTokens are destroyed when entering the privacy system
Token reveal (CommitRevealVault)Yes — mints GHOSTTokens are created when exiting the privacy system
Data commit (OpenGhostVault)NoOnly stores a commitment hash; no tokens burned
Data reveal (OpenGhostVault)NoOnly spends a nullifier; no tokens minted
Persistent key access (PersistentKeyVault)NoAccess proofs do not involve token operations

The data protocol's core primitives — Poseidon hashing, Merkle trees, nullifiers, ZK proofs — are entirely independent of the ghostmint precompile. The precompile is the mechanism by which one specific data type (GHOST token balances) enters and exits the privacy system.