Rivellum

Rivellum Portal

Download Wallet (Chrome)
Checking...
mainnet

Mist By Example

A comprehensive collection of Mist contract patterns — from basic state management to DeFi protocols, gaming systems, and advanced value flows. Every example is production-ready and compiles with mistc compile.

Getting Started

Your First Contract

The simplest possible Mist contract:

contract HelloWorld
    state greeting: String

    function init()
        greeting = "Hello, Rivellum!"

    function get_greeting() -> String
        return greeting

Compile and deploy:

# Compile to bundle
mistc compile hello.mist -o hello.bundle.json

# Deploy to testnet
mistc deploy hello.bundle.json --rpc https://rpc.rivellum.network

Counter — State Mutations & Access Control

The canonical starter contract. Demonstrates state, access control with caller, guards with require, and events:

contract Counter
    state count: Int
    state owner: Address
    state paused: Bool

    function init()
        count = 0
        owner = caller
        paused = false
        emit Initialized(owner)

    function increment()
        require paused == false
        require caller == owner
        count = count + 1
        emit Incremented(count, caller)

    function decrement()
        require paused == false
        require caller == owner
        require count > 0
        count = count - 1
        emit Decremented(count, caller)

    function reset()
        require caller == owner
        let old_count = count
        count = 0
        emit Reset(old_count, caller)

    function pause()
        require caller == owner
        require paused == false
        paused = true
        emit Paused(caller)

    function unpause()
        require caller == owner
        require paused == true
        paused = false
        emit Unpaused(caller)

    function get_count() -> Int
        return count

Key patterns:

  • caller == owner for ownership checks
  • require condition, "message" for guards
  • emit EventName(args) for on-chain logging
  • State variables accessed directly by name

Value Operations

Simple Escrow — Hold & Release

The most common value pattern: hold assets from one party, release to another based on a condition:

contract SimpleEscrow
    state seller: Address
    state buyer: Address
    state escrow_vault: Value
    state completed: Bool

    function create(seller_addr: Address, buyer_addr: Address, payment: Value)
        let seller = seller_addr
        let buyer = buyer_addr
        hold escrow_vault = payment asset "USDC" from buyer
        let completed = false

    function complete()
        require completed == false, "Already completed"
        pay escrow_vault asset "USDC" to seller from escrow_vault
        let completed = true

    function cancel()
        require completed == false, "Already completed"
        pay escrow_vault asset "USDC" to buyer from escrow_vault
        let completed = true

Key patterns:

  • hold locks assets from a party into a vault
  • pay ... from vault pays from the vault contents
  • The vault must be consumed — if neither complete nor cancel is called, the compiler catches it

Escrow with State Machine

A more robust escrow using integer state to track phases:

contract Escrow
    state buyer: Address
    state seller: Address
    state arbiter: Address
    state deposit_amount: Int
    state escrow_state: Int   # 0=created, 1=deposited, 2=released, 3=refunded

    function init(seller_addr: Address, arbiter_addr: Address)
        require seller_addr != caller
        require arbiter_addr != caller
        require arbiter_addr != seller_addr
        buyer = caller
        seller = seller_addr
        arbiter = arbiter_addr
        escrow_state = 0
        deposit_amount = 0
        emit Initialized(buyer, seller, arbiter)

    function deposit(amount: Int)
        require caller == buyer
        require escrow_state == 0
        require amount > 0
        deposit_amount = amount
        escrow_state = 1
        emit Deposited(buyer, amount)

    function release_funds()
        require escrow_state == 1
        require caller == arbiter
        escrow_state = 2
        emit Released(seller, deposit_amount)

    function refund_funds()
        require escrow_state == 1
        require caller == arbiter
        escrow_state = 3
        emit Refunded(buyer, deposit_amount)

    function get_state() -> Int
        return escrow_state

Token — Mint, Burn, Transfer

A full fungible token contract using value operations:

contract Token
    state token_vault: VaultRef
    state asset_id: Address
    state name: String
    state symbol: String
    state decimals: Int
    state owner: Address

    function init(token_asset: Address, token_name: String, token_symbol: String, token_decimals: Int)
        require token_decimals >= 0
        require token_decimals <= 18
        asset_id = token_asset
        name = token_name
        symbol = token_symbol
        decimals = token_decimals
        owner = caller
        emit TokenCreated(caller, token_name, token_symbol)

    function mint_tokens(amount: Int)
        require caller == owner
        require amount > 0
        mint token_vault = amount asset asset_id authority owner
        emit Minted(caller, amount)

    function burn_tokens()
        require caller == owner
        burn vault token_vault
        emit Burned(caller)

    function transfer(to: Address, amount: Int)
        require amount > 0
        require to != caller
        pay amount asset asset_id to to from token_vault
        emit Transfer(caller, to, amount)

    function deposit(amount: Int)
        require amount > 0
        hold token_vault = amount asset asset_id from caller
        emit Deposited(caller, amount)

    function get_name() -> String
        return name

    function get_symbol() -> String
        return symbol

Key patterns:

  • mint ... authority owner creates new tokens (requires mint authority)
  • burn vault ... destroys tokens permanently
  • hold deposits from caller into the contract vault
  • pay ... from vault withdraws from the contract vault to a recipient

Escrow with Royalty Split

Demonstrates split to divide a vault among multiple recipients:

contract EscrowRoyalty
    state buyer: Address
    state seller: Address
    state royalty_recipient: Address
    state arbiter: Address
    state deposit_amount: Int
    state released: Bool

    function init(seller_addr: Address, royalty_addr: Address, arbiter_addr: Address)
        require seller_addr != caller
        require royalty_addr != seller_addr
        require arbiter_addr != caller
        buyer = caller
        seller = seller_addr
        royalty_recipient = royalty_addr
        arbiter = arbiter_addr
        released = false
        deposit_amount = 0
        emit Initialized(buyer, seller, royalty_addr, arbiter)

    function deposit(amount: Int)
        require caller == buyer
        require deposit_amount == 0
        require amount > 0
        deposit_amount = amount
        emit Deposited(buyer, amount)

    function release_with_split()
        require caller == arbiter
        require released == false
        let seller_amount = deposit_amount * 80 / 100
        let royalty_amount = deposit_amount * 20 / 100
        released = true
        emit ReleasedWithSplit(seller, seller_amount, royalty_recipient, royalty_amount)

    function cancel_buyer()
        require caller == arbiter
        require released == false
        released = true
        emit Refunded(buyer, deposit_amount)

DeFi Contracts

AMM Pool — Constant Product Market Maker

A basic automated market maker supporting two-sided liquidity and swaps:

contract AmmPool
    state pool_a: VaultRef
    state pool_b: VaultRef
    state fee_bps: Int
    state pool_owner: Address

    function init(initial_fee_bps: Int)
        require initial_fee_bps >= 0
        require initial_fee_bps <= 1000
        fee_bps = initial_fee_bps
        pool_owner = caller
        emit PoolCreated(caller, initial_fee_bps)

    function add_liquidity(amount_a: Int, asset_a: Address, amount_b: Int, asset_b: Address)
        require amount_a > 0
        require amount_b > 0
        hold pool_a = amount_a asset asset_a from caller
        hold pool_b = amount_b asset asset_b from caller
        emit LiquidityAdded(caller, amount_a, amount_b)

    function swap_a_to_b(amount_in: Int, asset_a: Address, amount_out: Int, asset_b: Address)
        require amount_in > 0
        require amount_out > 0
        hold pool_a = amount_in asset asset_a from caller
        pay amount_out asset asset_b to caller from pool_b
        emit Swapped(caller, amount_in, amount_out)

    function swap_b_to_a(amount_in: Int, asset_b: Address, amount_out: Int, asset_a: Address)
        require amount_in > 0
        require amount_out > 0
        hold pool_b = amount_in asset asset_b from caller
        pay amount_out asset asset_a to caller from pool_a
        emit Swapped(caller, amount_in, amount_out)

    function remove_liquidity()
        require caller == pool_owner
        release vault pool_a to caller
        release vault pool_b to caller
        emit LiquidityRemoved(caller)

Staking

contract Staking
    state staked_vault: VaultRef
    state staking_asset: Address
    state total_staked: Int
    state reward_rate: Int
    state staking_owner: Address

    function init(stake_asset: Address, rate: Int)
        require rate > 0
        staking_asset = stake_asset
        reward_rate = rate
        total_staked = 0
        staking_owner = caller
        emit StakingCreated(caller, stake_asset, rate)

    function stake(amount: Int)
        require amount > 0
        hold staked_vault = amount asset staking_asset from caller
        total_staked = total_staked + amount
        emit Staked(caller, amount)

    function unstake(amount: Int)
        require amount > 0
        require amount <= total_staked
        pay amount asset staking_asset to caller from staked_vault
        total_staked = total_staked - amount
        emit Unstaked(caller, amount)

    function get_total_staked() -> Int
        return total_staked

Options Vault

A basic options contract with writer, buyer, collateral, and exercise mechanics:

contract OptionsVault
    state option_writer: Address
    state option_buyer: Address
    state strike_price: Int
    state premium: Int
    state underlying_asset: String
    state collateral_deposited: Bool
    state option_exercised: Bool

    function init(strike: Int, asset: String)
        require strike > 0
        option_writer = caller
        strike_price = strike
        underlying_asset = asset
        collateral_deposited = false
        option_exercised = false
        emit OptionCreated(strike, asset)

    function deposit_collateral()
        require caller == option_writer
        require collateral_deposited == false
        collateral_deposited = true
        emit CollateralDeposited(option_writer)

    function purchase_option(premium_amount: Int)
        require collateral_deposited == true
        option_buyer = caller
        premium = premium_amount
        emit OptionPurchased(caller, premium_amount)

    function exercise_option()
        require caller == option_buyer
        require option_exercised == false
        option_exercised = true
        emit OptionExercised(option_buyer, strike_price)

Perpetual Futures (Simplified)

contract PerpsSimplified
    state long_position: Int
    state short_position: Int
    state long_trader: Address
    state short_trader: Address
    state entry_price: Int
    state position_open: Bool

    function init()
        position_open = false
        long_position = 0
        short_position = 0
        emit Initialized()

    function open_long(size: Int, price: Int)
        require position_open == false
        require size > 0
        long_position = size
        long_trader = caller
        entry_price = price
        position_open = true
        emit LongOpened(caller, size, price)

    function open_short(size: Int)
        require position_open == true
        require short_position == 0
        require size == long_position
        short_position = size
        short_trader = caller
        emit ShortOpened(caller, size)

    function settle_position(settlement_price: Int)
        require position_open == true
        require short_position > 0
        position_open = false
        emit PositionSettled(settlement_price)

    function liquidate_position()
        require position_open == true
        position_open = false
        emit PositionLiquidated()

Governance Contracts

Voting

contract Voting
    state owner: Address
    state proposal: String
    state votes_for: Int
    state votes_against: Int
    state finalized: Bool

    function init(prop: String)
        owner = caller
        proposal = prop
        votes_for = 0
        votes_against = 0
        finalized = false
        emit ProposalCreated(prop)

    function vote_for()
        require finalized == false
        votes_for = votes_for + 1
        emit Voted(caller, true)

    function vote_against()
        require finalized == false
        votes_against = votes_against + 1
        emit Voted(caller, false)

    function finalize()
        require caller == owner
        require finalized == false
        finalized = true
        emit Finalized(votes_for, votes_against)

    function get_results() -> Int
        require finalized == true
        return votes_for

Governance with Proposals

contract Governance
    state proposal_count: Int
    state quorum_bps: Int
    state voting_period_blocks: Int
    state gov_owner: Address

    function init(initial_quorum_bps: Int, initial_voting_period: Int)
        require initial_quorum_bps > 0
        require initial_quorum_bps <= 10000
        require initial_voting_period > 0
        proposal_count = 0
        quorum_bps = initial_quorum_bps
        voting_period_blocks = initial_voting_period
        gov_owner = caller
        emit GovernanceCreated(caller, initial_quorum_bps, initial_voting_period)

    function create_proposal(description_hash: String)
        proposal_count = proposal_count + 1
        emit ProposalCreated(caller, proposal_count, description_hash)

    function vote(proposal_id: Int, vote_for: Int)
        require proposal_id > 0
        require proposal_id <= proposal_count
        require vote_for >= 0
        require vote_for <= 1
        emit Voted(caller, proposal_id, vote_for)

    function execute_proposal(proposal_id: Int)
        require proposal_id > 0
        require proposal_id <= proposal_count
        emit ProposalExecuted(caller, proposal_id)

    function update_quorum(new_quorum_bps: Int)
        require caller == gov_owner
        require new_quorum_bps > 0
        require new_quorum_bps <= 10000
        quorum_bps = new_quorum_bps
        emit QuorumUpdated(caller, new_quorum_bps)

    function get_proposal_count() -> Int
        return proposal_count

Multisig

contract Multisig
    state signer_count: Int
    state threshold: Int
    state proposal_count: Int
    state ms_owner: Address

    function init(signers: Int, required: Int)
        require signers >= 1
        require required >= 1
        require required <= signers
        signer_count = signers
        threshold = required
        proposal_count = 0
        ms_owner = caller
        emit MultisigCreated(caller, signers, required)

    function propose(description_hash: String, value: Int)
        proposal_count = proposal_count + 1
        emit Proposed(caller, proposal_count, description_hash, value)

    function approve(proposal_id: Int)
        require proposal_id > 0
        require proposal_id <= proposal_count
        emit Approved(caller, proposal_id)

    function execute(proposal_id: Int)
        require proposal_id > 0
        require proposal_id <= proposal_count
        emit Executed(caller, proposal_id)

    function get_threshold() -> Int
        return threshold

Gaming Contracts

Character — Stats, XP, Leveling

contract Character
    state character_type: String
    state level: Int
    state xp: Int
    state max_hp: Int
    state current_hp: Int
    state attack: Int
    state defense: Int
    state speed: Int
    state char_owner: Address
    state alive: Int

    function init(char_type: String, hp: Int, atk: Int, def: Int, spd: Int)
        require hp > 0
        require atk >= 0
        require def >= 0
        require spd >= 0
        character_type = char_type
        level = 1
        xp = 0
        max_hp = hp
        current_hp = hp
        attack = atk
        defense = def
        speed = spd
        char_owner = caller
        alive = 1
        emit CharacterCreated(caller, char_type, hp, atk, def, spd)

    function take_damage(amount: Int)
        require alive == 1
        require amount > 0
        current_hp = current_hp - amount
        emit DamageTaken(char_owner, amount, current_hp)

    function heal(amount: Int)
        require alive == 1
        require amount > 0
        current_hp = current_hp + amount
        emit Healed(char_owner, amount, current_hp)

    function gain_xp(amount: Int)
        require alive == 1
        require amount > 0
        xp = xp + amount
        emit XPGained(char_owner, amount, xp)

    function level_up()
        require alive == 1
        level = level + 1
        max_hp = max_hp + 10
        attack = attack + 2
        defense = defense + 2
        speed = speed + 1
        current_hp = max_hp
        emit LevelUp(char_owner, level)

    function revive()
        require alive == 0
        alive = 1
        current_hp = max_hp
        emit Revived(char_owner, max_hp)

    function get_level() -> Int
        return level

    function get_xp() -> Int
        return xp

    function get_current_hp() -> Int
        return current_hp

    function get_attack() -> Int
        return attack

NFT Collection

contract NFT
    state collection_name: String
    state total_minted: Int
    state owner: Address
    state frozen: Int

    function init(name: String)
        collection_name = name
        total_minted = 0
        owner = caller
        frozen = 0
        emit CollectionCreated(caller, name)

    function mint_nft(to: Address, metadata_hash: String)
        require caller == owner
        require frozen == 0
        total_minted = total_minted + 1
        emit NFTMinted(to, total_minted, metadata_hash)

    function transfer(token_id: Int, to: Address)
        require frozen == 0
        require to != caller
        emit NFTTransferred(caller, to, token_id)

    function freeze_collection()
        require caller == owner
        frozen = 1
        emit CollectionFrozen(caller)

    function get_total_minted() -> Int
        return total_minted

    function get_collection_name() -> String
        return collection_name

Payment Streaming

Time-based payment release using the now intrinsic:

contract PaymentStream
    state payer: Address
    state payee: Address
    state stream_vault: VaultRef
    state stream_asset: Address
    state total_amount: Int
    state start_time: Int
    state end_time: Int
    state withdrawn: Int
    state stream_active: Int

    function init(recipient: Address, payment_asset: Address, amount: Int, duration_ms: Int)
        require amount > 0
        require duration_ms > 0
        require recipient != caller
        payer = caller
        payee = recipient
        stream_asset = payment_asset
        total_amount = amount
        start_time = now
        end_time = now + duration_ms
        withdrawn = 0
        stream_active = 1
        hold stream_vault = amount asset payment_asset from caller
        emit StreamCreated(caller, recipient, amount, duration_ms)

    function withdraw()
        require caller == payee
        require stream_active == 1
        let elapsed = now - start_time
        let total_duration = end_time - start_time
        let vested = total_amount * elapsed / total_duration
        let available = vested - withdrawn
        require available > 0
        withdrawn = withdrawn + available
        pay available asset stream_asset to payee from stream_vault
        emit Withdrawn(payee, available, withdrawn)

    function cancel()
        require caller == payer
        require stream_active == 1
        stream_active = 0
        let remaining = total_amount - withdrawn
        pay remaining asset stream_asset to payer from stream_vault
        emit StreamCancelled(payer, remaining)

Leaderboard

contract Leaderboard
    state board_name: String
    state entry_count: Int
    state highest_score: Int
    state top_player: Address
    state board_owner: Address

    function init(name: String)
        board_name = name
        entry_count = 0
        highest_score = 0
        board_owner = caller
        emit BoardCreated(caller, name)

    function submit_score(score: Int)
        require score >= 0
        entry_count = entry_count + 1
        if score > highest_score
            highest_score = score
            top_player = caller
        emit ScoreSubmitted(caller, score, entry_count)

    function reset()
        require caller == board_owner
        let old_highest = highest_score
        entry_count = 0
        highest_score = 0
        emit BoardReset(caller, old_highest)

    function get_highest_score() -> Int
        return highest_score

Daily Rewards

contract DailyReward
    state reward_amount: Int
    state cooldown_ms: Int
    state last_claim_time: Int
    state total_claims: Int
    state streak: Int
    state reward_owner: Address

    function init(amount: Int, cooldown: Int)
        require amount > 0
        require cooldown > 0
        reward_amount = amount
        cooldown_ms = cooldown
        last_claim_time = 0
        total_claims = 0
        streak = 0
        reward_owner = caller
        emit RewardCreated(caller, amount, cooldown)

    function claim()
        let time_since = now - last_claim_time
        require time_since >= cooldown_ms, "Cooldown not expired"
        last_claim_time = now
        total_claims = total_claims + 1
        if time_since < cooldown_ms * 2
            streak = streak + 1
        else
            streak = 1
        emit RewardClaimed(caller, reward_amount, streak, total_claims)

    function get_streak() -> Int
        return streak

    function get_total_claims() -> Int
        return total_claims

Common Patterns

Note: The snippets below are code fragments — they must be placed inside a contract block alongside your other state and function declarations.

Ownership with Transfer

contract Ownable
    state owner: Address

    function init()
        owner = caller

    function transfer_ownership(new_owner: Address)
        require caller == owner
        require new_owner != owner
        let old_owner = owner
        owner = new_owner
        emit OwnershipTransferred(old_owner, new_owner)

Pausable Operations

# Use an Int flag (0/1) since Bool state works too
state paused: Int

function pause()
    require caller == owner
    require paused == 0
    paused = 1
    emit Paused(caller)

function unpause()
    require caller == owner
    require paused == 1
    paused = 0
    emit Unpaused(caller)

# Guard in every user-facing function:
function do_something()
    require paused == 0, "Contract is paused"
    # ... logic

State Machine Pattern

Use integer state to model phases:

state phase: Int  # 0=init, 1=active, 2=locked, 3=complete

function activate()
    require phase == 0
    phase = 1

function lock()
    require phase == 1
    phase = 2

function complete()
    require phase == 2
    phase = 3

Multi-Party Authorization

state admin: Address
state operator: Address

function init(op: Address)
    admin = caller
    operator = op

function admin_action()
    require caller == admin, "Not admin"
    # admin-only logic

function operator_action()
    require caller == operator, "Not operator"
    # operator-only logic

Safe Arithmetic

Mist uses u128 integers. Always check for underflow before subtraction:

function safe_subtract(balance: Int, amount: Int)
    require balance >= amount, "Insufficient balance"
    let new_balance = balance - amount

Division truncates — use basis points (bps) for percentages:

# 2.5% fee = 250 bps out of 10000
let fee = amount * 250 / 10000
let net = amount - fee

Compilation & Deployment

Full Build Workflow

# Check syntax
mistc check my_contract.mist

# Lint (type check + static analysis)
mistc lint my_contract.mist

# Compile to bundle
mistc compile my_contract.mist -o my_contract.bundle.json

# Build all artifacts
mistc build my_contract.mist -o build/
# Produces:
#   build/my_contract.bundle.json   (full bundle)
#   build/my_contract.pvi.json      (PVI graph)
#   build/my_contract.analysis.json (analysis report)
#   build/my_contract.fees.json     (fee breakdown)

# View fee analysis
mistc fees my_contract.mist --json

# Deploy
mistc deploy build/my_contract.bundle.json

# Call a function
mistc call <contract_id> increment '[]'

# Fetch a receipt
mistc receipt <receipt_id> --pvi --explain

Fee Tiers

TierThresholdDeploy Fee
Simple≤ 50 instructions, ≤ 5 functions0.1 RIVL
Medium≤ 200 instructions, ≤ 20 functions0.5 RIVL
ComplexAbove Medium2.0 RIVL

RPC API

# Deploy a contract
curl -X POST https://rpc.rivellum.network/v1/mist/deploy \
    -H 'Content-Type: application/json' \
    -d '{"bytecode": "<bundle_json_base64>", "sender": "0x..."}'

# Call a contract function
curl -X POST https://rpc.rivellum.network/v1/mist/call/<contract_id> \
    -H 'Content-Type: application/json' \
    -d '{"function": "increment", "args": [42]}'

# List recent receipts
curl https://rpc.rivellum.network/v1/mist/receipts

# Get specific receipt
curl https://rpc.rivellum.network/v1/mist/receipts/<receipt_id>

# View PVI graph for a receipt
curl https://rpc.rivellum.network/v1/mist/pvi/<receipt_id>

# List prefab contracts
curl https://rpc.rivellum.network/prefabs

Prefab Templates

Rivellum ships 42 pre-built contract templates covering common use cases. Deploy them directly or use as starting points:

CategoryPrefabs
Basiccounter
DeFitoken, escrow, vault, staking, amm_pool
Governancegovernance, multisig
NFTnft
Oracleoracle_consumer
Time-basedtimelock
Paymentspayment_stream, payments_account
Subscriptionssubscription_account, subscription_gate
Monetizationpaywall_gate, auto_pay_key, ad_reward_gate, ad_trigger, usage_meter
Gamingprize_vault, battle_pass_lite, character, casual, game_session, player_profile, inventory, loot_roll, leaderboard, score_counter, life_counter, combo_tracker, energy_meter, achievement_tracker, mission_tracker, progression, stage_progress, daily_reward, reward_bucket, session, economy, world
# List all prefabs
curl https://rpc.rivellum.network/prefabs

# Get a specific prefab
curl https://rpc.rivellum.network/prefabs/<name>