A guide to all the variable types in Solidity
In this tutorial, we are going to review and learn all the variable types in Solidity, and how and when to use them.
In this tutorial, we are going to review and learn all the variable types in Solidity, and how and when to use them.
Integers in Solidity
First off, we have signed and unsigned integer. The difference is that an unsigned integer cannot be negative whereas signed integers can be negative.
Unsigned integers are represented with uint
and signed integers are represented by int
.
However, the name of the type can use a suffix which is the bits that the number uses in memory.
So you have types int8
and uint8
up to uint256
and int256
with steps of 8
.
If you only put uint
or int
it's exactly like using uint256
and int256
, respectively.
Unsigned integers are usually more used than signed integers. For numbers, the go-to type is usually uint256
.
But you also have int256
if you want to use negative values.
Example:
uint256 myNumber = 123;
To sum up, usually the go-to type for integers is uint256
and if you want to support negative values it's int256
.
Both sign and unsigned integers support basic operations: additions, subtractions, multiplications, divisions and modulo.
They also support basic comparisons with <
, >
, <=
, >=
, !=
and ==
.
Lastly, with every of these integer types, you have shorthand syntaxes for operations like a = a + n
. So you have +=
, -=
, *=
, /=
, %=
.
To represent exponents, you can use **
so 10 to the power of 18 would be:10 ** 18
.
Booleans in Solidity
Booleans are represented with the bool
keyword in Solidity and the only possible values are true
or false
.
The logic operators that booleans have are:
!
(logical negation)&&
(logical conjunction, “and”)||
(logical disjunction, “or”)==
(equality)!=
(inequality)
Addresses in Solidity
Solidity has a type to represent addresses instead of using strings: address
.
There are 2 types of address types:
address
: holds an address and has the byte size of an Ethereum addressaddress payable
: Same asaddress
, but you can send and receive ETH from and to it.
The reason why there is a distinction is that address payable
is an address you can send Ether to while you're not sure if you can send ETH to a plain address
, for example because it might be a smart contract that was not made to accept ETH.
To convert and address
into a payable address
to be able to send ETH to it, you can do: payable(<address>)
(and replace <address>
with the variable you want to convert).
Strings in Solidity
Strings in Solidity hold characters between double quotes or single quotes. They work like arrays but don't have the same operations.
Strings don't support index based access of the values inside. Also, strings don't have the .length
property like arrays and they don't have all the other array functions like push
or pop
.
Also, Solidity doesn't have functions to easily manipulate strings although libraries exist for that.
However, you have the .concat()
function to concatenate two string values.
Example:
string a = "A";
string b = "B";
string c = a.concat(b); // equals "AB"
Bytes in Solidity
In Solidity the bytes
type represents a binary value. This type is used to store binary values. You have byte types from bytes1
to bytes32
.
You won't use that type very often but it's important to know it exists to not be surprised when you see it.
You can use it to store anything in binary as long as it's under the size of the type. If you use bytes32
, the value need to be less that or equal to 32B.
A few examples:
bytes32 a = "aaa"; // a string
bytes32 b = 0x01; // a binary value
bytes32 c = 1 // a number
The contract type in Solidity
When you create a contract in Solidity, you basically create a type. If you declare a contract A
, you can instantiate it in another contract and use its functions.
If I create an instance of a smart contract called MyContract
inside another smart contract and then check the type of that variable using the type
function, it will return MyContract
.
Enums in Solidity
Enums, or enumerables, in Solidity allow you to create your own type to represent choices, possible values for a variable or the state of something.
In the example below, I create a DeliveryStatus
enum that represents the state of a delivery.
Enums can be declared outside of a smart contract, inside of it or in a separate file that you can import to use the enum.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
enum DeliveryStatus {
Pending
Accepted
Rejected
Cancelled
Shipped
Delivered
FailedToDeliver
Returned
}
contract Order {
DeliveryStatus status;
// Returns uint
// Pending - 0
// Accepted - 1
// Rejected - 2
// Cancelled - 3
// Shipped - 4
// Delivered - 5
// FailedToDeliver - 6
// Returned - 7
function getStatus() public view returns (DeliveryStatus) {
return status;
}
// Update status by passing uint into input
function setStatus(DeliveryStatus _status) public {
status = _status;
}
// You can update to a specific enum like this
function cancelOrder() public {
status = DeliveryStatus.Cancelled;
}
}
The example above shows you how to create an enum and how to get and set the value of a variable that uses that enum type.
Note that when you get the value of a variable that uses an enum type, it will return you a uint
containing the position of the value in the enum declaration, starting at 0.
In our case, if status
is Pending
, the getStatus
function will return 0
. If the value is Accepted
, it's going to be 1
and so on.
To set a new value, you can either use a uint
with the position of the value you want to set in the enum (like in setStatus
) or you can use the enum and access the value you want directly (like in cancelOrder
).
Structs in Solidity
Structs in Solidity allow you to create a new data type that you can use to store complex data.
For example, if you want to store a person's information, you'll probably need variables for the name, age, email, gender and other things. Creating variables for all the data you need to store would be repetitive and you would only be ably to store information about a single person.
To avoid that problem, you can create a struct.
It's important to have in mind that a struct cannot have a variable of its own type inside of itself, not even in nested objects.
Like enums, you can declare them outside or inside a smart contract or in their own file and import it.
struct Entry {
address participant;
string email;
}
contract Lottery {
Entry[] public entries;
function createEntry(string calldata _email) public {
// 3 ways to initialize a struct
entries.push(Entry(msg.sender, _email));
// OR
// entries.push(Entry({participant:msg.sender, email:_email}));
// OR
// Entry memory entry;
// entry.participant = msg.sender;
// entry.email = _email;
// entries.push(entry);
}
// getting values
function getEntry(uint _index) public view returns (string memory email, address participant) {
Entry storage entry = entries[_index];
return (entry.email, entry.participant);
}
// update a value
function updateEmail(uint _index, string calldata _email) public {
entries[_index].email = email;
}
}
In the example above, you can see how to create a struct, how to create an instance of the struct and how to get and update a property of the struct (works like an object in other languages)
Arrays in Solidity
Arrays deserve an entire article because they need more explanations. You can find it here:
Mappings in Solidity
Finally, we have mappings. Mappings are basically like JSON. They are used to store any complex data with multiple properties in the format that you want, just like JSON.
To explain it differently, it's like an array but you can set the value you want in the indexes.
Here is an example:
contract MyToken {
mapping(address => uint256) balances;
function buyTokens(uint256 amount) public {
// add an element to the mapping
balances[msg.sender] = amount;
}
function sellTokens(uint256 amount) public {
// get a value
if (balances[msg.sender] >= amount) {
// update value
balances[msg.sender] = balances[msg.sender] - amount;
}
}
function sellAllTokens() public {
// completely remove a value
delete balances[msg.sender];
}
}
In the example above, you can see how to create a mapping, how to add a new value, how to delete a value how to get a value and how to update a value.
And that's it 🎉
Thank you for reading this article, if you want to get better at blockchain development, leave your email below and you'll get:
- access to the private Discord of a community of Web3 builders
- access to free guides that will teach you Blockchain Development