Solidity / view ба pure function

view ба pure function

Solidity-д function-ууд blockchain-ийн state-г ямар байдлаар ашигладаг-аас хамаарч гурван ангилалд хуваагдана: өөрчлөх, зөвхөн унших (view), огт хүрэхгүй (pure). Зөв ангилал сонгосноор gas хэмнэнэ ба кодын санаа илэрхий болно.

State-д ямар үйлдэл хийдгийн ангилал

код
State өөрчлөх          → energy дохио байхгүй (default)
State унших            → view
State-д огт хүрэхгүй  → pure

view function

view function нь blockchain-ийн state-г зөвхөн уншдаг, өөрчилдөггүй.

solidity
contract Scoreboard {
    mapping(address => uint256) public scores;
    uint256 public topScore;

    // ✅ view — state унших ч өөрчлөхгүй
    function getScore(address player) public view returns (uint256) {
        return scores[player];
    }

    function isTopPlayer(address player) public view returns (bool) {
        return scores[player] == topScore;
    }

    // msg.sender, block.timestamp зэрэг global variable унших ч view
    function getMyScore() public view returns (uint256) {
        return scores[msg.sender];
    }
}

view function-ийг гаднаас дуудахад gas үнэгүй — transaction илгээхгүй тул газ зарцуулдаггүй. Зөвхөн локал node-оос өгөгдөл унших тул мөнгө шаардахгүй.

код
scores[player] унших → gas: 0 (view)
scores[player] += 1  → gas: ~5,000+ (state өөрчлөлт)

view-д хориотой үйлдлүүд

solidity
contract ViewRules {
    uint256 public value;

    function badView() public view returns (uint256) {
        value = 10;        // ❌ state өөрчилж байна
        return value;
    }
}
// Compile error: Function declared as view, but this expression (potentially) modifies the state

view дотор хориотой үйлдлүүд:

код
❌ State variable-д утга оноох
❌ Event emit хийх
❌ Өөр contract үүсгэх (new)
❌ ETH илгээх
❌ low-level call ашиглах

pure function

pure function нь state-г уншдаг ч үгүй, өөрчилдөг ч үгүй. Зөвхөн параметрүүд дээр тооцоолол хийж, утга буцаана.

solidity
contract MathLibrary {
    // ✅ pure — параметраас л хамаарна, state-д хүрэхгүй
    function add(uint256 a, uint256 b) public pure returns (uint256) {
        return a + b;
    }

    function factorial(uint256 n) public pure returns (uint256 result) {
        result = 1;
        for (uint256 i = 2; i <= n; i++) {
            result *= i;
        }
    }

    function max(uint256 a, uint256 b) public pure returns (uint256) {
        return a >= b ? a : b;
    }

    function toWei(uint256 ether_amount) public pure returns (uint256) {
        return ether_amount * 1e18;
    }
}

pure function-г дуудахад мөн gas үнэгүй — transaction шаардахгүй.

pure-д хориотой үйлдлүүд

solidity
contract PureRules {
    uint256 public data = 5;

    function badPure() public pure returns (uint256) {
        return data;      // ❌ state variable унших — view шаардана
    }

    function alsoBadPure() public pure returns (uint256) {
        return block.timestamp;  // ❌ global variable унших — view шаардана
    }
}

pure дотор хориотой:

код
❌ State variable унших
❌ State variable өөрчлөх
❌ msg.sender, msg.value унших
❌ block.timestamp, block.number унших
❌ address(this).balance унших

view vs pure харьцуулалт

solidity
contract Comparison {
    uint256 public multiplier = 3;

    // pure — параметраас л хамаарна
    function doubleIt(uint256 n) public pure returns (uint256) {
        return n * 2;
    }

    // view — state variable (multiplier) унших тул pure болохгүй
    function multiplyIt(uint256 n) public view returns (uint256) {
        return n * multiplier;
    }

    // view ч биш, pure ч биш — state өөрчилдөг
    function setMultiplier(uint256 newMult) public {
        multiplier = newMult;
    }
}

Gas хэмнэлт: зөв ангилал сонгох

Гаднаас дуудах (call) үед:

код
pure / view → gas: 0       (read-only, transaction байхгүй)
default     → gas: 21000+  (transaction, mining шаардана)

Contract дотроос дуудах үед pure/view мөн gas хэмнэнэ — storage-д хандахгүй тул SLOAD opcode зарцуулдаггүй.

solidity
contract GasComparison {
    uint256[] public numbers;

    // ❌ storage-г дахин дахин уншина → gas өндөр
    function sumExpensive() public view returns (uint256 total) {
        for (uint256 i = 0; i < numbers.length; i++) {
            total += numbers[i];
        }
    }

    // ✅ memory-д нэг удаа хуулаад уншина → gas хямд
    function sumCheap() public view returns (uint256 total) {
        uint256[] memory nums = numbers;   // нэг удаа storage → memory
        for (uint256 i = 0; i < nums.length; i++) {
            total += nums[i];
        }
    }
}

Практик дүрэм

код
Тооцоолол, хөрвүүлэлт, логик шалгалт → pure
State унших, msg.sender шалгах         → view
State өөрчлөх, event гаргах, ETH явуулах → (тэмдэглэгдэхгүй)
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

contract PracticalExample {
    address public owner;
    uint256 public balance;

    constructor() {
        owner = msg.sender;
    }

    // pure — зөвхөн тооцоолол
    function calculateFee(uint256 amount) public pure returns (uint256) {
        return (amount * 3) / 100;
    }

    // view — state унших
    function getNetAmount(uint256 amount) public view returns (uint256) {
        uint256 fee = calculateFee(amount);   // pure дуудаж болно
        return balance + amount - fee;
    }

    // state өөрчлөх
    function deposit(uint256 amount) public {
        uint256 fee = calculateFee(amount);   // pure дуудаж болно
        balance += (amount - fee);
    }
}

Дараагийн хичээлд:

Constructor — contract deploy хийх үед нэг удаа ажиллах тусгай функц, owner загварыг судална.