Skip to main content

Module 0x2::coin

Defines the Coin type - platform wide representation of fungible tokens and coins. Coin can be described as a secure wrapper around Balance type.

use 0x1::ascii; use 0x1::option; use 0x1::string; use 0x1::type_name; use 0x2::balance; use 0x2::deny_list; use 0x2::object; use 0x2::transfer; use 0x2::tx_context; use 0x2::types; use 0x2::url;

Resource Coin

A coin of type T worth value. Transferable and storable

struct Coin<T> has store, key

Fields

Resource CoinMetadata

Each Coin type T created through create_currency function will have a unique instance of CoinMetadata<T> that stores the metadata for this coin type.

struct CoinMetadata<T> has store, key

Fields
id: object::UID
decimals: u8

Number of decimal places the coin uses. A coin with value N and decimals D should be shown as N / 10^D E.g., a coin with value 7002 and decimals 3 should be displayed as 7.002 This is metadata for display usage only.

name: string::String

Name for the token

symbol: ascii::String

Symbol for the token

description: string::String

Description of the token

icon_url: option::Option<url::Url>

URL for the token logo

Resource RegulatedCoinMetadata

Similar to CoinMetadata, but created only for regulated coins that use the DenyList. This object is always immutable.

struct RegulatedCoinMetadata<T> has key

Fields
id: object::UID
coin_metadata_object: object::ID

The ID of the coin's CoinMetadata object.

deny_cap_object: object::ID

The ID of the coin's DenyCap object.

Resource TreasuryCap

Capability allowing the bearer to mint and burn coins of type T. Transferable

struct TreasuryCap<T> has store, key

Fields
id: object::UID
total_supply: balance::Supply<T>

Resource DenyCap

Capability allowing the bearer to freeze addresses, preventing those addresses from interacting with the coin as an input to a transaction.

struct DenyCap<T> has store, key

Fields

Struct CurrencyCreated

struct CurrencyCreated<T> has copy, drop

Fields
decimals: u8

Constants

Trying to split a coin more times than its balance allows.

const ENotEnough: u64 = 2;

The index into the deny list vector for the iota::coin::Coin type.

const DENY_LIST_COIN_INDEX: u64 = 0;

A type passed to create_supply is not a one-time witness.

const EBadWitness: u64 = 0;

Invalid arguments are passed to a function.

const EInvalidArg: u64 = 1;

Function total_supply

Return the total number of T's in circulation.

public fun total_supply<T>(cap: &coin::TreasuryCap<T>): u64

Implementation

public fun total_supply<T>(cap: &TreasuryCap<T>): u64 { balance::supply_value(&cap.total_supply) }

Function treasury_into_supply

Unwrap TreasuryCap getting the Supply.

Operation is irreversible. Supply cannot be converted into a TreasuryCap due to different security guarantees (TreasuryCap can be created only once for a type)

public fun treasury_into_supply<T>(treasury: coin::TreasuryCap<T>): balance::Supply<T>

Implementation

public fun treasury_into_supply<T>(treasury: TreasuryCap<T>): Supply<T> { let TreasuryCap { id, total_supply } = treasury; id.delete(); total_supply }

Function supply_immut

Get immutable reference to the treasury's Supply.

public fun supply_immut<T>(treasury: &coin::TreasuryCap<T>): &balance::Supply<T>

Implementation

public fun supply_immut<T>(treasury: &TreasuryCap<T>): &Supply<T> { &treasury.total_supply }

Function supply_mut

Get mutable reference to the treasury's Supply.

public fun supply_mut<T>(treasury: &mut coin::TreasuryCap<T>): &mut balance::Supply<T>

Implementation

public fun supply_mut<T>(treasury: &mut TreasuryCap<T>): &mut Supply<T> { &mut treasury.total_supply }

Function value

Public getter for the coin's value

public fun value<T>(self: &coin::Coin<T>): u64

Implementation

public fun value<T>(self: &Coin<T>): u64 { self.balance.value() }

Function balance

Get immutable reference to the balance of a coin.

public fun balance<T>(coin: &coin::Coin<T>): &balance::Balance<T>

Implementation

public fun balance<T>(coin: &Coin<T>): &Balance<T> { &coin.balance }

Function balance_mut

Get a mutable reference to the balance of a coin.

public fun balance_mut<T>(coin: &mut coin::Coin<T>): &mut balance::Balance<T>

Implementation

public fun balance_mut<T>(coin: &mut Coin<T>): &mut Balance<T> { &mut coin.balance }

Function from_balance

Wrap a balance into a Coin to make it transferable.

public fun from_balance<T>(balance: balance::Balance<T>, ctx: &mut tx_context::TxContext): coin::Coin<T>

Implementation

public fun from_balance<T>(balance: Balance<T>, ctx: &mut TxContext): Coin<T> { Coin { id: object::new(ctx), balance } }

Function into_balance

Destruct a Coin wrapper and keep the balance.

public fun into_balance<T>(coin: coin::Coin<T>): balance::Balance<T>

Implementation

public fun into_balance<T>(coin: Coin<T>): Balance<T> { let Coin { id, balance } = coin; id.delete(); balance }

Function take

Take a Coin worth of value from Balance. Aborts if value > balance.value

public fun take<T>(balance: &mut balance::Balance<T>, value: u64, ctx: &mut tx_context::TxContext): coin::Coin<T>

Implementation

public fun take<T>( balance: &mut Balance<T>, value: u64, ctx: &mut TxContext, ): Coin<T> { Coin { id: object::new(ctx), balance: balance.split(value) } }

Function put

Put a Coin<T> to the Balance<T>.

public fun put<T>(balance: &mut balance::Balance<T>, coin: coin::Coin<T>)

Implementation

public fun put<T>(balance: &mut Balance<T>, coin: Coin<T>) { balance.join(into_balance(coin)); }

Function join

Consume the coin c and add its value to self. Aborts if c.value + self.value > U64_MAX

public entry fun join<T>(self: &mut coin::Coin<T>, c: coin::Coin<T>)

Implementation

public entry fun join<T>(self: &mut Coin<T>, c: Coin<T>) { let Coin { id, balance } = c; id.delete(); self.balance.join(balance); }

Function split

Split coin self to two coins, one with balance split_amount, and the remaining balance is left is self.

public fun split<T>(self: &mut coin::Coin<T>, split_amount: u64, ctx: &mut tx_context::TxContext): coin::Coin<T>

Implementation

public fun split<T>( self: &mut Coin<T>, split_amount: u64, ctx: &mut TxContext ): Coin<T> { take(&mut self.balance, split_amount, ctx) }

Function divide_into_n

Split coin self into n - 1 coins with equal balances. The remainder is left in self. Return newly created coins.

public fun divide_into_n<T>(self: &mut coin::Coin<T>, n: u64, ctx: &mut tx_context::TxContext): vector<coin::Coin<T>>

Implementation

public fun divide_into_n<T>( self: &mut Coin<T>, n: u64, ctx: &mut TxContext ): vector<Coin<T>> { assert!(n > 0, EInvalidArg); assert!(n <= value(self), ENotEnough);

let mut vec = vector[]; let mut i = 0; let split_amount = value(self) / n; while (i < n - 1) { vec.push_back(self.split(split_amount, ctx)); i = i + 1; }; vec }

Function zero

Make any Coin with a zero value. Useful for placeholding bids/payments or preemptively making empty balances.

public fun zero<T>(ctx: &mut tx_context::TxContext): coin::Coin<T>

Implementation

public fun zero<T>(ctx: &mut TxContext): Coin<T> { Coin { id: object::new(ctx), balance: balance::zero() } }

Function destroy_zero

Destroy a coin with value zero

public fun destroy_zero<T>(c: coin::Coin<T>)

Implementation

public fun destroy_zero<T>(c: Coin<T>) { let Coin { id, balance } = c; id.delete(); balance.destroy_zero() }

Function create_currency

Create a new currency type T as and return the TreasuryCap for T to the caller. Can only be called with a one-time-witness type, ensuring that there's only one TreasuryCap per T.

public fun create_currency<T: drop>(witness: T, decimals: u8, symbol: vector<u8>, name: vector<u8>, description: vector<u8>, icon_url: option::Option<url::Url>, ctx: &mut tx_context::TxContext): (coin::TreasuryCap<T>, coin::CoinMetadata<T>)

Implementation

public fun create_currency<T: drop>( witness: T, decimals: u8, symbol: vector<u8>, name: vector<u8>, description: vector<u8>, icon_url: Option<Url>, ctx: &mut TxContext ): (TreasuryCap<T>, CoinMetadata<T>) { // Make sure there's only one instance of the type T assert!(iota::types::is_one_time_witness(&witness), EBadWitness);

( TreasuryCap { id: object::new(ctx), total_supply: balance::create_supply(witness) }, CoinMetadata { id: object::new(ctx), decimals, name: string::utf8(name), symbol: ascii::string(symbol), description: string::utf8(description), icon_url } ) }

Function create_regulated_currency

This creates a new currency, via create_currency, but with an extra capability that allows for specific addresses to have their coins frozen. Those addresses cannot interact with the coin as input objects.

public fun create_regulated_currency<T: drop>(witness: T, decimals: u8, symbol: vector<u8>, name: vector<u8>, description: vector<u8>, icon_url: option::Option<url::Url>, ctx: &mut tx_context::TxContext): (coin::TreasuryCap<T>, coin::DenyCap<T>, coin::CoinMetadata<T>)

Implementation

public fun create_regulated_currency<T: drop>( witness: T, decimals: u8, symbol: vector<u8>, name: vector<u8>, description: vector<u8>, icon_url: Option<Url>, ctx: &mut TxContext ): (TreasuryCap<T>, DenyCap<T>, CoinMetadata<T>) { let (treasury_cap, metadata) = create_currency( witness, decimals, symbol, name, description, icon_url, ctx ); let deny_cap = DenyCap { id: object::new(ctx), }; transfer::freeze_object(RegulatedCoinMetadata<T> { id: object::new(ctx), coin_metadata_object: object::id(&metadata), deny_cap_object: object::id(&deny_cap), }); (treasury_cap, deny_cap, metadata) }

Function mint

Create a coin worth value and increase the total supply in cap accordingly.

public fun mint<T>(cap: &mut coin::TreasuryCap<T>, value: u64, ctx: &mut tx_context::TxContext): coin::Coin<T>

Implementation

public fun mint<T>( cap: &mut TreasuryCap<T>, value: u64, ctx: &mut TxContext, ): Coin<T> { Coin { id: object::new(ctx), balance: cap.total_supply.increase_supply(value) } }

Function mint_balance

Mint some amount of T as a Balance and increase the total supply in cap accordingly. Aborts if value + cap.total_supply >= U64_MAX

public fun mint_balance<T>(cap: &mut coin::TreasuryCap<T>, value: u64): balance::Balance<T>

Implementation

public fun mint_balance<T>( cap: &mut TreasuryCap<T>, value: u64 ): Balance<T> { cap.total_supply.increase_supply(value) }

Function burn

Destroy the coin c and decrease the total supply in cap accordingly.

public entry fun burn<T>(cap: &mut coin::TreasuryCap<T>, c: coin::Coin<T>): u64

Implementation

public entry fun burn<T>(cap: &mut TreasuryCap<T>, c: Coin<T>): u64 { let Coin { id, balance } = c; id.delete(); cap.total_supply.decrease_supply(balance) }

Function deny_list_add

Adds the given address to the deny list, preventing it from interacting with the specified coin type as an input to a transaction.

public fun deny_list_add<T>(deny_list: &mut deny_list::DenyList, _deny_cap: &mut coin::DenyCap<T>, addr: address, _ctx: &mut tx_context::TxContext)

Implementation

public fun deny_list_add<T>( deny_list: &mut DenyList, _deny_cap: &mut DenyCap<T>, addr: address, _ctx: &mut TxContext ) { let type = type_name::into_string(type_name::get_with_original_ids<T>()).into_bytes(); deny_list::add( deny_list, DENY_LIST_COIN_INDEX, type, addr, ) }

Function deny_list_remove

Removes an address from the deny list. Aborts with ENotFrozen if the address is not already in the list.

public fun deny_list_remove<T>(deny_list: &mut deny_list::DenyList, _deny_cap: &mut coin::DenyCap<T>, addr: address, _ctx: &mut tx_context::TxContext)

Implementation

public fun deny_list_remove<T>( deny_list: &mut DenyList, _deny_cap: &mut DenyCap<T>, addr: address, _ctx: &mut TxContext ) { let type = type_name::into_string(type_name::get_with_original_ids<T>()).into_bytes(); deny_list::remove( deny_list, DENY_LIST_COIN_INDEX, type, addr, ) }

Function deny_list_contains

Returns true iff the given address is denied for the given coin type. It will return false if given a non-coin type.

public fun deny_list_contains<T>(freezer: &deny_list::DenyList, addr: address): bool

Implementation

public fun deny_list_contains<T>( freezer: &DenyList, addr: address, ): bool { let name = type_name::get_with_original_ids<T>(); if (type_name::is_primitive(&name)) return false;

let type = type_name::into_string(name).into_bytes(); freezer.contains(DENY_LIST_COIN_INDEX, type, addr) }

Function mint_and_transfer

Mint amount of Coin and send it to recipient. Invokes mint().

public entry fun mint_and_transfer<T>(c: &mut coin::TreasuryCap<T>, amount: u64, recipient: address, ctx: &mut tx_context::TxContext)

Implementation

public entry fun mint_and_transfer<T>( c: &mut TreasuryCap<T>, amount: u64, recipient: address, ctx: &mut TxContext ) { transfer::public_transfer(mint(c, amount, ctx), recipient) }

Function update_name

Update name of the coin in CoinMetadata

public entry fun update_name<T>(_treasury: &coin::TreasuryCap<T>, metadata: &mut coin::CoinMetadata<T>, name: string::String)

Implementation

public entry fun update_name<T>( _treasury: &TreasuryCap<T>, metadata: &mut CoinMetadata<T>, name: string::String ) { metadata.name = name; }

Function update_symbol

Update the symbol of the coin in CoinMetadata

public entry fun update_symbol<T>(_treasury: &coin::TreasuryCap<T>, metadata: &mut coin::CoinMetadata<T>, symbol: ascii::String)

Implementation

public entry fun update_symbol<T>( _treasury: &TreasuryCap<T>, metadata: &mut CoinMetadata<T>, symbol: ascii::String ) { metadata.symbol = symbol; }

Function update_description

Update the description of the coin in CoinMetadata

public entry fun update_description<T>(_treasury: &coin::TreasuryCap<T>, metadata: &mut coin::CoinMetadata<T>, description: string::String)

Implementation

public entry fun update_description<T>( _treasury: &TreasuryCap<T>, metadata: &mut CoinMetadata<T>, description: string::String ) { metadata.description = description; }

Function update_icon_url

Update the url of the coin in CoinMetadata

public entry fun update_icon_url<T>(_treasury: &coin::TreasuryCap<T>, metadata: &mut coin::CoinMetadata<T>, url: ascii::String)

Implementation

public entry fun update_icon_url<T>( _treasury: &TreasuryCap<T>, metadata: &mut CoinMetadata<T>, url: ascii::String ) { metadata.icon_url = option::some(url::new_unsafe(url)); }

Function get_decimals

public fun get_decimals<T>(metadata: &coin::CoinMetadata<T>): u8

Implementation

public fun get_decimals<T>(metadata: &CoinMetadata<T>): u8 { metadata.decimals }

Function get_name

public fun get_name<T>(metadata: &coin::CoinMetadata<T>): string::String

Implementation

public fun get_name<T>(metadata: &CoinMetadata<T>): string::String { metadata.name }

Function get_symbol

public fun get_symbol<T>(metadata: &coin::CoinMetadata<T>): ascii::String

Implementation

public fun get_symbol<T>(metadata: &CoinMetadata<T>): ascii::String { metadata.symbol }

Function get_description

public fun get_description<T>(metadata: &coin::CoinMetadata<T>): string::String

Implementation

public fun get_description<T>(metadata: &CoinMetadata<T>): string::String { metadata.description }

Function get_icon_url

public fun get_icon_url<T>(metadata: &coin::CoinMetadata<T>): option::Option<url::Url>

Implementation

public fun get_icon_url<T>(metadata: &CoinMetadata<T>): Option<Url> { metadata.icon_url }

Function supply

public fun supply<T>(treasury: &mut coin::TreasuryCap<T>): &balance::Supply<T>

Implementation

public fun supply<T>(treasury: &mut TreasuryCap<T>): &Supply<T> { &treasury.total_supply }