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 mappingfunders
at a specific index it works because you're accepting a struct of typeFunder
=>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: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.