Out of gas while migrating a contract

2019-07-12 03:27发布

问题:

I have looked at the other "out of gas" SO posts and they haven't solved my problem. I am using ganache-cli started with

ganache-cli  --account="0xce2ddf7d4509856c2b7256d002c004db6e34eeb19b37cee04f7b493d2b89306d, 2000000000000000000000000000000"

I then execute

truffle migrate --reset

It returns with an error

Error encountered, bailing. Network state unknown. Review successful transactions manually.
Error: VM Exception while processing transaction: out of gas

(Full error is at the end) These are the files involved;

truffle.js

module.exports = {
   networks: {
   development: {
   host: "localhost",
   port: 8545,
   network_id: "*",
   gas: 470000
  }
 }
};

1_initial_migration.js

var Migrations = artifacts.require("./Migrations.sol");

module.exports = function(deployer) {
  deployer.deploy(Migrations,  {gas: 4500000});
};

2_deploy_contracts.js

var Voting = artifacts.require("./Voting.sol");

module.exports = function(deployer){
    deployer.deploy(Voting, ['Rama', 'Nick', 'Jose'], {gas: 290000});

}

Voting.sol

pragma solidity ^0.4.18;

contract Voting {

  mapping (bytes32 => uint8) public votesReceived;
  bytes32[] public candidateList;

  function Voting(bytes32[] candidateNames) public {
    candidateList = candidateNames;
  }

  function totalVotesFor(bytes32 candidate) view public returns (uint8) {
    require(validCandidate(candidate));
    return votesReceived[candidate];
  }

  function voteForCandidate(bytes32 candidate) public {
    require(validCandidate(candidate));
    votesReceived[candidate]  += 1;
  }

  function validCandidate(bytes32 candidate) view public returns (bool) {
    for(uint i = 0; i < candidateList.length; i++) {
      if (candidateList[i] == candidate) {
        return true;
      }
    }
    return false;
   }
}

Full error

Replacing Migrations...
... 0xaf3b7d40ac17f297a4970b75e1cc55659e86dea3ba7bcf13dd9f82e2b6cf0086
Migrations: 0x1ea6ea9d7528a8ac4b378ae799d2c38fe006b9b6
Saving successful migration to network...
... 0xa8400e873da3cb15719c2c31804ec558e73aa9bfa91c4dc48e922c0ed0db736f
Saving artifacts...
Running migration: 2_deploy_contracts.js
Deploying Voting...
... 0x72947eda435cf854abeeeb5483c9625efad45b664f3bcc7c2085f8aabdbb1076
Error encountered, bailing. Network state unknown. Review successful transactions manually.
Error: VM Exception while processing transaction: out of gas
at Object.InvalidResponse (C:\Users\Paul\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\errors.js:38:1)
at C:\Users\Paul\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\requestmanager.js:86:1
at C:\Users\Paul\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\truffle-migrate\index.js:225:1
at C:\Users\Paul\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\truffle-provider\wrapper.js:134:1
at XMLHttpRequest.request.onreadystatechange (C:\Users\Paul\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\httpprovider.js:128:1)
at XMLHttpRequestEventTarget.dispatchEvent (C:\Users\Paul\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\xhr2\lib\xhr2.js:64:1)
at XMLHttpRequest._setReadyState (C:\Users\Paul\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\xhr2\lib\xhr2.js:354:1)
at XMLHttpRequest._onHttpResponseEnd (C:\Users\Paul\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\xhr2\lib\xhr2.js:509:1)
at IncomingMessage.<anonymous> (C:\Users\Paul\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\xhr2\lib\xhr2.js:469:1)
at emitNone (events.js:91:20)

回答1:

The error message is correct. You're not sending enough gas for contract creation.

When you deploy a contract, gas is consumed for 3 different phases of the deployment:

  • Intrinsic gas: This is the baseline amount used in any transaction. For all transactions, there is an initial cost of 21,000 gas. For contract creation, there is an additional 32,000. Therefore, before anything is actually done for deployment, you're already in for 53,000 gas.
  • Constructor execution: This is the gas used for the OPCODES executed by your constructor. I deployed this contract on Rinkeby and you can see all of the OPCODES for constructor execution, and their costs, here. This portion consumed 81,040 in gas.
  • Contract code storage: Finally, you have the cost of storing your contract code. If you look at gas estimation tools, this is referred to as the "code deposit". This costs 200 gas for every byte of runtime contract code stored. To get the size of your contract code, run solc --optimize Voting.sol --bin-runtime -o . and look at the size of the resulting file. Your contract is 1116 bytes (I'm using solc version 0.4.19, so your size on .18 may be slightly different), which results in 223,200 gas consumed.

In total, this comes out to 357,240 gas, so your 290,000 limit is too low (The actual contract run on Rinkeby consumed 351,640 gas. Again, I believe the small discrepancy is due to slight differences in compiler version output. I'm not 100% sure of this, but the difference is small enough - effectively 28 bytes of contract code - that I didn't dig deeper to find the underlying reason).

There's a great write up on HackerNoon that goes into detail of each calculation with an example.



回答2:

If anyone else is getting the error:

Error encountered, bailing. Network state unknown. Review successful transactions manually.
Error: VM Exception while processing transaction: out of gas

Delete the ./build directory and enable the solc optimizer in truffle.js:

module.exports = {
    networks: {
        development: {
            host: "localhost",
            port: 8545, // Using ganache as development network
            network_id: "*",
            gas: 4698712,
            gasPrice: 25000000000
        }
    },
    solc: {
        optimizer: {
            enabled: true,
            runs: 200
        }
    }
};


标签: ethereum