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

Posted

技术标签:

【中文标题】如何将 RSK 代币余额转换为 Javascript 数字?【英文标题】:How to convert RSK token balance to a Javascript number? 【发布时间】:2021-08-25 15:25:11 【问题描述】:

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

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

为什么会这样?我如何从智能合约中获取特定账户的余额,作为数字(不是字符串)?

【问题讨论】:

【参考方案1】:

智能合约可以支持非常大的数字(在 Solidity 中高达 uint256)。然而,内置的 Number 类型的 javascript 不能表示那么大的数字,因此在 web3.js 中,任何数值都包含在 BN(大数字)中。你可以在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 除以 10 的小数次幂 BN,然后调用 .toNumber 就可以了

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

【讨论】:

【参考方案2】:

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

【讨论】:

以上是关于如何将 RSK 代币余额转换为 Javascript 数字?的主要内容,如果未能解决你的问题,请参考以下文章

如何计算 RSK 上代币的总交易量?

如何判断 RSK 上的智能合约是不是为 NFT?

如何将 ERC20 代币发送到智能合约余额?

ERC20 代币余额如何存储在以太坊区块链上

如何查找erc20代币余额

Solana - 如何获得外国账户的代币余额?