Aptos Move by Example
  • 🚀Getting Started
  • Set-Up
  • Why is Move Secure
    • Move prover
  • Move vs Solidity
    • Resources
    • Parallel Processing
    • Reentrancy attacks
    • Memory management
    • Smart contract verification
    • Compiled language
  • Basic Concepts
    • Move.toml
    • Primary data-types
    • Strings
    • Comments
    • Functions
    • Function Visibilities
    • Control flow and expressions
    • Loops
    • Error
    • Struct and its Abilities
    • Scripts
    • Operations
  • Intermediate Concepts
    • Local variables
    • Constants
    • Signer
    • Vector
    • Address
    • Uses and Aliases
    • Maps
    • Hash functions
    • References
    • Unit test
    • Generics
    • Type Arguments
    • Type Inference
  • Advanced Concepts
    • Global Storage Structure
    • Global Storage Operations
    • Phantom Type Parameters
    • Timestamps
    • Ownership
    • Move coding conventions
    • View functions
    • Aptos account
    • Aptos Coin
    • Aptos Token(Nft)
    • Object
    • Token V2
  • Applications
    • First App
    • ToDoList
    • Voting System
    • Basic Tokens
    • Storage using Generics
    • Company
    • Collection
    • Football Card
    • Staking Module
    • MultiSender Wallet
    • English Auction
    • Dutch Auction
    • Attendance Sheet
    • Polling Contract
    • Lottery Contract
  • Decentralized Finance
    • Simple Swap Protocol Contract
    • Code of Swapping Protocol
  • Hacks
    • Coming soon
  • Hands on tutorials
    • Indexer tutorials
Powered by GitBook
On this page
  • Structures
  • Creating a new CoinType
  • Minting Coins
  • Burning Coins​
  • Freezing Accounts​
  • Merging Coins​
  • Extracting Coins​
  • Withdrawing Coins from CoinStore​
  • Depositing Coins into CoinStore​
  • Transferring Coins​
  • Events​
Edit on GitHub
  1. Advanced Concepts

Aptos Coin

PreviousAptos accountNextAptos Token(Nft)

Last updated 1 year ago

provides a standard, typesafe framework for simple, fungible tokens or coins.

Structures

  • Reusability

A coin is defined in Move as:

struct Coin<phantom CoinType> has store {
    /// Amount of coin this address has.
    value: u64,
}

A Coin uses the CoinType to support re-usability of the Coin framework for distinct Coins. For example, Coin<A> and Coin<B> are two distinct coins.

  • Global Store

Coin also supports a resource for storing coins in global store:

struct CoinStore<phantom CoinType> has key {
    coin: Coin<CoinType>,
    frozen: bool,
    deposit_events: EventHandle<DepositEvent>,
    withdraw_events: EventHandle<WithdrawEvent>,
}

Coin information or metadata is stored in global store under the coin creators account:

struct CoinInfo<phantom CoinType> has key {
    name: string::String,
    /// Symbol of the coin, usually a shorter version of the name.
    /// For example, Singapore Dollar is SGD.
    symbol: string::String,
    /// Number of decimals used to get its user representation.
    /// For example, if `decimals` equals `2`, a balance of `505` coins should
    /// be displayed to a user as `5.05` (`505 / 10 ** 2`).
    decimals: u8,
    /// Amount of this coin type in existence.
    supply: Option<OptionalAggregator>,
}

Creating a new CoinType

A coin creator can publish to an on-chain account a new module that defines a struct to represent a new CoinType. The coin creator will then call coin:initialize<CoinType> from that account to register this as a valid coin, and in return receive back structs that enable calling the functions to burn and mint coins and freeze CoinStores. These will need to be stored in global storage by the creator to manage the use of the coin.

public fun initialize<CoinType>(
    account: &signer,
    name: string::String,
    symbol: string::String,
    decimals: u8,
    monitor_supply: bool,
): (BurnCapability<CoinType>, FreezeCapability<CoinType>, MintCapability<CoinType>) {
  • The first three of the above (name, symbol, decimals) are purely metadata and have no impact for on-chain applications. Some applications may use decimal to equate a single Coin from fractional coin.

  • Monitoring supply (monitor_supply) helps track total coins in supply. However, due to the way the parallel executor works, turning on this option will prevent any parallel execution of mint and burn. If the coin will be regularly minted or burned, consider disabling monitor_supply.

Minting Coins

If the creator or manager would like to mint coins, they must retrieve a reference to their MintCapability, which was produced in the initialize, and call:

public fun mint<CoinType>(
    amount: u64,
    _cap: &MintCapability<CoinType>,
): Coin<CoinType> acquires CoinInfo {

This will produce a new Coin struct containing a value as dictated by the amount. If supply is tracked, then it will also be adjusted.

If the creator or manager would like to burn coins, they must retrieve a reference to their BurnCapability, which was produced in the initialize, and call:

public fun burn<CoinType>(
    coin: Coin<CoinType>,
    _cap: &BurnCapability<CoinType>,
) acquires CoinInfo {

The creator or manager can also burn coins from a CoinStore:

public fun burn_from<CoinType>(
    account_addr: address,
    amount: u64,
    burn_cap: &BurnCapability<CoinType>,
) acquires CoinInfo, CoinStore {

If the creator or manager would like to freeze a CoinStore on a specific account, they must retrieve a reference to their FreezeCapability, which was produced in initialize, and call:

public entry fun freeze_coin_store<CoinType>(
    account_addr: address,
    _freeze_cap: &FreezeCapability<CoinType>,
) acquires CoinStore {

Two coins of the same type can be merged into a single Coin struct that represents the accumulated value of the two coins independently by calling:

public fun merge<CoinType>(
    dst_coin: &mut Coin<CoinType>,
    source_coin: Coin<CoinType>,
) {

A Coin can have value deducted to create another Coin by calling:

public fun extract<CoinType>(
        coin: &mut Coin<CoinType>,
        amount: u64,
): Coin<CoinType> {

A holder of a CoinStore can extract a Coin of a specified value by calling:

public fun withdraw<CoinType>(
    account: &signer,
    amount: u64,
): Coin<CoinType> acquires CoinStore {

Any entity can deposit coins into an account’s CoinStore by calling:

public fun deposit<CoinType>(
        account_addr: address,
        coin: Coin<CoinType>,
) acquires CoinStore {

A holder of a CoinStore can directly transfer coins from their account to another account’s CoinStore by calling:

public entry fun transfer<CoinType>(
    from: &signer,
    to: address,
    amount: u64,
) acquires CoinStore {
struct DepositEvent has drop, store {
    amount: u64,
}
struct WithdrawEvent has drop, store {
    amount: u64,
}

Burning Coins

Freezing Accounts

Merging Coins

Extracting Coins

Withdrawing Coins from CoinStore

Depositing Coins into CoinStore

Transferring Coins

Events

Coin
​
​
​
​
​
​
​
​