4

My version of solc:

"solc": "^0.7.1",

When I try to construct a struct that contains mapping, I got this error: "Struct containing a (nested) mapping cannot be constructed"

This is my solidity code.

Campaign.sol

pragma solidity >=0.5.0;

contract Campaign {
    struct Request {
        string description;

        // I declared a mapping inside of a struct.
        mapping(address => bool) approvals;

    }
    constructor(uint256 minimum, address creator) {
        ...
    }

    function createRequest(string memory description) public onlyManager {
        Request memory newRequest = Request({ 

            // Here the compiler gives me an error

            description : description

        });
    }
    ...

It says

Struct containing a (nested) mapping cannot be constructed.

Please help me.

8
  • You cannot create a mapping (or a struct containing one) in memory. – goodvibration Sep 14 '20 at 16:24
  • @goodvibration I've also tried a storage and just 'Request newRequest'. But it throws the same error – Sang-hoon Shin Sep 14 '20 at 16:25
  • Since nothing in your code suggests that you even need this struct, the easiest solution would be to simply get rid of it. – goodvibration Sep 14 '20 at 16:25
  • 1
    Storage is for existing items, not for new ones! – goodvibration Sep 14 '20 at 16:25
  • Aha, then how can I create my request with a given variable (in this case, description)? – Sang-hoon Shin Sep 14 '20 at 16:27
2

The problem is in the construction, i.e., Request({ description: description }) Therefore changing the location of newRequest from memory to storage will not help.

If you really want to make it work, create a state variable, say, mapping (uint => Request) requests. Now, inside your function, you can write Request storage newRequest = requests[index] where index will get incremented later.

For a reference, see: docs

5
  • Thank you very much! Then is there any way to put a specific address (which is from Request struct) to the key(instead of uint) of a mapping? – Sang-hoon Shin Sep 14 '20 at 20:06
  • You can change it to mapping(address => Request) – hrkrshnn Sep 17 '20 at 8:33
  • Thank you for yout help. I'll try. – Sang-hoon Shin Sep 17 '20 at 18:53
  • Where do you set the mapping for approvals? @hrkrshnn – alper Oct 4 '20 at 14:40
  • @alper you don't really set the mapping for approvals. If you have defined a local struct inside a function, then it has to be a pointer to a storage struct. – hrkrshnn Oct 5 '20 at 7:27
3

from 0.7.0 do like below:

 struct Request{
            string description;
            uint value;
            address recipient;
            bool complete;
            uint approvalsCount;
            mapping(address => bool) approvals;
        }
        
    uint numRequests;
    mapping (uint => Request) requests;
    
    function createRequest (string memory description, uint value,
            address recipient) public{
                Request storage r = requests[numRequests++];
                r.description = description;
                r.value = value;
                r.recipient = recipient;
                r.complete = false;
                r.approvalsCount = 0;
            
        }
0

You can't create a struct with a mapping inside. Create a local mapping in your contract at the top level.

3
  • Thank you! How can I connect the mapping with a specific Request? Because I want to check if the request has voted or not (as True or False) – Sang-hoon Shin Sep 14 '20 at 20:09
  • Use a common identifier. You keep a mapping with ids and a mapping with ids to structs – Merunas Grincalaitis Sep 15 '20 at 8:09
  • 1
    Thank you! I'll try – Sang-hoon Shin Sep 17 '20 at 18:52
0

This should be enough:

function createRequest(string memory description) public onlyManager {
    Request storage newRequest = requests.push();
    newRequest.description = description;
}

Cheers!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.