Lisk Smart Contract
Solidity Basics 02 - Main Contract Structure

Cấu trúc hợp đồng (Contract structure)

Biến trạng thái và biến cục bộ (State and local variables)

Biến trạng thái là các biến được khai báo ở phần đầu tiên của contract, bên ngoài phạm vi của biến cục bộ được khai báo trong function.

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
 
contract Bank {
    uint public totalDeposits; // Biến trạng thái toàn cục
 
    function deposit(uint amount) public {
        uint fee = amount / 100; // 1% fee, biến cục bộ
        uint netAmount = amount - fee;
 
        totalDeposits += netAmount; // cập nhật biến trạng thái
    }
 
    function getNetAmount() public view returns (uint) {
        // return netAmount; // Lỗi: netAmount chỉ tồn tại trong hàm deposit
        return totalDeposits; // Đúng: totalDeposits là biến trạng thái
    }
}

[Giải thích]

totalDeposits là biến trạng thái – tồn tại trên blockchain và có thể được truy cập từ bất kỳ hàm nào trong contract.

feenetAmount là biến cục bộ – chỉ tồn tại trong nội bộ hàm deposit.

Nếu bạn cố truy cập netAmount từ hàm khác như getNetAmount, trình biên dịch sẽ báo lỗi giống như ví dụ bạn đã đưa ra.

Hàm (Functions)

Hàm là các function được khai báo để thực hiện tính toán, thay đổi giá trị biến, v.v. Một ví dụ về function như sau.

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.1 <0.9.0;
 
contract GradeBook {
    mapping(address => uint) public scores;
 
    function submitScore(uint score) public {
        require(score <= 100, "Score must be between 0 and 100");
        scores[msg.sender] = score;
    }
 
    function getGrade() public view returns (string memory) {
        uint score = scores[msg.sender];
        return convertToGrade(score);
    }
}
 
// Hàm trợ giúp nằm ngoài contract
function convertToGrade(uint score) pure returns (string memory) {
    if (score >= 90) return "A";
    else if (score >= 80) return "B";
    else if (score >= 70) return "C";
    else if (score >= 60) return "D";
    else return "F";
}

[Giải thích]

GradeBook lưu trữ điểm của mỗi người dùng trong một mapping.

getGrade() sử dụng convertToGrade(score) – một helper function nằm ngoài contract – để xác định hạng điểm.

Hàm helper không thể truy cập vào trạng thái của contract

Bộ sửa đổi hàm (Function modifiers)

Function modifier là các khai báo cho function để tạo điều kiện cho việc thực thi hành động của hàm đó.

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.22 <0.9.0;
 
contract Voting {
    address public chairperson;
    mapping(address => bool) public voters;
 
    constructor() {
        chairperson = msg.sender;
    }
 
    // hàm Modifier chỉ cho phép người dùng là chairperson mới có thể thực hiện hàm addVoter
    modifier onlyChairperson() {
        require(msg.sender == chairperson, "Only chairperson can perform this action");
        _;
    }
 
    function addVoter(address voter) public onlyChairperson {
        require(!voters[voter], "Already registered");
        voters[voter] = true;
    }
 
    function isRegistered(address voter) public view returns (bool) {
        return voters[voter];
    }
}
 
 

[Giải thích]

onlyChairperson là một modifier dùng để giới hạn quyền truy cập – chỉ cho phép chairperson gọi một số hàm nhất định.

Hàm addVoter() sử dụng modifier này để đảm bảo chỉ người triển khai hợp đồng (Chair person) mới được phép đăng ký cử tri.

Sự kiện (Events) và lỗi (Errors)

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

contract Bank {
    mapping(address => uint) private balances;

    // 🔔 Sự kiện được phát khi người dùng nạp tiền
    event Deposited(address indexed user, uint amount);

    // 🔔 Sự kiện được phát khi người dùng rút tiền thành công
    event Withdrawn(address indexed user, uint amount);

    // ❌ Lỗi tùy chỉnh khi không đủ số dư
    error InsufficientBalance(uint requested, uint available);

    // Hàm nạp tiền
    function deposit() public payable {
        balances[msg.sender] += msg.value;
        emit Deposited(msg.sender, msg.value); // Phát sự kiện
    }

    // Hàm rút tiền có xử lý lỗi tùy chỉnh
    function withdraw(uint amount) public {
        uint balance = balances[msg.sender];
        if (amount > balance) {
            revert InsufficientBalance(amount, balance); // Gọi lỗi tùy chỉnh
        }

        balances[msg.sender] -= amount;
        payable(msg.sender).transfer(amount);

        emit Withdrawn(msg.sender, amount); // Phát sự kiện
    }

    // Hàm xem số dư
    function getBalance() public view returns (uint) {
        return balances[msg.sender];
    }
}

Giải thích

Sự kiện:

  1. event Deposited(address, uint) – ghi lại các giao dịch nạp tiền
  1. event Withdrawn(address, uint) – ghi lại các giao dịch rút tiền
  1. Sự kiện được dùng để giao tiếp với frontend hoặc theo dõi lịch sử giao dịch qua logs.

Lỗi tùy chỉnh:

  1. error InsufficientBalance(uint requested, uint available);