I'm trying to understand the following code from the Solidity documentation:
struct Funder {
address addr;
uint amount;
}
contract Crowdfunding {
struct Campaign {
address payable beneficiary;
uint fundingGoal;
uint numOfFunders;
uint amount;
mapping(uint => Funder) funders;
}
uint numOfCampaigns;
mapping(uint => Campaign) campaigns;
function newCampaign(address payable beneficiary, uint goal) public returns (uint campaignID) {
numOfCampaigns ++;
Campaign storage c = campaigns[campaignID]; // this line
c.beneficiary = beneficiary;
c.fundingGoal = goal;
}
}
But, I have three questions:
Why doesn't this line
Campaign storage c = campaigns[campaignID];
throw an out-of-range failing assertion? As far as I understand, the instance ofCampaign
with a matchingcampaignID
doesn't exist in thecampaigns
array since we're creating a new one. Is this a way of instantiating a newCampaign
struct?The documentation explains that the reason they're not instantiating a new
Campaign
struct withcampaigns[campaignID] = Campaign(beneficiary, goal, 0, 0)
in this case is "because the RHS creates a memory-struct "Campaign" that contains a mapping". But, here also says that "Assignments between storage and memory (or from calldata) always create an independent copy", which seem to mean it's permitted. So, I'm not sure why assigning a memory-struct to a storage is a problem.Finally, the
newCampaign
function signature says that it's to returncampaignID
by statingreturns (uint campaignID)
. But, the executable code doesn't actuallyreturn
anything. Is this simply implied that the variablecampaignID
will be returned?