We get these occasionally when we make a change to MyEtherWallet, and we don't use Solidity or web3. It's a JS thing in the BigNumber.js library that web3 also uses.
Somewhere you have something that you think is a number but it's actually a string, null, array, object, or something else. This was some code for sending a signed TX via the offline tab. The error in our case was BigNumber Error: new BigNumber() not a number: 0x
. And the fix:
- [before]
$scope.tx.value = etherUnits.toEther('0x'+eTx.value.toString('hex'),'wei');
- [after]
$scope.tx.value = eTx.value.toString('hex')!='' ? etherUnits.toEther('0x'+eTx.value.toString('hex'),'wei') : 0;
So before we were just like "take that value and do stuff with it". The fix was "if this value isn't empty, then do stuff with it, otherwise return 0
.
So. Things to try...
console.log your variables before AND after, error or no error, and also log their types: console.log(typeof myContract)
Make sure that you are catching any empty or null values and either retuning a number (e.g. 0
), or not continuing on
Make sure you are passing what you think you are passing. For example, are you really passing the address
, or fromaddress
, or contract.address
, or something else?
In your case, it's saying [Object object], which makes me think something is an object. In that case do console.log( JSON.stringify(myContract) )
as well so you can actually see what it is.
Anything that you log that returns something funky like Object { s: 1, e: 0, c: Array1 }
, you need to either
toString
to get it's value as a decimal string
toNumber
to approximate it as a JS number.
- (That object is the object from BigNumber.js)
If you do all of those things, you will discover the spot where you thought something was something, but it was actually somethingElse. Then it's an easy fix.
Each storage variable has its own storage slot whose address is a sequential number of this variable within contract:
contract Foo {
uint internal x; // Storage slot #0
mapping (uint => uint) internal y; // Storage slot #1
uint [] internal z; // Storage slot #2
}
For atomic variables, such as x
, this slot holds variable value.
For mapping variables, such as y
, this slot is not used, but still allocated.
For dynamic array variables, such as z
, this slot contains array length.
Array data is stored separately in consequent storage slots starting from the slot with address keccak256 (n)
where n
is variable sequential number.
So, to access array z
declared above, you may use the following assembly:
function zLength () public view returns (uint r) {
assembly {
r := sload (2)
}
}
function zElement (uint i) public view returns (uint r) {
assembly {
mstore (0, 2)
r := sload (add (keccak256 (0, 32), i))
}
}
Of cause, keccak256 (2)
should not be calculated every time, such should be substituted as compile-time constant.
See documentation for more details.
Best Answer
the number is not only what is contained inside
c
but the whole BigNumber notation, which is accessible with af.toString()
f.toString()
will give you a string, which can be saved into a variable. Same as you can keep it inside theBigNumber
object and use the.toString
to access to a readable valuethis question doesn't make sense given the answers above, that kind of structure is the internal representation of the number stored into the
BigNumber
object