State variable ба local variable
Solidity-д хувьсагч хаана зарлагдаж, хаана хадгалагдах-аас хамаарч гурван ангилалд хуваагдана: state variable, local variable, global variable.
State variable — blockchain-д байнга хадгалагдана
State variable нь contract-ийн биеийн хэсэгт (функцийн гадна) зарлагдаж, Ethereum blockchain дээр байнга хадгалагдана.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
contract BankAccount {
// ↓ Эдгээр нь state variable — blockchain-д хадгалагдана
address public owner;
uint256 public balance;
bool public isLocked;
string public accountName;
}
Онцлог:
- Contract deploy хийсний дараа storage-д бичигдэнэ
- Transaction бүрийн дараа утга хадгалагдана — сүлжээ унтарч асахад алдагдахгүй
- Storage бичих (
SSTORE) нь хамгийн gas өндөртэй үйлдлүүдийн нэг - Шинэ утга хадгалах: ~20,000 gas, байгаа утга шинэчлэх: ~5,000 gas
// State variable өөрчлөх → transaction шаардана → gas зарцуулна
function deposit(uint256 amount) public {
balance += amount; // storage-д бичинэ
}
Local variable — функц дотор түр хадгалагдана
Local variable нь функцийн дотор зарлагдаж, функц дуусахад санах ойгоос арилна. Blockchain-д хадгалагдахгүй.
function calculateFee(uint256 amount) public pure returns (uint256) {
// ↓ Local variable — stack/memory-д хадгалагдана
uint256 feePercent = 3;
uint256 fee = (amount * feePercent) / 100;
uint256 result = amount - fee;
return result;
// функц дуусмагц feePercent, fee, result устана
}
Онцлог:
- Storage-д бичигдэхгүй тул gas хямд
- Stack эсвэл memory-д хадгалагдана
- Функц дуусахад утга алдагдана — дараагийн дуудалтад тэр утга байхгүй
function getDoubled(uint256 n) public pure returns (uint256) {
uint256 doubled = n * 2; // local variable
return doubled;
}
Global variable — Ethereum-ийн нөхцлийн мэдээлэл
Global variable нь Solidity-д урьдчилан тодорхойлогдсон тусгай хувьсагчид — зарлах шаардлагагүй, ашиглахад л бэлэн байна. Тухайн transaction, блок, илгээгчийн тухай мэдээлэл агуулна.
msg — илгээгчийн мэдээлэл
msg.sender // функцийг дуудаж байгаа хүний address
msg.value // илгээсэн ETH хэмжээ (wei-ээр)
msg.data // дуудалтын raw data
contract Owned {
address public owner;
constructor() {
owner = msg.sender; // deploy хийсэн хүн → owner болно
}
function getOwner() public view returns (address) {
return msg.sender; // функцийг дуудаж байгаа хүний хаяг
}
}
block — блокийн мэдээлэл
block.timestamp // блок үүссэн цаг (Unix timestamp, секундэд)
block.number // одоогийн блокийн дугаар
block.chainid // сүлжээний ID (Mainnet: 1, Sepolia: 11155111)
block.basefee // тухайн блокийн суурь gas үнэ
contract TimeLock {
uint256 public unlockTime;
constructor(uint256 lockDuration) {
// одоогийн цаг + хүлээлгийн хугацаа
unlockTime = block.timestamp + lockDuration;
}
function isUnlocked() public view returns (bool) {
return block.timestamp >= unlockTime;
}
}
tx — transaction-ийн мэдээлэл
tx.origin // анхны илгээгчийн address (хамгийн эхний дуудагч)
tx.gasprice // тухайн transaction-ийн gas price
⚠️ tx.origin-г аюулгүй байдлын шалгалтанд ашиглаж болохгүй — phishing attack-д өртөх эрсдэлтэй. Үүний оронд msg.sender ашигла.
Практик жишээ: гурвыг хамтад нь ашиглах
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
contract Vault {
// State variable — blockchain-д хадгалагдана
address public owner;
uint256 public totalDeposited;
mapping(address => uint256) public balances;
constructor() {
owner = msg.sender; // global variable
}
function deposit() public payable {
// msg.value → global variable
// balances[...] → state variable
uint256 amount = msg.value; // local variable
balances[msg.sender] += amount; // state variable шинэчлэх
totalDeposited += amount; // state variable шинэчлэх
}
function getMyBalance() public view returns (uint256) {
// msg.sender → global variable
// balances[...] → state variable унших
uint256 myBalance = balances[msg.sender]; // local variable
return myBalance;
}
function getTimestamp() public view returns (uint256) {
return block.timestamp; // global variable буцаана
}
}
Хадгалах байршлын ялгаа
| Хувьсагч | Хадгалагдах газар | Gas | Хугацаа | | --------------- | -------------------- | ------ | ------------- | | State variable | Storage (blockchain) | Өндөр | Байнга | | Local variable | Stack / Memory | Бага | Функц дотор | | Global variable | EVM-д суурилагдсан | Үнэгүй | Тухайн момент |
Нийтлэг алдаа
// ❌ БУРУУ — state variable шаардлагагүй үед
contract Bad {
uint256 result; // бүх дуудалтын үр дүн хуучнаа дарж бичнэ
function double(uint256 n) public returns (uint256) {
result = n * 2; // gas шаардлагагүй зарцуулж байна
return result;
}
}
// ✅ ЗӨВ — local variable ашиглах
contract Good {
function double(uint256 n) public pure returns (uint256) {
uint256 result = n * 2; // stack-д хадгалагдана, gas хямд
return result;
}
}
Storage бичих нь хамгийн gas өндөртэй үйлдэл тул шаардлагатай үед л state variable-д бич.
Дараагийн хичээлд:
Function-уудыг дэлгэрэнгүй — параметр, буцаах утга, function overloading-г судална.