ERC1155合约铸NFT部署时Gas估算失败execution reverted问题求助
问题原因
- 核心原因是构造函数执行消耗的gas超出了区块gas上限:你在构造函数里手动重复了3690次
_mint调用,单链上单笔交易(包括合约部署交易)的gas消耗不能超过对应链的区块gas上限,你的构造函数执行逻辑消耗的gas远高于上限,所以触发执行回滚,gas估算失败。 - 次要冗余问题:Solidity 0.8+版本默认内置了整数溢出/下溢检查,不需要额外引入SafeMath库,属于无效引入,会略微增加合约部署成本。
解决方案
方案1:使用批量铸造接口大幅降低gas消耗
ERC1155原生提供了_mintBatch批量铸造方法,不需要逐次调用单ID铸造,优化后构造函数逻辑如下:
pragma solidity 0.8.0; import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC1155/ERC1155.sol"; contract NFT is ERC1155 { // 移除无用的SafeMath引用 constructor() ERC1155("ipfs://[IPFS_HASH]/{id}.json") { uint256 total = 3690; uint256[] memory ids = new uint256[](total); uint256[] memory amounts = new uint256[](total); for(uint256 i=0; i<total; i++){ ids[i] = i; amounts[i] = 1; } _mintBatch(msg.sender, ids, amounts, ""); } }
这个方案可以把铸造逻辑的gas消耗降低90%以上,如果你的链区块gas上限足够覆盖优化后的gas消耗,直接部署即可。
方案2:拆分铸造逻辑,避免构造函数过载
如果优化后gas依然超过上限,就不要把全部铸造逻辑放在构造函数里,拆分成分批次调用的公开方法:
pragma solidity 0.8.0; import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC1155/ERC1155.sol"; import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol"; contract NFT is ERC1155, Ownable { uint256 public constant TOTAL_SUPPLY = 3690; uint256 public currentMinted = 0; constructor() ERC1155("ipfs://[IPFS_HASH]/{id}.json") {} // 每次最多铸造1000个,可根据区块gas上限调整单次铸造数量 function batchMint(uint256 count) external onlyOwner { require(currentMinted + count <= TOTAL_SUPPLY, "exceed total supply"); uint256[] memory ids = new uint256[](count); uint256[] memory amounts = new uint256[](count); for(uint256 i=0; i<count; i++){ ids[i] = currentMinted + i; amounts[i] = 1; } _mintBatch(msg.sender, ids, amounts, ""); currentMinted += count; } }
部署完成后,分多次调用batchMint方法,直到所有NFT铸造完成即可,完全避免构造函数gas超限问题。
内容的提问来源于stack exchange,提问作者ReX357
相关产品推荐
相关产品推荐

