tomusdrw / rust-web3

Ethereum JSON-RPC multi-transport client. Rust implementation of web3 library. ENS address: rust-web3.eth
MIT License
1.46k stars 471 forks source link

Querying a contract with a int256 input requires using ethabi::Token::Int variable #172

Open AvishaiW opened 5 years ago

AvishaiW commented 5 years ago

Hi, If I have a contract with a function like:

  {
    "constant": true,
    "inputs": [
      {
        "name": "a",
        "type": "int256"
      },
      {
        "name": "b",
        "type": "int256"
      }
    ],
    "name": "add",
    "outputs": [
      {
        "name": "",
        "type": "int256"
      }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
  },

I Can't call it using:

let result: QueryResult<U256, _> = contract.query("add", (5,7,),None, Options::default(), None);

Or even:

let result: QueryResult<U256, _> = contract.query("add", (U256::From(5),U256::From(7),),None, Options::default(), None);

I must do:

let result: QueryResult<U256, _> = contract.query("add", (Token::Int(5.into()),Token::Int(7.into()),),None, Options::default(), None);

Otherwise I get this error:

Err(Error(Abi(InvalidData), State { next_error: None, backtrace: InternalBacktrace { backtrace: None } }))

I can't explain why this happens, but it means I must import ethabi to use this.

tomusdrw commented 5 years ago

Perhaps an incorrect handling of conversions in ethabi.

CPerezz commented 5 years ago

As I've experienced, U256 isn't compatible with Solidity Int variable type. The Se/Deserialization does not work/it's not implemented. I've not had time to review it. I don't know if there's any workarround to work with Int.

ethereum_types crate on it's new release 0.4.0. maybe has something to solve it. I've not seen anything about it.. but I've not reiwed it.

So maybe @debris can bring some light here.

debris commented 5 years ago

so, there is no conversion between U256 and Int because... we never needed it. I'm happy to add it, but tbh I'm not sure how out of range values should be handled. Any suggestions?

elichai commented 5 years ago

@debris I think it should be handled the same way it's handled by the evm. In the end everything in the evm is u256, so what how is -150 represented? (I'll guess it's some sort of underflowing...)

CPerezz commented 5 years ago

As @elichai says it can be solved by implementing the 2's Complement as evm does. The solution can be then loose a bit to gain the symbol property.

I think it's important to point out that with non huge numbers like X < 10^77 aprox. it should handle the signs, otherwise, I think we can experience unexpected behaviors.

I've used quite a bit the BigInt/BigUint crate. Maybe contains something helpful.