Learning Objectives – after this chapter you will be able to:
- Declare an enum and use its members.
- Explain an enum’s default value and its conversion to and from integers.
- Model a simple state machine (e.g. an order life-cycle) with an enum.
Enum (Enumeration)
- An enum is a user-defined type whose value must be one of a fixed list of named constants.
- It gives meaningful names to a small set of related values, for example the states of an order:
Placed,Shipped,Delivered,Cancelled. - Syntax:
enum <Name> { Member1, Member2, ... }– no semicolon after the closing brace. - An enum can be declared inside a contract or at file level (outside any contract) so several contracts can share it.
Rules You Must Know
| Members | At least one and at most 256 members. |
| Storage | Represented internally as the smallest integer type that fits – uint8 for up to 256 members. |
| Order | Members are numbered in the order they are declared, starting at 0 (their “natural order”). |
| Default value | The first member (value 0). |
| Conversion | Only explicit: uint(status) and Status(2). Converting a number that is out of range reverts. |
| Limits | type(Status).min and type(Status).max give the first and last members. |
| ABI | Outside the contract (e.g. in Web3.js) an enum appears as a uint8 number. |
Benefits of Using Enumerations
- Readability –
Status.Shippedis clearer than the number 1. - Fewer errors – a variable can only hold valid members, so mistyped or out-of-range numbers are rejected.
- Easier maintenance – names are used throughout the code, so adding a state is simpler.
- Ideal for state machines – contracts often move through stages (open → closed → paid) and enums make each stage explicit.
- Gas-efficient – stored as a small integer.
Example : Order Status State Machine
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract OrderTracker {
enum Status { Placed, Shipped, Delivered, Cancelled } // 0, 1, 2, 3
Status public status; // default value: Status.Placed (0)
function ship() external {
require(status == Status.Placed, "Order not in Placed state");
status = Status.Shipped;
}
function deliver() external {
require(status == Status.Shipped, "Order not shipped yet");
status = Status.Delivered;
}
function cancel() external {
require(status == Status.Placed, "Too late to cancel");
status = Status.Cancelled;
}
function statusNumber() external view returns (uint) {
return uint(status); // explicit conversion to an integer
}
function setByNumber(uint n) external {
status = Status(n); // reverts if n > 3
}
function lastStatus() external pure returns (Status) {
return type(Status).max; // Status.Cancelled
}
}
Key Takeaways
- An enum is a named set of constants; its default is the first member.
- Members are numbered from 0 in declaration order; conversion to/from integers must be explicit.
- Enums with require checks are the standard way to build contract state machines.
Download | Print E-Notes
The PDF E-Notes are the earlier printable version of this chapter. The notes on this page are the latest, revised version.
Question / Answer (15 questions)
Answer : An enum is a user-defined type whose variables can only take one of a fixed set of named constant values, for example
enum Status { Placed, Shipped, Delivered }.Answer : Members follow their natural order – the order in which they are declared. The first member has the value 0, the second 1, and so on.
Answer : Its first member, whose integer value is 0.
Answer : At least one member and at most 256 members.
Answer : As the smallest unsigned integer type that can hold all its values – uint8 for enums with up to 256 members.
Answer : Explicitly:
uint(status) converts to an integer, and Status(n) converts an integer back. Implicit conversion is not allowed.Answer : The conversion is checked at run time and the transaction reverts with a Panic error.
Answer : With
type(Status).min and type(Status).max.Answer : Yes, enums can be declared at file level so that multiple contracts in the file (or files that import it) can use them.
Answer : In the ABI an enum is represented as a uint8 number, so the front end receives and sends numeric values.
Answer : More readable code, fewer errors because only valid members are allowed, and clear modelling of contract states; they are also cheap to store.
Answer : A state machine is a design in which a contract moves through defined stages and allows certain actions only in certain stages. An enum stores the current stage, and require checks enforce valid transitions.
Answer : The initial status is Placed, but deliver() requires the status to be Shipped, so the require check fails and the call reverts.
Answer : No. An enum declaration ends with the closing brace and no semicolon.
Answer :
enum candidateCode {AJIT, ASHISH, MAYANK, KUNAL, NOTA}. It gives each candidate a readable name that is converted to a number to use as the key of the candidate mapping.MCQ Test : Check Your Understanding (5 questions)
Select an option and press Check Answer, or answer all questions and press Submit Test to see your score. Each answer comes with an explanation.
Bibliography/References
The notes, questions and MCQs on this page are original explanations written for this course. The works listed below were consulted and are cited for attribution and further reading. Product names, logos and trademarks belong to their respective owners. Short quotations, where used, are marked and attributed.
- Solidity Team. (n.d.). Types (value types, reference types, mappings, operators, conversions). Solidity Documentation. https://docs.soliditylang.org/en/latest/types.html
- Solidity Team. (n.d.). Cheatsheet. Solidity Documentation. https://docs.soliditylang.org/en/latest/cheatsheet.html
- Microsoft Learn. (n.d.). When to Use an Enumeration (Visual Basic programming guide). https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/constants-enums/when-to-use-an-enumeration
- Modi, R. (2018). Solidity Programming Essentials: A beginner’s guide to build smart contracts for Ethereum and blockchain. Packt Publishing. ISBN 978-1-78883-138-3.