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

Investigate: provider.waitForTransaction not working with TestRPC #67

Closed mirek closed 6 years ago

mirek commented 6 years ago

I'm having problems with getting an address of deployed contract, is there something silly I'm doing here?


const ethers = require('ethers');
const TestRpc = require("ethereumjs-testrpc");

const wallet = ethers.Wallet.createRandom();

const port = 8546;

const testRpc = TestRpc.server({
  port,
  logger: console,
  blocktime: 0.5,
  network_id: 15,
  unlocked_accounts: [ wallet.address ],
  accounts: [{
    balance: '8000000000000000000000000000000000000000000000000000000000000000',
    secretKey: wallet.privateKey
  }]
});

// pragma solidity ^0.4.15;
//
// contract HelloWorld {
//   function helloWorld() public pure returns (string) {
//     return "hello world!";
//   }
// }

const bytecode = '0x6060604052341561000f57600080fd5b6101578061001e6000396000f300606060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c605f76c14610046575b600080fd5b341561005157600080fd5b6100596100d4565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561009957808201518184015260208101905061007e565b50505050905090810190601f1680156100c65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6100dc610117565b6040805190810160405280600c81526020017f68656c6c6f20776f726c64210000000000000000000000000000000000000000815250905090565b6020604051908101604052806000815250905600a165627a7a72305820d8b2159004f129414fcf03d4bf32f4f1a664fa8ef8dd4636652436a18acd988e0029';

const abi = '[{"constant":true,"inputs":[],"name":"helloWorld","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"}]';

async function main() {

  // Start testRpc.
  await new Promise((resolve, reject) => testRpc.listen(port, err => err ? reject(err) : resolve()));

  const deployTransaction = ethers.Contract.getDeployTransaction(bytecode, abi);
  console.log(deployTransaction);

  // Connect to the network.
  const provider = new ethers.providers.JsonRpcProvider(`http://localhost:${port}`, { chainId: 15 });

  // Set wallet's provider.
  wallet.provider = provider;

  const sendResult = await wallet.sendTransaction(deployTransaction);
  console.log(sendResult);

  // ...testRpc logs...
  // Transaction: 0x135e04955eab95f04eb567f3782ea399b0149228fc60495a68657c348d64ad0b
  // Contract created: 0x0d46e8bf9808db5030a20a886f811ffc182c72fd
  // Gas usage: 142532
  // Block Number: 1
  // Block Time: Mon Nov 13 2017 23:55:47 GMT+0000 (GMT)

  // But this never resolves...
  const waitResult = await provider.waitForTransaction(sendResult.hash, 10 * 1000);
  console.log(waitResult);

  // ...instead logs:
  // (node:85556) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: invalid address
  // (node:85556) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
  // (node:85556) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: invalid address
  // Error: timeout
  //     at Timeout._onTimeout (/project/node_modules/ethers-providers/provider.js:611:24)
  //     at ontimeout (timers.js:488:11)
  //     at tryOnTimeout (timers.js:323:5)
  //     at Timer.listOnTimeout (timers.js:283:5)

  // Stop testRpc.
  testRpc.close();

}

main()
  .then(() => console.log('done.'))
  .catch(err => console.error(err.stack));
ricmoo commented 6 years ago

Several people have been reporting issues with waitForTransaction, but I have been unable to reproduce it so far. I will try out your example shortly, hopefully it will help narrow down the cause.

Based on your error, I wonder if it is related to the response from TestRPC. Does it fail against Ropsten too? No worries if you don't know, I'll experiment.

ricmoo commented 6 years ago

One other note though, you can compute the contract address using:

// sendResult is the transaction object returned from wallet.sendTransaction
var contractAddress = ethers.utils.getContractAddress(sendResult);
mirek commented 6 years ago

Thanks @ricmoo getting an address is great workaround for this. Of course it would be nice to have working waitForTransaction.

ricmoo commented 6 years ago

Fixed in https://github.com/ethers-io/ethers.js/commit/5a837e1b0a5956d454c05a4c501039034557dd3b.

I will update this ticket once Travis CI is complete and the package has been published to npm.

ricmoo commented 6 years ago

This should be fixed now in ethers-providers 2.1.11. If you blow away package-lock.json and 'node_modules/and do annpm install` it should all be peachy now, in TestRPC.