trufflesuite / drizzle

Reactive Ethereum dapp UI suite
906 stars 235 forks source link

VM Exception while processing transaction: out of gas #84

Open caseyjkey opened 4 years ago

caseyjkey commented 4 years ago

If I am using Buidler EVM for my testnet, both functions work fine without gas specified. However, when I go to use truffle's testnet, truffle develop, I start getting the out of gas errors. It seems like Drizzle's automatic gas estimation is broken. I'd like this to work as it will add more complexity to explicitly estimate cost for every cacheSend.

I'd like to get Truffle working because my team is used to it, and Truffle has a more comfortable development process than Buidler.

Steps to Reproduce

  1. Clone this repo https://github.com/caseykey/the-payment-pals/.
  2. Checkout the branch 'buidler-evm'
  3. Run npm install && cd app && npm install && cd ..
  4. Run truffle develop then enter migrate
  5. In a new terminal, open the repository and run cd app && npm run start
  6. Click "Add Friend"
  7. Enter a name, i.e. Casey, and address, i.e. 0x47d0e9f0fde14b48ea9223f2e94bf2aea4ffbeaa
  8. Click "Send"

A new friend shouldn't show up, and the error should be present in the Developer Console.

The specific call is this one: await this.props.drizzle.contracts.PaymentHub.methods["addFriend"].cacheSend({ name: this.state.name, balance: 0, addy: this.state.address }, this.props.groupId);

A similar call was fixed by explicitly allowing enough gas for the transaction: drizzle.contracts.PaymentHub.methods["transaction"].cacheSend(addresses, amountsTemp, gid, {gas: 140000})

Expected behavior

The transaction succeeds and a Friend is added to the list of Friends.

Environment

Truffle versions:

Truffle v5.1.10 (core: 5.1.10)
Solidity v0.5.16 (solc-js)
Node v10.16.3
Web3.js v1.2.1
adrianmcli commented 4 years ago

truffle develop uses Ganache under the hood and Web3.js for calling methods. It sounds like this is an issue of Web3.js' default gas as well as Ganache.

caseyjkey commented 4 years ago

truffle develop uses Ganache under the hood and Web3.js for calling methods. It sounds like this is an issue of Web3.js' default gas as well as Ganache.

You're right, it is a Ganache setting, but I don't know how to fix it. I read here that "[Drizzle] will fall back to values set by your wallet, like MetaMask, or the client (geth, parity, etc.)." but then he goes on to say, "...the gas settings in the truffle.js file only affect migrations."

I only have truffle-config.js so I'm confused on how I can change the values of Ganache provided by truffle develop.

caseyjkey commented 4 years ago

Should I be estimating the cost of the transaction within my dApp, and then pass that estimation as the gas limit for the transaction?

Example:

let estimate = web3.estimate....
...cacheSend(arg1, arg2, {gas: estimate});
maasoomraj commented 4 years ago

I had the same issue but now its fixed. When using web3 the default gas usage is set to 90000 which is not enough for some transaction. This can be conquered by setting the gas while sending transaction.

For eg. await this.state.instance.methods. cacheSend().send({ from : this.state.account, gas : 1000000})

caseyjkey commented 4 years ago

I had the same issue but now its fixed. When using web3 the default gas usage is set to 90000 which is not enough for some transaction. This can be conquered by setting the gas while sending transaction.

For eg. await this.state.instance.methods. cacheSend().send({ from : this.state.account, gas : 1000000})

Yup, this is what I ended up doing as well. However, does this override any estimation provided by the wallet provider, i.e. metamask?

I am worried because I set a hard limit for a dynamic transaction. For example, my transaction method loops through the addresses provided as an argument, making changes to the blockchain for each account. To implement the fix, I set the gas limit manually while testing 4 addresses.

The user may provide more than 4 addresses and then there wouldn't be enough gas. How do I make the gas limit large enough to accommodate the number of addresses provided by a user?

Thykof commented 4 years ago

@caseyjkey, as you said, I have written a code that estimate the gas used with the web3 instance injected into the drizzle prop.

  handleSubmit(event) {
    event.preventDefault();
    const { drizzle, drizzleState } = this.props;
    const contract = drizzle.contracts.MyContract;

    const instance = new drizzle.web3.eth.Contract(contract.abi, contract.address);
    instance.methods.createGame(
// insert contract function parameters here 
)
    .estimateGas()
    .then(gasAmount => {
      const stackId = contract.methods.createGame.cacheSend(
// insert contract function parameters here 
        { from: drizzleState.accounts[0], gas: gasAmount }
      );
      // save the `stackId` for later reference
      this.setState({ stackId });
    })
    .catch(error => {
        console.log(47, error);
    });
  }

I had the same problem and this solution solve it.

caseyjkey commented 4 years ago

@caseyjkey, as you said, I have written a code that estimate the gas used with the web3 instance injected into the drizzle prop.

  handleSubmit(event) {
    event.preventDefault();
    const { drizzle, drizzleState } = this.props;
    const contract = drizzle.contracts.MyContract;

    const instance = new drizzle.web3.eth.Contract(contract.abi, contract.address);
    instance.methods.createGame(
// insert contract function parameters here 
)
    .estimateGas()
    .then(gasAmount => {
      const stackId = contract.methods.createGame.cacheSend(
// insert contract function parameters here 
        { from: drizzleState.accounts[0] }
      );
      // save the `stackId` for later reference
      this.setState({ stackId });
    })
    .catch(error => {
        console.log(47, error);
    });
  }

I had the same problem and this solution solve it.

I was expecting you would use the gasAmount within the following object: { from: drizzleState.accounts[0] }, but you didn't. Where do you use the estimated gas amount?

Thykof commented 4 years ago

Right, my bad, I have edited the comment.

kader46 commented 3 years ago

Hello ! i'm new to ethereum and i'm having this problem ! RPCError: got code -32000 with msg "VM Exception while processing transaction: out of gas". Any Solutions ?!!

mx51damon commented 2 years ago

increase gas value works for me, better using Remix suggested value: image