Solidity / State variable ба local variable

State variable ба local variable

Solidity-д хувьсагч хаана зарлагдаж, хаана хадгалагдах-аас хамаарч гурван ангилалд хуваагдана: state variable, local variable, global variable.

State variable — blockchain-д байнга хадгалагдана

State variable нь contract-ийн биеийн хэсэгт (функцийн гадна) зарлагдаж, Ethereum blockchain дээр байнга хадгалагдана.

solidity
// 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
solidity
// State variable өөрчлөх → transaction шаардана → gas зарцуулна
function deposit(uint256 amount) public {
    balance += amount;   // storage-д бичинэ
}

Local variable — функц дотор түр хадгалагдана

Local variable нь функцийн дотор зарлагдаж, функц дуусахад санах ойгоос арилна. Blockchain-д хадгалагдахгүй.

solidity
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-д хадгалагдана
  • Функц дуусахад утга алдагдана — дараагийн дуудалтад тэр утга байхгүй
solidity
function getDoubled(uint256 n) public pure returns (uint256) {
    uint256 doubled = n * 2;   // local variable
    return doubled;
}

Global variable — Ethereum-ийн нөхцлийн мэдээлэл

Global variable нь Solidity-д урьдчилан тодорхойлогдсон тусгай хувьсагчид — зарлах шаардлагагүй, ашиглахад л бэлэн байна. Тухайн transaction, блок, илгээгчийн тухай мэдээлэл агуулна.

msg — илгээгчийн мэдээлэл

solidity
msg.sender   // функцийг дуудаж байгаа хүний address
msg.value    // илгээсэн ETH хэмжээ (wei-ээр)
msg.data     // дуудалтын raw data
solidity
contract Owned {
    address public owner;

    constructor() {
        owner = msg.sender;   // deploy хийсэн хүн → owner болно
    }

    function getOwner() public view returns (address) {
        return msg.sender;    // функцийг дуудаж байгаа хүний хаяг
    }
}

block — блокийн мэдээлэл

solidity
block.timestamp   // блок үүссэн цаг (Unix timestamp, секундэд)
block.number      // одоогийн блокийн дугаар
block.chainid     // сүлжээний ID (Mainnet: 1, Sepolia: 11155111)
block.basefee     // тухайн блокийн суурь gas үнэ
solidity
contract TimeLock {
    uint256 public unlockTime;

    constructor(uint256 lockDuration) {
        // одоогийн цаг + хүлээлгийн хугацаа
        unlockTime = block.timestamp + lockDuration;
    }

    function isUnlocked() public view returns (bool) {
        return block.timestamp >= unlockTime;
    }
}

tx — transaction-ийн мэдээлэл

solidity
tx.origin      // анхны илгээгчийн address (хамгийн эхний дуудагч)
tx.gasprice    // тухайн transaction-ийн gas price

⚠️ tx.origin-г аюулгүй байдлын шалгалтанд ашиглаж болохгүй — phishing attack-д өртөх эрсдэлтэй. Үүний оронд msg.sender ашигла.

Практик жишээ: гурвыг хамтад нь ашиглах

solidity
// 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-д суурилагдсан | Үнэгүй | Тухайн момент |

Нийтлэг алдаа

solidity
// ❌ БУРУУ — 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-г судална.