Like other languages, Solidity provides various data types that allow developers to store and manipulate data efficiently. In this article, we’ll explore the fundamental data types in Solidity, their characteristics, and practical examples of their usage.
1. Numeric Types (Integer Types)
1.1. Integer Types (int and uint)
Solidity offers two main types of integers:
- int (signed integer) — can store both negative and positive values.
- uint (unsigned integer) — can store only non-negative values.
Each integer type can have different sizes, ranging from `8` to `256` bits (in increments of 8). Examples include:
- `int8`, `int16`, `int32`, ... `int256`
- `uint8`, `uint16`, `uint32`, ... `uint256`
By default, Solidity uses `uint256`, which is recommended for most cases to avoid precision issues.
Example:
contract IntegerExample {
int256 public signedNumber = -100;
uint256 public unsignedNumber = 100;
}
1.2. Arithmetic Operations
Solidity supports standard arithmetic operations:
- `+` (addition)
- `-` (subtraction)
- `*` (multiplication)
- `/` (division)
- `%` (modulus)
Important: Prior to Solidity 0.8.0, integer overflows and underflows were not checked, requiring the use of SafeMath. Starting from Solidity 0.8.0, overflow checks are built into the language.
Example:
contract MathExample {
function add(uint256 a, uint256 b) public pure returns (uint256) {
return a + b; // Addition
}
}
---
2. Boolean Type (bool)
The bool type stores only two values:
- `true` (logical true)
- `false` (logical false)
Boolean values are commonly used in conditions and logical operations.
Example:
contract BooleanExample {
bool public isActive = true;
function toggle() public {
isActive = !isActive; // Toggle the value
}
}
---
3. Strings and Bytes (Strings & Bytes)
3.1. Strings (string)
The string type is used to store text data.
Example:
contract StringExample {
string public greeting = "Hello, Solidity!";
}
Limitations:
- Individual characters in a string cannot be modified directly.
- String operations can be costly in terms of gas.
3.2. Byte Arrays (bytes and bytes32)
The bytes type is used for storing raw binary data.
- `bytes` — a dynamically sized byte array.
- `bytes1` to `bytes32` — fixed-size byte arrays (from 1 to 32 bytes).
Example:
contract BytesExample {
bytes32 public fixedData = "Solidity"; // Fixed-size bytes
bytes public dynamicData = "Hello"; // Dynamic bytes
}
When to use `string` vs. `bytes`?
- Use string when working with text intended for human reading.
- Use bytes when dealing with binary data or when optimizing for gas efficiency.
---
4. Address Type (address)
The address type is used to store Ethereum addresses (20 bytes).
4.1. address vs. address payable
- `address` — a standard Ethereum address.
- `address payable` — an address that can send and receive Ether.
Example:
contract AddressExample {
address public userAddress = 0x1234567890123456789012345678901234567890;
}
4.2. Address Functions
- `.balance` — checks the Ether balance of an address.
- `.transfer()` and `.send()` — send Ether to another address.
contract Wallet {
function getBalance(address _addr) public view returns (uint) {
return _addr.balance; // Get address balance
}
}
---
5. Arrays
5.1. Fixed-Size and Dynamic Arrays
- `uint256[5]` — an array of fixed size (5 elements).
- `uint256[]` — a dynamic array that can grow or shrink.
Example:
contract ArrayExample {
uint256[] public numbers;
function addNumber(uint256 _num) public {
numbers.push(_num); // Add an element
}
function getNumber(uint256 index) public view returns (uint256) {
return numbers[index]; // Retrieve element by index
}
}
---
6. Structs (Custom Data Structures)
Structs allow grouping multiple variables of different types into a single data type.
Example:
contract StructExample {
struct User {
string name;
uint256 age;
}
User public user = User("Alice", 25);
}
---
7. Enums (Enumerations)
Enums allow defining a fixed set of named values.
Example:
contract EnumExample {
enum Status { Pending, Active, Completed }
Status public currentStatus = Status.Pending;
function activate() public {
currentStatus = Status.Active;
}
}
---
Conclusion
Solidity provides a rich set of data types to efficiently manage and structure smart contract logic. Here are key takeaways:✔ Use uint for positive numbers to optimize gas usage.
✔ string is for textual data, while bytes is for raw binary storage.
✔ address is crucial for handling Ethereum addresses.
✔ arrays, structs, and enums help organize complex data structures.
By understanding these data types, you can write secure and optimized smart contracts for Ethereum and other EVM-compatible blockchains.