¿Cómo convertir BigNumber a Number en Truffle framework?

Escribí un contrato de token ERC20 y lo implementé en la red de prueba utilizando el marco de trufa. Cuando verifico el saldo del token de una cuenta usando web3, estaba dando el resultado en BigNumber cuando intento convertirlo en un número usando toNumber() obteniendo un resultado inesperado.

Código de solidez:

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

Código JavaScript:

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());
})

Resultado Esperado

decimales = 18

Saldo real del token = 100000000.000000000000000000

Resultado actual

Saldo de fichas = 1000000000000

Resultado:

¿Probó balance.div(1e18) o balance.toNumber().div(1e18) ?
balance.div(1e18) me dará los dígitos antes del punto decimal. Necesito dígitos después del punto decimal también para mostrar el saldo exacto.

Respuestas (5)

Si tu token tiene 18 decimales

como un éter que puedes usar

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

Use fromWei para convertir su bigNumber a ether y luego conviértalo a Number. Tenga en cuenta que no se mostrará el 0 innecesario después del punto flotante.

En web3 ^1.0 puede cambiar a web3.utils.fromWeien lugar de web3.fromWei doc . Tenga en cuenta que la trufa ^5.0 usa web3 ^1.0.

Si tienes un token decimal diferente

Digamos 6. Tendrás que hacer la conversión manualmente con algo como:

var tokenBalance = balance.ToNumber() / Math.pow(10, tokenDecimals)
Experimenté un problema con este ejemplo, si el saldo tenía 18 decimales, lo reduciría a 16. Para solucionar esto, usé web3.fromWei(balance.toString(), "ether"), aviso .toString(). No estoy seguro si esta es la mejor práctica.
sí, usar toString() también funcionó para mí, cuando usé toNumber(), me dio un error porque creo que no podemos almacenar ese gran número en ese tipo de datos.
ToNumber no es una función en trufa
@PhilipRego esto fue respondido hace 3 años. Es obvio que cambió ahora.
Desde Etherjs BigNumber.from(bn).div(BigNumber.from(10).pow(decimal)).toNumber()

Puede usar la sintaxis de números exponenciales en javascript para acortar su código.

Ejemplo (18 decimales):

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

PD. Lo siento, no puedo hacer comentarios debido a la baja reputación.

Personalmente, me gusta trabajar con números grandes y no convertirlos en números "normales". Supongo que tengo miedo de que se produzca un desbordamiento si no lo hago.

Por lo tanto, si un contrato devuelve a uint, analizo el valor devuelto a a BigNumber(de bignumber.js ), así:

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

y me gusta usar la BigNumberAPI para mis afirmaciones, así:

assert(balanceBefore.minus(amountSent).minus(gasCost).isEqualTo(balanceAfter));
Si usted -1 por favor agregue también un comentario con el motivo... gracias.

Una forma rápida podría ser

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);

Creo que solo quieres registrar el saldo, debes usar

    console.log(balance.toString());

en cambio.

Lanza un error genuino de que no puede caber el número en el numbertipo js.