Solidity / Function үндэс

Function үндэс

Function бол contract-ийн ажиллах логикийг агуулсан кодын хэсэг. Solidity-д function бичих синтакс болон параметр, буцаах утга ашиглах аргыг энэ хичээлд судална.

Function-ийн үндсэн бүтэц

solidity
function нэр(параметрийн_төрөл параметрийн_нэр) visibility returns (буцаах_төрөл) {
    // логик
}

Жишээ:

solidity
function add(uint256 a, uint256 b) public returns (uint256) {
    return a + b;
}

Хэсэг бүрийг задлаад үзье:

код
function     → түлхүүр үг
add          → function-ийн нэр
(uint256 a, uint256 b) → параметрүүд: төрөл + нэр
public       → visibility (хэн дуудаж болох)
returns (uint256) → буцааж өгөх утгын төрөл
{ return a + b; } → функцийн бие

Параметргүй, буцаалтгүй function

solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

contract SimpleCounter {
    uint256 public count;

    // параметр байхгүй, буцаалт байхгүй
    function increment() public {
        count += 1;
    }

    function reset() public {
        count = 0;
    }
}

Параметртэй function

solidity
contract Calculator {
    // нэг параметр
    function double(uint256 n) public pure returns (uint256) {
        return n * 2;
    }

    // хоёр параметр
    function add(uint256 a, uint256 b) public pure returns (uint256) {
        return a + b;
    }

    // гурав ба түүнээс дээш параметр
    function clamp(uint256 value, uint256 min, uint256 max) public pure returns (uint256) {
        if (value < min) return min;
        if (value > max) return max;
        return value;
    }
}

Олон утга буцаах

Solidity-д function нэгээс олон утга буцааж болно — энэ нь JavaScript-ийн [a, b] array буцаахтай ялгаатай, tuple хэлбэрээр ажилладаг.

solidity
contract MultiReturn {
    // хоёр утга буцаана
    function minMax(uint256 a, uint256 b) public pure returns (uint256 min, uint256 max) {
        if (a < b) {
            return (a, b);
        } else {
            return (b, a);
        }
    }

    // гурван утга буцаана
    function getInfo() public pure returns (string memory name, uint256 age, bool active) {
        return ("Болд", 25, true);
    }
}

Нэрлэсэн буцаалт (named return)returns-д нэр өгвөл return бичихгүйгээр л утга буцаах боломжтой:

solidity
function divide(uint256 a, uint256 b) public pure returns (uint256 result, uint256 remainder) {
    result    = a / b;
    remainder = a % b;
    // return бичихгүй ч result ба remainder автоматаар буцана
}

Function дуудах

Contract дотроос дуудах:

solidity
contract MathHelper {
    function square(uint256 n) public pure returns (uint256) {
        return n * n;
    }

    function sumOfSquares(uint256 a, uint256 b) public pure returns (uint256) {
        // өөрийн функцийг шууд дуудна
        return square(a) + square(b);
    }
}

Олон утга буцаадаг функцийг дуудах:

solidity
contract Caller {
    MathHelper helper;

    function test(uint256 a, uint256 b) public pure returns (uint256, uint256) {
        // tuple destructuring
        (uint256 lo, uint256 hi) = sortTwo(a, b);
        return (lo, hi);
    }

    function sortTwo(uint256 x, uint256 y) internal pure returns (uint256, uint256) {
        if (x < y) return (x, y);
        return (y, x);
    }
}

Зарим утга авахгүй бол _ тавина:

solidity
(uint256 lo, ) = sortTwo(5, 3);   // зөвхөн lo авна, hi-г орхино

Параметрийн memory ба calldata

string, bytes, array зэрэг reference type параметрт санах ойн байршил заах шаардлагатай:

solidity
// memory — функц дотор хуулбар үүснэ, өөрчлөх боломжтой
function greet(string memory name) public pure returns (string memory) {
    return name;
}

// calldata — хуулбар үүсгэхгүй, зөвхөн уншина — gas хямд
function greetExternal(string calldata name) external pure returns (string memory) {
    return name;
}

calldata нь external функцийн параметрт зөвхөн ашиглагдана. memory-тай харьцуулахад gas хямд тул боломж байвал calldata ашигла.

Нийтлэг загвар: validate → update → return

solidity
contract BankAccount {
    mapping(address => uint256) public balances;

    function deposit(uint256 amount) public returns (uint256 newBalance) {
        require(amount > 0, "Дүн тэгээс их байх ёстой");   // 1. шалгах
        balances[msg.sender] += amount;                      // 2. шинэчлэх
        newBalance = balances[msg.sender];                   // 3. буцаах
    }

    function withdraw(uint256 amount) public returns (bool success) {
        require(amount > 0, "Дүн тэгээс их байх ёстой");
        require(balances[msg.sender] >= amount, "Үлдэгдэл хүрэлцэхгүй");

        balances[msg.sender] -= amount;
        success = true;
    }
}

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

public, private, internal, external — function visibility-ийн ялгаа, аюулгүй байдалд яагаад чухал болохыг судална.