web3 / web3.js

Collection of comprehensive TypeScript libraries for Interaction with the Ethereum JSON RPC API and utility functions.
https://web3js.org/
Other
19.34k stars 4.96k forks source link

"Transaction has been reverted by the EVM" deploying contract with version higher than 1.0.0-beta.46 #2560

Closed iccicci closed 5 years ago

iccicci commented 5 years ago

Description

Even if following the doc, I get the error in subject if I try to use a Web3 version higher than 1.0.0-beta.46

Expected behavior

Simply "42" as output.

Actual behavior

With version "1.0.0-beta.46": simply "42" as output. With version higher that "1.0.0-beta.46" (beta[47, 50] when I write) following error:

Deploying contract Error: Transaction has been reverted by the EVM:
{
  "transactionHash": "0x529b02d61d0484ab9229eec76583bfa10b712f8fa9158f9683282c008edef315",
  "transactionIndex": 0,
  "blockHash": "0x8ff40212e949b855054da8255ee93eff718360ad030f7230bb4a8be515931512",
  "blockNumber": 12,
  "from": "0x993505074674e20472e6a501ef1219f2df7d6e7e",
  "to": null,
  "gasUsed": 103535,
  "cumulativeGasUsed": 103535,
  "contractAddress": "0x42E96A5Ff0801BC0A45b66344cBCfF8a80Aa2F7A",
  "logs": [],
  "status": true,
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "v": "0x1b",
  "r": "0x4e4e887da0d461dcefda452f2953eed8797f5a2f9dcd8d0092bee6b23b466a0f",
  "s": "0x0ceb42646f3bc220bb8a14d6df25fb84e3961940a000e9dd6d0c54a5f74ad00e"
}

Steps to reproduce the behavior

In an empty directory create following two files:

package.json

{
    "name": "report",
    "version": "0.0.0",
    "description": "report",
    "engines": {
        "node": ">=8.0"
    },
    "license": "MIT",
    "dependencies": {
        "web3": "1.0.0-beta.50",
        "ganache-cli": "6.4.1"
    }
}

report.js

"use strict";

const cp = require("child_process");
const fs = require("fs");
const bc = cp.spawn("./node_modules/.bin/ganache-cli");
const Web3 = require("web3");

// read the relevant part of solc output
const input = JSON.parse(fs.readFileSync(0, "utf-8")).contracts["<stdin>:x"];
const abi = JSON.parse(input.abi);

bc.on("error", err => console.log("Launching ganache-cli", err, process.nextTick(process.exit.bind())));
bc.stdout.on("data", data => {
  // ganache-cli is ready to accept commands
  if(data.toString().indexOf("Listening") !== -1) {
    const end = bc.kill.bind(bc);
    const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

    web3.eth.getAccounts((err, accounts) => {
      if(err) return console.log("Getting accounts", err, end());

      const tx = new web3.eth.Contract(abi).deploy({ arguments: [], data: input.bin }).send({ from: accounts[0], gas: 4700000, gasPrice: "30000000000" });

      tx.on("error", err => console.log("Deploying contract", err, end()));
      tx.on("receipt", receipt => {
        const contract = new web3.eth.Contract(abi, receipt.contractAddress);

        contract.methods.g(21).call({}, (err, res) => {
          if(err) return console.log("Calling 'g(21)'", err, end());

          console.log(res.ret);
          end();
        });
      });
    });
  }
});

Then issue following two commands:

$ npm instal
$ echo 'contract x { constructor() public {} function g(uint32 a) public pure returns(uint32 ret) { ret = a + 21; } }' | solc - --combined-json abi,bin | node report.js

Please note the the reason I'm reporting the problem here is that only changing Web3 version to "1.0.0-beta.46" everything works as expected.

Versions

Thank you all, iCC

fireblockdev commented 5 years ago

I can confirm that ganache doesn't work for version 48,49,50. A single operation like this crashes:

    await web3.eth.sendTransaction({from: ACCOUNTS[0], to: ACCOUNTS[1], value: 1})

This code was working until beta 37. Versions 37-46 were incompatible with ganache.

nivida commented 5 years ago

@iccicci Thanks for opening this issue! I've checked it and ganache is returning an invalid value in the status property. As documented in the JSON-RPC API of geth and parity should the status field contain a hex string and not a boolean.

@fireblockdev Web3.js is using the eth_chainId JSON-RPC method to determine the chain id of the actual connected chain and ganache doesn't have it implemented until now (I've informed them). The eth_chainId implementation got merged on the 08.18.2017 in geth and parity merged it on the 09.26.2017.

Because of this do I close this issue and ask you to open a new one in the ganache repository.

iccicci commented 5 years ago

Thank you very much for your extremely fast reaction, guys!

iccicci commented 5 years ago

It seems there already is a issue tracking that: https://github.com/trufflesuite/ganache-core/issues/339 @nivida can you please confirm it's actually what's missed in ganache to solve my case?

Thank you again, iCC

iheqi commented 5 years ago

So how to solve it, wait ganache fix?

iheqi commented 5 years ago

@nivida Hi nivida, why I deploy contract to infura got the same error, is infura use ganache too?

deploy.js:

const path = require('path');
const Web3 = require('web3');
const HdWalletProvider = require('truffle-hdwallet-provider'); 

const Imooc = require(path.resolve(__dirname, '../src/compiled/Imooc.json'));

const mnemonic = 'xxxxxx';
const url = 'https://ropsten.infura.io/v3/xxxxxx';
const provider = new HdWalletProvider(mnemonic, url);

const web3 = new Web3(provider);

(async () => {
  const accounts = await web3.eth.getAccounts();
  console.log('合约部署的账号: ', accounts[0]);

  const courseList = await new web3.eth.Contract(Imooc.CourseList.abi, accounts[0]);

  const result = await courseList.deploy({
    data: Imooc.CourseList.evm.bytecode.object
  })
  .send({
    from: accounts[0],
    gas: 5000000
  });  
  console.log('合约部署到的地址:', result.options.address);
})();
SwissArmyBud commented 5 years ago

@iccicci There are two specific issues here, one is an internal posting error and the other is Ganache failing to deal with eth_chainId correctly. The two references (issue/PR) above this post have more information about the "reverted by EVM" problem.