Solidity

Solidity 合約規模突然膨脹

  • August 22, 2022

我的智能合約的大小突然膨脹到**24.385 KB——**我不知道為什麼會這樣。

該合約是一個非常標準的ERC721合約:它導入了OpenZeppelinERC721.sol合約,以及幾個OpenZeppelin ,以及我編寫的另一個合約——所以這沒有什麼特別之處。這些都是我在其他一百萬個項目中看到的非常標準的東西。

".sol"這是我項目中所有文件的細分:

在此處輸入圖像描述

注意:我正在使用HARDHATETHERS.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

我真的很想知道這裡到底發生了什麼。

我正在粘貼下面的程式碼 - 請注意如何:

  1. 真的沒有那麼大,而且
  2. 我什至完全截斷了我所有的“要求”錯誤消息,所以它們是最小的,一點也不冗長。

編碼:

// 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 合約。

引用自:https://ethereum.stackexchange.com/questions/134152