3

I'm facing a little issue here, that's the mintTo function from contract for NFT. Which I require the sender to send a value with >= 0.1 Ether:

pragma solidity ^0.5.0;


import "./TradeableERC721Token.sol";
import "openzeppelin-solidity/contracts/ownership/Ownable.sol";

/**
 * @title Creature
 * Creature - a contract for my non-fungible creatures.
 */
contract Creatures is TradeableERC721Token {
  constructor(address _proxyRegistryAddress) TradeableERC721Token("Creatures", "CRE", _proxyRegistryAddress) public {  }


  function baseTokenURI() public view returns (string memory) {
    return "https://metadata-link.com/api/tokens/";
  }
}


pragma solidity ^0.5.0;

import 'openzeppelin-solidity/contracts/token/ERC721/ERC721Full.sol';
import 'openzeppelin-solidity/contracts/ownership/Ownable.sol';
import './Strings.sol';

 contract TradeableERC721Token is ERC721Full, Ownable {
  using Strings for string;

  address proxyRegistryAddress;
  uint256 private _currentTokenId = 0;

  constructor(string memory _name, string memory _symbol, address _proxyRegistryAddress) ERC721Full(_name, _symbol) public {
    proxyRegistryAddress = _proxyRegistryAddress;
  }


  /**
      * @dev Mints a token to an address with a tokenURI.
      * @param _to address of the future owner of the token
      */
  function mintTo(address _to) public payable {
    require(msg.value >= 0.1 ether);
    address contractOwner = owner();
    address(uint160(contractOwner)).transfer(msg.value);
    uint256 newTokenId = _getNextTokenId();
    _mint(_to, newTokenId);
    _incrementTokenId();
  }

  /**
    * @dev calculates the next token ID based on value of _currentTokenId 
    * @return uint256 for the next token ID
    */
  function _getNextTokenId() private view returns (uint256) {
    return _currentTokenId.add(1);
  }

  /**
    * @dev increments the value of _currentTokenId 
    */
  function _incrementTokenId() private  {
    _currentTokenId++;
  }

  function baseTokenURI() public view returns (string memory) {
    return "";
  }

  function tokenURI(uint256 _tokenId) external view returns (string memory) {
    return Strings.strConcat(
        baseTokenURI(),
        Strings.uint2str(_tokenId)
    );
  }

  /**
   * Override isApprovedForAll to whitelist user's OpenSea proxy accounts to enable gas-less listings.
   */
  function isApprovedForAll(
    address owner,
    address operator
  )
    public
    view
    returns (bool)
  {
    // Whitelist OpenSea proxy contract for easy trading.
    ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress);
    if (address(proxyRegistry.proxies(owner)) == operator) {
        return true;
    }

    return super.isApprovedForAll(owner, operator);
  }
}

And Then from the client I use [email protected] to call mintTo function:

    const web3 = window.web3;

    const nftContract = new web3.eth.Contract(NFT_ABI, NFT_CONTRACT_ADDRESS, { gasLimit: "1000000" });

    const minterAccount = await web3.eth.getAccounts();
    const minter = minterAccount[0];
    const result = await nftContract.methods.mintTo(minter).send({
      from: minter,
      value: web3.utils.toWei("0.1", "ether"),
      gas: "25000",
    })
      .on('error', (err) => {
        if (err) {
          console.log(err);
        }
      });

Then, I get this error:


Error: "Transaction ran out of gas. Please provide more gas:
{
  "blockHash": "0x9b477437e6fef51a85f0700099d4b765b199bc412dcbd912daacdfc3b1337140",
  "blockNumber": 6207136,
  "contractAddress": null,
  "cumulativeGasUsed": 139877,
  "from": "0x34b8d058df685de17c64b46248d4794ff87bb458",
  "gasUsed": 21678,
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "status": false,
  "to": "0x5b40cde4bde153fef88ba435cf18d7433b4113f8",
  "transactionHash": "0xe9af511d933eca45d633799eada763950fee7d622c7f5b49601058fc96ed8ca8",
  "transactionIndex": 4,
  "events": {}
}"

I've changed send options to:

    const result = await nftContract.methods.mintTo(minter).send({
      from: minter,
      value: web3.utils.toWei("0.1", "ether"),
      gasLimit: "25000",
    })
      .on('error', (err) => {
        if (err) {
          console.log(err);
        }
      });

// And

   const result = await nftContract.methods.mintTo(minter).send({
      from: minter,
      value: web3.utils.toWei("0.1", "ether"),
      gas: 25000,
    })
      .on('error', (err) => {
        if (err) {
          console.log(err);
        }
      });

Also got the same error, I did my search but didn't figured out where is the issue from. Thanks for Help.

12
  • You obviously need to provide more than 25000 gas for executing this function. Mar 27, 2020 at 4:35
  • And BTW, what's the point in address(uint160(contractOwner)) when contractOwner is already an address type??? Mar 27, 2020 at 4:37
  • I've tried to change the gas many times to more higher than 25000 but get the same error also!!
    – penguin
    Mar 27, 2020 at 10:26
  • I've added address(uint160()) to be able to change it to payable account and then can receive the value
    – penguin
    Mar 27, 2020 at 10:27
  • Post the entire contract, so we can give it a try. Mar 27, 2020 at 10:37

2 Answers 2

0

Error: "Transaction ran out of gas. Please provide more gas:

This happens when you want to execute a transaction that requires X amount of gas for successful execution but you send gas less than X.

Solution:

  • On Ganache: the default gasLimit is 6721975 you can pass that value as the gasLimit for the execution of your transaction.
  • On other networks say Ropsten, Rinkeby, Kovan, Goerli etc you can use web3's estimateGas function to get a rough idea about how much gas will your transaction take for its successful execution
Example: 
    const Web3 = require('web3');
    const web3 = new Web3(new Web3.providers.HttpProvider("http://SERVER_IP:PORT"));

    web3.eth.estimateGas(callObject [, callback])

    web3.eth.estimateGas({
    to: "0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe",
    data: "0xc6888fa10000000000000000000000000000000000000000000000000000000000000003"
    })
    .then(console.log);
    > "0x0000000000000000000000000000000000000000000000000000000000000015"

In order to be on the safer side pass a value which is greater than the output of estimateGas

Web3 estimateGas API

2
  • 6721975 is most likely already many times more than he needs for this function to execute (unless there is a lot that we don't know about the call-tree inside it). In addition to that, he already write in a comment that he's tried to change the gas many times to more higher than 25000 but still getting the same error. Mar 27, 2020 at 10:36
  • I've tried nftContract.methods.mintTo.estimateGas() and it outputs '21678', then I changed gas: 21678 and changed it many times with higher than that but still get the same error.
    – penguin
    Mar 27, 2020 at 11:31
0

All type of Ethereum transaction requires gas. When we make the transaction, we can set the gas limit so that the transaction use the gas to the limit. If the transaction requires more gas than gas limit, then the EVM revert the transaction. This helps users not to use too much transaction fee for the transaction.

Anyway, the reason why you faced the error is because you set low gas fee for the transaction.

Normal ether send transaction require 21000 gas and normal mint requires about 43000(or may require much more). So for the perfect transaction, I would like you to set the gas limit as 1000000. And also, seems like you did not set the transaction type and priority fees.

So the send code must be like this.

const result = await nftContract.methods.mintTo(minter).send({
  from: minter,
  value: web3.utils.toWei("0.1", "ether"),
  gasLimit: "1000000",
  type: 2,
  maxPriorityFeePerGas: web3.utils.toWei("1", "gwei"),
  maxFeePerGas: web3.utils.toWei("50", "gwei"),
})
  .on('error', (err) => {
    if (err) {
      console.log(err);
    }
  });

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.