Under the Hood with Solidity Reference Types

Ifeoma Sandra
Coinmonks

--

Reference Type…What does it even mean?😏

A reference type is a code object that is not stored directly where it is created, but that acts as a kind of pointer to a value stored elsewhere.

Let’s look at it differently by just calling it an alias which is just another name by which you would refer to the object you are creating a reference to.

A very relatable example would be pet names that you call your friends with. The person remains the same, only the names are different.

In Solidity, unlike value types that stores it own data as we discussed in our previous article on value types, reference types do not store the data directly to the variable, instead it stores the location of the data. Values of reference types can be modified through multiple different names. When using reference types, we always have to explicitly provide the data area or data location that is, where the type is stored.

Data Location…

There are 3 data locations in which we can store reference types:

  • memory — whose lifetime is limited to an external function call
  • storage — the location where the state variables are stored and the lifetime is limited to the lifetime of a contract
  • calldata — is a special data location that is non-modifiable, non-persistent and contains the function arguments. It has similar behavioural pattern like memory

Reference types in solidity consist of the following:

  • Arrays
  • Structs
  • Mappings

Arrays

An array is a container that contains a group of elements of the same datatype such as integers or strings. Each element of the array has a particular location called the index, it can be identified and accessed with. Arrays are in different sizes:

  • Fixed size arrays
  • Dynamic arrays

A fixed size array is an array for which the size or length is determined when the array is created and/or allocated. For example, an array of fixed size 5 and element type uint is written as,

uint[5] myFixedArray;

A dynamic array is a random access, variable-size list data structure that allows elements to be added or removed. The size of a dynamic array is not predetermined at the point of declaration. For example an array of dynamic size is written as,

uint[] myDynamicArray;

There are some special arrays we should also mention and they are bytes and strings. The bytes type is similar to bytes1[], but it is packed tightly in calldata and memory. string is equal to bytes but does not allow length or index access. As a general rule, use bytes for arbitrary-length raw byte data and string for arbitrary-length string (UTF-8) data. If you can limit the length to a certain number of bytes, always use one of the value types bytes1 to bytes32 because they are much cheaper.

Now let’s learn about some array members

  • length - the length member is used to get the number of elements in the array. For memory arrays, the length is fixed and dynamic, which means it can depend on runtime parameters once they are created.
  • push - appends an element at the end of dynamic storage arrays and bytes (not string). The newly-added element is zero-initialized.
  • pop removes an element at the end of dynamic storage arrays and bytes (not string).

Okay😀…so that’s quite enough information about arrays. You can learn more about arrays in solidity here. Let’s get to know what structs are😎🎯

Structs

Generally, structs is used to represent a record of something. In solidity, structs allows user to create their own datatype in the form of structure. They are used for grouping related data together. Structs can contain both value types and reference types but it is impossible to contain members of its own type.

For example, suppose you want to keep track of your friends, you might want to track the following attributes:

  • name
  • age
  • email
  • job

We’d represent this record of friends in a struct like so,

struct Friend {     string name;     uint256 age;     string email;     string job;}

Here’s a simple contract to get the record of a friend,

Let’s take a sneak-peek at mappings...

Mappings…

Mappings are used to store data or information in a key-value pair format. The key type can be of any built-in type, bytes, strings or any contract or enum type but not reference types. The value type can be of any type including reference types such as mappings, arrays and structs.

There are a few things we need to note about mappings..

  • storage is the only data location mappings can have.
  • mappings are allowed for state variables as storage reference types in functions.
  • mappings do not have the concept of setting a key or a value neither do they have length.
  • mappings are commonly used to link the unique Ethereum address to the associated value type

Variables of mappings type can be declared as,

mapping(_KeyType => _ValueType) _VariableName

A more definite example of declaring a mapping variable with actual variable name, key type and value type is written as,

mapping(address => uint) public myBalances;

We can take a look at how mappings work in the example below of storing and receiving user information using mappings:

The MappingExample contract defines a public myBalances mapping, with the key type an address, and a value type a uint, mapping an Ethereum address to an unsigned integer value and we retrieved the value of the balance we stored on the address key.

Conclusion:

In this article we’ve learned about the different reference types in solidity such as arrays, structs and mappings.

Key Reference

https://docs.soliditylang.org/en/v0.8.11/types.html

--

--

Ifeoma Sandra
Coinmonks

Ifeoma is passionate about technology and its many applications with experience in backend web development (NodeJs/NestJs).