Imagine you keep address entries in a table in your contract:
/// @abi table
struct addrbook {
account_name owner;
string name;
string address;
string url;
auto primary_key()const { return owner; }
};
You store them in side a multi_index in your contract, and your users fill it with data.
Now imagine you want to add a new field, “email”, to the address book entry. What happens if you just add it to the source code and set a new version of the contract to your dApp account? Well, the whole table will become unusable. Trying to read or modify it will cause exceptions. You would have to revert to the old version of your contract as soon as possible.
The thing is, your multi_index data is stored in virtual memory of nodeos
process on the node servers of EOS network. The struct
statement defines a binary structure in the memory, and multi_index is organizing these pieces of data into a vector and a few indexes alongside.
So, once you change the data structure, the old vector in RAM becomes totally unusable, as the new data structure occupies a different amount of bytes.
What you can do to mitigate this problem, is create an upgrade method in your contract that would move all data to a new structure, and then create a new multi-index with the old name, and move the data again.
But the RAM for the data entries may be paid by other accounts, and when you copy the data to a new structure, the payer information will be lost. The payers will receive back their RAM allotment, and your contact will have to sponsor the new RAM storage.
So far, I haven’t found a way to change the data structure, still maintaining the old RAM payer information.