Hardhat Waffle本地NFT合约测试:铸造时以太不足报错求助
问题描述
在使用Hardhat与Waffle进行本地智能合约测试时,执行铸造首个NFT的单元测试报错,错误信息如下:
Unit tests Governor mint first nft: Error: VM Exception while processing transaction: reverted with reason string 'Not enough ether to purchase NFTs.' at MyNftToken.approve (@openzeppelin/contracts/token/ERC721/ERC721.sol:114) at MyNftToken.safeMint (contracts/MyNftToken.sol:54) at async HardhatNode._mineBlockWithPendingTxs (node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:1773:23) at async HardhatNode.mineBlock (node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:466:16) at async EthModule._sendTransactionAndReturnHash (node_modules/hardhat/src/internal/hardhat-network/provider/modules/eth.ts:1504:18) at async HardhatNetworkProvider.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:118:18) at async EthersProviderWrapper.send (node_modules/@nomiclabs/hardhat-ethers/src/internal/ethers-provider-wrapper.ts:13:20)
测试前已通过以下代码为管理员地址设置10 ETH余额:
await this.token.deployed(); await hre.network.provider.request({ method: 'hardhat_setBalance', params: [this.signers.admin.address, ethers.utils.parseEther('10').toHexString()] });
调用safeMint时已指定gasLimit避免预估gas错误:
const myFirstMint = await this.token.safeMint(this.signers.admin.address, { gasLimit: 250000, }); await myFirstMint.wait();
解决措施
- 补充mint所需的ETH转账:报错核心是“余额不足无法购买NFT”,说明你的
safeMint函数要求调用者支付ETH。调用时需在交易参数中添加value字段,传入合约规定的mint价格,示例:const mintPrice = ethers.utils.parseEther("0.1"); // 假设mint价格为0.1ETH const myFirstMint = await this.token.safeMint(this.signers.admin.address, { gasLimit: 250000, value: mintPrice }); - 验证管理员地址余额是否生效:添加代码打印余额,确认
hardhat_setBalance操作是否成功执行:const adminBalance = await ethers.provider.getBalance(this.signers.admin.address); console.log("Admin balance:", ethers.utils.formatEther(adminBalance)); - 检查合约内的权限与付费逻辑顺序:如果合约允许管理员免费mint,需确认权限判断是否在付费检查之前执行。比如合约代码中是否先验证调用者是admin,再跳过余额检查,避免管理员也被要求支付ETH。
- 排查
safeMint内部的逻辑:查看MyNftToken.sol第54行的safeMint实现,确认报错的“余额不足”判断是否正确,是否存在逻辑错误导致误判(比如把mint数量和单价的计算写错)。 - 指定gasPrice确保余额足够支付gas:虽然10ETH余额足够,但可手动指定gasPrice避免网络预估异常,示例:
const myFirstMint = await this.token.safeMint(this.signers.admin.address, { gasLimit: 250000, gasPrice: ethers.utils.parseUnits("10", "gwei") });
内容的提问来源于stack exchange,提问作者Julia
相关产品推荐
相关产品推荐

