我正在构建一个简单的 NFT 以部署到 IMX zkEVM...但在部署过程中遇到错误。
error: ProviderError: unable to apply transaction even for the highest gas limit 30000000: execution reverted
at HttpProvider.request (C:\src\gumi\contracts\node_modules\hardhat\src\internal\core\providers\http.ts:88:21)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async EthersProviderWrapper.send (C:\src\gumi\contracts\node_modules\@nomiclabs\hardhat-ethers\src\internal\ethers-provider-wrapper.ts:13:20)
部署脚本
/* eslint-disable prettier/prettier */
/* eslint-disable dot-notation */
/* eslint-disable spaced-comment */
/* eslint-disable no-unused-vars */
/* eslint-disable camelcase */
/* eslint-disable node/no-missing-import */
/* eslint-disable no-process-exit */
import * as dotenv from "dotenv";
import { ethers } from "hardhat";
import { craft__factory } from "../typechain";
import { insertRecord } from "./build_artifact";
import fs from 'fs'
dotenv.config();
// get baseURI from .env
const BASE_URI = process.env.BASE_URI!;
async function main() {
const signers = await ethers.getSigners();
const address = signers[0];
const contractURI = "ipfs";
const operatorAllowlist = address.address;
console.log(address.address, BASE_URI, contractURI, operatorAllowlist);
const factory = new craft__factory(address);
const contract = await factory.deploy(address.address, BASE_URI, contractURI, operatorAllowlist);
const nft = await contract.deployed();
const data = fs.readFileSync("artifacts/src/Gumicraft.sol/Gumicraft.json", 'utf8');
const json = JSON.parse(data);
const name = "Gumicraft";
console.log(`${name} deployed to: ${nft.address}\nwith artifact ${json}`);
await insertRecord([name, nft.address, json]);
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
NFT
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.17;
import "./base/NFT.sol";
# contract craft is NFT {
// a constructor that takes a baseURI, an imxContract and an array of defaultOperators
constructor(
address owner_,
string memory baseURI_,
string memory contractURI_,
address operatorAllowlist_
)
NFT(
owner_,
"craft",
"GCRAFT",
baseURI_,
contractURI_,
operatorAllowlist_,
owner_,
1000
) {
}
}
NFT合约
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.17;
import {Counters} from "@openzeppelin/contracts/utils/Counters.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import {ImmutableERC721} from "@imtbl/zkevm-contracts/contracts/token/erc721/preset/ImmutableERC721.sol";
abstract contract NFT is ImmutableERC721, ReentrancyGuard {
event NftMinted(address to, uint256 id, string url);
struct Nft {
uint256 id;
string url;
}
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
mapping(uint256 => string) private tokenParameters;
constructor(
address owner_,
string memory name_,
string memory symbol_,
string memory baseURI_,
string memory contractURI_,
address operatorAllowlist_,
address receiver_,
uint96 feeNumerator_
)
ImmutableERC721(
owner_,
name_,
symbol_,
baseURI_,
contractURI_,
operatorAllowlist_,
receiver_,
feeNumerator_
)
{
}
function setTokenParams(uint256 tokenId, string memory tokenParams)
public
virtual
onlyRole(MINTER_ROLE)
{
// validate that string is not empty
require(
bytes(tokenParams).length > 0,
"NFT: token params can not be empty"
);
tokenParameters[tokenId] = tokenParams;
}
function getTokenFullURL(uint256 tokenId)
public
view
virtual
returns (string memory)
{
return
string(
abi.encodePacked(
baseURI,
contractURI,
tokenId,
tokenParameters[tokenId]
)
);
}
function createToken(address to, string memory tokenParams)
public
payable
virtual
nonReentrant
onlyRole(MINTER_ROLE)
returns (uint256)
{
_tokenIds.increment();
uint256 newTokenId = _tokenIds.current();
super._safeMint(to, newTokenId);
setTokenParams(newTokenId, tokenParams);
emit NftMinted(to, newTokenId, getTokenFullURL(newTokenId));
return newTokenId;
}
function getTokensFor(address ownerId) public view returns (Nft[] memory) {
uint256 balance = balanceOf(ownerId);
require(balance > 0, "NFT: no tokens for this owner");
uint256 total = _tokenIds.current();
Nft[] memory tokens = new Nft[](balance);
uint256 start = 1;
for (uint256 i = 1; i < total; i++) {
address _owner = ownerOf(i);
if (_owner != ownerId) {
continue;
} else {
tokens[start] = Nft(i, getTokenFullURL(i));
start++;
if (start == balance) {
break;
}
}
}
return tokens;
}
}
我已经重构了基类,删除了基于逻辑构造函数的调用,但仍然收到
cannot estimate gas; transaction may fail or may require manual gas limit
错误,这告诉我 SC 实例化可能存在问题...我很确定...
问题出在 dependencyCompiler 元素的
hardhatg.config.ts
中。
{
JSON...,
dependencyCompiler: {
paths: ["@imtbl/zkevm-contracts/contracts/allowlist/OperatorAllowlist.sol"],
},