Как преобразовать баланс токена 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/

Другие вопросы по тегам