如何将RSK代币余额转换为Javascript数字



我想从代币智能合约中获取余额(代币数量(。

我正在使用web3.js与合同进行交互,并能够获得返回值。但是,使用这个值,如果我执行.toString(),我会看到它具有正确的值。但是,如果我执行.toNumber(),它会给我一个错误:Error: Number can only safely store up to 53 bits

为什么会发生这种情况?我如何从智能合约中获得特定帐户的余额,作为数字(而不是字符串(?

智能合约可以支持非常大的数量(Solidity中最高可达uint256(。然而,内置的Number类型的Javascript不能表示那么大的数字,因此在web3.js中,任何数值都封装在BN(Big Number(中。你可以在web3.utils.BN中找到这个类。

这就是为什么当你在余额查询中得到错误时,因为余额是uint256并且通常用于表示18的小数位数。我们可以只使用web3.js复制,而不使用

const web3 = require('web3');
// the balance is a `1` with 21 `0`-s after it
// typical token would return this value for an account with 1000 tokens
const balanceBN = new web3.utils.BN('1000000000000000000000');
const balance = balanceBN.toNumber();

这会引发以下错误:

Uncaught Error: Number can only safely store up to 53 bits
at assert (/some/path/node_modules/bn.js/lib/bn.js:6:21)
at BN.toNumber (/some/path/node_modules/bn.js/lib/bn.js:519:7)

因此,您的选择是:

  • 如果BN足够小,则可以使用.toNumber()
  • 如果BN太大,请在调用.toNumber()之前使用.div()缩小其大小

将以上内容应用于您关于获取代币余额的特定问题,我们可以做以下操作:

const balanceBN = contract.methods.balanceOf(myAddress).call();
const decimalsBN = contract.methods.decimals().call();
// when we know that the BN is small engouh to be represented in JS number
const decimals = decimalsBN.toNumber();
// when we know that the BN is too alrge to be represented in JS number
const balance = balanceBN.div(new  web3.utils.BN(10).pow(decimalsBN)).toNumber();
  • 查询代币合约以获得余额和小数值,均为BN
  • 使用.toNumber()将小数直接转换为数字,因为我们希望它足够小
  • 将余额BN除以小数BN的10次方,然后调用其上的.toNumber

注意:balance的结果值将与用户界面中通常显示的令牌数量相匹配。。。而不是存储在智能合约本身中的价值。

或使用BN from-它扩展了字节长度,实际上更好(xmr/vet也需要更多的数字(-http://silentmatt.com/biginteger/

最新更新