23

I have written an ERC20 token contract and deployed it in test network using truffle framework. When I check the token balance for an account using web3 it was giving the result in BigNumber when I try to convert it to a number using toNumber() getting an unexpected result.

Solidity code:

  function balanceOf(address _from) constant public returns (uint256 balance) {
    return balances[_from];
}

Javascript code:

instantiateBalance() {
const contract = require('truffle-contract')
const token = contract(Token)
token.setProvider(this.state.web3.currentProvider)
var tokenInstance;
token.deployed().then(function(instance) {
tokenInstance = instance;
return tokenInstance.balanceOf.call("0xb1Cf866ced575FD1A1997Daa5d6F099efb282E41", {from: "0xb1Cf866ced575FD1A1997Daa5d6F099efb282E41"});
}).then(function(balance) {
console.log(balance.toNumber());
})

Expected Result

Decimals = 18

Actual Token Balance = 100000000.000000000000000000

Actual Result

Token Balance = 1000000000000

Result:

Karthikeyan Thangavel
  • 1,206
  • 2
  • 12
  • 25

5 Answers5

27

If your token have 18 decimals

like an ether you can use

then(function(balance) {
    console.log(web3.fromWei(balance.toNumber(), "ether" ) );
})

Use fromWei to convert your bigNumber to ether and then convert it to Number. Be aware that unnecessary 0 after the floating point will not be displayed.

In web3 ^1.0 it may change to web3.utils.fromWei instead of web3.fromWei doc. Note that truffle ^5.0 uses web3 ^1.0.

If you have a different token decimal

Let's say 6. You'll have to do the conversion manually with something like:

var tokenBalance = balance.ToNumber() / Math.pow(10, tokenDecimals)
Paul Razvan Berg
  • 17,902
  • 6
  • 73
  • 143
0xCrema.eth
  • 1,182
  • 1
  • 12
  • 21
7

You can use exponential number syntax in javascript to shorten you code.

Example (18 decimals):

const balance = getBalance().toNumber() / 1E18

PS. Sorry, i can not make comment due to low reputation.

Nikita
  • 189
  • 1
  • 3
3

Personally, I like to work with big numbers and not parse them into "normal" numbers. I guess I'm afraid some overflow may happen if I don't.

Therefore, if a contract returns a uint, then I parse the return value to a BigNumber (from bignumber.js), like so:

const balanceBefore = new BigNumber(await contract.getBalance(...));

and I like to use the BigNumber API for my assertions, like so:

assert(balanceBefore.minus(amountSent).minus(gasCost).isEqualTo(balanceAfter));
Ytsen de Boer
  • 391
  • 1
  • 11
0

I believe you just want log the balance, you should use

    console.log(balance.toString());

instead.

It's throws genuine error that it can't fit the number in js number type.

0

A fast way could be

import web3 from 'web3';

const ethProvider = new web3(web3.givenProvider).eth; const accounts = await ethProvider.requestAccounts(); const ethBalance = web3.utils.fromWei(await ethProvider.getBalance(accounts[0]), 'ether'); console.log(ethBalance);

I.G. Pascual
  • 101
  • 2