Search code examples
structmappingblockchainsolidityhardhat

Solidity Error: Version 0.8.0 : Struct containing a (nested) mapping cannot be constructed


struct Campaign {
        address payable campaignOwner; 
        string campaignTitle;
        string campaignDescription; 
        uint256 goalAmount;
        uint256 totalAmountFunded;
        uint256 deadline;
        bool goalAchieved; 
        bool isCampaignOpen; 
        bool isExists;

        mapping(address => uint256) contributions;
    }
   
    //stores a Campaign struct for each unique campaign ID.
    mapping(uint256 => Campaign) campaigns; 

function createCampaign(string memory _campaignTitle, string memory _campaignDescription, uint256 _goalAmount, uint256 _fundingPeriodInDays ) public {
        ++totalCampaigns;

        uint256 period = block.timestamp + (_fundingPeriodInDays * 1 days);

        Campaign memory aCampaign = Campaign(payable(msg.sender),_campaignTitle, _campaignDescription, _goalAmount, 0, period , false, true, true);
        campaigns[totalCampaigns] = aCampaign; 
     } 

I am using Solc version 0.8.0. When I try to create a Struct that contains mapping, I received an error:

Struct containing a (nested) mapping cannot be constructed.

When I use older versions of solc (0.5.8), the code compiles without problems. But this version is not supported with other solidity files and giving error as:

Source file requires different compiler version (current compiler is 0.8.13+commit.abaa5c0e.Emscripten.clang) - note that nightly builds are considered to be strictly less than the released version


Solution

  • You can not keep a struct containing a mapping in memory, and you can not initialize a storage object in a function, it must be a state variable. So what you can do is, get an object from your mapping, assign it to a local variable and modify it. Like this:

    function createCampaign(string memory _campaignTitle, string memory _campaignDescription, uint256 _goalAmount, uint256 _fundingPeriodInDays ) public {
            ++totalCampaigns;
    
            uint256 period = block.timestamp + (_fundingPeriodInDays * 1 days);
    
            Campaign storage aCampaign = campaigns[totalCampaigns];
    
            aCampaign.campaignOwner = payable(msg.sender);
            aCampaign.campaignTitle = _campaignTitle;
            aCampaign.campaignDescription = _campaignDescription;
            aCampaign.goalAmount = _goalAmount;
            aCampaign.totalAmountFunded = 0;
            aCampaign.deadline = period;
            aCampaign.goalAchieved = false;
            aCampaign.isCampaignOpen = true;
            aCampaign.isExists = true;
         }