0

i use the solidity version pragma solidity 0.8.6;

i have a this struct :

   struct Request {
    string description;
    uint256 value;
    address recipient;
    bool complete;
    uint256 approvalCount;
    mapping(address => bool) approvals;
}

and when I need to create instance for that struct it show me this error :

Struct containing a (nested) mapping cannot be constructed

    Request memory newRequest = Request({
        description: description,
        value: value,
        recipient: recipient,
        complete: false,
        approvalCount: 0
    });

and it show me this error when I need to transfer :

       request.recipient.transfer(request.value);

"send" and "transfer" are only available for objects of type "address payable", not "address".

whats the problem ? how can I solve this problem ?

Mr Coder
  • 761
  • 2
  • 13
  • 34
  • 2
    Does this answer your question? [ERROR send and transfer are only available for objects of type address payable , not address](https://stackoverflow.com/questions/67341914/error-send-and-transfer-are-only-available-for-objects-of-type-address-payable) – Petr Hejda Aug 10 '21 at 08:49
  • I think about the second error you should fix in struct Request (address recipient; -> address payable recipient) – Chíp Thảo Aug 10 '21 at 10:51
  • @PetrHejda whats your idea about the first error ? – Mr Coder Aug 11 '21 at 05:37
  • Does this answer your question? [Solidity, Solc Error: Struct containing a (nested) mapping cannot be constructed](https://stackoverflow.com/questions/63170366/solidity-solc-error-struct-containing-a-nested-mapping-cannot-be-constructed) – JohnL Dec 13 '21 at 20:52

2 Answers2

1

Change starting with Solidity v0.7.0 (unsafe feature)

Assignments to structs or arrays in storage do not work if they contain mappings. Previously, mappings were silently skipped during the copy operation, which is misleading and error-prone.

See v0.7.0 Breaking Changes: https://docs.soliditylang.org/en/v0.8.9/070-breaking-changes.html

Edit: Solution: Add your struct instance to storage first

ouflak
  • 2,458
  • 10
  • 44
  • 49
parseb
  • 71
  • 5
0

This is a deliberate limitation. See Disallow mappings in memory and copying mappings. The problem is that mappings are only allowed in storage due to their layout and cannot really be copied together with the struct (see my answer for "How to return an array of structs that has mappings nested within them?").

It used to be possible to create a struct containing a mapping in memory but this would just leave the mapping blank. This silent behavior can easily lead to bugs and starting with 0.8.0 it is explicitly disallowed.

The solution in your case depends on what exactly you're trying to accomplish. Either make a separate struct without the mapping field for use in memory or, better, avoid copying it to memory at all.

You could make newRequest a storage variable and overwrite if when you make a new request. You could also change the type to Request[] and use push() when creating a new one to preserve the old ones.

cameel
  • 706
  • 2
  • 8