我正在尝试使用 hardhat 和 hardhat-etherscan 验证并发布已部署到 rinkeby 网络的智能合约。当我运行验证脚本时,出现错误。
我运行以下命令
npx hardhat clean
npx hardhat verify --network rinkeby 0xDDeE39Ae632760906d273B450493405Dc3C455Fe "ipfs://QmX6MjxS5NsEFGe9WtKCskf5fhuifFvZ9Xi12tTBYPjEiH"
运行上面的脚本后,出现以下错误。
Compiling 17 files with 0.8.4
Compilation finished successfully
Compiling 1 file with 0.8.4
Successfully submitted source code for contract
contracts/NFTCollectible.sol:NFTCollectible at 0xDDeE39Ae632760906d273B450493405Dc3C455Fe
for verification on Etherscan. Waiting for verification result...
我们尝试在不包含任何不相关的合同的情况下验证您的合同 NFTCollectible,但它失败了。使用用于编译和部署它的完整 solc 输入再次尝试。这意味着不相关的合约可能会显示在 Etherscan...
在 0xDDeE39Ae632760906d273B450493405Dc3C455Fe 成功提交了合约合约/NFTCollectible.sol:NFTCollectible 的源代码,用于在 Etherscan 上进行验证。等待验证结果...
Error in plugin @nomiclabs/hardhat-etherscan: The contract verification failed.
Reason: Fail - Unable to verify
hardhat.config.js
require("@nomiclabs/hardhat-waffle");
require("@nomiclabs/hardhat-etherscan");
require('dotenv').config();
const { API_URL, PRIVATE_KEY, ETHERSCAN_API } = process.env;
// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
const accounts = await hre.ethers.getSigners();
for (const account of accounts) {
console.log(account.address);
}
});
// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more
/**
* @type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: "0.8.4",
defaultNetwork: "rinkeby",
networks: {
rinkeby: {
url: API_URL,
accounts: [PRIVATE_KEY]
}
},
etherscan: {
apiKey: ETHERSCAN_API
}
};
我的智能合约包括几个来自 openzepplin 的导入。
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
contract NFTCollectible is ERC721Enumerable, Ownable {
using SafeMath for uint256;
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
uint256 public constant MAX_SUPPLY = 100;
uint256 public constant PRICE = 0.01 ether;
uint256 public constant MAX_PER_MINT = 5;
string public baseTokenURI;
constructor(string memory baseURI) ERC721("NFT Collectible", "NFTC") {
setBaseURI(baseURI);
}
function reserveNFTs() public onlyOwner {
uint256 totalMinted = _tokenIds.current();
require(totalMinted.add(10) < MAX_SUPPLY, "Not enough NFTs");
for (uint256 i = 0; i < 10; i++) {
_mintSingleNFT();
}
}
function _baseURI() internal view virtual override returns (string memory) {
return baseTokenURI;
}
function setBaseURI(string memory _baseTokenURI) public onlyOwner {
baseTokenURI = _baseTokenURI;
}
function mintNFTs(uint256 _count) public payable {
uint256 totalMinted = _tokenIds.current();
require(totalMinted.add(_count) <= MAX_SUPPLY, "Not enough NFTs!");
require(
_count > 0 && _count <= MAX_PER_MINT,
"Cannot mint specified number of NFTs."
);
require(
msg.value >= PRICE.mul(_count),
"Not enough ether to purchase NFTs."
);
for (uint256 i = 0; i < _count; i++) {
_mintSingleNFT();
}
}
function _mintSingleNFT() private {
uint256 newTokenID = _tokenIds.current();
_safeMint(msg.sender, newTokenID);
_tokenIds.increment();
}
function tokensOfOwner(address _owner)
external
view
returns (uint256[] memory)
{
uint256 tokenCount = balanceOf(_owner);
uint256[] memory tokensId = new uint256[](tokenCount);
for (uint256 i = 0; i < tokenCount; i++) {
tokensId[i] = tokenOfOwnerByIndex(_owner, i);
}
return tokensId;
}
function withdraw() public payable onlyOwner {
uint256 balance = address(this).balance;
require(balance > 0, "No ether left to withdraw");
(bool success, ) = (msg.sender).call{value: balance}("");
require(success, "Transfer failed.");
}
}