install_code
can be called with a number of modes, but if the mode is upgrade
, then the Motoko stable variables (and the IC stable memory used to store them during upgrade) will be preserved.
The general rule is that any actor fields that are declared stable
will be serialized to stable memory before upgrade, and deserialized from stable memory after upgrade. The type of such a variable must itself be a stable
type which is basically most types with the exception of functions and type containing functions (such as objects with methods).
Because the old value has to be compatible with the new type, the type of a existing field can only evolve to a Motoko supertype: i.e. a Nat
can become an Int
, a record type can lose some fields, a variant type can gain some variants, but not the other way around.
In addition, the replacement actor can declare some new stable variables, whose values will be obtained from the initializers for the variables (and retained in future upgrades).
The recommended way to change the type of an old field to an unrelated type (e.g. adding a field to a record or more generally changing a data structure), is to declare a new stable variable, with a new name, explicitly initialized from the old stable variable, but adding the field/changing the representation. Question on updating data structures of stable variables in Motoko - #11 by chenyan sketches an example.
In addition to this basic mechanism, Motoko also lets you declare specific pre- and post- upgrade system
methods that let you explicitly modify/restore additional state just before and after an upgrade, for example, if you need to transfer some transient state to stable variables before doing the upgrade.
Some relevant Motoko documentation: