EVM - Transferring Fungible Tokens
This article covers what steps you need to follow to transfer EVM-compatible Fungible Tokens (ERC-20, BEP-20, or compatible). The Fee Estimate is also included.
The following steps and examples are based on Ethereum Sepolia (testnet).
Steps
Step_1: Gather the transfer parameter details
- Confirm the EVM network where the transaction will be executed.
- Confirm the "Token contract address" and the "digits" (decimals). See Example Token Contract
- Confirm the Sender's blockchain address.
- Confirm the
PrivateKey
to sign the transaction is matching with the Sender's blockchain address. - Confirm the Recipient blockchain address.
Step_2: Check the Native asset balance of an address
Token transfer gas fees are paid with Native chain assets. You need to make sure the Sender's blockchain address has enough Native chain assets to cover the gas fees of the transfer. See the Fee Estimate step below.
Example request:
- Returns address balance in Native assets
curl --location 'https://api.tatum.io/v3/ethereum/account/balance/0xc1eb70a67e8fd5ff1863c22d4f2856cc7953a7d2' \
--header 'x-api-key: {YOUR_API_KEY}'
//Response:
{
"balance": "0.914730098011893734"
}
Token transfers are paid with Native chain assets. That's now blockchain transactions work. Tatum has no say over this.
Step_3: Check the Token asset balance of an address
You need to make sure the Sender's blockchain address has enough Token assets for the transfer.
Example request:
- Returns the Token balances from an address by Token Contract Address
curl --location 'https://api.tatum.io/v4/data/balances?chain=ethereum-sepolia&addresses=0xc1eb70a67e8fd5ff1863c22d4f2856cc7953a7d2&tokenTypes=fungible&pageSize=50&offset=0' \
--header 'x-api-key: {YOUR_API_KEY}'
//Response:
{
"result": [
{
"chain": "ethereum-sepolia",
"address": "0xc1eb70a67e8fd5ff1863c22d4f2856cc7953a7d2",
"balance": "50",
"tokenAddress": "0x03cee0939f57855eb95437f4a0efa7b1afbfa4c6",
"lastUpdatedBlockNumber": 6111418,
"type": "fungible"
}
],
"prevPage": "",
"nextPage": ""
}
Step_4: Estimate the transfer fees
Transferring tokens has a cost associated with gas fees to be paid with Native assets. Additional information on Fee Estimate is available at the following link.
Request Example:
- Request Body Schema:
EstimateFee
with type:TRANSFER_ERC20
- Returns the estimated
GasPrice
andGasLimit
curl --location 'https://api.tatum.io/v3/blockchain/estimate' \
--header 'Content-Type: application/json' \
--header 'x-api-key: {YOUR_API_KEY}' \
--data '{
"chain": "ETH",
"type": "TRANSFER_ERC20",
"sender": "0xc1eb70a67e8fd5ff1863c22d4f2856cc7953a7d2",
"recipient": "0x5593549ead3b3bd6e4b049ed607ec0f422208298",
"contractAddress": "0x03cee0939F57855EB95437f4a0EFA7B1AfBFA4c6",
"amount": "1.123456789123456789" // The token supports 18 decimals (see Token Contract)
}'
//Response:
{
"gasLimit": 52036,
"gasPrice": 23.084985187
}
Mind the Token decimals.
Step_5: Check the current "nonce" value from the sender's address
The "nonce
" is a unique and incremental counter used to ensure that each transaction is processed only once, preventing replay attacks. EVM transactions require this. Find more about the "nonce" in the following article.
Request example:
curl --location 'https://api.tatum.io/v3/ethereum/transaction/count/0xc1eb70a67e8fd5ff1863c22d4f2856cc7953a7d2' \
--header 'x-api-key: {YOUR_API_KEY}'
//response:
13 // Current nonce value in decimals, at the time of the request
Step_6: Transfer fungible tokens with manual fees
Request Example:
- Returns the hash (ID) of the transfer transaction
curl --location 'https://api.tatum.io/v3/blockchain/token/transaction' \
--header 'Content-Type: application/json' \
--header 'x-api-key: {YOUR_API_KEY}' \
--data '{
"chain": "ETH",
"contractAddress": "0x03cee0939F57855EB95437f4a0EFA7B1AfBFA4c6",
"digits": 18, // The token supports 18 decimals (see Token Contract)
"amount": "1.123456789123456789", //Decimals in amount must be lower or equal to "digits"
"to": "0x5593549ead3b3bd6e4b049ed607ec0f422208298",
"nonce": 13,
"fee": {
"gasLimit": "52036",
"gasPrice": "23"
},
"fromPrivateKey": "SENDER_ADDRESS_PRIVATE_KEY"
}'
//Response:
{
"txId": "0xa806b84380b998bbad47aa3826cc3805890b29dd5c7ba59349b219ca0e529926"
}
Mind the Token decimals. Make sure the PrivateKey matches the sender address.
Step_7: Get the details of a transaction
Request example:
curl --location 'https://api.tatum.io/v4/data/transactions/hash?chain=ethereum-sepolia&hash=0xa806b84380b998bbad47aa3826cc3805890b29dd5c7ba59349b219ca0e529926' \
--header 'x-api-key: {YOUR_API_KEY}'
//Response:
[
{
"chain": "ethereum-sepolia",
"hash": "0xa806b84380b998bbad47aa3826cc3805890b29dd5c7ba59349b219ca0e529926",
"address": "0xc1eb70a67e8fd5ff1863c22d4f2856cc7953a7d2",
"blockNumber": 6238790,
"transactionIndex": 77,
"transactionType": "fungible",
"transactionSubtype": "outgoing",
"amount": "-1.123456789123456789",
"timestamp": 1720020792000,
"tokenAddress": "0x03cee0939f57855eb95437f4a0efa7b1afbfa4c6",
"counterAddress": "0x5593549ead3b3bd6e4b049ed607ec0f422208298"
},
{
"chain": "ethereum-sepolia",
"hash": "0xa806b84380b998bbad47aa3826cc3805890b29dd5c7ba59349b219ca0e529926",
"address": "0xc1eb70a67e8fd5ff1863c22d4f2856cc7953a7d2",
"blockNumber": 6238790,
"transactionIndex": 77,
"transactionType": "native",
"transactionSubtype": "zero-transfer",
"amount": "0",
"timestamp": 1720020792000,
"counterAddress": "0x03cee0939f57855eb95437f4a0efa7b1afbfa4c6"
}
]
Good to Know
- Fee Estimates may fluctuate one way or the other, within seconds.
- Tatum Mainnet Fee Estimates are generally in line with other providers.
- The Testnet Fee Estimate is generally unreliable. Since testnet coins have "no value", users tend to set random amounts greatly skewing the estimates.
- Be mindful of Tatum's derivation path. Find additional information in the following article.
- Familiarize yourself with the Safety & Security Basics in the following article.
Error Troubleshooting
Updated 2 months ago