Skip to main content

Define the State

In smart contract state storage, there is only a single key/value map, where both the key and value are constituted of raw data bytes. To ensure the retrieval of valid data, access it in the manner it was stored.

The Schema Tool facilitates this by generating a type-safe layer that oversees the consistent utilization of the expected data type during data storageContrary to the internet, neither the IOTA nor Shimmer protocols serve as data storage. The Tangle is not designed as a data repository. If one wishes to maintain a decentralized transaction history, they can either design a second-layer solution themselves or commission third parties for this task. At its core, IOTA and Shimmer prioritize performance, throughput, and security over acting as a global database. and retrieval.

State Section in Schema Definition File

In the schema definition file the state section hosts field definitions, delineating the variables stored in the state storage. Each field is defined with a YAML key/value pair, indicating its name and data type. This pair can optionally be followed by a descriptive comment.

With these details, the Schema Tool creates specific code to type-safely access state variables. Take a closer look at the state section in the dividend example to understand this better:

state:
memberList: Address[] # array with all the recipients of this dividend

# factors per member

members: map[Address]Uint64 # map with all the recipient factors of this dividend
owner: AgentID # owner of contract, the only one who can call 'member' func
totalFactor: Uint64 # sum of all recipient factors

Simple Variables

Starting with straightforward state variables, totalFactor, and owner are characterized as Uint64 and AgentID, respectively. These represent predefined WasmLib value types.

Arrays and Maps

Next, the memberList variable denoted by empty brackets [], symbolizing an array. This array accommodates elements of a homogenous predefined Address value type.

Lastly, the members variable, signified as a map with map[], houses keys of a uniform predefined Address type. Following the brackets, the homogenous value type, here Uint64, is mentioned.

type MutableDividendState struct {
proxy wasmtypes.Proxy
}

func (s MutableDividendState) AsImmutable() ImmutableDividendState {
return ImmutableDividendState(s)
}

// array with all the recipients of this dividend
func (s MutableDividendState) MemberList() ArrayOfMutableAddress {
return ArrayOfMutableAddress{proxy: s.proxy.Root(StateMemberList)}
}

// map with all the recipient factors of this dividend
func (s MutableDividendState) Members() MapAddressToMutableUint64 {
return MapAddressToMutableUint64{proxy: s.proxy.Root(StateMembers)}
}

// owner of contract, the only one who can call 'member' func
func (s MutableDividendState) Owner() wasmtypes.ScMutableAgentID {
return wasmtypes.NewScMutableAgentID(s.proxy.Root(StateOwner))
}

// sum of all recipient factors
func (s MutableDividendState) TotalFactor() wasmtypes.ScMutableUint64 {
return wasmtypes.NewScMutableUint64(s.proxy.Root(StateTotalFactor))
}

Generated Code Overview

Examining the state.xxcode, generated by the Schema Tool, you can find the MutableDividendState struct. This interface allows type-safe access to each state variable through mutable proxies, establishing a one-to-one relationship with the state section in the schema definition file.

Proxy Interfaces

Note the generated proxy interface named MutableDividendState for mutable dividend state. It enables type-safe proxy object access for each corresponding variable. Moreover, the tool auto-generates intermediate map and array proxy types, such as ArrayOfMutableAddress and MapAddressToMutableUint64, enforcing the utilization of respective homogenous types.

See the full state.xx for more details.