Skip to content

Create Publication

We are looking for publications that demonstrate building dApps or smart contracts!
See the full list of Gitcoin bounties that are eligible for rewards.

Create a fungible token

What are fungible tokens?

Fungible tokens, or FTs for short, are a type of asset split into multiple units that are fundamentally the same and interchangeable one-to-one with each other. Algos are fungible, but since they are also a utility token for the Algorand network, they are implemented differently from the types of fungible tokens we’ll talk about in this guide.

Examples of FTs

Examples of fungible token use cases: local currencies, travel program loyalty points, in-game tokens.

Loyalty programs that offer reward points that can be traded in for merchandise or services are considered fungible. Fiat currencies are fungible and can be represented on the blockchain as stablecoins (a token that maintains a steady value usually by having backed reserves or through some stabilization algorithms) or by direct issuance on the blockchain (central bank digital currencies). Tokenized shares in real estate, a company, or a fund are usually fungible too.

Tokenizing a fungible asset is an onramp to all the benefits of a blockchain ecosystem that we learned about in the first section of this getting started guide (security, trust, immutability, efficiency, low costs, composability).

How to create fungible tokens

Fungible tokens, like NFTs, are implemented as Algorand Standard Assets (ASAs). Also like NFTs, you do not need to write smart contract code. You just need to specify a few parameters to identify it as an FT (e.g. total count is greater than 1) and attach metadata so that potential owners have the information they need to validate the integrity of the asset. The relevant code snippet in each of the SDKs is as follows:

txn = AssetConfigTxn(sender=accounts[1]['pk'],
                     sp=params,
                     total=10000,           // Fungible tokens have totalIssuance greater than 1
                     default_frozen=False,
                     unit_name="ALICE",
                     asset_name="Alice's [email protected]",
                     manager="",
                     reserve="",
                     freeze="",
                     clawback="",
                     url="https://path/to/my/fungible/asset/metadata.json",
                     metadata_hash=json_metadata_hash,
                     decimals=2)            // Fungible tokens typically have decimals greater than 0
const creator = alice.addr;
const defaultFrozen = false;    
const unitName = "ALICE"; 
const assetName = "Alice's [email protected]";
const url = "https://path/to/my/fungible/asset/metadata.json";
const managerAddr = undefined; 
const reserveAddr = undefined;  
const freezeAddr = undefined;
const clawbackAddr = undefined;
const total = 10000;               // Fungible tokens have totalIssuance greater than 1
const decimals = 2;                 // Fungible tokens typically have decimals greater than 0
const txn = algosdk.makeAssetCreateTxnWithSuggestedParamsFromObject({
    creator,
    total,
    decimals,
    assetName,
    unitName,
    assetURL: url,
    assetMetadataHash: metadata,
    defaultFrozen,
    freeze: freezeAddr,
    manager: managerAddr,
    clawback: clawbackAddr,
    reserve: reserveAddr,
    suggestedParams: params,}); 
    String creator = aliceAccount.getAddress().toString();
    boolean defaultFrozen = false;
    String unitName = "ALICE";
    String assetName = "Alice's [email protected]";
    String url = "https://path/to/my/fungible/asset/metadata.json";
    Address manager = null;  
    Address reserve = null;
    Address freeze = null;
    Address clawback = null;      
    BigInteger assetTotal = BigInteger.valueOf(10000); // Fungible tokens have totalIssuance greater than 1
    Integer decimals = 2;                               // Fungible tokens typically have decimals greater than 0
    Transaction tx = Transaction.AssetCreateTransactionBuilder()
            .sender(creator)
            .assetTotal(assetTotal)
            .assetDecimals(decimals)
            .assetUnitName(unitName)
            .assetName(assetName)
            .url(url)
            .metadataHash(assetMetadataHash)
            .manager(manager)
            .reserve(reserve)
            .freeze(freeze)
            .defaultFrozen(defaultFrozen)
            .clawback(clawback)
            .suggestedParams(params)
            .build();       
creator := account.Address.String()
assetName := "Alice's [email protected]"
unitName := "ALICE"
assetURL := "https://path/to/my/fungible/asset/metadata.json"
assetMetadataHash := metadataHash
totalIssuance := uint64(10000)  // Fungible tokens have totalIssuance greater than 1
decimals := uint32(2)           // Fungible tokens typically have decimals greater than 0
manager := ""
reserve := ""
freeze := ""
clawback := ""
defaultFrozen := false
note := []byte(nil)

    txn, err := transaction.MakeAssetCreateTxn(
    creator, note, txParams, totalIssuance, decimals,
    defaultFrozen, manager, reserve, freeze, clawback,
    unitName, assetName, assetURL, assetMetadataHash)

Let’s imagine that Alice wants to create a loyalty point program for her buyers. She’ll represent these points as a fungible asset on Algorand and will call it AliceCoin. Owners of AliceCoin can use them to buy future artwork or trade it in for priority access to some of Alice’s art events. Let’s mint AliceCoin on TestNet. We will use the Algorand Foundation’s proposed ARC-0003 FT standard.

Notice that we didn't set the mutable asset parameters manager, reserve, freeze, and clawback. When you set them to undefined or an empty string, the protocol will interpret them as immutable from that point forward. That means you can't change these asset parameters anymore. You can find all asset parameters here

Other fungible token resources