Gas-Estimate
如何估算 ERC721 鑄幣交易?
我的契約;
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()'" },