Как преобразовать баланс токена RSK в номер Javascript?
Я хочу получить баланс (количество токенов) из смарт-контракта токена.
Я использую web3.js для взаимодействия с контрактом и могу получить возвращаемое значение. Однако с этим значением, если я это сделаю
.toString()
, Я вижу, что у него правильное значение. Однако, если я это сделаю
.toNumber()
, это дает мне ошибку:
Error: Number can only safely store up to 53 bits
Почему это происходит? И как я могу получить баланс конкретной учетной записи из смарт-контракта в виде числа (а не строки)?
2 ответа
Смарт-контракты могут поддерживать очень большие числа (вплоть до Solidity). Однако встроенный
Number
тип Javascript не может представлять такие большие числа, и, следовательно, в
web3.js
, любые числовые значения заключаются в (большое число). Вы можете найти этот класс в
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 достаточно мала.
- Если BN слишком большой, используйте
.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();
- Запросите контракт токена, чтобы получить значения баланса и десятичные дроби, как
- Преобразуйте десятичные дроби в числа напрямую, используя
.toNumber()
, так как мы ожидаем, что это будет достаточно маленьким - Разделите баланс на 10 в степени десятичной дроби.
BN
, а затем позвоните.toNumber
в теме
ПРИМЕЧАНИЕ. Полученное значение
balance
будет соответствовать количеству токенов, которое обычно отображается в пользовательских интерфейсах ... а не значению, хранящемуся в самом смарт-контракте.
или используйте BN from - он увеличивает длину байтов и на самом деле лучше (xmr / vet также требует больше цифр) - http://silentmatt.com/biginteger/