web3dart icon indicating copy to clipboard operation
web3dart copied to clipboard

Bug: Zero address returned from contract call causes exception

Open cryptobys-rami opened this issue 3 years ago • 20 comments

I found this bug in the library where a zero address returned from a contract results in an exception (because zero address is '0x0'). I suggest manipulating return data from contracts to check for zero address. It is quite typical for contracts to search an internal map for an address, returning zero address if it cannot find it. BAF41D45-AD45-494E-8338-BDC3B8CA8235_4_5005_c

cryptobys-rami avatar Dec 07 '21 17:12 cryptobys-rami

I think this is related to #239

0x is linked to UintType(length 256) then final result = type.decode(buffer, offset + headersLength); and fail on _decode32Bytes

Solido avatar Jan 14 '22 10:01 Solido

BTW - this happens any time any function returns the default variable. Not just for addresses, also other value types... maybe this is a hint?

cryptobys-rami avatar Jan 14 '22 11:01 cryptobys-rami

Trying to debug the cause. Effect is a problem with Buffer decoding but even the 0x response is incorrect. But I'm just starting using the API so it is a lot of research. Let's discuss here about details to solve this.

Solido avatar Jan 14 '22 11:01 Solido

Sure im happy to help. I ve worked around it by using a different library for reading from functions. Very annoying!

cryptobys-rami avatar Jan 14 '22 11:01 cryptobys-rami

That was my question! This is the basic call of a function so not sure how the tests passes. Which lib are you using? can we provide a PR to this lib?

Solido avatar Jan 14 '22 11:01 Solido

I used this: https://github.com/y-pakorn/flutter_web3

the problem with flutter_web3 library is that its not native dart, so impossible to debug anything. Also smaller community/less testing? plus side of flutter_web3 is that it uses ethers js library which is the gold standard.

Happy to help make web3dart better

cryptobys-rami avatar Jan 14 '22 11:01 cryptobys-rami

Oh I see it is a wrapper around .js so it also mean limitation in going mobile or desktop. Like you said less community and commits.

I'd rather help build a standard around web3dart if possible for multi platforms.

Digging now. Keep you updated in the coming hours.

Solido avatar Jan 14 '22 11:01 Solido

Im very keen on the mobile part.

basically at the moment its impossible to use web3dart with metamask on mobile platform its also impossible to use it on mobile web unless it is run in metamask browser

would love to cooperate to make this possible.

cryptobys-rami avatar Jan 14 '22 11:01 cryptobys-rami

It is possible you need to use wallet connect You can reach me here https://twitter.com/BlueAquilae

Solido avatar Jan 14 '22 11:01 Solido

Hi @simolus3 would you accept a bounty to resolve this case? 40euros to help support this project and help us with timing resolution. Thank you for your consideration on the matter.

Solido avatar Jan 14 '22 11:01 Solido

happy to contribute (to the bounty) as well!

cryptobys-rami avatar Jan 14 '22 12:01 cryptobys-rami

Sorry for the delay on this issue. I'm not too involved in the Ethereum ecosystem anymore, but I'll try to maintain this package as best as I can.

I tried to reproduce this issue with the following contract:

pragma solidity >=0.7.0 <0.9.0;

contract ReturnDefaults {
    function zero_int() public pure returns (int) {
        return 0;
    }

    function zero_address() public pure returns (address) {
        return address(0);
    }
}

I've deployed this to a local Ganache instance and then ran this script:

import 'package:http/http.dart';
import 'package:web3dart/web3dart.dart';

import 'test.g.dart';

Future<void> main() async {
  final client = Web3Client('http://localhost:7545', Client());
  final contract = Test(
      address:
          EthereumAddress.fromHex('0x4BBA8dcCAff0Dd855e6EC6400cc8494Bfa904c57'),
      client: client);

  print(await contract.zero_address());
  print(await contract.zero_int());
}

This prints zero for me, I don't get the range error here. If you have clear instructions on how to reproduce this (ideally, some simple contract source code + the local chain software) I'm happy to take another look. I don't need a bounty for this, just happy to help.

simolus3 avatar Jan 14 '22 13:01 simolus3

Thx for the quick reply. The easiest way is to use hardhat https://hardhat.org/getting-started/#installation

It will create a default local chain and contract

pragma solidity ^0.8.0;

import "hardhat/console.sol";

contract Greeter {
    string private greeting;

    constructor(string memory _greeting) {
        console.log("Deploying a Greeter with greeting:", _greeting);
        greeting = _greeting;
    }

    function greet() public view returns (string memory) {
        return greeting;
    }

    function setGreeting(string memory _greeting) public {
        console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
        greeting = _greeting;
    }
}

Called greet() will fail as a default example.

Solido avatar Jan 14 '22 13:01 Solido

@simolus3 Who is taking care of this repo now?

Solido avatar Jan 14 '22 13:01 Solido

That also works for me? I ran npx hardhat node followed by npx hardhat run scripts/sample-script.js --network localhost.

import 'package:http/http.dart';
import 'package:web3dart/web3dart.dart';

import 'test.g.dart';

Future<void> main() async {
  final client = Web3Client('http://localhost:8545', Client());
  final contract = Test(
      address:
          EthereumAddress.fromHex('0x5FbDB2315678afecb367f032d93F642f64180aa3'),
      client: client);

  print(await contract.greet()); // Hello, Hardhat!
}

I get the "Value not in range: 32" error only if I pick the wrong contract address. The error message sure could be better here, but I assume that's not the actual cause for you?

Who is taking care of this repo now?

I still am. If anyone wants to help, I'm happy to add new maintainers or transfer the repo, but I need to make sure it's not going into the wrong hands since this package may manage private keys for users.

simolus3 avatar Jan 14 '22 14:01 simolus3

That is a good news!

Just need to find where the diff is. I tried the generator, building from Abi or even manual function setup for the same result.

Also I test in a Flutter app. Need to try a direct call like you. Edit: idem in dart

Contract address are always the same in hardhat EthereumAddress.fromHex('0x5FbDB2315678afecb367f032d93F642f64180aa3') too.

And this is my Greeter.abi.json

{
  "_format": "hh-sol-artifact-1",
  "contractName": "Greeter",
  "sourceName": "contracts/Greeter.sol",
  "abi": [
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "_greeting",
          "type": "string"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "inputs": [],
      "name": "greet",
      "outputs": [
        {
          "internalType": "string",
          "name": "",
          "type": "string"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "_greeting",
          "type": "string"
        }
      ],
      "name": "setGreeting",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    }
  ],
  "bytecode": "0x60806040523480156200001157600080fd5b5060405162000c3238038062000c32833981810160405281019062000037919062000278565b6200006760405180606001604052806022815260200162000c1060229139826200008760201b620001ce1760201c565b80600090805190602001906200007f92919062000156565b5050620004c5565b620001298282604051602401620000a0929190620002fe565b6040516020818303038152906040527f4b5c4277000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506200012d60201b60201c565b5050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b8280546200016490620003ea565b90600052602060002090601f016020900481019282620001885760008555620001d4565b82601f10620001a357805160ff1916838001178555620001d4565b82800160010185558215620001d4579182015b82811115620001d3578251825591602001919060010190620001b6565b5b509050620001e39190620001e7565b5090565b5b8082111562000202576000816000905550600101620001e8565b5090565b60006200021d620002178462000362565b62000339565b9050828152602081018484840111156200023657600080fd5b62000243848285620003b4565b509392505050565b600082601f8301126200025d57600080fd5b81516200026f84826020860162000206565b91505092915050565b6000602082840312156200028b57600080fd5b600082015167ffffffffffffffff811115620002a657600080fd5b620002b4848285016200024b565b91505092915050565b6000620002ca8262000398565b620002d68185620003a3565b9350620002e8818560208601620003b4565b620002f381620004b4565b840191505092915050565b600060408201905081810360008301526200031a8185620002bd565b90508181036020830152620003308184620002bd565b90509392505050565b60006200034562000358565b905062000353828262000420565b919050565b6000604051905090565b600067ffffffffffffffff82111562000380576200037f62000485565b5b6200038b82620004b4565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015620003d4578082015181840152602081019050620003b7565b83811115620003e4576000848401525b50505050565b600060028204905060018216806200040357607f821691505b602082108114156200041a576200041962000456565b5b50919050565b6200042b82620004b4565b810181811067ffffffffffffffff821117156200044d576200044c62000485565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b61073b80620004d56000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063a41368621461003b578063cfae321714610057575b600080fd5b6100556004803603810190610050919061043d565b610075565b005b61005f61013c565b60405161006c91906104b7565b60405180910390f35b6101226040518060600160405280602381526020016106e3602391396000805461009e90610610565b80601f01602080910402602001604051908101604052809291908181526020018280546100ca90610610565b80156101175780601f106100ec57610100808354040283529160200191610117565b820191906000526020600020905b8154815290600101906020018083116100fa57829003601f168201915b50505050508361026a565b8060009080519060200190610138929190610332565b5050565b60606000805461014b90610610565b80601f016020809104026020016040519081016040528092919081815260200182805461017790610610565b80156101c45780601f10610199576101008083540402835291602001916101c4565b820191906000526020600020905b8154815290600101906020018083116101a757829003601f168201915b5050505050905090565b61026682826040516024016101e49291906104d9565b6040516020818303038152906040527f4b5c4277000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610309565b5050565b61030483838360405160240161028293929190610510565b6040516020818303038152906040527f2ced7cef000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610309565b505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b82805461033e90610610565b90600052602060002090601f01602090048101928261036057600085556103a7565b82601f1061037957805160ff19168380011785556103a7565b828001600101855582156103a7579182015b828111156103a657825182559160200191906001019061038b565b5b5090506103b491906103b8565b5090565b5b808211156103d15760008160009055506001016103b9565b5090565b60006103e86103e384610581565b61055c565b90508281526020810184848401111561040057600080fd5b61040b8482856105ce565b509392505050565b600082601f83011261042457600080fd5b81356104348482602086016103d5565b91505092915050565b60006020828403121561044f57600080fd5b600082013567ffffffffffffffff81111561046957600080fd5b61047584828501610413565b91505092915050565b6000610489826105b2565b61049381856105bd565b93506104a38185602086016105dd565b6104ac816106d1565b840191505092915050565b600060208201905081810360008301526104d1818461047e565b905092915050565b600060408201905081810360008301526104f3818561047e565b90508181036020830152610507818461047e565b90509392505050565b6000606082019050818103600083015261052a818661047e565b9050818103602083015261053e818561047e565b90508181036040830152610552818461047e565b9050949350505050565b6000610566610577565b90506105728282610642565b919050565b6000604051905090565b600067ffffffffffffffff82111561059c5761059b6106a2565b5b6105a5826106d1565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b82818337600083830152505050565b60005b838110156105fb5780820151818401526020810190506105e0565b8381111561060a576000848401525b50505050565b6000600282049050600182168061062857607f821691505b6020821081141561063c5761063b610673565b5b50919050565b61064b826106d1565b810181811067ffffffffffffffff8211171561066a576106696106a2565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f830116905091905056fe4368616e67696e67206772656574696e672066726f6d202725732720746f2027257327a264697066735822122062b06e5bdee39e73f7ae7ef8606fe9f23da851629e4e297316ce7747f5074b1964736f6c634300080400334465706c6f79696e67206120477265657465722077697468206772656574696e673a",
  "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063a41368621461003b578063cfae321714610057575b600080fd5b6100556004803603810190610050919061043d565b610075565b005b61005f61013c565b60405161006c91906104b7565b60405180910390f35b6101226040518060600160405280602381526020016106e3602391396000805461009e90610610565b80601f01602080910402602001604051908101604052809291908181526020018280546100ca90610610565b80156101175780601f106100ec57610100808354040283529160200191610117565b820191906000526020600020905b8154815290600101906020018083116100fa57829003601f168201915b50505050508361026a565b8060009080519060200190610138929190610332565b5050565b60606000805461014b90610610565b80601f016020809104026020016040519081016040528092919081815260200182805461017790610610565b80156101c45780601f10610199576101008083540402835291602001916101c4565b820191906000526020600020905b8154815290600101906020018083116101a757829003601f168201915b5050505050905090565b61026682826040516024016101e49291906104d9565b6040516020818303038152906040527f4b5c4277000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610309565b5050565b61030483838360405160240161028293929190610510565b6040516020818303038152906040527f2ced7cef000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610309565b505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b82805461033e90610610565b90600052602060002090601f01602090048101928261036057600085556103a7565b82601f1061037957805160ff19168380011785556103a7565b828001600101855582156103a7579182015b828111156103a657825182559160200191906001019061038b565b5b5090506103b491906103b8565b5090565b5b808211156103d15760008160009055506001016103b9565b5090565b60006103e86103e384610581565b61055c565b90508281526020810184848401111561040057600080fd5b61040b8482856105ce565b509392505050565b600082601f83011261042457600080fd5b81356104348482602086016103d5565b91505092915050565b60006020828403121561044f57600080fd5b600082013567ffffffffffffffff81111561046957600080fd5b61047584828501610413565b91505092915050565b6000610489826105b2565b61049381856105bd565b93506104a38185602086016105dd565b6104ac816106d1565b840191505092915050565b600060208201905081810360008301526104d1818461047e565b905092915050565b600060408201905081810360008301526104f3818561047e565b90508181036020830152610507818461047e565b90509392505050565b6000606082019050818103600083015261052a818661047e565b9050818103602083015261053e818561047e565b90508181036040830152610552818461047e565b9050949350505050565b6000610566610577565b90506105728282610642565b919050565b6000604051905090565b600067ffffffffffffffff82111561059c5761059b6106a2565b5b6105a5826106d1565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b82818337600083830152505050565b60005b838110156105fb5780820151818401526020810190506105e0565b8381111561060a576000848401525b50505050565b6000600282049050600182168061062857607f821691505b6020821081141561063c5761063b610673565b5b50919050565b61064b826106d1565b810181811067ffffffffffffffff8211171561066a576106696106a2565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f830116905091905056fe4368616e67696e67206772656574696e672066726f6d202725732720746f2027257327a264697066735822122062b06e5bdee39e73f7ae7ef8606fe9f23da851629e4e297316ce7747f5074b1964736f6c63430008040033",
  "linkReferences": {},
  "deployedLinkReferences": {}
}

Solido avatar Jan 14 '22 15:01 Solido

• Flutter version 2.8.1 at .../flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 77d935af4d (il y a 4 semaines), 2021-12-16 08:37:33 -0800 • Engine revision 890a5fca2e • Dart version 2.15.1

Solido avatar Jan 14 '22 15:01 Solido

I'm on Dart 2.15.1 as well, I'll try to reproduce this with Flutter as well.

Either way, it might be easier to find differences by adding a logging layer for RPC requests to the Ethereum node:

class LoggingRpc extends RpcService {
  final RpcService inner;

  LoggingRpc(this.inner);

  factory LoggingRpc.defaults() {
    return LoggingRpc(JsonRPC('http://localhost:8545', Client()));
  }

  @override
  Future<RPCResponse> call(String function, [List? params]) async {
    print('REQ: Call $function with $params');
    final response = await inner(function, params);
    print('RES: ${response.id} = ${response.result}');
    return response;
  }
}

void main() {
  final client = Web3Client.custom(LoggingRpc.defaults());
  // ...
}

The request should be Call eth_call with [{to: 0x5fbdb2315678afecb367f032d93f642f64180aa3, data: 0xcfae3217}, latest], does that match what you're seeing?

simolus3 avatar Jan 14 '22 15:01 simolus3

Interesting points in this code

final  tx1 = await contract.setGreeting('Hello', credentials: privateKey);
final  tx2 = await contract.greet();

The first line will complete and I get an explorable Transaction. The second call fail with RangeError: Value not in range: 32

With log REQ: Call eth_call with [{to: 0x5fbdb2315678afecb367f032d93f642f64180aa3, data: 0xcfae3217}, latest] RES: 1 = 0x

Solido avatar Jan 14 '22 15:01 Solido

Also logged what the node is seeing and I get

  WARNING: Calling an account which is not a contract
  From:        0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
  To:          0x5fbdb2315678afecb367f032d93f642f64180aa3

So something fishy here no doubt

Solido avatar Jan 14 '22 15:01 Solido