Gas-Estimate

如何估算 ERC721 鑄幣交易?

  • January 18, 2019

我的契約;

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);
   }
}

我試圖執行我自己的節點腳本;

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

我有;

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

僅供參考,我在松露控制台中成功執行了交易。任何的想法?

以下是一個完整的測試,您可以在開發機器上使用 Node 進行複制。此測試需要訪問 web3 提供程序。我正在使用 Infura,您將使用密碼。

mint函式不是ERC-721 標準的一部分,但在ERC-721 參考實現中有一個mint實現範例。

依賴項

將此最小文件安裝為package.json

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

然後執行npm install

注意:Web3 的最新版本存在各種問題。下面的程式碼經過測試並確認可與版本 ^1.0.0-beta.36 一起使用。

測試套件

將此文件安裝為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);
 });

現在您可以通過執行來執行測試案例npm estimate.js

執行薄荷的估計氣體:66791

討論

如果您使用不可替代代幣合約的不同實現,或者如果您的網路(所有已部署的程式碼和儲存)上的某些情況發生變化,您的估計氣體測試將返回不同的氣體值。以下是一些需要檢查的特殊情況:

  • 收件人是否mint已經擁有任何代幣?這與ERC721Enumerable.
  • 這個令牌 ID 是不是已經鑄造了?
  • 您的mint實施是否需要onERC721Received收件人?
  • 如果它確實呼叫,接收者會拋出嗎?

下面是我的節點腳本(“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);
};

package.json 中的“腳本”部分:

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

引用自:https://ethereum.stackexchange.com/questions/65050