Solidity 合約規模突然膨脹
我的智能合約的大小突然膨脹到**24.385 KB——**我不知道為什麼會這樣。
該合約是一個非常標準的ERC721合約:它導入了
OpenZeppelin
的ERC721.sol
合約,以及幾個OpenZeppelin
庫,以及我編寫的另一個合約——所以這沒有什麼特別之處。這些都是我在其他一百萬個項目中看到的非常標準的東西。
".sol"
這是我項目中所有文件的細分:注意:我正在使用HARDHAT和ETHERS.JS進行開發。
如您所見,這是列表中的最後一個契約PHPMinter,它非常大,達到24.385 KB
(順便說一下,“PHP”與 PHP 程式語言無關,它只是我的項目。)
所以事情是這樣的:PHPMinter合約實際上並沒有那麼大,就其中有多少程式碼,它有多少函式,或者它正在做什麼而言。事實上,我實際上從其中取出了一堆程式碼,並將其粘貼到一個名為“ PHPCollectionManager ”的新單獨契約中 - 我明確創建了該契約以使 PHPMinter 更小。
因此,現在PHPMinter將PHPCollectionManager導入到自身中,並且一切都執行良好 - 除了PHPMinter在空間方面仍然完全耗盡。所以基本上只要我在其中添加一行程式碼 - 整個事情“崩潰”,我在終端中得到這個錯誤:
ProviderError: Error: Transaction reverted: trying to deploy a contract whose code is too large
我真的很想知道這裡到底發生了什麼。
我正在粘貼下面的程式碼 - 請注意如何:
- 真的沒有那麼大,而且
- 我什至完全截斷了我所有的“要求”錯誤消息,所以它們是最小的,一點也不冗長。
編碼:
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "hardhat/console.sol"; import "./PHPCollectionsMngr.sol"; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; import "@openzeppelin/contracts/security/Pausable.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; contract PHPMinter is PHPCollectionManager, ERC721, ERC721Enumerable, ERC721URIStorage, Pausable { using Counters for Counters.Counter; using Strings for uint256; // Mapping to keep track of Addresses that have already MINTED: mapping(address => uint256) private alreadyMintedGMPHolders; mapping(address => uint256) private alreadyMintedSMPHolders; // Base Metadata URI: string private baseTokenURI; // EVENTS: event BaseURIUpdated(string newlyUpdatedURI); event GMPClaimed(address indexed GPBuyerAddress, uint256 indexed passIDNumber); event SMPBought(address indexed SPBuyerAddress, uint256 indexed passIDNumber); constructor() PHPCollectionManager() ERC721("PHPMintNFT", "PHP") baseTokenURI = "https://mydomainname.com/MP/jsonFILES/MPMetadata"; console.log(">baseTokenURI = %s", baseTokenURI); console.log(">GMPCounter = %s", GMPCounter); console.log("\n\n>'SMPCounter' = %s", SMPCounter); } // Mints ONE "GMP" - but ONLY IF the CALLER is "QUALIFIED"! function claimGPHP(address claimerAddress) external payable whenNotPaused() { console.log("\n>In 'claimGPHP()', Caller Address = %s, 'GMPCounter' = %s", claimerAddress, GMPCounter); // 1. Is Claiming ALLOWED yet? require(GMPClaimingAllowed == true, "Z1"); // 2. Any GMPs LEFT to claim - or have they all been claimed already? require(GMPCounter < MAX_GMPs, "Z2"); // 3. Has this address already claimed a GMP? require(alreadyMintedGMPHolders[msg.sender] == 0, "Z3"); // OK to mint: _safeMint(msg.sender, GMPCounter); emit GMPClaimed(msg.sender, GMPCounter); // Add Minter's Address to the ARRAY of GMP Minting Addresses: MintPassHoldersArray.push(msg.sender); alreadyMintedGMPHolders[msg.sender] = GMPCounter; GMPCounter++; } function mintSPHP() external payable whenNotPaused() { console.log("\n>In 'mintSPHP()' = %s \n>'msg.value' = %s \n>'SMPCounter' = %s", msg.value, SMPCounter); // 1. Any SPHP's LEFT available still? Or are we sold out? require(SMPCounter < MAX_SMPS, "Z4"); // 2. Has this person already minted a SPHP? require(alreadyMintedSMPHolders[msg.sender] == 0, "Z5"); // 3. Has this person sent enough ETH to buy this SPHP? require(msg.value >= SPHPPrice, "Z6"); // We're good to go: _safeMint(msg.sender, SMPCounter); emit SMPBought(msg.sender, SMPCounter); SMPHoldersArray.push(msg.sender); alreadyMintedSMPHolders[msg.sender] = SMPCounter; SMPCounter ++; } function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal whenNotPaused override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer(from, to, tokenId); } // The following functions are overrides required by Solidity: function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) { super._burn(tokenId); } function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) { return super.supportsInterface(interfaceId); } function pause() public onlyOwner { _pause(); } function unpause() public onlyOwner { _unpause(); } function getContractBalance() public view onlyOwner returns(uint) { return address(this).balance; } function cashOut(address transferToAddress, uint amountToTransfer) public onlyOwner returns (bool transferSucceeded) { console.log("\n\nIn 'cashOut()'\nThe amount getting cashed-out: %s \n-The address that'll be getting the cash: %s", amountToTransfer, transferToAddress); require(transferToAddress == contractOwner, "Z7"); require(amountToTransfer <= address(this).balance, "Z8"); // Try to "send" the funds back to the Bidder - but wrap in an "if" statement so if it fails, we // have recourse: (bool sent, bytes memory data) = payable(msg.sender).call{ value: amountToTransfer } (""); // (bool sent, bytes memory data) = payable(msg.sender).call{ value: amountToTransfer } (""); require(sent, "Z9"); data = ""; // emit CashedOut(amountCashedOut); return sent; // Originally: return true; } // Here I'm OVERRIDING the standard "_baseURI()" function that comes in "ERC721.sol" and making it return the // value of "baseTokenURI" - otherwise, it would just return "" - which is what it's written to do out of the box: function _baseURI() internal view virtual override returns (string memory) { return baseTokenURI; } // Here I'm OVERRIDING again: function tokenURI(uint256 tokenId) public view override(ERC721, ERC721URIStorage) returns (string memory) { // console.log(" -->In 'tokenURI()', inquiring about 'tokenId' = %s", tokenId); // Code I'm copy-pasting from the "parent" ERC721.sol Contract: require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); // If "baseURI" is EMPTY, return "", otherwise, concatenate ("") the "baseURI" with the "tokenId": return bytes(baseTokenURI).length > 0 ? string(abi.encodePacked(baseTokenURI, tokenId.toString(), ".json")) : ""; } // And in case I need to update the BASE-URI: function updateBaseURI(string calldata newBaseURI) public onlyOwner() { baseTokenURI = newBaseURI; emit BaseURIUpdated(baseTokenURI); } }
注意:您在本契約中看到的任何變數或 CONST 都沒有在本契約中聲明,它們是在
PHPCollectionsMngr
導入本契約的契約中聲明的。
導入合約會導入合約的大小。您可以嘗試將 ERC721 合約和鑄幣者合約分開,然後讓鑄幣者通過介面呼叫 ERC721 合約。