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

  1. Confirm the EVM network where the transaction will be executed.
  2. Confirm the "Token contract address" and the "digits" (decimals). See Example Token Contract
  3. Confirm the Sender's blockchain address.
  4. Confirm the PrivateKey to sign the transaction is matching with the Sender's blockchain address.
  5. 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 estimatedGasPrice and GasLimit
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.

🚧

For Complex Smart Contracts, a Transaction Simulation could be required.

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.
    • Complex Smart Contracts may require you to perform a Transaction Simulation to estimate the gas fees properly.
  • 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