The Hedera Token Service enables you to create, mint, and transfer a custom fungible/non-fungible token. There are two ways of creating a token on Hedera, one is using the Hedera SDKs, and the other one is using a Solidity Smart Contract.
In this article, you will learn how to create a fungible token using the Hedera SDK and a Solidity Smart Contract. Let's start with the SDK!
First off, in this example, you will need to create a Treasury account. To create an account, you need to use the AccountCreateTransaction() function. It’s useful to create an accountCreator method to simplify the account creation process like this one below.
Note that you can use the accountCreator function to create other accounts if you need to.
2. Create your Fungible Token on Hedera
Use the TokenCreateTransaction() function to create your token using Hedera SDK. In this example, you will specify these parameters:
Name
Symbol
Treasury Account
Initial Supply
Decimals
Auto-renew Account Id
Auto-renew Period
Max Transaction Fee
You have to specify Auto-renew Account ID because you'll need to pay an auto-renewal fee for entities to persist on the Hedera Network. To better understand how auto-renew works you can check out HIP-16 and HIP-372.
//Create the transaction and freeze for manual signing
const transaction = await new TokenCreateTransaction()
.setTokenName("USD Bar")
.setTokenSymbol("USDB")
.setTreasuryAccountId(treasuryId)
.setInitialSupply(10000)
.setDecimals(2)
.setAutoRenewAccountId(treasuryId)
.setAutoRenewPeriod(7000000)
.setMaxTransactionFee(new Hbar(30)) //Change the default max transaction fee
.freezeWith(client);
//Sign the transaction with the token treasury account private key
const signTx = await transaction.sign(treasuryKey);
//Sign the transaction with the client operator private key and submit it to a Hedera network
const txResponse = await signTx.execute(client);
Awesome! You just created a fungible token with an initial supply of 100. Before executing the transaction, make sure you sign it using treasuryKey.
Now you can get your token ID from the transaction receipt.
//Get the receipt of the transaction
const receipt = await txResponse.getReceipt(client);
//Get the token ID from the receipt
const tokenId = receipt.tokenId;
console.log("The new token ID is " + tokenId);
Console Output:
Done! You are now a proud owner of your custom fungible token created using Hedera SDK.
Create a Fungible Token using Solidity
1. Write and Compile your Contract
Using the SDK is usually easier than using a smart contract to create a token. However, contracts can give you additional flexibility and help you automate certain flows.
So to start, you have to create a new Solidity contract, in this case, it’s called TokenCreator.sol but you can give it the name you prefer. In the contract, a createFungible function deals with creating your token by calling the HederaTokenService.createFungibleToken() method. As you can see other than that it's all about specifying a bunch of parameters.
Notice that in this smart contract example, the contract itself will act as a treasury and auto-renew account. This ensures a trustless workflow where the contract is the only entity managing various aspects of the token.
Since you will use the Hedera Token Service precompile functions, you need to import these files into your working directory by downloading them from the contracts folder here.
IHederaTokenService.sol
HederaTokenService.sol
HederaResponseCodes.sol
ExpiryHelper.sol
FeeHelper.sol
KeyHelper.sol
Solidity Contract:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;
import './HederaResponseCodes.sol';
import './IHederaTokenService.sol';
import './HederaTokenService.sol';
import './ExpiryHelper.sol';
contract TokenCreator is ExpiryHelper{
// create a fungible Token with no custom fees
function createFungible(
string memory name,
string memory symbol,
uint initialSupply,
uint decimals,
uint32 autoRenewPeriod
) external payable returns (address createdTokenAddress) {
IHederaTokenService.HederaToken memory token;
token.name = name;
token.symbol = symbol;
token.treasury = address(this);
// create the expiry schedule for the token using ExpiryHelper
token.expiry = getAutoRenewExpiry(address(this), autoRenewPeriod);
// call HTS precompiled contract, passing initial supply and decimals
(int responseCode, address tokenAddress) =
HederaTokenService.createFungibleToken(token, initialSupply, decimals);
if (responseCode != HederaResponseCodes.SUCCESS) {
revert ();
}
createdTokenAddress = tokenAddress;
}
}
As your contract is going to run on the EVM you first need to compile it and get low-level machine code. To do that, you need to install solc using this command:
npm install -g solc
And then to compile your contract you just run:
solcjs --bin TokenCreator.sol -o binaries
This command will create a new directory called /binaries that contains multiple .bin files. The one you are going to use it’s called TokenCreator_sol_TokenCreator.bin.
You can check out the bytecode that will run on the EVM in this Codesandbox
Always make sure that the Gas fee you are specifying as a parameter is enough to execute the transaction or you'll get an error.
const createContract = new ContractCreateFlow()
.setGas(150000) // Increase if revert
.setBytecode(bytecode); // Contract bytecode
const createContractTx = await createContract.execute(client);
const createContractRx = await createContractTx.getReceipt(client);
const contractId = createContractRx.contractId;
console.log(`Contract created with ID: ${contractId}`);
Console Output:
3. Execute a Contract function to create a Fungible Token
Now it’s time to execute your contract function by using ContractExecuteTransaction() to create your fungible token. Make sure every parameter is correct and the number of parameters you are passing is the same as the ones in your contract or you will get a CONTRACT_REVERT_EXECUTED error.
// Create FT using precompile function
const createToken = new ContractExecuteTransaction()
.setContractId(contractId)
.setGas(300000) // Increase if revert
.setPayableAmount(20) // Increase if revert
.setFunction("createFungible",
new ContractFunctionParameters()
.addString("USD Bar") // FT name
.addString("USDB") // FT symbol
.addUint256(1000000000) // FT initial supply
.addUint256(2) // FT decimals
.addUint32(7000000)); // auto renew period
const createTokenTx = await createToken.execute(client);
const createTokenRx = await createTokenTx.getRecord(client);
const tokenIdSolidityAddr = createTokenRx.contractFunctionResult.getAddress(0);
const tokenId = AccountId.fromSolidityAddress(tokenIdSolidityAddr);
console.log(`Token created with ID: ${tokenId} \n`);
Console Output:
Perfect! So this wraps up Part 1 of How to Create Hedera Tokens. Check out Part 2 to learn how to create an NFT using Hedera SDK and a Solidity Contract.
Check out the Code
Check out the Hedera SDK example code on GitHub Check out the Smart Contract example code on GitHub