Skip to content
This repository has been archived by the owner on Feb 4, 2022. It is now read-only.

Negative value from BigInt is wrong #73

Closed
timmornYE opened this issue Jan 15, 2020 · 4 comments
Closed

Negative value from BigInt is wrong #73

timmornYE opened this issue Jan 15, 2020 · 4 comments
Assignees

Comments

@timmornYE
Copy link

Description

Negative return value from smart contract results in a wrong number in dart. Checking the same in web3.js results in the correct value. Positive value gets printed correct.

Example

Minimal contract example

pragma solidity >=0.4.24 <0.7.0;
contract Credit {
    int32 public credits;
    constructor() public {
    }
    function getSupply() public view returns (int32) {
	    return credit;
    }
    function chargeCredit(int32 amount) public returns (bool success) {
        credit += amount;
	    return true;
    }

}

Minimal Dart code example

import 'package:http/http.dart'; //You can also import the browser version
import 'package:web3dart/web3dart.dart';
void main() {
  final functionChargeCredit = contract.function('chargeCredit');
  final functionGetSupply = contract.function('getSupply');
  await ethClient.sendTransaction(credentials, Transaction.callContract(
      contract: contract, 
      function: functionChargeCredit, 
      gasPrice: EtherAmount.inWei(BigInt.one),
      maxGas: 100000,
      parameters: [new BigInt.from(-200)]),); 
  
  voucherBalance = await ethClient.call(
      contract: contract, function: functionGetSupply, params: []); 
  BigInt balanceBigInt = voucherBalance.first;
  print( 'Credit: ${balanceBigInt.toString()} ');
}

Minimal web3.js minimal example

        // [...]
        dec = (await instance.getSupply()).toNumber();
        console.log(dec);

Result

Expected output (= web3.js output): -200
Dart output: 115792089237316195423570985008687907853269984665640564039457584007908834672440

@simolus3 simolus3 self-assigned this Jan 15, 2020
@timmornYE
Copy link
Author

I checked... invert binary representation of 115792089237316195423570985008687907853269984665640564039457584007908834672440, convert most left bit which is 1 to 0 and add 1 --> you get 200. This means, that dart does not recognize that the binary representation of this number is a negative in two's complement.

@timmornYE
Copy link
Author

Ok, solved... the problem is, that i return a 32 bit integer from smart contract. So it is not recognized by dart that this is a negative integer, because the returned most left bit is not the most left in the BigInt. This way it can be solved:

  // [...]
  BigInt balanceBigInt = voucherBalance.first;
  print( 'Credit: ${balanceBigInt.toSigned(32)} ');
}

If this behavior is expected I can not decide. web3.js does recognize it without explicit conversion.

@simolus3
Copy link
Owner

This is definitely a bug in web3dart. It should report "-200" as well, without any explicit conversion.
I actually had a check for this, but it was buggy and didn't respect sign-extension padding (32 bit ints are encoded as a 256 bit block). I only tested -1 where it didn't make any difference 🤦‍♂️

This will be fixed in 1.2.2, which I'll release after the CI passes. Thanks for the report!

@simolus3
Copy link
Owner

Just released version 1.2.2 to pub, which contains this fix.

makinghappen pushed a commit to makinghappen/webthree that referenced this issue Jan 14, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants