Data Structures
Helping Us Store Data
Any programming language would not be complete without the inclusion of data structures; in Solidity, we are provided with the following data structures:
Mappings
Mappings can be thought of as dictionaries, where we are mapping keys to values. The syntax for mappings are as follows:
As an example, if I wanted to create a mapping called ages which mapped users (represented by their addresses) to their age, I could create the following mapping:
Perhaps one of best known use cases of mappings is for tracking the ERC20 token balances of user within a smart contract. Listed below is an elementary ERC20 contract which shows this off:
Assuming map
is a mapping, the following code below demonstrates how to assign a key-value pair within a mapping:
One note about mappings is that they can only be used as state variables. In other words, one cannot create a new mapping within a function; one can only use a mapping associated with a state variable within a function.
Aside: Default Values
In languages like Python, we run into exceptions whenever we try to query an undefined key-value pair. An example is as follows:
In Solidity, however, we are able to query undefined key-value pairs (assuming we obey relevant type rules). An interesting question, then, is what values are returned when querying an undefined key? For any undefined key, the value returned is the default value for the value type. As an example, assume we have the following (empty) mapping:
If we try to query the value paired to key 7
, we will get the value 0
. If we try to query any key in map
, we will always get the value 0
in return. Listed below are the default values for some types:
uint
/int
:0
bool
:false
Static Arrays
Static arrays are arrays whose size is defined at creation time. The syntax for creating an array in memory is as follows:
where T
is the type of the array and n
is the size of the array. In Solidity, all elements of an array must be of the same type. Another way of creating an array in memory is as follows:
As the name might imply, we cannot change the size of a static array once initialized. If you wish to have flexibility with the size of your array, consider using a dynamic array.
To create a state variable of the static array type, we can again use the folowing syntax:
In the case that we know how to define our static array, below is an example of how we can declare and define a static array at the same time (this holds for both memory and storage):
Nested Arrays
In certain situations, it may be necessary to use a nested array. Solidity allows us to create static nested arrays as follows:
where T
is the type of the array, and n
, m
are the 1st and 2nd dimension sizes of the nested array respectively.
Accessing Array Elements
Below is an example of how to access an element of an array:
Structs
Structs are data structures that can be used to hold several variables in one place; below is an example of structs in the C++ programming language:
In Solidity, we can create structs as follows:
Below is an example of how to create a struct in memory and how to access an element of a struct:
Enums
Enums, or enumerations, allow us to group 'constants' without having to explicitly declare them.
Consider a contract where we want to organize students by their year. If we wanted to map students (represented by their addresses) to their year, we could use integers to represent their year, as seen below:
However, keeping track of these constants manually introduces the possibility of bugs. Enums allow us to use these constants without explicitly using their values:
Below is an example of a contract which uses the Year
enum to keep track of students:
The function admitStudent
, in particular, takes the address of an admitted students and maps them to the Freshman
value.
References
Solidity Types: https://docs.soliditylang.org/en/v0.8.7/types.html#
Solidity Expressions and Control Structures: https://docs.soliditylang.org/en/latest/control-structures.html#
Last updated