First Fungible Token
In Alephium, when deploying a new contract, you can issue a specified amount of tokens and optionally send them to a recipient. The id of the newly issued token is the same as the id of the contract that issues it.
In this guide, you will learn how to issue a token that complies with the Fungible Token Standard using the Typescript SDK.
Prerequisites:
- Write code in Typescript
- Understand how to compile and deploy contracts in a project using Typescript SDK
You can clone the example in this guide and run it like this:
git clone [email protected]:alephium/ralph-example.git
cd ralph-example/your-firsts
npm install
npm compile
npx ts-node src/fungible-token.ts
Create token contract
A contract that complies with the Fungible Token
Standard
needs to implement the IFungibleToken
interface, which
defines methods to get the name
, symbol
, decimals
as well as the
totalSupply
of the token. The IFungibleToken
interface is available
automatically from the SDK:
import "std/fungible_token_interface"
Contract ShinyToken() implements IFungibleToken {
pub fn getTotalSupply() -> U256 {
return 10000
}
pub fn getSymbol() -> ByteVec {
return b`Stk`
}
pub fn getName() -> ByteVec {
return b`ShinyToken`
}
pub fn getDecimals() -> U256 {
return 18
}
}
Issue token
Once the token contract is created and compiled, it can be deployed using Typescript SDK:
import { web3 } from '@alephium/web3'
import { testNodeWallet } from '@alephium/web3-test'
import { ShinyToken } from '../artifacts/ts'
async function fungibleToken() {
web3.setCurrentNodeProvider('http://127.0.0.1:22973', undefined, fetch)
const signer = await testNodeWallet()
const issueTokenAmount = 10000n
// Deploy `ShinyToken` contract and issue `10000` shiny tokens to `issueTokenTo` address.
const shinyToken = await ShinyToken.deploy(signer, {
initialFields: {},
issueTokenAmount,
issueTokenTo: signer.address
})
const tokenId = shinyToken.contractInstance.contractId
const signerBalance = await web3.getCurrentNodeProvider().addresses.getAddressesAddressBalance(signer.address)
const signerShinyTokenBalance = signerBalance.tokenBalances!.find((token) => token.id === tokenId)
console.log(`token issued to ${signer.address}`, signerShinyTokenBalance)
}
fungibleToken()
In this example, the ShinyToken
token contract will be deployed along
with 10000
tokens, all of which are immediately sent to
signer.address
. Note that if signer.address
is not specified, the
newly issued tokens will be owned by the ShinyToken
contract.
Interact with the token
Congratulations! You have issued your first fungible token. Since the newly issued token adheres to the Fungible Token Standard, it is compatible with wallets, explorer and other services. It also enables SDK to get its information in a standard way:
// Use SDK to call methods individually
const getDecimalResult = await shinyToken.view.getDecimals()
const getTotalSupplyResult = await shinyToken.view.getTotalSupply()
const getNameResult = await shinyToken.view.getName()
console.log("TokenFaucet name, decimals, totalSupply", getNameResult.returns, getDecimalResult.returns, getTotalSupplyResult.returns)
// Use SDK to call all multiple methods at the same time
const multicallResult = await shinyToken.multicall({
getDecimals: {},
getTotalSupply: {},
getName: {},
})
console.log("TokenFaucet name, decimals, totalSupply", multicallResult.getName.returns, multicallResult.getDecimal.returns, multicallResult.getTotalSupply.returns)
In fact, SDK provides a canonical way to fetch all metadata for a fungible token.
const metadata = await web3.getCurrentNodeProvider().fetchFungibleTokenMetaData(shinyToken.contractId)
console.log("TokenFaucet name, decimals, totalSupply", metadata.name, metadata.decimals, metadata.totalSupply)
IFungibleToken also enables SDK to guess the type of a token, so that dApps and wallets can handle them respectively:
// Guess token type
const tokenType = await web3.getCurrentNodeProvider().guessStdTokenType(shinyToken.contractId)
expect(tokenType).toEqual('fungible')
// Guess token interface id
const tokenInterfaceId = await web3.getCurrentNodeProvider().guessStdInterfaceId(shinyToken.contractId)
expect(tokenInterfaceId).toEqual('0001')
What's Next
To make the token display properly in wallets and explorer, you can also make a PR to add it to the token list.