Unicorn Ultra
  • Welcome to unicorn ultra — let’s build the future
  • Getting Started
    • Introduction
    • Environment Setup
    • Create an Account
    • Transfer U2U
    • Query Ledger Data
  • Tutorials
    • Smart Contracts
      • Deploy Your First Smart Contract
      • Deploy a Contract Using the Hedera Token Service
      • Send and Receive HBAR Using Solidity Smart Contracts
      • Create an HBAR Faucet App Using React and MetaMask
      • Deploy By Leveraging Ethereum Developer Tools On Hedera
      • Deploy a Smart Contract Using Hardhat
      • Deploy a Subgraph Using The Graph and JSON-RPC
      • How to Set Up Foundry to Test Smart Contracts on Hedera
      • Deploy Smart Contracts on Hedera Using Truffle
    • Consensus
      • Submit Your First Message
      • Submit Message to Private Topic
      • Query Messages with Mirror Node
    • Tokens
      • Create and Transfer Your First NFT
      • Create and Transfer Your First Fungible Token
      • Create and Transfer an NFT using a Solidity Contract
      • Structure Your Token Metadata Using JSON Schema V2
    • More Tutorials
      • How to Auto-Create Hedera Accounts with HBAR and Token Transfers
      • How to Configure a Mirror Node and Query Data
      • How to Generate a Random Number on Hedera
      • Get Started with the Hedera Consensus Service Fabric Plugin
        • Virtual Environment Setup
      • Schedule Your First Transaction
      • How to Connect to Hedera Networks Over RPC
        • Configuring Hashio RPC endpoints
        • Configuring Arkhia RPC endpoints
        • Configuring Hedera JSON-RPC Relay endpoints
    • Demo Applications
    • Starter Projects
  • Networks
    • Mainnet
      • Mainnet Accounts
      • Mainnet Consensus Nodes
        • Node Requirements
          • Reference Configuration
          • FAQ
      • Fees
        • Transaction Records
    • Testnets
      • Testnet Accounts
      • Testnet Consensus Nodes
    • Network Explorers and Tools
    • Release Notes
      • Hedera Services
      • Hedera Mirror Node
  • Core Concepts
    • Accounts
      • Account Creation
      • Auto Account Creation
      • Account Properties
    • Keys and Signatures
    • Scheduled Transaction
    • Smart Contracts
      • Hyperledger Besu EVM
      • Gas and Fees
      • Solidity Variables and Opcodes
      • Supported ERC Token Standards
      • Hedera Services Integration with Smart Contracts
      • JSON-RPC Relay
      • Hethers
      • Smart Contract Security
    • Staking
      • Staking Program
      • Stake HBAR
    • Hashgraph Consensus Algorithm
      • Gossip About Gossip
      • Virtual Voting
    • Transactions and Queries
    • State and History
    • Mirror Nodes
      • Hedera Mirror Node
      • One Click Mirror Node Deployment
      • Run Your Own Mirror Node
        • Run Your Own Mirror Node with Google Cloud Storage (GCS)
        • Run Your Mirror Node with Amazon Web Services S3 (AWS)
      • Hedera ETL
  • SDKs & APIs
    • SDKs
      • Build Your Hedera Client
      • Set Up Your Local Network
      • Network Address Book
      • Keys
        • Generate a new key pair
        • Import an existing key
        • Create a key list
        • Create a threshold key
        • Generate a mnemonic phrase
        • Recover keys from a mnemonic phrase
      • HBAR
      • Specialized Types
      • Pseudorandom Number Generator
      • Transactions
        • Transaction ID
        • Modify transaction fields
        • Create an unsigned transaction
        • Manually sign a transaction
        • Submit a transaction
        • Sign a multisignature transaction
        • Get a transaction receipt
        • Get a transaction record
      • Schedule Transaction
        • Schedule ID
        • Create a scheduled transaction
        • Sign a scheduled transaction
        • Delete a scheduled transaction
        • Get schedule info
        • Network Response Messages
        • Schedule FAQ
      • Queries
      • General Network Response Messages
      • Accounts and HBAR
        • Create an account
        • Update an account
        • Transfer cryptocurrency
        • Approve an allowance
        • Delete an allowance
        • Delete an account
        • Get account balance
        • Get account info
        • Network Response Messages
      • Consensus Service
        • Create a topic
        • Update a topic
        • Submit a message
        • Delete a topic
        • Get topic messages
        • Get topic info
        • Network Response
      • Token Service
        • Token ID
        • NFT ID
        • Token types
        • Create a token
        • Custom token fees
        • Update a token
        • Update token custom fees
        • Transfer tokens
        • Delete a token
        • Mint a token
        • Burn a token
        • Freeze an account
        • Unfreeze an account
        • Enable KYC account flag
        • Disable KYC account flag
        • Associate tokens to an account
        • Dissociate tokens from an account
        • Pause a token
        • Unpause a token
        • Wipe a token
        • Atomic swaps
        • Get account token balance
        • Get token info
        • Get NFT info
        • Network Response Messages
      • File Service
        • Create a file
        • Append to a file
        • Update a file
        • Delete a file
        • Get file contents
        • Get file info
        • Network Response Messages
      • Smart Contract Service
        • Delegate Contract ID
        • Create a smart contract
        • Update a smart contract
        • Delete a smart contract
        • Call a smart contract function
        • Ethereum transaction
        • Get a smart contract function
        • Get smart contract bytecode
        • Get smart contract info
        • Hedera Service Solidity Libraries
        • Network Response Messages
      • Signature Provider
        • Provider
        • Signer
        • Wallet
        • Local Provider
    • REST API
    • Hedera Consensus Service gRPC API
    • Hedera APIs
      • Basic Types
        • AccountAmount
        • AccountID
        • ContractID
        • CryptoAllowance
        • CurrentAndNextFeeSchedule
        • FeeComponents
        • FeeData
        • FeeSchedule
        • FileID
        • Fraction
        • HederaFunctionality
        • Key
        • KeyList
        • NftAllowance
        • NftTransfer
        • NodeAddress
        • NodeAddressBook
        • RealmID
        • ScheduleID
        • SemanticVersion
        • ServicesConfigurationList
        • ServiceEndpoint
        • Setting
        • ShardID
        • Signature
        • SignatureList
        • SignatureMap
        • SignaturePair
        • SubType
        • TransferList
        • TransactionID
        • ThresholdKey
        • ThresholdSignature
        • TokenAllowance
        • TokenBalance
        • TokenBalances
        • TokenFreezeStatus
        • TokenPauseStatus
        • TokenID
        • TokenKycStatus
        • TokenRelationship
        • TokenTransferList
        • TokenType
        • TokenSupplyType
        • TopicID
        • TransactionFeeSchedule
      • Cryptocurrency Accounts
        • CryptoService
        • CryptApproveAllowance
        • CryptoDeleteAllowance
        • CryptoCreate
        • CryptoTransfer
        • CryptoUpdate
        • CryptoDelete
        • CryptoGetAccountBalance
        • CryptoGetAccountRecords
        • CryptoGetInfo
        • CryptoGetStakers
      • Consensus Service
        • Consensus Service
        • ConsensusCreateTopic
        • ConsensusUpdateTopic
        • ConsensusSubmitMessage
        • ConsensusDeleteTopic
        • ConsensusTopicInfo
        • ConsensusGetTopicInfo
      • Schedule Service
        • ScheduleService
        • SchedulableTransactionBody
        • ScheduleCreate
        • ScheduleDelete
        • ScheduleSign
        • ScheduleGetInfo
      • Token Service
        • TokenService
        • CustomFees
          • AssessedCustomFee
          • CustomFee
          • FractionalFee
          • FixedFee
          • RoyaltyFee
        • TokenCreate
        • TokenUpdate
        • TokenFeeScheduleUpdate
        • TokenDelete
        • TokenMint
        • TokenBurn
        • TokenFreezeAccount
        • TokenUnfreezeAccount
        • TokenGrantKyc
        • TokenRevokeKyc
        • TokenAssociate
        • TokenDissociate
        • TokenWipeAccount
        • TokenPause
        • TokenUnpause
        • TokenGetInfo
        • TokenGetNftInfo
        • TokenGetNftInfos
        • TokenGetAccountNftInfo
      • File Service
        • FileService
        • FileCreate
        • FileAppend
        • FileUpdate
        • FileDelete
        • FileGetContents
        • FileGetInfo
      • Smart Contracts
        • SmartContractService
        • ContractCall
        • ContractCallLocal
        • ContractCreate
        • ContractUpdate
        • ContractDelete
        • ContractGetByteCode
        • ContractGetInfo
        • ContractGetRecords
      • Miscellaneous
        • Duration
        • ExchangeRate
        • Freeze
        • FreezeType
        • GetByKey
        • GetBySolidityID
        • NetworkGetVersionInfo
        • NetworkService
        • Query
        • QueryHeader
        • Response
        • ResponseCode
        • ResponseHeader
        • SystemDelete
        • SystemUndelete
        • TimeStamp
        • Transaction
        • TransactionBody
        • TransactionContents
        • TransactionGetFastRecord
        • TransactionGetReceipt
        • TransactionGetRecord
        • TransactionReceipt
        • TransactionRecord
        • TransactionResponse
        • UncheckedSubmit
    • Deprecated
      • SDKs (V1)
        • Build your Hedera client
        • Set-up Your Local Network
        • Network address book
        • Keys
          • Generate a new key pair
          • Import an existing key
          • Create a key list
          • Create a threshold key
          • Generate a mnemonic phrase
          • Recover keys from a mnemonic phrase
        • Hbars
        • Specialized Types
        • Pseudorandom Number Generator
        • Transactions
          • Transaction ID
          • Modify transaction fields
          • Create an unsigned transaction
          • Manually sign a transaction
          • Submit a transaction
          • Sign a multisignature transaction
          • Get a transaction receipt
          • Get a transaction record
        • Scheduled Transaction
          • Schedule ID
          • Create a scheduled transaction
          • Sign a scheduled transaction
          • Delete a scheduled transaction
          • Get schedule info
          • Network Response Messages
          • Schedule FAQ
        • Queries
        • General Network Response Messages
        • Accounts and hbar
          • Create an account
          • Update an Account
          • Transfer cryptocurrency
          • Approve an allowance
          • Delete an allowance
          • Delete an account
          • Get account balance
          • Get account info
          • Network Response Messages
        • Consensus Service
          • Create a topic
          • Update a topic
          • Submit a message
          • Delete a topic
          • Get topic messages
          • Get topic info
        • Token Service
          • Token ID
          • NFT ID
          • Token types
          • Create a token
          • Custom token fees
          • Update a token
          • Update token custom fees
          • Transfer tokens
          • Delete a token
          • Mint a token
          • Burn a token
          • Freeze an account
          • Unfreeze an account
          • Enable KYC account flag
          • Disable KYC account flag
          • Associate tokens to an account
          • Dissociate tokens from an account
          • Pause a token
          • Unpause a token
          • Wipe a token
          • Atomic swaps
          • Get account token balance
          • Get token info
          • Get NFT info
          • Network Response Messages
        • File Service
          • Create a file
          • Append to a file
          • Update a file
          • Delete a file
          • Get file contents
          • Get file info
          • Network Response Messages
  • Support & Community
    • Glossary
    • Discord
    • GitHub
    • Stack Overflow
    • Hedera Blog
    • Bug Bounty
    • Hedera Help
    • Meetups
    • Contributing Guide
    • Brand Guidelines
    • Status Page
Powered by GitBook
On this page
  • Summary
  • Prerequisites
  • 1. Create a Fungible Token
  • 2. Associate User Accounts with Token
  • 3. Transfer the Token
  • Code Check ✅
  1. Tutorials
  2. Tokens

Create and Transfer Your First Fungible Token

PreviousCreate and Transfer Your First NFTNextCreate and Transfer an NFT using a Solidity Contract

Last updated 1 year ago

Summary

Fungible tokens share a single set of properties and have interchangeable value with one another. Use cases for fungible tokens include applications like stablecoins, in-game rewards systems, crypto tokens, loyalty program points, and much more.

Prerequisites

We recommend you complete the following introduction to get a basic understanding of Hedera transactions. This example does not build upon the previous examples.

1. Create a Fungible Token

Use TokenCreateTransaction() to create a fungible token and configure its properties. At a minimum, this constructor requires setting a name, symbol, and treasury account ID. All other fields are optional, so if they’re not specified then default values are used. For instance, not specifying an admin key, makes a token immutable (can’t change or add properties); not specifying a supply key, makes a token supply fixed (can’t mint new or burn existing tokens); not specifying a token type, makes a token fungible.

After submitting the transaction to the Hedera network, you can obtain the new token ID by requesting the receipt.

Unlike NFTs, fungible tokens do not require the decimals and initial supply to be set to zero during creation. In this case, we set the initial supply to 100 units, which is shown in the code as 10000 to account to 2 decimals.

// CREATE FUNGIBLE TOKEN (STABLECOIN)
TokenCreateTransaction tokenCreateTx = new TokenCreateTransaction()
        .setTokenName("USD Bar")
        .setTokenSymbol("USDB")
        .setTokenType(TokenType.FUNGIBLE_COMMON)
        .setDecimals(2)
        .setInitialSupply(10000)
        .setTreasuryAccountId(treasuryId)
        .setSupplyType(TokenSupplyType.INFINITE)
        .setSupplyKey(supplyKey)
        .freezeWith(client);

//SIGN WITH TREASURY KEY
TokenCreateTransaction tokenCreateSign = tokenCreateTx.sign(treasuryKey);

//SUBMIT THE TRANSACTION
TransactionResponse tokenCreateSubmit = tokenCreateSign.execute(client);

//GET THE TRANSACTION RECEIPT
TransactionReceipt tokenCreateRx = tokenCreateSubmit.getReceipt(client);

//GET THE TOKEN ID
TokenId tokenId = tokenCreateRx.tokenId;

//LOG THE TOKEN ID TO THE CONSOLE
System.out.println("Created token with ID: " +tokenId);
// CREATE FUNGIBLE TOKEN (STABLECOIN)
let tokenCreateTx = await new TokenCreateTransaction()
	.setTokenName("USD Bar")
	.setTokenSymbol("USDB")
	.setTokenType(TokenType.FungibleCommon)
	.setDecimals(2)
	.setInitialSupply(10000)
	.setTreasuryAccountId(treasuryId)
	.setSupplyType(TokenSupplyType.Infinite)
	.setSupplyKey(supplyKey)
	.freezeWith(client);

//SIGN WITH TREASURY KEY
let tokenCreateSign = await tokenCreateTx.sign(treasuryKey);

//SUBMIT THE TRANSACTION
let tokenCreateSubmit = await tokenCreateSign.execute(client);

//GET THE TRANSACTION RECEIPT
let tokenCreateRx = await tokenCreateSubmit.getReceipt(client);

//GET THE TOKEN ID
let tokenId = tokenCreateRx.tokenId;

//LOG THE TOKEN ID TO THE CONSOLE
console.log(`- Created token with ID: ${tokenId} \n`);
//CREATE FUNGIBLE TOKEN (STABLECOIN)
tokenCreateTx, err := hedera.NewTokenCreateTransaction().
	SetTokenName("USD Bar").
	SetTokenSymbol("USDB").
	SetTokenType(hedera.TokenTypeFungibleCommon).
	SetDecimals(2).
	SetInitialSupply(10000).
	SetTreasuryAccountID(treasuryAccountId).
	SetSupplyType(hedera.TokenSupplyTypeInfinite).
	SetSupplyKey(supplyKey).
	FreezeWith(client)

//SIGN WITH TREASURY KEY
tokenCreateSign := tokenCreateTx.Sign(treasuryKey)

//SUBMIT THE TRANSACTION
tokenCreateSubmit, err := tokenCreateSign.Execute(client)

//GET THE TRANSACTION RECEIPT
tokenCreateRx, err := tokenCreateSubmit.GetReceipt(client)

//GET THE TOKEN ID
tokenId := *tokenCreateRx.TokenID

//LOG THE TOKEN ID TO THE CONSOLE
fmt.Println("Created fungible token with token ID", tokenId)

2. Associate User Accounts with Token

Before an account that is not the treasury for a token can receive or send this specific token ID, the account must become “associated” with the token.

// TOKEN ASSOCIATION WITH ALICE's ACCOUNT
TokenAssociateTransaction associateAliceTx = new TokenAssociateTransaction()
        .setAccountId(aliceAccountId)
        .setTokenIds(Collections.singletonList(tokenId))
	.freezeWith(client)
        .sign(aliceKey);
        
//SUBMIT THE TRANSACTION
TransactionResponse associateAliceTxSubmit = associateAliceTx.execute(client);
        
//GET THE RECEIPT OF THE TRANSACTION
TransactionReceipt associateAliceRx = associateAliceTxSubmit.getReceipt(client);
        
//LOG THE TRANSACTION STATUS
System.out.println("Token association with Alice's account: " +associateAliceRx.status);
// TOKEN ASSOCIATION WITH ALICE's ACCOUNT
let associateAliceTx = await new TokenAssociateTransaction()
	.setAccountId(aliceId)
	.setTokenIds([tokenId])
	.freezeWith(client)
	.sign(aliceKey);

//SUBMIT THE TRANSACTION
let associateAliceTxSubmit = await associateAliceTx.execute(client);

//GET THE RECEIPT OF THE TRANSACTION
let associateAliceRx = await associateAliceTxSubmit.getReceipt(client);

//LOG THE TRANSACTION STATUS
console.log(`- Token association with Alice's account: ${associateAliceRx.status} \n`);
//TOKEN ASSOCIATION WITH ALICE's ACCOUNT
associateAliceTx, err := hedera.NewTokenAssociateTransaction().
	SetAccountID(aliceAccountId).
	SetTokenIDs(tokenId).
	FreezeWith(client)

//SIGN WITH ALICE'S KEY TO AUTHORIZE THE ASSOCIATION
signTx := associateAliceTx.Sign(aliceKey)

//SUBMIT THE TRANSACTION
associateAliceTxSubmit, err := signTx.Execute(client)

//GET THE RECEIPT OF THE TRANSACTION
associateAliceRx, err := associateAliceTxSubmit.GetReceipt(client)

//LOG THE TRANSACTION STATUS
fmt.Println("Non-fungible token association with Alice's account:", associateAliceRx.Status)

3. Transfer the Token

Now, transfer 25 units of the token from the Treasury to Alice and check the account balances before and after the transfer.

//BALANCE CHECK
AccountBalance balanceCheckTreasury = new AccountBalanceQuery().setAccountId(treasuryId).execute(client);
System.out.println(" Treasury balance: " +balanceCheckTreasury.tokens + " units of token ID" +tokenId);
AccountBalance balanceCheckAlice = new AccountBalanceQuery().setAccountId(aliceAccountId).execute(client);
System.out.println("Alice's balance: " + balanceCheckAlice.tokens + " units of token ID " + tokenId);

//TRANSFER STABLECOIN FROM TREASURY TO ALICE
TransferTransaction tokenTransferTx = new TransferTransaction()
        .addTokenTransfer(tokenId, treasuryId, -2500)
        .addTokenTransfer(tokenId, aliceAccountId, 2500)
        .freezeWith(client)
        .sign(treasuryKey);
        
//SUBMIT THE TRANSACTION
TransactionResponse tokenTransferSubmit = tokenTransferTx.execute(client);
        
//GET THE RECEIPT OF THE TRANSACTION
TransactionReceipt tokenTransferRx = tokenTransferSubmit.getReceipt(client);
        
//LOG THE TRANSACTION STATUS
System.out.println("Stablecoin transfer from Treasury to Alice: " + tokenTransferRx.status );

//BALANCE CHECK
AccountBalance balanceCheckTreasury2 = new AccountBalanceQuery().setAccountId(treasuryId).execute(client);
System.out.println("Treasury balance " + balanceCheckTreasury2.tokens +  " units of token ID " + tokenId);
AccountBalance balanceCheckAlice2 = new AccountBalanceQuery().setAccountId(aliceAccountId).execute(client);
System.out.println("Alice's balance: " +balanceCheckAlice2.tokens + " units of token ID " + tokenId);
        
//BALANCE CHECK
var balanceCheckTx = await new AccountBalanceQuery().setAccountId(treasuryId).execute(client);
console.log(`- Treasury balance: ${balanceCheckTx.tokens._map.get(tokenId.toString())} units of token ID ${tokenId}`);
var balanceCheckTx = await new AccountBalanceQuery().setAccountId(aliceId).execute(client);
console.log(`- Alice's balance: ${balanceCheckTx.tokens._map.get(tokenId.toString())} units of token ID ${tokenId}`);

// TRANSFER STABLECOIN FROM TREASURY TO ALICE
let tokenTransferTx = await new TransferTransaction()
	.addTokenTransfer(tokenId, treasuryId, -2500)
	.addTokenTransfer(tokenId, aliceId, 2500)
	.freezeWith(client)
	.sign(treasuryKey);

//SUBMIT THE TRANSACTION
let tokenTransferSubmit = await tokenTransferTx.execute(client);

//GET THE RECEIPT OF THE TRANSACTION
let tokenTransferRx = await tokenTransferSubmit.getReceipt(client);

//LOG THE TRANSACTION STATUS
console.log(`\n- Stablecoin transfer from Treasury to Alice: ${tokenTransferRx.status} \n`);

// BALANCE CHECK
var balanceCheckTx = await new AccountBalanceQuery().setAccountId(treasuryId).execute(client);
console.log(`- Treasury balance: ${balanceCheckTx.tokens._map.get(tokenId.toString())} units of token ID ${tokenId}`);
var balanceCheckTx = await new AccountBalanceQuery().setAccountId(aliceId).execute(client);
console.log(`- Alice's balance: ${balanceCheckTx.tokens._map.get(tokenId.toString())} units of token ID ${tokenId}`);
//CHECK THE BALANCE BEFORE THE TRANSFER FROM THE TREASURY ACCOUNT
balanceCheckTreasury, err := hedera.NewAccountBalanceQuery().SetAccountID(treasuryAccountId).Execute(client)
fmt.Println("Treasury balance:", balanceCheckTreasury.Tokens, "units of token ID", tokenId)

//CHECK THE BALANCE BEFORE THE TRANSFER FOR ALICE'S ACCOUNT
balanceCheckAlice, err := hedera.NewAccountBalanceQuery().SetAccountID(aliceAccountId).Execute(client)
fmt.Println("Alice's balance:", balanceCheckAlice.Tokens, "units of token ID", tokenId)

//TRANSFER THE STABLECOIN TO ALICE
tokenTransferTx, err := hedera.NewTransferTransaction().
	AddTokenTransfer(tokenId, treasuryAccountId, -2500).
	AddTokenTransfer(tokenId, aliceAccountId, 2500).
	FreezeWith(client)

//SIGN WITH THE TREASURY KEY TO AUTHORIZE THE TRANSFER
signTransferTx := tokenTransferTx.Sign(treasuryKey)

//SUBMIT THE TRANSACTION
tokenTransferSubmit, err := signTransferTx.Execute(client)

//GET THE TRANSACTION RECEIPT
tokenTransferRx, err := tokenTransferSubmit.GetReceipt(client)

fmt.Println("Token transfer from Treasury to Alice:", tokenTransferRx.Status)

//CHECK THE BALANCE AFTER THE TRANSFER FOR THE TREASURY ACCOUNT
balanceCheckTreasury2, err := hedera.NewAccountBalanceQuery().SetAccountID(treasuryAccountId).Execute(client)
fmt.Println("Treasury balance:", balanceCheckTreasury2.Tokens, "units of token", tokenId)

//CHECK THE BALANCE AFTER THE TRANSFER FOR ALICE'S ACCOUNT
balanceCheckAlice2, err := hedera.NewAccountBalanceQuery().SetAccountID(aliceAccountId).Execute(client)
gofmt.Println("Alice's balance:", balanceCheckAlice2.Tokens, "units of token", tokenId)

Code Check ✅

Java
import com.hedera.hashgraph.sdk.*;
import io.github.cdimascio.dotenv.Dotenv;

import java.util.Collections;
import java.util.Objects;
import java.util.concurrent.TimeoutException;

public class CreateFungibleTutorial {
    public static void main(String[] args) throws TimeoutException, PrecheckStatusException, ReceiptStatusException {

        //Grab your Hedera testnet account ID and private key
        AccountId myAccountId = AccountId.fromString(Objects.requireNonNull(Dotenv.load().get("MY_ACCOUNT_ID")));
        PrivateKey myPrivateKey = PrivateKey.fromString(Objects.requireNonNull(Dotenv.load().get("MY_PRIVATE_KEY")));

        //Create your Hedera testnet client
        Client client = Client.forTestnet();
        client.setOperator(myAccountId, myPrivateKey);

        //Treasury Key
        PrivateKey treasuryKey = PrivateKey.generate();
        PublicKey treasuryPublicKey = treasuryKey.getPublicKey();

        //Create treasury account
        TransactionResponse treasuryAccount = new AccountCreateTransaction()
                .setKey(treasuryPublicKey)
                .setInitialBalance(new Hbar(10))
                .execute(client);

        AccountId treasuryId = treasuryAccount.getReceipt(client).accountId;

        //Alice Key
        PrivateKey aliceKey = PrivateKey.generate();
        PublicKey alicePublicKey = aliceKey.getPublicKey();

        //Create Alice's account
        TransactionResponse aliceAccount = new AccountCreateTransaction()
                .setKey(alicePublicKey)
                .setInitialBalance(new Hbar(10))
                .execute(client);

        AccountId aliceAccountId = aliceAccount.getReceipt(client).accountId;

        //Alice Key
        PrivateKey supplyKey = PrivateKey.generate();
        PublicKey supplyPublicKey = supplyKey.getPublicKey();

        // CREATE FUNGIBLE TOKEN (STABLECOIN)
        TokenCreateTransaction tokenCreateTx = new TokenCreateTransaction()
                .setTokenName("USD Bar")
                .setTokenSymbol("USDB")
                .setTokenType(TokenType.FUNGIBLE_COMMON)
                .setDecimals(2)
                .setInitialSupply(10000)
                .setTreasuryAccountId(treasuryId)
                .setSupplyType(TokenSupplyType.INFINITE)
                .setSupplyKey(supplyKey)
                .freezeWith(client);

        //Sign with the treasury key
        TokenCreateTransaction tokenCreateSign = tokenCreateTx.sign(treasuryKey);

        //Submit the transaction
        TransactionResponse tokenCreateSubmit = tokenCreateSign.execute(client);

        //Get the transaction receipt
        TransactionReceipt tokenCreateRx = tokenCreateSubmit.getReceipt(client);

        //Get the token ID
        TokenId tokenId = tokenCreateRx.tokenId;

        //Log the token ID to the console
        System.out.println("Created token with ID: " +tokenId);

        // TOKEN ASSOCIATION WITH ALICE's ACCOUNT
        TokenAssociateTransaction associateAliceTx = new TokenAssociateTransaction()
                .setAccountId(aliceAccountId)
                .setTokenIds(Collections.singletonList(tokenId))
	        .freezeWith(client)
                .sign(aliceKey);

        //Submit the transaction
        TransactionResponse associateAliceTxSubmit = associateAliceTx.execute(client);

        //Get the receipt of the transaction
        TransactionReceipt associateAliceRx = associateAliceTxSubmit.getReceipt(client);

        //Get the transaction status
        System.out.println("Token association with Alice's account: " +associateAliceRx.status);

        // BALANCE CHECK
        AccountBalance balanceCheckTreasury = new AccountBalanceQuery().setAccountId(treasuryId).execute(client);
        System.out.println(" Treasury balance: " +balanceCheckTreasury.tokens + " units of token ID" +tokenId);
        AccountBalance balanceCheckAlice = new AccountBalanceQuery().setAccountId(aliceAccountId).execute(client);
        System.out.println("Alice's balance: " + balanceCheckAlice.tokens + " units of token ID " + tokenId);

        // TRANSFER STABLECOIN FROM TREASURY TO ALICE
        TransferTransaction tokenTransferTx = new TransferTransaction()
                .addTokenTransfer(tokenId, treasuryId, -2500)
                .addTokenTransfer(tokenId, aliceAccountId, 2500)
                .freezeWith(client)
                .sign(treasuryKey);

        //SUBMIT THE TRANSACTION
        TransactionResponse tokenTransferSubmit = tokenTransferTx.execute(client);

        //GET THE RECEIPT OF THE TRANSACTION
        TransactionReceipt tokenTransferRx = tokenTransferSubmit.getReceipt(client);

        //LOG THE TRANSACTION STATUS
        System.out.println("Stablecoin transfer from Treasury to Alice: " + tokenTransferRx.status );

        // BALANCE CHECK
        AccountBalance balanceCheckTreasury2 = new AccountBalanceQuery().setAccountId(treasuryId).execute(client);
        System.out.println("Treasury balance " + balanceCheckTreasury2.tokens +  " units of token ID " + tokenId);
        AccountBalance balanceCheckAlice2 = new AccountBalanceQuery().setAccountId(aliceAccountId).execute(client);
        System.out.println("Alice's balance: " +balanceCheckAlice2.tokens + " units of token ID " + tokenId);

    }
}
JavaScript
console.clear();
require("dotenv").config();
const {
	AccountId,
	PrivateKey,
	Client,
	TokenCreateTransaction,
	TokenType,
	TokenSupplyType,
	TransferTransaction,
	AccountBalanceQuery,
	TokenAssociateTransaction,
} = require("@hashgraph/sdk");

// Configure accounts and client, and generate needed keys
const operatorId = AccountId.fromString(process.env.OPERATOR_ID);
const operatorKey = PrivateKey.fromString(process.env.OPERATOR_PVKEY);
const treasuryId = AccountId.fromString(process.env.TREASURY_ID);
const treasuryKey = PrivateKey.fromString(process.env.TREASURY_PVKEY);
const aliceId = AccountId.fromString(process.env.ALICE_ID);
const aliceKey = PrivateKey.fromString(process.env.ALICE_PVKEY);

const client = Client.forTestnet().setOperator(operatorId, operatorKey);

const supplyKey = PrivateKey.generate();

async function createFungibleToken() {
	//CREATE FUNGIBLE TOKEN (STABLECOIN)
	let tokenCreateTx = await new TokenCreateTransaction()
		.setTokenName("USD Bar")
		.setTokenSymbol("USDB")
		.setTokenType(TokenType.FungibleCommon)
		.setDecimals(2)
		.setInitialSupply(10000)
		.setTreasuryAccountId(treasuryId)
		.setSupplyType(TokenSupplyType.Infinite)
		.setSupplyKey(supplyKey)
		.freezeWith(client);

	let tokenCreateSign = await tokenCreateTx.sign(treasuryKey);
	let tokenCreateSubmit = await tokenCreateSign.execute(client);
	let tokenCreateRx = await tokenCreateSubmit.getReceipt(client);
	let tokenId = tokenCreateRx.tokenId;
	console.log(`- Created token with ID: ${tokenId} \n`);

	//TOKEN ASSOCIATION WITH ALICE's ACCOUNT
	let associateAliceTx = await new TokenAssociateTransaction()
		.setAccountId(aliceId)
		.setTokenIds([tokenId])
		.freezeWith(client)
		.sign(aliceKey);
	let associateAliceTxSubmit = await associateAliceTx.execute(client);
	let associateAliceRx = await associateAliceTxSubmit.getReceipt(client);
	console.log(`- Token association with Alice's account: ${associateAliceRx.status} \n`);

	//BALANCE CHECK
	var balanceCheckTx = await new AccountBalanceQuery().setAccountId(treasuryId).execute(client);
	console.log(`- Treasury balance: ${balanceCheckTx.tokens._map.get(tokenId.toString())} units of token ID ${tokenId}`);
	var balanceCheckTx = await new AccountBalanceQuery().setAccountId(aliceId).execute(client);
	console.log(`- Alice's balance: ${balanceCheckTx.tokens._map.get(tokenId.toString())} units of token ID ${tokenId}`);

	//TRANSFER STABLECOIN FROM TREASURY TO ALICE
	let tokenTransferTx = await new TransferTransaction()
		.addTokenTransfer(tokenId, treasuryId, -2500)
		.addTokenTransfer(tokenId, aliceId, 2500)
		.freezeWith(client)
		.sign(treasuryKey);
	let tokenTransferSubmit = await tokenTransferTx.execute(client);
	let tokenTransferRx = await tokenTransferSubmit.getReceipt(client);
	console.log(`\n- Stablecoin transfer from Treasury to Alice: ${tokenTransferRx.status} \n`);

	//BALANCE CHECK
	var balanceCheckTx = await new AccountBalanceQuery().setAccountId(treasuryId).execute(client);
	console.log(`- Treasury balance: ${balanceCheckTx.tokens._map.get(tokenId.toString())} units of token ID ${tokenId}`);
	var balanceCheckTx = await new AccountBalanceQuery().setAccountId(aliceId).execute(client);
	console.log(`- Alice's balance: ${balanceCheckTx.tokens._map.get(tokenId.toString())} units of token ID ${tokenId}`);
}
createFungibleToken();
Go
package main

import (
	"fmt"
	"os"

	"github.com/hashgraph/hedera-sdk-go/v2"
	"github.com/joho/godotenv"
)

func main() {

	//LOADS THE .ENV FILE AND THROWS AN EROOR IF IT CANNOT LOAD THE VARIABLES
	err := godotenv.Load(".env")
	if err != nil {
		panic(fmt.Errorf("Unable to load enviroment variables from .env file. Error:\n%v\n", err))
	}

	//GRAB YOUR TESTNET ACCOUNT ID AND KEY FROMZ THE .ENV FILE
	myAccountId, err := hedera.AccountIDFromString(os.Getenv("MY_ACCOUNT_ID"))
	if err != nil {
		panic(err)
	}

	myPrivateKey, err := hedera.PrivateKeyFromString(os.Getenv("MY_PRIVATE_KEY"))
	if err != nil {
		panic(err)
	}

	//PRINT ACCOUNT ID AND KEY TO MAKE SURE THERE WASN'T AN ERROR READING FROM THE .ENV FILE
	fmt.Printf("The account ID is = %v\n", myAccountId)
	fmt.Printf("The private key is = %v\n", myPrivateKey)

	//CREATE TESTNET CLIENT
	client := hedera.ClientForTestnet()
	client.SetOperator(myAccountId, myPrivateKey)

	//CREATE TREASURY KEY
	treasuryKey, err := hedera.GeneratePrivateKey()
	treasuryPublicKey := treasuryKey.PublicKey()

	//CREATE TREASURY ACCOUNT
	treasuryAccount, err := hedera.NewAccountCreateTransaction().
		SetKey(treasuryPublicKey).
		SetInitialBalance(hedera.NewHbar(10)).
		Execute(client)
	
	//GET THE RECEIPT OF THE TRANSACTION
	receipt, err := treasuryAccount.GetReceipt(client)

	//GET THE ACCOUNT ID
	treasuryAccountId := *receipt.AccountID

	//ALICE'S KEY
	aliceKey, err := hedera.GeneratePrivateKey()
	alicePublicKey := aliceKey.PublicKey()

	//CREATE AILICE'S ACCOUNT
	aliceAccount, err := hedera.NewAccountCreateTransaction().
		SetKey(alicePublicKey).
		SetInitialBalance(hedera.NewHbar(10)).
		Execute(client)

	//GET THE RECEIPT OF THE TRANSACTION
	receipt2, err := aliceAccount.GetReceipt(client)

	//GET ALICE'S ACCOUNT ID
	aliceAccountId := *receipt2.AccountID

	//CREATE SUPPLY KEY
	supplyKey, err := hedera.GeneratePrivateKey()

	//CREATE FUNGIBLE TOKEN (STABLECOIN)
	tokenCreateTx, err := hedera.NewTokenCreateTransaction().
		SetTokenName("USD Bar").
		SetTokenSymbol("USDB").
		SetTokenType(hedera.TokenTypeFungibleCommon).
		SetDecimals(2).
		SetInitialSupply(10000).
		SetTreasuryAccountID(treasuryAccountId).
		SetSupplyType(hedera.TokenSupplyTypeInfinite).
		SetSupplyKey(supplyKey).
		FreezeWith(client)

	//SIGN WITH TREASURY KEY
	tokenCreateSign := tokenCreateTx.Sign(treasuryKey)

	//SUBMIT THE TRANSACTION
	tokenCreateSubmit, err := tokenCreateSign.Execute(client)

	//GET THE TRANSACTION RECEIPT
	tokenCreateRx, err := tokenCreateSubmit.GetReceipt(client)

	//GET THE TOKEN ID
	tokenId := *tokenCreateRx.TokenID

	//LOG THE TOKEN ID TO THE CONSOLE
	fmt.Println("Created fungible token with token ID", tokenId)

	//TOKEN ASSOCIATION WITH ALICE's ACCOUNT
	associateAliceTx, err := hedera.NewTokenAssociateTransaction().
		SetAccountID(aliceAccountId).
		SetTokenIDs(tokenId).
		FreezeWith(client)

	//SIGN WITH ALICE'S KEY TO AUTHORIZE THE ASSOCIATION
	signTx := associateAliceTx.Sign(aliceKey)

	//SUBMIT THE TRANSACTION
	associateAliceTxSubmit, err := signTx.Execute(client)

	//GET THE RECEIPT OF THE TRANSACTION
	associateAliceRx, err := associateAliceTxSubmit.GetReceipt(client)

	//LOG THE TRANSACTION STATUS
	fmt.Println("STABLECOIN token association with Alice's account:", associateAliceRx.Status)

	//Check the balance before the transfer for the treasury account
	balanceCheckTreasury, err := hedera.NewAccountBalanceQuery().SetAccountID(treasuryAccountId).Execute(client)
	fmt.Println("Treasury balance:", balanceCheckTreasury.Tokens, "units of token ID", tokenId)

	//Check the balance before the transfer for Alice's account
	balanceCheckAlice, err := hedera.NewAccountBalanceQuery().SetAccountID(aliceAccountId).Execute(client)
	fmt.Println("Alice's balance:", balanceCheckAlice.Tokens, "units of token ID", tokenId)

	//Transfer the STABLECOIN from treasury to Alice
	tokenTransferTx, err := hedera.NewTransferTransaction().
		AddTokenTransfer(tokenId, treasuryAccountId, -2500).
		AddTokenTransfer(tokenId, aliceAccountId, 2500).
		FreezeWith(client)

	//SIGN WITH THE TREASURY KEY TO AUTHORIZE THE TRANSFER
	signTransferTx := tokenTransferTx.Sign(treasuryKey)

	//SUBMIT THE TRANSACTION
	tokenTransferSubmit, err := signTransferTx.Execute(client)

	//GET THE TRANSACTION RECEIPT
	tokenTransferRx, err := tokenTransferSubmit.GetReceipt(client)

	fmt.Println("Token transfer from Treasury to Alice:", tokenTransferRx.Status)

	//CHECK THE BALANCE AFTER THE TRANSFER FOR THE TREASURY ACCOUNT
	balanceCheckTreasury2, err := hedera.NewAccountBalanceQuery().SetAccountID(treasuryAccountId).Execute(client)
	fmt.Println("Treasury balance:", balanceCheckTreasury2.Tokens, "units of token", tokenId)

	//CHECK THE BALANCE AFTER THE TRANSFER FOR ALICE'S ACCOUNT
	balanceCheckAlice2, err := hedera.NewAccountBalanceQuery().SetAccountID(aliceAccountId).Execute(client)
	fmt.Println("Alice's balance:", balanceCheckAlice2.Tokens, "units of token", tokenId)

}

Have a question?

Ask it on StackOverflow

INTRODUCTION
ENVIRONMENT SETUP