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 == ownerfor ownership checksrequire condition, "message"for guardsemit 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:
holdlocks assets from a party into a vaultpay ... from vaultpays from the vault contents- The vault must be consumed — if neither
completenorcancelis 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 ownercreates new tokens (requires mint authority)burn vault ...destroys tokens permanentlyholddeposits from caller into the contract vaultpay ... from vaultwithdraws 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
contractblock alongside your otherstateandfunctiondeclarations.
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
| Tier | Threshold | Deploy Fee |
|---|---|---|
| Simple | ≤ 50 instructions, ≤ 5 functions | 0.1 RIVL |
| Medium | ≤ 200 instructions, ≤ 20 functions | 0.5 RIVL |
| Complex | Above Medium | 2.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:
| Category | Prefabs |
|---|---|
| Basic | counter |
| DeFi | token, escrow, vault, staking, amm_pool |
| Governance | governance, multisig |
| NFT | nft |
| Oracle | oracle_consumer |
| Time-based | timelock |
| Payments | payment_stream, payments_account |
| Subscriptions | subscription_account, subscription_gate |
| Monetization | paywall_gate, auto_pay_key, ad_reward_gate, ad_trigger, usage_meter |
| Gaming | prize_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>