Lesson 08 of 25
Structs & Enums
Group related data with structs and represent states cleanly with enums.
BeginnerDefining and Using Structs
Structs let you bundle multiple fields into a single named type — similar to a class with only data fields.
Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract StructDemo {
struct Person {
string name;
uint256 age;
address wallet;
}
Person[] public people;
function addPerson(string memory _name, uint256 _age) public {
people.push(Person({
name: _name,
age: _age,
wallet: msg.sender
}));
}
function getPerson(uint256 idx) public view
returns (string memory, uint256, address)
{
Person storage p = people[idx]; // reference — not a copy
return (p.name, p.age, p.wallet);
}
}
Structs in Mappings
Combining structs with mappings is one of the most common Solidity patterns — used in virtually every DeFi protocol.
Solidity
contract UserRegistry {
struct User {
string username;
uint256 joinedAt;
bool isActive;
}
mapping(address => User) public users;
function register(string memory _username) public {
require(!users[msg.sender].isActive, "Already registered");
users[msg.sender] = User({
username: _username,
joinedAt: block.timestamp,
isActive: true
});
}
function deactivate() public {
require(users[msg.sender].isActive, "Not registered");
users[msg.sender].isActive = false;
}
}
Enums
Enums define a set of named constants. Under the hood they are
uint8 values starting from 0. Use them to represent discrete states.
Solidity
contract OrderStatus {
enum Status { Pending, Shipped, Delivered, Cancelled }
struct Order {
uint256 orderId;
address buyer;
Status status;
}
Order[] public orders;
function createOrder() public returns (uint256 id) {
id = orders.length;
orders.push(Order(id, msg.sender, Status.Pending));
}
function ship(uint256 id) public {
require(orders[id].status == Status.Pending, "Cannot ship");
orders[id].status = Status.Shipped;
}
function getStatus(uint256 id) public view returns (Status) {
return orders[id].status;
}
}