ethers-io / ethers.js

Complete Ethereum library and wallet implementation in JavaScript.
https://ethers.org/
MIT License
7.93k stars 1.84k forks source link

Support for loose JSON-RPC providers (e.g. TestRPC) #45

Closed padelagani closed 6 years ago

padelagani commented 6 years ago

While calling a function provider.getTransaction it throws an error invalid hexlify value.

Following transaction hash I got while creating transaction Hash: 0x38796338be290d9733a362ae609bd507b9625a86b4262898c12715dcbaaf38c3

But while fetching transaction details gets the following error error

ricmoo commented 6 years ago

Hey @padelagani!

Which Provider are you using and would you mind providing the transaction hash?

Looks like the provider is returning a weird value for the data.

padelagani commented 6 years ago

@ricmoo I am using JsonRpcProvider

And calling following api for doing transaction provider.sendTransaction

ricmoo commented 6 years ago

So, you are connecting to a local Ethereum node then?

Are you using Parity or Geth?

Can you provider a quick code snippet? Make sure you redact any private keys. You can also send the details to support@ethers.io if you'd prefer not publish it on a GitHub issue.

ricmoo commented 6 years ago
/Users/ethers> ethers --testnet
testnet> p = new providers.InfuraProvider(true);
InfuraProvider {
  ensAddress: '0x112234455c3a32fd11230c42e7bccd4a84e02010',
  testnet: true,
  chainId: 3,
  _events: {},
  resetEventsBlock: [Function],
  url: 'https://ropsten.infura.io/',
  apiAccessToken: null }
testnet> privateKey = [ redacted ];
testnet> wallet = new Wallet(privateKey, provider)
Wallet {
  privateKey: [ redacted ],
  provider: [Getter/Setter],
  defaultGasLimit: [Getter/Setter],
  address: '0x14791697260E4c9A71f18484C9f997B308e59325',
  sign: [Function] }
testnet> tx = wallet.sign({ to: wallet.address, nonce: 5, value: 1, gasPrice: 100000000000, gasLimit: 21000 })
'0xf8640585174876e8008252089414791697260e4c9a71f18484c9f997b308e59325018029a0a5d15299f6b83c46b6dc3be4183e50aa22e71640fa0ca9b5adba9182df19496da03317e2d274dfa90947f3a57a0e5b8fbb3e56df427d2bdec39edfe0eb718d096b'
testnet> p.sendTransaction(tx)
Resolved:
'0x4572f3ec2d27b079d0108c6d2bc03fcf01625624f50e067e8f7c7267c032dfba'
testnet> txid = _
'0x4572f3ec2d27b079d0108c6d2bc03fcf01625624f50e067e8f7c7267c032dfba'
testnet> p.getTransaction(txid)
Resolved:
{ hash: '0x4572f3ec2d27b079d0108c6d2bc03fcf01625624f50e067e8f7c7267c032dfba',
  blockHash: '0x8147b11bb51bdb2d22593bb16c4de6e0a4ce424e444fa3b0cd379bb5316c4d3f',
  blockNumber: 1949760,
  transactionIndex: 0,
  from: '0x14791697260E4c9A71f18484C9f997B308e59325',
  gasPrice: BigNumber { _bn: <BN: 174876e800> },
  gasLimit: BigNumber { _bn: <BN: 5208> },
  to: '0x14791697260E4c9A71f18484C9f997B308e59325',
  value: BigNumber { _bn: <BN: 1> },
  nonce: 5,
  data: '0x',
  r: '0xa5d15299f6b83c46b6dc3be4183e50aa22e71640fa0ca9b5adba9182df19496d',
  s: '0x3317e2d274dfa90947f3a57a0e5b8fbb3e56df427d2bdec39edfe0eb718d096b',
  v: 41,
  creates: null,
  raw: '0xf8640585174876e8008252089414791697260e4c9a71f18484c9f997b308e59325018029a0a5d15299f6b83c46b6dc3be4183e50aa22e71640fa0ca9b5adba9182df19496da03317e2d274dfa90947f3a57a0e5b8fbb3e56df427d2bdec39edfe0eb718d096b',
  networkId: 3 }
padelagani commented 6 years ago

@ricmoo Yes I am connecting to local Ethereum node (Using testrpc - https://github.com/ethereumjs/testrpc)

Following is the code snippet

var ethers = require('ethers');

var providers = ethers.providers;
var Wallet = ethers.Wallet;
var utils = ethers.utils;

var provider = new providers.JsonRpcProvider('http://localhost:8545', 'ropsten');

var address1 = '0x290073a0c6e50fbb58031338ef7da5830e457850';
var address2 = '0x3a4861c9dac5ff2a6c4292df967663efe9f62683';

var privateKey = "0x02DE9C7D0CB5AEA1085385A873ACB9580BEACC1C46E97FE97084B690FBD42DFC"; // Private Key of address1
var wallet = new Wallet(privateKey);

console.log('Address: ' + wallet.address);

var transaction = {
  nonce: 0,
  gasLimit: 21000,
  gasPrice: utils.bigNumberify("0"),

  to: address2,

  value: utils.parseEther("2.0"),
  data: "0x",

  // This ensures the transaction cannot be replayed on different networks
  chainId: providers.Provider.chainId.ropsten
};

var signedTransaction = wallet.sign(transaction);

console.log(signedTransaction);

// This can now be sent to the Ethereum network
provider.sendTransaction(signedTransaction).then(function (hash) {
  console.log('Hash: ' + hash);
  // Hash:

  provider.getTransaction(hash).then(function (transaction) {
    console.log(transaction);
  });

  provider.getTransactionReceipt(hash).then(function (transactionReceipt) {
    console.log(transactionReceipt);
  });
}).catch(function (err) {
  console.log(err);
});
ricmoo commented 6 years ago

Ah! I have a custom version of TestRPC in a package called ethers-cli, but it is not ready for general use yet. It is also for more specific uses.

The problem is that TestRPC isn't fully standards compliant. I will update the provider though to be more lenient with loose providers. I probably won't get to that until tomorrow afternoon though.

ricmoo commented 6 years ago

I've reproduced the issue. TestRPC doesn't return the signature (r, s or v) nor a raw, so when ethers tries to compute the raw transaction, it fails.

I will have ethers skip computing raw if there are any missing transaction fields.

There is another issue with TestRPC I also just found; I will open an issue with them. The input is returned 0x0 (instead of 0x), so the data won't be correct for null-data transactions.

padelagani commented 6 years ago

@ricmoo Thank you!

So should I wait or try an alternative for this. If you can suggest an alternative to use.

padelagani commented 6 years ago

@ricmoo Can you suggest an alternative ?

ricmoo commented 6 years ago

An alternative to TestRPC? I usually just use Ropsten or Rinkeby.

If you are feeling experimental, try npm install -g ethers-cli. There are no docs yet, but you can try out:

var build = require(“ethers-cli”);
var builder = new build.TestBuilder();
var accounts = builder.accounts;
var provider = builder.provider;

The providers state is reset every time though, it doesn’t run persistent like the CLI of TestRPC.

Otherwise, tomorrow afternoon (GMT-5) there should be a fixed version of the ethers Provider up. :)

ricmoo commented 6 years ago

The test cases are running locally right now, then I will push and once the Travis CI tests have passed, I will publish to NPM.

ricmoo commented 6 years ago

Added in https://github.com/ethers-io/ethers.js/commit/e4c455bdb61112af75ad123bc0f6f53ad6ae5145.

ricmoo commented 6 years ago

Published to npm as ethers-providers 2.1.5. Updating ethers (the umbrella package) will get this latest version.

Thanks! Let me know if there are any further issues.

padelagani commented 6 years ago

@ricmoo Thank you!! There's an issue with this function as well if you can address it

provider.getTransactionReceipt(transactionHash).then(function(transactionReceipt) {
    console.log(transactionReceipt);
});

error

ricmoo commented 6 years ago

Thanks. I’ll look into that tomorrow. Probably a similar issue for receipts...

Re-opening to track.

padelagani commented 6 years ago

@ricmoo Any updates ??

ricmoo commented 6 years ago

I have completed the test cases and reproduced the issue and have a fix in place locally.

There are a few differences since the hard-fork I’m adding some extra testing and updating the receipt parsing for. root has been removed and status has been added.

I should finish this tomorrow on the plane along with ABI v2.

padelagani commented 6 years ago

Ok, thanks

ricmoo commented 6 years ago

This should be fixed now. In https://github.com/ethers-io/ethers.js/commit/883522565579df6e2a49e268d3643f3b21f1f783.

Thanks! Please re-open this issue if you still have problems with 2.1.7.

tyler17 commented 6 years ago

Edit: this was fixed updating to Ethers 3.0.15

@ricmoo Similarly, I'm getting the invalid hexlify value error when calling getTransactionReceipt() connected to a local node using Ganache (previously called TestRPC) -What's different from the above situation is that I'm using the Web3Provider (new ethers.providers.Web3Provider) rather than JsonRpcProvider -running Ethers version 2.2.6 -When using Kovan, getTransactionReceipt works as intended

Here's the full error log: { Error: invalid hexlify value at throwError (/node_modules/ethers-utils/throw-error.js:4:17) at Object.hexlify [as logsBloom] (node_modules/ethers-utils/convert.js:157:5) at check (node_modules/ethers-providers/provider.js:44:36) at checkTransactionReceipt (/node_modules/ethers-providers/provider.js:313:18) at /node_modules/ethers-providers/provider.js:781:44 at <anonymous> at process._tickCallback (internal/process/next_tick.js:188:7) name: undefined, input: undefined, checkKey: 'logsBloom', checkValue: undefined }