Structs and enums

Group related data with structs. Represent state machines with enums.

Structs

Structs let you group related data into a single named type — essential for anything more complex than a single value per address.

solidity
struct Position {
    uint256 amount;        // Token amount deposited
    uint256 entryPrice;    // Price at deposit time
    uint256 timestamp;     // When the position was opened
    address owner;
}

mapping(uint256 => Position) public positions;
uint256 public nextPositionId;

function openPosition(uint256 amount, uint256 price) external returns (uint256 id) {
    id = nextPositionId++;
    positions[id] = Position({
        amount: amount,
        entryPrice: price,
        timestamp: block.timestamp,
        owner: msg.sender
    });
}

Structs in memory vs. storage

When you read a struct from storage and plan to modify it, use a storage reference to avoid copying.

solidity
// Efficient: modifies storage in-place
function updateAmount(uint256 id, uint256 newAmount) external {
    Position storage pos = positions[id];
    require(pos.owner == msg.sender, 'Not owner');
    pos.amount = newAmount;
}

// Inefficient: copies entire struct to memory just to read one field
function getAmount(uint256 id) external view returns (uint256) {
    Position memory pos = positions[id];  // full copy
    return pos.amount;
    // Better: return positions[id].amount;
}

Enums

Enums define a fixed set of named states. Under the hood they're stored as uint8 values. They make state-machine logic readable and less error-prone than using raw integers.

solidity
enum OrderStatus { Pending, Filled, Cancelled, Expired }

struct Order {
    address maker;
    uint256 amount;
    OrderStatus status;
}

mapping(uint256 => Order) public orders;

function cancelOrder(uint256 orderId) external {
    Order storage order = orders[orderId];
    require(order.maker == msg.sender, 'Not maker');
    require(order.status == OrderStatus.Pending, 'Cannot cancel');
    order.status = OrderStatus.Cancelled;
}

Enums are readable but limited

Solidity enums don't have names at runtime — they're just integers. When you emit an event or return an enum, the ABI encodes it as a uint8. Your frontend needs the ABI to decode it back to a human-readable name.

solidity
// Returning an enum
function getStatus(uint256 orderId) external view returns (OrderStatus) {
    return orders[orderId].status;
}
// Returns 0 for Pending, 1 for Filled, 2 for Cancelled, 3 for Expired
←   Mappings and arraysEvents and logging   →