Data types
In Solidity, data types specify the kind of values a variable can store. They are divided into two categories:
- Value Types → Data is copied when assigned or passed to functions.
- Reference Types → Data is stored by reference (like a pointer); multiple variables can point to the same storage location.
Understanding these types is crucial for efficient smart contract development.
1. Value Types
Value types are data types that store their data directly in the variable and are passed by value, meaning a copy of the data is created during assignment or function calls.
1.1 Boolean (bool)
The bool data type represents a logical value that can be either true or false. It is commonly used for conditional checks and control flow.
Characteristics:
- Only two possible values: true or false
- Default value is false
bool isVerified = true;
Example:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract BooleanExample {
bool public isActive = true;
function toggle() public {
isActive = !isActive; // Switches between true and false
}
}
1.2 Integer (int and uint)
Integer types are used to store whole numbers. Solidity supports both signed and unsigned integers with varying bit sizes.
Types:
- int → Signed integer (can store negative values)
- uint → Unsigned integer (only non-negative values)
Size Range: From 8 bits to 256 bits in steps of 8 (int8 to int256)
Default size: int256, uint256
uint count = 100;
int temperature = -20;
Example:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract IntegerExample {
uint public balance = 100; // Unsigned integer
int public temperature = -5; // Signed integer
function increaseBalance(uint amount) public {
balance += amount;
}
function decreaseTemperature(int amount) public {
temperature -= amount;
}
}
1.3 Address: Address Data Types in Solidity
Solidity provides two closely related address types:
- address
- address payable
Both represent Ethereum account addresses, but they differ in Ether transfer capability.
1.3.1 address (Non-Payable Address)
address is a 160-bit (20-byte) data type used to store an Ethereum account or contract address. It is mainly used for identification, access control, and interaction with contracts, but cannot send Ether directly.
Syntax:
address addr;
Key Characteristics:
- Stores EOA or contract address
- Cannot send Ether
- Can read Ether balance
- Used for ownership, permissions, mappings
Available Properties:
| Property | Description |
|---|---|
| addr.balance | Returns balance in wei |
| addr.code.length | Size of contract code at address |
Example – Using address for Ownership
pragma solidity ^0.8.0;
contract OwnerExample {
address public owner;
constructor() {
owner = msg.sender;
}
function isOwner(address user) public view returns (bool) {
return user == owner;
}
}
Explanation:
- msg.sender is assigned to an address
- No Ether transfer is involved
- Ideal use of address
When to Use address
- ✔ Storing owner/admin
- ✔ Access control
- ✔ Contract identification
- ✔ Mapping keys
- ❌ Ether transfer
1.3.2 address payable (Payable Address)
address payable is a specialized version of address that is allowed to send and receive Ether.
address payable payAddr;
Key Characteristics:
- Can send Ether
- Can receive Ether
- Required for all Ether transfers
- Used in payments, refunds, withdrawals
Example – Sending Ether
pragma solidity ^0.8.0;
contract PaymentExample {
function sendEther(address payable receiver) public payable {
require(msg.value > 0, "Send some Ether");
(bool success, ) = receiver.call{value: msg.value}("");
require(success, "Transfer failed");
}
}
Receiving Ether Example
pragma solidity ^0.8.0;
contract ReceiveEther {
receive() external payable {}
}
address a = msg.sender;
address payable p = payable(a);
1.4 Enum
An enum is a user-defined data type that represents a set of named constant values.
enum OrderStatus { Created, Shipped, Delivered }
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract EnumExample {
enum Status { Pending, Shipped, Delivered }
Status public orderStatus;
function setStatus(Status _status) public {
orderStatus = _status;
}
function getStatus() public view returns (Status) {
return orderStatus;
}
}
2. Reference Types
Reference types do not store data directly in the variable; instead, they store a reference to the data location. Changes made through one reference affect the original data.
2.1 String
The string data type is used to store human-readable text encoded in UTF-8 format.
Characteristics:
- Dynamic in size
- Expensive in terms of gas
string public courseName = "Solidity Programming";
Example:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract StringExample {
string public greeting = "Hello, Ethereum!";
function updateGreeting(string memory newGreeting) public {
greeting = newGreeting;
}
}
2.2 Bytes
The bytes data type stores variable-length raw binary data. It is more gas-efficient than string when handling binary information.
bytes public rawData;
Example:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract BytesExample {
bytes32 public fixedData = "SolidityBytes"; // Fixed-size
bytes public dynamicData = "DynamicBytes"; // Dynamic
function updateDynamicData(bytes memory newData) public {
dynamicData = newData;
}
}
Summary Table
| Data Type | Category | Example | Notes |
|---|---|---|---|
| bool | Value | bool isActive = true; | Stores true/false |
| uint / int | Value | uint256 age = 30; | Unsigned vs signed |
| address | Value | address owner = msg.sender; | Stores Ethereum addresses |
| enum | Value | enum Status {Pending, Shipped} | Custom states |
| string | Reference | string name = "Alice"; | Dynamic UTF-8 text |
| bytes | Reference | bytes32 data = "Hello"; | Raw binary data |
Key Takeaways
- Value types are copied, safe, and cheap.
- Reference types are pointers (need storage or memory keyword).
- Use strings for text, bytes for raw data, enums for states, and addresses for user/wallet identification.
Continue Learning
Explore more topics in Solidity or browse other tutorials.