1

My contract;

contract My721 is ERC721Full, ERC721Mintable, Ownable {

    constructor() ERC721Full("My721", "MY721") public {}

    function mintUniqueTokenTo (address _to, uint256 _tokenId, string  _tokenURI) public{        
        super.mint(_to, _tokenId);        
        super._setTokenURI(_tokenId, _tokenURI);
    }
}

I tried to run my own node script;

my721Instance.methods.mintUniqueTokenTo(...)
    .estimateGas()
    .then(function(estimate) {
        console.log("Estimated Gas Consumptions: ", estimate);           
});

I got;

(node:27428) UnhandledPromiseRejectionWarning: TypeError: my721Instance.methods.mintUniqueTokenTo is not a function

Fyi, I successfully ran the transaction in truffle console. Any idea?

  • As the error says, my721Instance.methods.mintUniqueTokenTo is not a function. If that's unexpected to you and you need help figuring out why that happened, you'll need to share the code that defines my721Instance. – smarx Jan 5 at 18:36
  • I used openzeppelin-solidity library to code My721 contract as shown above. I also checked the My721.json and console.log(my721Instance.methods). And yes there is mintUniqueTokenTo function. Also the function works but when I tried to use with estimateGas() it gave the error. – Cryptocert Thuleen Jan 5 at 19:48
  • The error is in JavaScript, so the Solidity code is irrelevant. You claim that my721Instance.methods.mintUniqueTokenTo is a function, but the JavaScript interpreter believe differently. You need to figure it why there's a discrepancy. (I can't help without code.) – smarx Jan 5 at 19:52
2

Following is a complete test which you can replicate using Node on your development machine. This test will require access to a web3 provider. I am using Infura which you will a password to use.

The mint function is not part of the ERC-721 standard but there is an example of a mint implementation in the ERC-721 reference implementation.

Dependencies

Install this minimal file as package.json:

{
  "dependencies": {
    "@0xcert/ethereum-erc721": "^2.0.0-rc1",
    "web3": "^1.0.0-beta.36"
  }
}

Then run npm install.

Note: recent versions of Web3 have various issues. The code below was tested and confirmed working with version ^1.0.0-beta.36.

Test suite

Install this file as estimate.js:

const Web3 = require("web3");
const web3 = new Web3(new Web3.providers.HttpProvider('https://ropsten.infura.io/' + INFURA_PASSWORD));

// Test specimen
const nftAddr = '0xd8bbf8ceb445de814fb47547436b3cfeecadd4ec'; // https://github.com/0xcert/ethereum-erc721#playground
const nftArtifacts = require("@0xcert/ethereum-erc721/build/nf-token-mock.json"); // Standards compliant implementation plus publicly accessible mint & burn
const nftContract = new web3.eth.Contract(nftArtifacts.NFTokenMock.abi, nftAddr);

// Test parameters
const randomEthereumAddress = nftAddr; // TODO: improve this
const randomTokenID = 42; // TODO: improve this

// Test procedure
nftContract.methods
  .mint(randomEthereumAddress, randomTokenID)
  .estimateGas()
  .then(function (estimate) {
    console.log("Estimated gas to execute mint: ", estimate);
  });

Now you may perform the test case by running npm estimate.js.

Estimated gas to execute mint: 66791

Discussion

Your estimate gas test will return a different gas value if you use a different implementation of the non-fungible token contract or if certain circumstances change on your network (all deployed code and storage). Following are some particular circumstances to check:

  • Does the mint recipient already own any tokens? This matters with ERC721Enumerable.
  • Was this token ID already minted?
  • Does your mint implementation call onERC721Received on the recipient?
  • If it does call, does the recipient throw?
0

Below is my node script ("check.js"):

require("dotenv").config();
const Web3 = require("web3");
var fs = require("fs"); // File stream
var csv = require("fast-csv");
var Papa = require("papaparse");
var BigNumber = require("bignumber.js");
const chalk = require("chalk");
const chalkerror = chalk.bold.red;

// NFT
const nftArtifacts = require("../build/contracts/My721.json");
const contract = require("truffle-contract");
var nftContract = contract(nftArtifacts);

var IPFS = require("ipfs-mini");
var orgPath = process.env.npm_config_org;
var nftAddr = process.env.npm_config_nft;

const ipfs = new IPFS({
  host: "127.0.0.1",
  port: 5001,
  protocol: "http"
});

if (typeof web3 !== "undefined") {
  web3 = new Web3(web3.currentProvider);
  console.log("web3 connect to current provider");
} else {
  // set the provider you want from Web3.providers
  web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
  console.log("web3 connected to: ", web3._requestManager.provider.host);
}

//Instantiate nft at an address
var nft;
var coinbase;
nftContract.setProvider(web3.currentProvider);
nftContract.at(nftAddr).then(function(_instance) {
    nft = _instance;
    web3.eth.getAccounts().then(async (_accounts, error) => {
        coinbase = _accounts[0];
        var isMinter = await nft.isMinter(coinbase);
        if (!isMinter) {
            console.log(
                chalkerror(`You ${coinbase} is not a minter. aridrop will exit.`)
            );
            process.exit(0);
        }
        var nftName = await nft.name();
        var nftSymbol = await nft.symbol();

        nft.methods
            .mintUniqueTokenTo(_accounts[1], 10, "DummyURI", {
                from: coinbase
            })
            .estimateGas()
            .then(function(estimate) {
                console.log("Estimated Gas Consumptions: ", estimate);
                requiredGas = estimate;
            });
});

module.exports.cost = function() {
    var index = 0;
    var validIndex = 0;
    var stream = fs.createReadStream(`data/${orgPath}/receipients.csv`);
    var csvStream = csv()
    .on("data", function(data) {
        index++;
    })
    .on("end", function() {
        console.log(chalk.yellow(`Receipient count: ${index}`));
        if (validIndex == 0) {
            console.log(`Great! All addresses are valid!`);
        } else {
            console.log(chalkerror(`There is invalid receipient address.`));
            console.log(
                chalkerror(
                    `Please refer data/${orgPath}/invalid.csv file for list of 
                     invalid addresses.`
           )
        );
    }
});
    stream.pipe(csvStream);
};

the "script" section in the package.json:

"scripts": {
    "dev": "lite-server",
    "test": "echo \"Error: no test specified\" && exit 1",
    "check": "node -e 'require(\"./scripts/2_check\").check()'"
},

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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