How to get the ERC-20 token balance of an address using Ethers JS

In this tutorial, we are going to learn how to interact with ERC-20 tokens smart contracts to get the token balance of an address using Ethers JS.

In this tutorial, we are going to learn how to interact with ERC-20 tokens smart contracts to get the token balance of an address using Ethers JS.

In the smart contract of ERC-20 tokens, there is a function called balanceOf that takes in parameter the address that you want to check the balance of and returns the amount of tokens that address has in wei.

Here is how to use it:

const ethers = require("ethers")

const providers = new ethers.providers.Web3Provider(YOUR_PROVIDER_HERE)

// Getting the balance of Uniswap tokens (UNI)

const contractAddress = "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"

// ABI in the human-readable format of Ethers
const ABI = [
    "function balanceOf(address account) view returns (uint256)"
]

const contract = new ethers.Contract(contractAddress, ABI, provider)

// Call the balanceOf function
const addressToCheck = "0x5b8f1310A956ee1521A7bB56160451C786289aa9"
const balanceInWei = await contract.balanceOf(addressToCheck)

// Convert the balance from wei to ether
const balance = ethers.utils.formatEther(balanceInWei)

Unfortunately, you have to repeat that same code for every token balance that you want to check, you can't get all token balances at once.

Let's break down how this code works.

First, we need to get the address and the ABI of the smart contract because we need to create a Contract instance to call the functions of the smart contract.

To find both the address of the smart contract of a token and the ABI, search for it on Etherscan.

Then, on the page of the token on Etherscan, the address is at the top and there is a button for us to copy it.

Next, if you go to the "Contract" tab in the "Code" section, you can find the full ABI after the contract source code.

We don't really need the full ABI, we just need an ABI with the balanceOf function because that's the only one we use. So if you want to use more functions, you can find the ABI there for these functions there but for the balanceOf function, it looks like this:

// The ABI in the normal format that's in smart contract
const ABI = [
    {
        "constant":true,
        "inputs":[{
            "internalType":"address",
            "name":"account",
            "type":"address"
        }],
        "name":"balanceOf",
        "outputs":[{
            "internalType":"uint256",
            "name":"",
            "type":"uint256"
        }],
        "payable":false,
        "stateMutability":"view",
        "type":"function"
    }
]

// A new format that you can use in Ethers to make the ABI more readable
const ABI = [
    "function balanceOf(address account) view returns (uint256)"
]

The ABI can have 2 formats, either the "normal" format that you can find in smart contracts or the human-readable format introduced by Ether.

More information about the human-readable format here:

ABI Formats
Documentation for ethers, a complete, tiny and simple Ethereum library.

Next, we can create a Contract instance for our token contract and call the balanceOf function:

const contract = new ethers.Contract(contractAddress, ABI, provider)

const unformattedBalance = await contract.balanceOf(addressToCheck)

The balanceOf function returns the balance in wei (the smallest sub-unit of ether with 18 decimals) and you can format that number using Ethers' utils:

const balance = ethers.utils.formatEther(unformattedBalance)

Be careful with stablecoins like USDT and USDC because they only have 6 decimals of precision so to convert these balances into Ether, we need to do it like this:

const unformattedBalance = await contract.balanceOf(addressToCheck)
const balance = ethers.utils.formatUnits(unformattedBalance, 6)

And that's it 🎉

Thank you for reading this article