question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Feature request: option to change the big number library

See original GitHub issue

When interacting with any contract fields with ethers, I get a result that looks like this:

tokenBalance: v
  _hex: "0x033b2b2062ddfc98de7fffff"
  _ethersType: "BigNumber

After enquiring on StackExchange, I now understand the ethers is piggybacking off the bn.js library, but in my codebase I use bignumber.js, so I have to extract the _hex property from the ethers value and make a conversion.

It would be nice to have a global config where one can select what kind of big number the ethers library should return. Afaik, the most popular libraries are bn.js and bignumber.js, and they would probably be sufficient for many users.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

3reactions
ricmoocommented, Nov 28, 2019

Heya!

First off, that is a BigNumber object; you never need to (nor should) access any _property. They should be considered internal, and in v6 will likely be wrapped in a Weak Map and completely inaccessible. You should be able to just use v.toString() for base-10 string or v.toHexString() for a hex-prefixed hex string; the former can easily be passed into your Big Number library of choice. You should not rely on _hex always existing, which brings me to point 1. 😃

  1. A main reason to abstract the BN.js number is in case in the future I wish to remove it as a dependency, swap it out with something else, or provide an alternate underlying implementation. In the case that no ECC library is needed, the Big Number library can be greatly reduced in size.

  2. Keep in mind that BigNumber is used extensively inside the ethers.js library. The reason to provide this one is that it provides the necessary features required internally. If it could be swapped out, I would have to do checks everywhere to determine if I should call .mul or .times, or whatever other possible options exist on various libraries. This doesn’t even begin to scratch the surface of features other Big Number libraries do not have (for example, .nmask, .toTwos and .fromTwos). When the Signer calls estimateGas and getGasPrice, it knows it can .mul them together to get the fee.

  3. This would break the ability for multiple libraries to use ethers safely within the same project. If you pull in ethers, and Takoyaki (which uses ethers) and your own code, and change the global Big Number library, then the Takoyaki library will fail all over the place internally, since it cannot call functions it expects to exist but have slightly different names or slightly different behaviour.

  4. Immutability; the main reason for this implementation, which cannot be enforced against arbitrary (or even BN.js and BigNumber.js) Big Number libraries. This greatly simplifies a lot of code, but more importantly creates substantially safer and less error-prone code. Imagine passing a mutable value into a Contract; it would be quite easy a mistake to not create a deep copy of the value, and if an outside reference changes the value between various stages (like gas estimation and signing) could lead to unexpected results.

Generally allowing these “global” type of configuration makes incredibly brittle code that can no longer be used by frameworks, or by frameworks of frameworks, or even multiple libraries depending on the same library.

The BigNumber class is exposed though, so you could easily add ethers.BigNumber.prototype.toMyBigNumber = function() { return new BigNumberLib(this.toString()); }.

1reaction
paulrbergcommented, Nov 29, 2019

Thanks @ricmoo for the in-depth, well-crafted answer. I now understand the rationale behind your design choice of using a bespoke big number type - I think this is something worthy to be mentioned (as a warning?) in the docs.

The toMyBigNumber/ toString workaround works great for me and I’ll change my code to not use _hex anymore.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Pocket's Top Feature Requests
Below is a list of some of the most popular feature requests that we have implemented. We're hoping that this working document will...
Read more >
What are your "Top 5 Feature Requests"? - Qualtrics Community
1. Re-code seen but not selected on data export - The ability to re-code downloaded data where the respondent saw an answer option,...
Read more >
Manage large lists and libraries - Microsoft Support
Learn how to manage large lists and libraries for SharePoint 2013 and SharePoint 2016 on premise by planning and using key list and...
Read more >
Feature request | Altium Designer | Knowledge Base
We recommend that you search to see If there's already one there so you can add your vote to it. We have set...
Read more >
Feature Request: Hot (834 ideas) - Adobe Bridge Feedback
So, I closed the extra tabs and went to open my new windows and was stunned to find I no longer could. This...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found