solidity – Solidity Structs Storage and Memory – In-Depth Analysis

solidity

When I use the below contract in solidity.

struct Funder {
    address addr;
    uint amount;
}

contract FundContract
{
    struct Campaign {
        uint numFunders;
        mapping (uint => Funder) funders;
    }
    mapping (uint => Campaign) campaigns;
       
    function updatestruct(uint campaignID) public
    {
          Campaign storage c = campaigns[campaignID];
         
          c.funders[c.numFunders++] = Funder(msg.sender, 100);  //  How this is fine ?
          
          Funder storage f  = Funder(msg.sender, 100); // Why this is a compilation error
    }

}

As per the solidity documentation, the line

 c.funders[c.numFunders++] = Funder(msg.sender, 100);

creates a new temporary memory struct, initialized with the given values, and copies it over to local storage c.

Similarly, I tried the below line

Funder storage f  = Funder(msg.sender, 100);

I was expecting the same, however, I get the compilation error instead
" Type struct Funder memory is not implicitly convertible to expected type struct Funder storage pointer."

Why is there a compilation error here, as I expected it to create a temp memory and copy it over to the local storage f like the previous one with local storage c?

Are some details available as to how solidity struct memory works in both cases?

Best Answer

When you declare a mapping inside a struct, it can only be of type storage, you can't assign values to it in a temp memory, it just won't work. Here's a link that might help you: using mappings inside structs. When you create a struct Funder and assign it to your mapping funders at a specific index it works because you're accepting a struct of type Funder=>mapping (uint => Funder) funders;However, when you're trying to allocate a struct to a type storage, you have to explicitly do so. For ex:

c.numFunders++;
Funder storage f = c.funders[c.numFunders];
f.addr = msg.sender;
f.amount = 100;

The method you used is for the memory allocation. Here's another link that will explain the process. https://medium.com/loom-network/ethereum-solidity-memory-vs-storage-how-to-initialize-an-array-inside-a-struct-184baf6aa2eb. An array has been used in this example but it's based on the same principle.

Related Topic