1

I'm using the Remix editor and I have a nonsense function that takes a int data type as an argument that simply just returns it.

pragma solidity ^0.4.19;

contract someContract {

    function doSomething (int a) public pure returns (int) {
        return a;
    }
}

When I pass in a whole number for example, 1, I get back:

{
    "0": "int256: 1"
}

which makes sense to me.

But when I pass in a number with an ether unit, for example, 1 ether, I get back:

{
    "0": "int256: 270867"
}

Or if I try 1 wei, I get back:

{
    "0": "int256: 4358"
}

Is this a Remix bug, or is there something special about 1 ether == int256(270867) or 1 wei == int256(4358)?

This is how I'm passing these values.

https://remix.ethereum.org/#optimize=false&version=soljson-v0.4.19+commit.c4cbbb05.js

debug output input of 1 ether

  • Can you describe how you're passing in 1 ether or 1 wei? Via another contract? Can you share that code too? – smarx Dec 22 '17 at 9:27
  • For comparison, if I write function test() public pure returns (uint256) { return 1 ether; } and execute it in Remix, I get back uint256: 1000000000000000000. – smarx Dec 22 '17 at 15:13
  • @smarx, I tried your function and it worked great. But when I modify your function to function test(uint256 a) public pure returns (uint256) { return a; } and take a 1 ether input, I still get { "0": "int256: 270867" } back – Kevin Dec 22 '17 at 17:15
0

It looks from you screenshot like you're passing a string: "1 ether". I'm not sure how Remix is interpreting that, but you can see from the "decoded input" that it's indeed sending the value 270867.

If you try "hello" instead, you'll see the value 186334 is sent.

I would say this should be an error in Remix, since you're not passing a valid uint256. I don't know if web3.js treats strings the same way.

If you want to pass 1 ether via web3, you can use web3.toWei(1, 'ether').

UPDATE

I've tracked this down to ethereumjs-abi, which is used under the hood in Remix to do the ABI encoding:

> const abi = require('ethereumjs-abi');
> parseInt(abi.rawEncode(['uint256'], ['hello']).toString('hex'), 16);    
186334

UPDATE 2

I've further tracked this down to bn.js, which is used under the hood in ethereumjs-abi:

> new BN('hello')
<BN: 2d7de>
> 0x2d7de
186334

UPDATE 3

The issue is probably in parseBase: https://github.com/indutny/bn.js/blob/master/lib/bn.js#L245. But essentially, we're passing invalid data (violating some assumptions made in bn.js), since it's expecting a number. What's missing is some parameter validation.

  • Great investigative work! But in the docs on solidity.readthedocs.io/en/develop/…, it says that "A literal number can take a suffix of wei, finney, szabo or ether to convert between the subdenominations of Ether". Isn't 1 ether then considered a valid uint data type? – Kevin Dec 22 '17 at 23:26
  • 1
    Yes, in Solidity. But you're typing JSON into a web app. – smarx Dec 22 '17 at 23:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.