Enum
enum бол тодорхой нэрлэгдсэн утгуудын жагсаалт тодорхойлдог өгөгдлийн төрөл. Contract-ийн төлөвийг 0, 1, 2 тоогоор биш утга учиртай нэрээр (Pending, Shipped, Delivered) илэрхийлэх боломж олгодог.
Enum тодорхойлох
enum EnumName {
Value1,
Value2,
Value3
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
contract OrderSystem {
enum OrderStatus {
Pending, // 0
Confirmed, // 1
Shipped, // 2
Delivered, // 3
Cancelled // 4
}
}
Enum дотоодоо uint8 хэлбэрээр хадгалагддаг — Pending = 0, Confirmed = 1 гэх мэт. Гэхдээ кодод тоо биш нэрийг ашиглана.
Default утга
Enum-ийн default утга нь жагсаалтын эхний элемент — тоогоор бол 0.
contract StatusExample {
enum Status { Inactive, Active, Banned }
Status public userStatus; // default: Inactive (0)
function activate() public {
userStatus = Status.Active;
}
function isActive() public view returns (bool) {
return userStatus == Status.Active;
}
}
State machine загвар
State machine бол тодорхой төлөвүүдтэй, тэдгээр хоорондоо шилжих дүрэмтэй систем. Enum нь state machine-г хэрэгжүүлэхэд хамгийн тохиромжтой.
Pending → Confirmed → Shipped → Delivered
↓ ↑
Cancelled ←←←←←←←←←←←←←←←←←←←←←←
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
contract OrderTracking {
enum OrderStatus {
Pending, // захиалга өгсөн, баталгаажаагүй
Confirmed, // худалдагч баталгаажуулсан
Shipped, // тээвэрт гарсан
Delivered, // хүргэгдсэн
Cancelled // цуцлагдсан
}
struct Order {
uint256 id;
address buyer;
uint256 amount;
OrderStatus status;
uint256 createdAt;
}
mapping(uint256 => Order) public orders;
uint256 public orderCount;
address public owner;
constructor() {
owner = msg.sender;
}
function placeOrder() public payable returns (uint256 orderId) {
require(msg.value > 0, "ETH илгээх ёстой");
orderId = orderCount++;
orders[orderId] = Order({
id: orderId,
buyer: msg.sender,
amount: msg.value,
status: OrderStatus.Pending, // анхдагч төлөв
createdAt: block.timestamp
});
}
function confirmOrder(uint256 orderId) public {
require(msg.sender == owner, "Зөвхөн эзэмшигч");
require(orders[orderId].status == OrderStatus.Pending, "Pending төлөвт байх ёстой");
orders[orderId].status = OrderStatus.Confirmed;
}
function shipOrder(uint256 orderId) public {
require(msg.sender == owner, "Зөвхөн эзэмшигч");
require(orders[orderId].status == OrderStatus.Confirmed, "Confirmed төлөвт байх ёстой");
orders[orderId].status = OrderStatus.Shipped;
}
function confirmDelivery(uint256 orderId) public {
require(orders[orderId].buyer == msg.sender, "Зөвхөн худалдан авагч");
require(orders[orderId].status == OrderStatus.Shipped, "Shipped төлөвт байх ёстой");
orders[orderId].status = OrderStatus.Delivered;
// ETH-г худалдагчид шилжүүлэх логик...
}
function cancelOrder(uint256 orderId) public {
Order storage order = orders[orderId];
require(order.buyer == msg.sender, "Зөвхөн худалдан авагч");
require(
order.status == OrderStatus.Pending ||
order.status == OrderStatus.Confirmed,
"Энэ үед цуцлах боломжгүй"
);
order.status = OrderStatus.Cancelled;
payable(msg.sender).transfer(order.amount); // буцааж өгнө
}
function getStatus(uint256 orderId) public view returns (OrderStatus) {
return orders[orderId].status;
}
}
Enum харьцуулах ба шилжүүлэх
enum Phase { Setup, Active, Closed }
Phase public phase = Phase.Setup;
// харьцуулах
function isSetup() public view returns (bool) {
return phase == Phase.Setup;
}
// uint8 болгон хөрвүүлэх
function getPhaseNumber() public view returns (uint8) {
return uint8(phase); // Setup=0, Active=1, Closed=2
}
// uint8-аас enum болгон хөрвүүлэх
function setPhaseByNumber(uint8 n) public {
require(n <= uint8(Phase.Closed), "Хүчингүй утга");
phase = Phase(n);
}
Enum-г contract-ийн гадна тодорхойлох
Олон contract ашиглах тохиолдолд enum-г дахин ашиглах боломжтой:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
// Тусдаа файлд тодорхойлж, import хийж болно
enum UserRole {
Guest,
Member,
Moderator,
Admin
}
contract Forum {
mapping(address => UserRole) public roles;
function assignRole(address user, UserRole role) public {
roles[user] = role;
}
function canPost(address user) public view returns (bool) {
return roles[user] >= UserRole.Member;
}
function canModerate(address user) public view returns (bool) {
return roles[user] >= UserRole.Moderator;
}
}
Enum-ийн утгуудыг >=, <= операторуудаар харьцуулж болно — дотооддоо uint8 тул тооны харьцуулалт хийдэг.
Нийтлэг алдаа
enum Color { Red, Green, Blue }
// ❌ хүрээнээс гадуур хөрвүүлэх — runtime revert
Color c = Color(5); // 0,1,2 л хүчинтэй
// ✅ шалгаад хөрвүүлэх
function setColor(uint8 n) public {
require(n <= uint8(Color.Blue), "Хүчингүй өнгө");
myColor = Color(n);
}
Дараагийн хичээлд:
event ба emit — blockchain-д log бичих, frontend-д мэдэгдэл илгээх аргыг судална.