SUI is the native token of the Sui blockchain, serving multiple critical functions in the ecosystem. Understanding SUI’s mechanics and use cases is essential for participating in the Sui network.
SUI Token Functions
Gas Payment Pay for transaction fees and storage costs
Staking Stake to validators to participate in consensus
Governance Participate in on-chain governance decisions
Medium of Exchange Use as currency in the Sui ecosystem
Token Denomination
SUI uses MIST as its smallest unit:
1 SUI = 1,000,000,000 MIST (10^9)
All on-chain amounts are denominated in MIST. The human-readable SUI amount is MIST / 1,000,000,000.
SUI as a Coin
SUI is implemented as a native coin type:
public struct Coin < phantom T > has key , store {
id: UID ,
balance: Balance < T >,
}
The gas coin is a special Coin<SUI> object:
pub fn new_gas_coin ( version : SequenceNumber , id : ObjectID , value : u64 ) -> Self {
unsafe {
Self :: new_from_execution_with_limit (
GasCoin :: type_ () . into (),
true ,
version ,
GasCoin :: new ( id , value ) . to_bcs_bytes (),
256 ,
)
. unwrap ()
}
}
Total Supply
SUI has a fixed maximum supply of 10 billion tokens:
Max Supply: 10,000,000,000 SUI
Distribution
The tokens are distributed across different allocations:
Token Release Schedule
SUI tokens are released over time through:
Staking Rewards
New tokens minted as staking rewards each epoch
Vesting Schedules
Locked tokens released according to vesting timelines
Storage Fund Returns
SUI returned when objects are deleted
Using SUI in Transactions
Splitting Coins
import { Transaction } from '@mysten/sui/transactions' ;
const tx = new Transaction ();
// Split 1 SUI into separate coin
const [ coin ] = tx . splitCoins ( tx . gas , [ 1_000_000_000 ]); // 1 SUI in MIST
tx . transferObjects ([ coin ], recipient );
Merging Coins
const tx = new Transaction ();
// Merge all coins into primary coin
tx . mergeCoins ( primaryCoin , [ coin1 , coin2 , coin3 ]);
Getting Balance
const balance = await client . getBalance ({
owner: address ,
coinType: '0x2::sui::SUI' ,
});
console . log ( `Balance: ${ Number ( balance . totalBalance ) / 1e9 } SUI` );
Gas Coin Selection
Sui automatically selects gas coins for transactions:
const tx = new Transaction ();
// Gas coin automatically selected from sender's balance
tx . setGasBudget ( 10_000_000 );
You can also specify gas coins manually:
tx . setGasPayment ([
{
objectId: coinId1 ,
version: version1 ,
digest: digest1 ,
},
{
objectId: coinId2 ,
version: version2 ,
digest: digest2 ,
},
]);
SUI in Smart Contracts
Receiving SUI Payments
use sui::coin::{ Self , Coin };
use sui::sui:: SUI ;
public fun pay_fee (payment: Coin < SUI >) {
let amount = payment. value ();
assert! (amount >= MINIMUM_FEE , EInsufficientPayment );
// Process payment
transfer:: public_transfer (payment, TREASURY_ADDRESS );
}
Splitting SUI
use sui::coin::{ Self , Coin };
use sui::sui:: SUI ;
public fun split_payment (
coin: & mut Coin < SUI >,
amount: u64 ,
ctx: & mut TxContext ,
) {
let split_coin = coin. split (amount, ctx);
transfer:: public_transfer (split_coin, recipient);
}
Minting (Not Possible)
SUI cannot be minted arbitrarily. New SUI only enters circulation through:
Staking rewards (controlled by the protocol)
Vesting schedules (predetermined allocations)
Storage rebates (returning previously paid fees)
Economic Properties
Deflationary Mechanisms
Storage Fees : Part of storage fees goes to non-refundable fund
Burned Fees : Certain operations may burn SUI
Lost Keys : Inaccessible wallets effectively reduce circulating supply
Inflationary Mechanisms
Staking Rewards : New SUI issued to validators and stakers
Subsidies : Temporary subsidies for network bootstrapping
Token Utility
As Gas
// Every transaction requires SUI for gas
const tx = new Transaction ();
tx . moveCall ({
target: ` ${ packageId } ::module::function` ,
arguments: [ /* ... */ ],
});
tx . setGasBudget ( 10_000_000 ); // SUI required
As Stake
public ( package ) fun request_add_stake (
pool: & mut StakingPool ,
stake: Balance < SUI >,
stake_activation_epoch: u64 ,
ctx: & mut TxContext ,
): StakedSui {
let sui_amount = stake. value ();
assert! (!pool. is_inactive (), EDelegationToInactivePool );
assert! (sui_amount > 0 , EDelegationOfZeroSui );
pool.pending_stake = pool.pending_stake + sui_amount;
StakedSui {
id: object:: new (ctx),
pool_id: object:: id (pool),
stake_activation_epoch,
principal: stake,
}
}
As Payment
public fun purchase_item (
payment: Coin < SUI >,
item_id: ID ,
shop: & mut Shop ,
) {
let item = shop.items. remove (&item_id);
let price = item.price;
assert! (payment. value () >= price, EInsufficientPayment );
// Handle payment
transfer:: public_transfer (payment, shop.owner);
transfer:: public_transfer (item, tx_context:: sender (ctx));
}
Best Practices
Always use MIST for on-chain values
// Bad: Using decimal SUI values
const PRICE : u64 = 1 ; // Unclear if this is 1 SUI or 1 MIST
// Good: Explicit MIST values
const PRICE_MIST : u64 = 1_000_000_000 ; // 1 SUI in MIST
Handle coin splits properly
// Ensure enough balance before splitting
const balance = await client . getBalance ({ owner: address });
if ( BigInt ( balance . totalBalance ) < amount ) {
throw new Error ( 'Insufficient balance' );
}
// Estimate gas before execution
const dryRun = await client . dryRunTransactionBlock ({
transactionBlock: await tx . build ({ client }),
});
const totalCost = BigInt ( dryRun . effects . gasUsed . computationCost ) +
BigInt ( dryRun . effects . gasUsed . storageCost ) -
BigInt ( dryRun . effects . gasUsed . storageRebate );
Gas Mechanism Understand gas costs
Staking Learn about staking SUI
Storage Fund Storage economics