Web3.js: Bignumber issue in web3 invalid number value (arg="_value", coderType="uint256", value=10000000000000000)

Created on 29 Nov 2018  路  61Comments  路  Source: ChainSafe/web3.js

Getting invalid number error when calling a method of a contract which take uint256 argument.

Example:
myContract.methods.transfer(accounts[1], 1e16).send({ from: accounts[0] })

1) When sending value 1e16 it throw error
web3 invalid number value (arg="_value", coderType="uint256", value=10000000000000000)
2) When sending value 10000000000000000 throw same error
3) When sending value 1e16 as hex it work okay. No error.
4) When sending value 1e15 or less value as number like 100000000000000 if work okay. No error

I am using web3 1.0.0-beta.36

1.x 2.x Stale bug

Most helpful comment

I have the same error before but it works now, You can try this.

// Decimal
const decimals = web3.utils.toBN(18);

// Amount of token
const tokenAmount = web3.utils.toBN(10000000000);

// Amount as Hex - contract.methods.transfer(toAddress, tokenAmountHex).encodeABI();
const tokenAmountHex = '0x' + tokenAmount.mul(web3.utils.toBN(10).pow(decimals)).toString('hex');

All 61 comments

Thanks for submitting this issue!
I think this an issue of the new AbiCoder from ethers.js I will update the ethers.js package and test it.

@nivida . More details- I tested in old version of web3 . This is not in issue in beta.35 and beta.34 . Seems like breaking in beta.36 only.

@patidarmanoj10 Yes this is because we use the new AbiCoder of ethers.js since beta36. This should be fixed quickly and released with the next build thanks for testing it. My plan is to write the AbiCoder by my self after the 1.0 stable release because it's dangerous to have such an important part of this lib as external dep. :-)

@nivida what version of ethers.js do you think is good?

@gabmontes Hopefully the latest version has fixed it. (4.0.15)
I will test it by own asap.

I was able to reproduce the bug in version 4.0.15:

> ethersAbiCoder.encode(['uint256'], [1e+14])
'0x00000000000000000000000000000000000000000000000000005af3107a4000'
> ethersAbiCoder.encode(['uint256'], [1e+16])
Error: invalid number value (arg="", coderType="uint256", value=10000000000000000, version=4.0.15)
    at Object.throwError (/private/tmp/node_modules/ethers/errors.js:76:17)
    at CoderNumber.encode (/private/tmp/node_modules/ethers/utils/abi-coder.js:390:20)
    at /private/tmp/node_modules/ethers/utils/abi-coder.js:642:59
    at Array.forEach (<anonymous>)
    at pack (/private/tmp/node_modules/ethers/utils/abi-coder.js:641:12)
    at CoderTuple.encode (/private/tmp/node_modules/ethers/utils/abi-coder.js:801:16)
    at AbiCoder.encode (/private/tmp/node_modules/ethers/utils/abi-coder.js:938:77)
> ethersAbiCoder.encode(['uint256'], [1e+15])
'0x00000000000000000000000000000000000000000000000000038d7ea4c68000'

This is also referenced in #1920 just fyi

The same issue in beta.37.

Any update on this issue??
I just met in beta.37.

@patidarmanoj10 , you mentioned

When sending value 1e16 as hex it work okay. No error.

Does that mean a workaround for this issue?? If I convert my number to that format.

Thanks!

@yueawang yes.

In addition to the BigNumber issue we are also getting an error with Bytes3:
Error: invalid bytes3 value (arg="ccy", coderType="bytes3", value="USD")

Workaround:
web3.utils.asciiToHex('USD')

We are using truffle 5.0.1 and most unit tests are failing due to this error.

Any update on if/when this issue will be resolved?

Many thanks!

I'm using the following truffle version and this same issue is cropping up:
Truffle v5.0.2 (core: 5.0.2)
Solidity v0.5.0 (solc-js)
Node v11.6.0
[email protected]

once I allocate a value greater than 1e15 to uint256 (like 1e16, or 1e17), it breaks and throws an error during truffle deployment of contract (using constructor arguments):

Error: invalid number value (arg="_var", coderType="uint256", value=10000000000000000)

I am facing the same issue for latest web3 1.0.0 version

This should be solved in this git tag and will be released within the next week:
https://github.com/ethereum/web3.js/tree/v1.0.0-beta.38-rc2

Would be great if someone could quickly test it for me.

@nivida It looks like I'm still getting the error:

Error: invalid BigNumber string value (arg="value", value="1e+24", version=4.0.21)

I cloned Truffle, checked out v5.0.2, cloned web3 inside truffle/packages and checked out v1.0.0-beta.38-rc2, and then updated relevant package.json files to point everything in my project and in truffle to that version of web3. Not sure if that's the easiest way to do it, but the stack trace for the error above is pointing to mytruffle/packages/truffle-contract/node_modules/ethers/errors.js:76:17.

Edit: I think the problem is just that it's still pointing to the wrong version of web3-eth-abi and ethers. I'll look for a better way to replace web3 in my local clone of truffle.

I have the same error on Remix, after generating a smart contract from circom (0k knowledge proof).

@markerdmann I will release a Web3.js version with the latest release of ethers.js. But as I saw are you already using the latest version of ethers.js version=4.0.21. Because of this would I recommend to open an issue in the ethers.js repository for fixing this.

The same issue on 1.0.0-beta.40

Same issue also on 1.0.0-beta.41.

@nivida
I made a little dig into code the of ethers.js and found that they are using their own implementation of bignumber. So when I (and the others I suppose) talk about bignumber.js, ethers got their own implementation.

In beta.36 ethers.js was introduced to web3-eth-abi and since than it's not functioning with bignumber.js.

I had the same error when passing wei values in truffle tests and my temporary solution is using web3.utils.toWei which seems to work. Maybe someone will find this helpful as an interim solution.

@chrsengel yeah it works cause it converts the bignumber to string, and ethers accepts strings.

It's actually may be a good idea to accepts less types to eliminate errors. I think it's ok to translate every number to a string.

Web3.js does have currently two other issues with the abi coder of ethers.js the possible quick fixes are:

  • back to an older version of ethers.js
  • using of the ethereumjs abi coder
  • quick fixing of web3-utils and web3-core-helpers
  • Creation of an web3-types module with all possible types (Hex, Iban, Address etc.)

I will check all the possibilities tomorrow and will choose the fastest end best solution of all.

I've tested it now and this is an issue of ethers.js and will also occur in the latest version of ethers.js. I've created an issue in the ethers.js GitHub repository: https://github.com/ethers-io/ethers.js/issues/418

@nivida Yes that makes sense, ethers.js using now their own implementation of BigNumber (or maybe doing some wrapping), wrote it in my last comment 馃憖 .

@nivida - The issue persists with 1.0.0-beta.46 . Any workaround for this ?

@nivida - I'm having the same issue. The numbers I'm trying to pass are 5*10^18 and 10^18. I have tried the following and have had the same error as what is within the header of this issue.

Example:
myContract.methods.transfer(accounts[1], 1e16).send({ from: accounts[0] })

  1. When sending value 1e18 an error is thrown.
    web3 invalid number value (arg="_value", coderType="uint256", value=1000000000000000000)
  2. When sending value 1000000000000000000 the same error is thrown
  3. When sending value 1e18 as hex through ...

amount = number(10**18);

myContract.methods.transfer(accounts[1], amount.toString(16)
).send({ from: accounts[0] })

  1. When sending value 1e16 - 1 or less works.

I am using "web3": "^1.0.0-beta.37"

If anyone knows a workaround for this please let me know via email, [email protected] ,or through github.

@pjonson2 Did you tried the solution suggested by chrsengel here https://github.com/ethereum/web3.js/issues/2077#issuecomment-461199427 ? Passing just a string like "1000000000000000000" as amount should work.

web3.utils.toHex and web3.utils.toWei does not work for me. As the convert-to-string workaround mentioned above, I tried the following and it works:

1e18.toString()

I have the same error before but it works now, You can try this.

// Decimal
const decimals = web3.utils.toBN(18);

// Amount of token
const tokenAmount = web3.utils.toBN(10000000000);

// Amount as Hex - contract.methods.transfer(toAddress, tokenAmountHex).encodeABI();
const tokenAmountHex = '0x' + tokenAmount.mul(web3.utils.toBN(10).pow(decimals)).toString('hex');

@kingdido999 web3.utils.toWei should receive a price in ether. If you pass 1e18 to it you already pass it in wei, so that must be the reason it fails.

When I looked into ethers source code I've found that passing the values as strings in wei should work. No matter which transform function you use.

Any solutions right now? Got the error in 1.0.0-beta.50. Tried also with 1.0.0-beta.34, 1.0.0-beta.35, without success.

downgraded to ^1.0.0-beta.35 to get it work

Any updates on this. I have been getting this error too for a while now with
MyToken.transfer(_toCrowdsaleContractAddress, web3.utils.toBN(value)) where value = Mytoken.totalSupply().

Also tried using this web3.utils.toBN(value.toString()) and this Number(value.toString()).

Any suggestions on this would be appreciated. Have been stuck on this for quite sometime now.

@sowmyakannan try just to pass the string in wei. it Works for me with [email protected]

const tokenAmountHex = '0x' + tokenAmount.mul(web3.utils.toBN(10).pow(decimals)).toString('hex');

This actually worked for me, thanks for posting

Just to be aware of, there are some problems/bugs with BN, so whenever you can, pass strings(like in @rmindo case) and not BNs. So it's more BN problem, than web3. Caused me a lot of trouble..

Got the same issue with 1.0.0-beta.53 downgrading.

@sowmyakannan try just to pass the string in wei. it Works for me with [email protected]

This worked for me

It is annoying.

Using truffle test and 1.0.0-beta.37

Works for me: https://github.com/ethereum/web3.js/issues/2077#issuecomment-482932690

try just to pass the string in wei

In case you want to check things out...

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>web3.js 1.0.0-beta TESTING (open console)</title>
    <script src="https://cdn.jsdelivr.net/gh/ethereum/[email protected]/dist/web3.js"></script>
  </head>
  <body>
    <h1>web3.js 1.0.0-beta TESTING (open console)</h1>
    <script>
      const web3 = new Web3(Web3.givenProvider || 'ws://localhost:8546', null, {}); // initialising it: https://web3js.readthedocs.io/en/1.0/getting-started.html   
      console.log(web3.version);
      console.log("toWei: " + web3.utils.toWei("1"));
      console.log("fromWei:" + web3.utils.fromWei("1000000000000000001"));
    </script>

  </body>
</html>

Should uint256 work with web3.utils.toBN(...)? I have to call methods with uint256 parameters using a hexa expression. I think that's wrong.

This Solidity method:

function shaBid(bytes32 _hash, address _owner, uint _value, bytes32 _salt) public pure returns (bytes32)

| Called with | Output |
| - | - |
| contract.methods.shaBid(hash, owner, web3.utils.toBN(1), '0x00') | Error: invalid number value (arg="_value", coderType="uint256", value="1") |
| contract.methods.shaBid(hash, owner, '0x00', '0x00') | No error |

Same issue here
I'm using

Truffle v5.0.25 (core: 5.0.25)
Solidity v0.5.0 (solc-js)
Node v8.10.0
Web3.js v1.0.0-beta.37

and I'm trying to give a "price" value from web3 ($('#article_price').val() in Wei) to a uint256 in Solidity in ether.
Here are some examples I tested

var _price = $('#article_price').val()*1e18;
Error: "invalid number value (arg="_price", coderType="uint256", value=10500000000000000000)"
var _price = web3.utils.toWei($('#article_price').val(),'ether');
Error: "Error: [number-to-bn] while converting number 1e+22 to BN.js instance, error: invalid number value. Value must be an integer, hex string, BN or BigNumber instance. Note, decimals are not supported. Given value: "1e+22""



md5-c6f7a4a643dd579fb80461f6eed0410e



var _price = $('#article_price').val()*1e18.toString();
Error: "Error: [number-to-bn] while converting number 1e+22 to BN.js instance, error: invalid number value. Value must be an integer, hex string, BN or BigNumber instance. Note, decimals are not supported. Given value: "1e+22""

I tried also BN conversions, Hex conversions ... to the same disappointing answer.
I don't know what else I should try ...

Also a different error here :

var _price = web3.utils.toWei($('#article_price').val() || 0,"ether");
Error: "Please pass numbers as strings or BigNumber objects to avoid precision errors."

Same error in the latest version "web3": "1.2.1".

I'm passing a BigNumber variable to an ERC20 transfer function: erc20contract.methods.transfer(to, bigNumberValue) I'm passing a BigNumber which should be a valid type according to the error message.

Error:

(node:21061) UnhandledPromiseRejectionWarning: Error: Error: [number-to-bn] while converting number 1e+21 to BN.js instance, error: invalid number value. Value must be an integer, hex string, BN or BigNumber instance. Note, decimals are not supported. Given value: "1e+21"

Workaround:
It works if I pass the number like this: erc20contract.methods.transfer(to, this.node.utils.toHex(bigNumberValue))

@nivida The solution also needs to attach a special case:

After the BN.js code is obfuscated, his name is no longer 'BN', and it has become a random r or other.

test case: nuxt+web3+truffle-Contract , nuxt dev works fine, but nuxt start fails after nuxt build.

BN isBN funcation:

BN.isBN = function isBN (num) {
    if (num instanceof BN) {
      return true;
    }
    return num !== null && typeof num === 'object' &&
      num.constructor.wordSize === BN.wordSize && Array.isArray(num.words);
  };

I have add some code for encode funcation:

return ethersAbiCoder.encode(
        this.mapTypes(types),
        params.map(function (param) {
            if (utils.isBN(param) || utils.isBigNumber(param)) {
                return param.toString(10);
            }
            if (param !== null
                && typeof param === 'object'
                &&  param.constructor.wordSize === 26 // ==BN.word
                && Array.isArray(param.words) ){
                    return param.toString(10);
            }
            return param;
        })
    );

"OraclizeTest" -- invalid number value (arg="_amount", coderType="uint256", value={"from":"0xb5Fb3E9BB73e742689F1001C519d6763a39A4Bc5","gas":6.721976666666666e+21,"value":"1000000000000000000"}).

at /root/.nvm/versions/node/v9.11.2/lib/node_modules/truffle/build/webpack:/packages/deployer/src/deployment.js:364:1
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:182:7)

Please can anyone help me to fix this

Slightly off topic but anyone struggling with encoding large numbers in ethers.js can use the following:

const constants = ethers.constants;
constants.One.mul(10).pow(18) // 0x0de0b6b3a7640000 (10e18)

any updates on this? still broken on the latest version.

I'm using the following truffle version and this same issue is cropping up:
Truffle v5.0.2 (core: 5.0.2)
Solidity v0.5.0 (solc-js)
Node v11.6.0
[email protected]

once I allocate a value greater than 1e15 to uint256 (like 1e16, or 1e17), it breaks and throws an error during truffle deployment of contract (using constructor arguments):

Error: invalid number value (arg="_var", coderType="uint256", value=10000000000000000)

hello锛宨 want to know if you have any way to answer this question, can you tell me ?thank you

@pjonson2 Did you tried the solution suggested by chrsengel here #2077 (comment) ? Passing just a string like "1000000000000000000" as amount should work.

This worked for me. Thanks

The best way to mitigate it that I found was to do something like this:

const num = 6200 * Math.pow(10, 18);
const numAsHex = "0x" + num.toString(16);

When you pass numAsHex to the contract method, it will be treated as uint256.

Same issue still. Passing the number as a string does the job.

Can confirm passing numbers as string does the job. On the other hand I think that's less than optimal considering a lot of people rely on BN.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions. If you believe this was a mistake, please comment.

Issue still has not been fixed

use web3.utils.toWei('1000000000') for workaround way

web3.utils.toWei(amount) seems dead. web3.toWei(amount) worked for me though.

Quick fixes:
const num256 = 42*10**18;
const fix1 = num256.toString();
const fix2 = "0x"+num256.toString(16);

@crameur why must it be like that?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions. If you believe this was a mistake, please comment.

Rename the variable while importing

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions. If you believe this was a mistake, please comment.

Was this page helpful?
0 / 5 - 0 ratings