Solidity is a high-level, object-oriented programming language compiled for write smart contractsas well as create and deploy Dapps on different blockchains.
Solidity, like any other programming language, has its own Data types And data structuresbut with different syntax and application.
This tutorial will review some of the most commonly used data types and data structures in Solidity programming languages.
Nature of Solidity data types
Solidity is a statically and strongly typed language that performs type checking before source code execution.
Like a statically typed languageSolidity requires the programmer to declare the data type of each variable before compiling the code (at compile time).
While Solidity as strongly typed language means that the data type of a variable cannot be changed or converted to another data type in the program.
Solidity Data Types
Solidity, like other programming languages, divides its data types into two categories: value types And reference types.
Value Types in Solidity
A value type variable is a variable that stores data directly in the stack memory allocated to it.
These types are passed by value, meaning that they are copied every time they are assigned to a new variable or provided as an argument to a function and any changes to the new copies do not affect the original data .
1.) Integers
The integer data type in Solidity is used to store integer values. An entire type is then grouped into int And uint used to declare sign And Unsigned type of integers respectively.
I. The int/signed integer
THE int
The keyword is used to declare signed integers. Signed integer is a data type that can hold positive and negative integer values in smart contracts.
pragma solidity ^ 0.8.13;
contract Signed_Integer_Example{
int year = 2022;
int temperature = -89;
}
ii. The uint/unsigned int
THE uint
The keyword is used to declare unsigned integers. Unsigned integer is a data type that can only hold positive integer values in smart contracts.
pragma solidity ^ 0.8.13;
contract Unsigned_Integer_Example{
uint year = 2022;
uint temperature = -89;
}
When you try to assign a negative value to an unsigned data type, you will receive the following message TypeError
message:
TypeError: Type int_const -89 is not implicitly convertible to expected type uint256. Cannot implicitly convert signed literal to an unsigned type.
2.) Bytes
Bytes in Solidity are fixed-size byte arrays that contain a sequence of bytes. The length of the byte array is defined at the start of the bytes as in bytes1
has bytes32
.
The number is equivalent to the number of characters the byte array variable can hold.
pragma solidity ^ 0.8.13;
contract Bytes_Array_Example{
bytes1 one_character = "a";
bytes2 two_characters = "ab";
bytes3 three_characters = "abc";
bytes4 four_characters = "abcd";
bytes5 five_characters = "abcde";
bytes32 thrity_two_characters = "abcdefghijklmnopqrstuvwxyz123456";
}
When you attempt to assign a number of characters exceeding the fixed byte size, as shown below:
pragma solidity ^ 0.8.13;
contract Bytes_Array_Example{
bytes1 one_character = "ab";
bytes1 two_characters = "abc";
}
You will receive the following TypeError
message:
TypeError: Type literal_string "abc" is not implicitly convertible to expected type bytes1. Literal is larger than the type.
3.) Booleans
The boolean in Solidity is denoted by the bool
keyword and like any other programming language, boolean in Solidity only accepts two values: true
And false
:
pragma solidity ^ 0.8.13;
contract Boolean_Example{
bool isEthereumMerge = true;
bool currentUserCanMintToken = false;
bool isRaining = "true";
bool isAdmin = "false";
}
When you try to assign a non-Boolean value to a Boolean variable, you will receive the following message TypeError
message:
TypeError: Type literal_string "true" is not implicitly convertible to the expected type bool.
4.) Address
Address is a special data type in Solidity, capable of receiving and sending Ether to and from it. The address data type is designed to store an Ethereum address, which usually starts with the 0x
value.
Addresses are 20 bytes in size and contain 42 characters.
0x0000000000000000000000000000000000000000
Addresses are also case-insensitive hexadecimal digits, generated from the Keccak-256 Hash of the Public key.
When trying to assign a string to an address data type as shown below:
pragma solidity ^ 0.8.13;
contract Address_Example{
address user_address = 0x0000000000000000000000000000000000000000;
address user_home_address = "Street 2, downtown road";
}
You will get the following TypeError
message:
TypeError: Type literal_string "Street 2, downtown road" is not implicitly convertible to expected type address.
When trying to assign a non-hexadecimal number to an address data type as shown below with an octal number:
pragma solidity ^ 0.8.13;
contract Address_Example{
address user_address = 0x0000000000000000000000000000000000000000;
address phone_address = 080123456789;
}
You will get the following ParserError
message:
ParserError: Octal numbers not allowed.
Address value types are divided into two:
function | address |
address payable |
---|---|---|
Check address balance | ✅ | ✅ |
Send ether | ❌ | ✅ |
Receive Ether | ❌ | ✅ |
Pro Tip: When you want your smart contract to receive and send Ether, use the address payable
value type. When you don't want your smart contract to receive or transfer Ether, use the simple address
value type.
5.) Enumerations
Enum data types, also called enumerations, allow developers to create user-defined data types. User-defined data are names assigned to an integral constant value starting at zero.
pragma solidity ^ 0.8.13;
contract Enum_Example{
enum Status {
Sending,
Success,
Failed
}
Status status;
function sendSomething () public {
status = Status.Sending;
}
}
From the code snippet above, we created a Status
enum which holds action status when we send something. We can then use the enumeration to update the status of the action to one of the predefined statuses in the Status
enumeration.
Reference types in Solidity (data structure)
A reference type variable is a variable that stores the location (memory address) of its data on the Heap memory and they do not share their data directly.
Changes to the reference data will always affect the original data.
Examples of reference types in Solidity include strings, structs, arrays, and mapping.
1.) Chain
THE string
type is a sequence of characters. Solidity supports both literal strings using single quotes ' '
and double quotes " "
.
pragma solidity ^ 0.8.13;
contract String_Example{
string name = "John Doe";
}
2.) Structures
THE struct
The data type is a reference data type that can be used to create a structure for other data types. A structure can contain both a value type and a reference type, including other structures but not a structure itself.
A structure can be created in Solidity using the syntax below:
struct <Struct_Name> {
<data_type> <variable_name>;
}
THE data_type
maybe a string
, int
, uint
, bool
, or any type of solidity data. Structures can be declared outside of a smart contract and imported into another contract.
A use case of a structure can be seen below:
pragma solidity ^ 0.8.13;
contract Struct_Example{
struct UserProfile {
string fullName;
bool isOnboarded;
uint age;
}
UserProfile _newUserProfile = UserProfile("Ayodele Samuel Adebayo", true, 19);
function getUserProfile() public view returns (string memory, bool , uint ){
return (_newUserProfile.fullName, _newUserProfile.isOnboarded, _newUserProfile.age);
}
}
According to the code above; we created a structure for the user profile that expects a fullName
THE isOnboarded
status and user age
. We then use this structure to create a new user with a function that returns the information from the created profile.
Take away: Using structures in Solidity makes our code more organized, maintainable, reusable and readable.
3.) Tables
An array is a collection of variables with the same data type. They are stored in a continuous memory location, with each array element having a unique index.
The array in Solidity can be fixed or dynamic size and each element in the array can be searched by its unique index.
I. Dynamic table
A dynamic array can be created in Solidity using the syntax below:
pragma solidity ^ 0.8.13;
contract Dynamic_Array_Syntax{
<datatype()> <variable_name> = <(array_items)>
}
Below is an example of string
dynamic array of names and a uint
dynamic array of numbers:
pragma solidity ^ 0.8.13;
contract Dynamic_Array_Example{
string() arrayOfNames = ("Faith", "Becky", "Steve");
uint() arrayOfNumbers = (0, 1, 2, 3, 4, 5);
}
ii. Fixed size chart
A fixed size array can be created using the syntax below:
pragma solidity ^ 0.8.13;
contract Fixed_Size_Array_Syntax{
<datatype(size)> <variable_name> = <(array_items)>
}
Below is an example of 2 string
array of names and 1 of fixed size uint
dynamic array of numbers:
pragma solidity ^ 0.8.13;
contract Fixed_Size_Array_Example{
string(2) arrayOfNames = ("Faith", "Becky");
uint(1) arrayOfNumbers = (0);
}
When trying to exceed the fixed size limit:
pragma solidity ^ 0.8.13;
contract Fixed_Size_Array_Example{
string(2) arrayOfNames = ("Faith", "Becky", "Steve");
uint(1) arrayOfNumbers = (0, 1, 2);
}
You will get the following TypeError
messages, respectively:
TypeError: Type string(3) memory is not implicitly convertible to expected type string(2) storage ref.
TypeError: Type uint8(3) memory is not implicitly convertible to expected type uint256(1) storage ref.
4.) Mapping
The mapping in Solidity is a key-value pair data structure that works similarly to a dictionary in Python and hash tables or objects in JavaScript.
The mapping can be created in Solidity with the following syntax:
pragma solidity ^ 0.8.13;
contract Mapping_Syntax{
mapping (key => value) variable_name;
}
Where the key
can be any data type except reference type and value
can be both a value type and a reference type.
Below is an example of mapping users' wallet addresses to their balances:
pragma solidity ^ 0.8.13;
contract Mapping_Example{
mapping (address => uint) users_balances;
}
From the implementation of the above data structure, we can retrieve the crypto balance of blockchain users in uint
type using their wallet address
.
Wrap
Data types and data structures are the foundation of any programming language and the building blocks of developing advanced Dapps with Solidity.
In this tutorial, we reviewed the most commonly used data types and data structures in the Solidity programming language.
And after?
Now that you've learned about data types and data structures in Solidity:
This article is part of the Hashnode Web3 Blog, where a team of selected editors offers new resources to help you discover the world of web3. Visit us to learn more about NFTs, DAOs, blockchains and the decentralized future.