[Ethereum] How to get the balance of an ERC 20 token for an Ethereum address using Web3js

web3jsweb3js-v1.x

I'm trying to implement the question in a web3js app I have.

The code I have so far is:

// Get ERC20 Token contract instance
let contract = new Web3Client.eth.Contract(minABI, tokenAddress);

// Call balanceOf function
contract.methods.balanceOf(walletAddress).call((error, balance) => {
  contract.methods.decimals().call((error, decimals) => {
    balance = Web3Client.utils.toBN(balance);
    balance = balance.divn(10 ** decimals).toString();

  });
});

This gives me an error:

if (!val) throw new Error(msg || 'Assertion failed');
              ^

Error: Assertion failed
    at assert (/home/noah/Dev/ERC20Tutorial/node_modules/number-to-bn/node_modules/bn.js/lib/bn.js:6:21)
    at BN.idivn (/home/noah/Dev/ERC20Tutorial/node_modules/number-to-bn/node_modules/bn.js/lib/bn.js:2471:5)
    at BN.divn (/home/noah/Dev/ERC20Tutorial/node_modules/number-to-bn/node_modules/bn.js/lib/bn.js:2484:25)
    at Object.callback (/home/noah/Dev/ERC20Tutorial/index.js:43:23)
    at sendTxCallback (/home/noah/Dev/ERC20Tutorial/node_modules/web3-core-method/lib/index.js:533:29)
    at /home/noah/Dev/ERC20Tutorial/node_modules/web3-core-requestmanager/lib/index.js:308:9
    at XMLHttpRequest.request.onreadystatechange (/home/noah/Dev/ERC20Tutorial/node_modules/web3-providers-http/lib/index.js:98:13)
    at XMLHttpRequestEventTarget.dispatchEvent (/home/noah/Dev/ERC20Tutorial/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:22)
    at XMLHttpRequest._setReadyState (/home/noah/Dev/ERC20Tutorial/node_modules/xhr2-cookies/dist/xml-http-request.js:208:14)
    at XMLHttpRequest._onHttpResponseEnd (/home/noah/Dev/ERC20Tutorial/node_modules/xhr2-cookies/dist/xml-http-request.js:318:14)
    at IncomingMessage.<anonymous> (/home/noah/Dev/ERC20Tutorial/node_modules/xhr2-cookies/dist/xml-http-request.js:289:61)
    at IncomingMessage.emit (node:events:377:35)
    at endReadableNT (node:internal/streams/readable:1312:12)
    at processTicksAndRejections (node:internal/process/task_queues:83:21)

Curious as I don't know what would be causing the issue. There are a few different tutorials that walk through this, but none of them are using current web3 versions.

Best Answer

If you just want to just get the balance, then all you have to do is:

contract.methods.balanceOf(walletAddress)
  .call((error, balance) => {
    console.log(web3.utils.fromWei(balance));
    // Do whatever else you want with the code.
  }

Since .balanceOf() returns the account balance in Wei, you have to use web3.utils.fromWei() to convert it to your desired unit amount.

In the example above, I passed in only the balance as an argument without specifying what unit to convert to. This is because the default conversion value for the 2nd parameter is "ether", so if you wanted to convert to Ether, you can just pass in the first argument, the balance.

Or you can do it a cleaner way like this:

contract.methods.balanceOf(walletAddress)
  .call()
  .then(balance => console.log(web3.utils.fromWei(balance));

Or (the cleanest way):

async function getBalance() {
  const balance = await contract.methods.balanceOf(walletAddress).call();
  const balanceInWei = web3.utils.fromWei(balance);
  console.log(balanceInWei);
}

getBalance();

As far as the error, it seems to be an issue with the part of the code where you used

.divn(10 ** decimals)

Hope this helped! :)

Related Topic