Skip to main content

Creating Coins and Tokens

Coins and tokens in IOTA are similar concepts, often used interchangeably, but there are subtle differences in their implementation. To understand these differences, refer to the standard documentation for Closed-Loop Token and Coin.

Publishing a Coin

Publishing a coin on IOTA is almost as straightforward as publishing a new type. The key difference is the requirement of a one-time witness when creating a coin.

// Copyright (c) Mysten Labs, Inc.
// Modifications Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

module examples::my_coin {
use iota::coin::{Self, TreasuryCap};

// The type identifier of coin. The coin will have a type
// tag of kind: `Coin<package_object::mycoin::MYCOIN>`
// Make sure that the name of the type matches the module's name.
public struct MY_COIN has drop {}

// Module initializer is called once on module publish. A treasury
// cap is sent to the publisher, who then controls minting and burning.
fun init(witness: MY_COIN, ctx: &mut TxContext) {
let (treasury, metadata) = coin::create_currency(witness, 6, b"MY_COIN", b"", b"", option::none(), ctx);
// Freezing this object makes the metadata immutable, including the title, name, and icon image.
// If you want to allow mutability, share it with public_share_object instead.
transfer::public_freeze_object(metadata);
transfer::public_transfer(treasury, ctx.sender())
}

// Create MY_COINs using the TreasuryCap.
public fun mint(
treasury_cap: &mut TreasuryCap<MY_COIN>,
amount: u64,
recipient: address,
ctx: &mut TxContext,
) {
let coin = coin::mint(treasury_cap, amount, ctx);
transfer::public_transfer(coin, recipient)
}
}

The Coin<T> is a generic coin implementation in IOTA. By accessing the TreasuryCap, you gain control over minting and burning coins. You can send further transactions directly to iota::coin::Coin using the TreasuryCap object for authorization.

Extending the Coin Module

To extend the coin module, add a mint function. This function utilizes the mint method from the Coin module to create a coin and transfer it to a specified address.

IOTA CLI

Minting Coins

After publishing the coin module to the IOTA network, you can mint coins and send them to an address using the iota client call command. For more details on the command-line interface, see IOTA CLI.

iota client call --function mint --module mycoin --package <PACKAGE-ID> --args <TREASURY-CAP-ID> <COIN-AMOUNT> <RECIPIENT-ADDRESS>

Upon successful execution, the console displays output including a Balance Changes section:

...

Owner: Account Address ( <RECIPIENT-ADDRESS> )
CoinType: <PACKAGE-ID>::mycoin::MYCOIN
Amount: <COIN-AMOUNT>

...

Implementing a Deny List

If you need to restrict specific addresses from accessing your coin, consider implementing a DenyList.

Creating a Regulated Coin

To deny specific addresses from holding your coin, use the create_regulated_currency function instead of create_currency.

Internally, create_regulated_currency calls create_currency to create the coin and also produces a DenyCap object. This object allows you to manage the deny list in a DenyList object. The process is similar to the previous example but includes transferring the DenyCap object to the module publisher.

Creating Tokens

Tokens reuse the TreasuryCap defined in the iota::coin module and follow the same initialization process. The coin::create_currency function ensures the uniqueness of the TreasuryCap and enforces the creation of a CoinMetadata object.

You can mint and burn tokens using functions similar to those for coins, both requiring the TreasuryCap:

For complete details on working with tokens, refer to the Closed-Loop Token standard.

Additional Examples

Explore these topics for practical examples of coin and token creation:

Question 1/3

What is the main difference between publishing a coin and publishing a new type on IOTA?