A contract has a state variable, which is complex. For the example, lets say it is a mapping of structs. Inside a method, I want to access that and store the changes. Like so:
contract FooManager {
struct Foo {
uint expiresAt;
uint balance;
}
mapping(address => Foo) public fooIndex;
public function claimFrom(address minter) public payable {
require(fooIndex[minter].balance < amount);
fooIndex[minter].balance += msg.value;
fooIndex[minter].expiresAt += 1000;
}
}
In this simple example, the repetition of fooIndex[minter].method
is still manageable and readable. But with e.g. child mappings in, say the Foo
struct, it quickly becomes tangled and ugly. fooIndex[minter].claimants[msg.sender].balance = msg.value
are no exceptions there.
What is the common pattern to DRY
this? I can create a memory-variable, like below, but that is not stored. The extra gas for allocating memory, may become an issue if this pattern is repeated, but is proably negligible in most cases.
public function claimFrom(address minter) public payable {
Foo memory thisFoo;
thisFoo = fooIndex[minter];
require(thisFoo.balance < amount);
thisFoo.balance += msg.value;
thisFoo.expiresAt += 1000;
}
}
I've seen some examples in which, at the end, the memory-variable gets assigned back to the storage variable. Like so:
public function claimFrom(address minter) public payable {
Foo memory thisFoo;
thisFoo = fooIndex[minter];
require(thisFoo.balance < amount);
thisFoo.balance += msg.value;
thisFoo.expiresAt += 1000;
fooIndex[minter] = thisFoo;
}
It works, but seems clumsy to me: assigning the wrong thing, or forgetting to re-assign is an obvious mistake to make. It also seems wasteful to me, esp in the case of large structs, in which only the dirty (changed) attributes need to be overridden, and not the entire struct; again, this is more obvious in situations where a struct contains child-mappings with other structs and so on: a tree. I'm not sure, if the compiler can and will optimize this, though.
Did I miss an obvious language construct? Did I misunderstand the storage
and memory
completely?