Initialization
Storage is declared through the use of the storage keyword.
Inside the storage block each variable is named, associated with a type and a default value.
storage {
    // variable_name1: variable_type1 = default_value1,
    // variable_name2: variable_type2 = default_value2,
    // ...
}
Example
In the following example we will take a look at two ways of storing a struct.
- Explicitly declaring the values in the storageblock
- Encapsulating the values in an associated function
We'll begin by defining the Owner & Role data structures and implement a default constructor on the Owner.
struct Owner {
    maximum_owners: u64,
    role: Role,
}
impl Owner {
    // a constructor that can be evaluated to a constant `Owner` during compilation
    fn default() -> Self {
        Self {
            maximum_owners: 10,
            role: Role::FullAccess,
        }
    }
}
enum Role {
    FullAccess: (),
    PartialAccess: (),
    NoAccess: (),
}
Now that we have our data structures we'll keep track of how many current_owners we have and declare the owner in the two aforementioned styles.
storage {
    current_owners: u64 = 0,
    explicit_declaration: Owner = Owner {
        maximum_owners: 10,
        role: Role::FullAccess,
    },
    encapsulated_declaration: Owner = Owner::default(),
}
An explicit declaration is likely to be sufficient for most types. However, it may be preferable to encapsulate the initialization of complex types within a constructor in order to keep the code concise.
Note that the constructors used in storage blocks must evaluate to a constant during compilation.