Buổi 5 — Hợp đồng thông minh (Smart Contracts)

Môn học: Blockchain: Nền tảng, Ứng dụng & Bảo mật
Giảng viên: Trần Tuấn Dũng


Mục tiêu buổi học


1. Smart Contract là gì?

1.1 Lịch sử & Ý tưởng sơ khai

Ý tưởng về Hợp đồng thông minh có từ rất lâu trước cả Bitcoin. Vào năm 1994, nhà mật mã học Nick Szabo đã đưa ra định nghĩa đầu tiên, ví von Hợp đồng thông minh với một chiếc máy bán hàng tự động.

1.2 Ví von kinh điển: Máy bán hàng tự động

graph LR A["NẾU bạn bỏ vào đúng số tiền..."] --> B["VÀ bạn nhấn nút chọn món hàng..."] B --> C["THÌ máy sẽ tự động nhả ra món hàng đó."]

Chiếc máy này có các đặc tính giống hệt một Hợp đồng thông minh:

1.3 Định nghĩa chính thức


2. Solidity

Solidity là ngôn ngữ lập trình chính để viết Hợp đồng thông minh trên Ethereum và các blockchain tương thích EVM khác.

2.1 Hello World

// 1. Khai báo phiên bản trình biên dịch
pragma solidity ^0.8.20;

// 2. Khai báo Hợp đồng
contract HelloWorld {
    // 3. Khai báo một biến trạng thái (State Variable)
    string public greet = "Hello, World!";
}

2.2 Biến trạng thái (State Variables)

Biến trạng thái là các biến có giá trị được lưu trữ vĩnh viễn trên blockchain. Chúng đại diện cho “bộ nhớ” của hợp đồng.

contract SimpleStorage {
    // Biến này sẽ được lưu mãi mãi trên blockchain
    uint256 public favoriteNumber;
}

2.3 Hàm (Functions)

Hàm là các khối mã có thể thực thi. Chúng là cách chúng ta tương tác và thay đổi trạng thái của hợp đồng.

contract SimpleStorage {
    uint256 public favoriteNumber;

    // Một hàm để thay đổi biến trạng thái
    function store(uint256 _newNumber) public {
        favoriteNumber = _newNumber;
    }

    // Một hàm chỉ để đọc biến trạng thái (không tốn gas)
    function retrieve() public view returns (uint256) {
        return favoriteNumber;
    }
}

So sánh Hàm Write vs. Hàm Read

Tiêu chíHàm thay đổi trạng thái (Write)Hàm chỉ đọc (Read)
Mục đíchThay đổi dữ liệu trên blockchainĐọc dữ liệu từ blockchain
Từ khóa(không có)view, pure
Chi phí Gas, vì thay đổi trạng tháiKHÔNG, khi được gọi từ bên ngoài
Thực thiCần một giao dịch, được xác thực bởi toàn mạng lướiThực thi tức thì trên một node duy nhất
Ví dụtransfer(), mint()balanceOf(), ownerOf()

2.4 Kiểu dữ liệu

Kiểu dữ liệu cơ bản

KiểuMô tả
booltrue / false
uint / intSố nguyên không dấu và có dấu (ví dụ: uint256)
addressLưu trữ địa chỉ Ethereum (20 bytes). Có .balance, .transfer()
stringChuỗi ký tự
bytesDãy byte động

Kiểu dữ liệu phức hợp

Mảng (Arrays):

uint[] public numbers;

Struct:

struct Person { string name; uint age; }

Mappings — cấu trúc dữ liệu dạng key-value, giống hash table / dictionary. Rất hiệu quả về gas:

// Ánh xạ từ một địa chỉ tới một số dư
mapping(address => uint) public balances;

2.5 Visibility (Phạm vi truy cập)

Từ khóaAi có thể gọi?Ghi chú
publicBất kỳ ai (bên ngoài hoặc nội bộ)Tự động tạo ra một hàm getter
privateChỉ bên trong hợp đồng nàyKhông thể được truy cập bởi hợp đồng con
internalBên trong hợp đồng này và các hợp đồng con kế thừa nóGiống protected trong các ngôn ngữ khác
externalChỉ từ bên ngoài hợp đồng (qua giao dịch)Tối ưu gas khi nhận dữ liệu lớn

3. Vòng đời của một Smart Contract

graph TD A["✍️ 1. Viết mã (Code)\nNhà phát triển viết logic bằng Solidity"] --> B["⚙️ 2. Biên dịch (Compile)\nSolidity → Bytecode + ABI"] B --> C["🚀 3. Triển khai (Deploy)\nGửi Bytecode lên mạng Ethereum\nTạo ra tài khoản hợp đồng mới"] C --> D["🤝 4. Tương tác (Interact)\nGọi hàm qua giao dịch đến địa chỉ hợp đồng"]

4. Tiêu chuẩn Smart Contract (ERC)


4.1 ERC-20: Token Có thể thay thế (Fungible)

Fungible = mỗi đơn vị đều giống hệt nhau và có thể thay thế cho nhau. Ví dụ: một tờ 100.000 VNĐ này có giá trị y hệt một tờ 100.000 VNĐ khác.

ERC-20 định nghĩa một bộ hàm chung cho các token, cho phép chúng được niêm yết trên sàn giao dịch và được lưu trữ trong ví một cách dễ dàng.

Ví dụ: USDT, SHIB, UNI, LINK…

Các hàm cốt lõi của ERC-20

function totalSupply() public view returns (uint256);
function balanceOf(address account) public view returns (uint256);
function transfer(address recipient, uint256 amount) public returns (bool);
function allowance(address owner, address spender) public view returns (uint256);
function approve(address spender, uint256 amount) public returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) public returns (bool);

4.2 ERC-721: Token Không thể thay thế (Non-Fungible)

Non-Fungible = mỗi token là duy nhất và không thể thay thế cho token khác. Ví dụ: bức tranh Mona Lisa không giống với bất kỳ bức tranh nào khác.

ERC-721 cho phép tạo ra các tài sản số độc nhất, có thể chứng minh quyền sở hữu và nguồn gốc.

Ứng dụng: Tác phẩm nghệ thuật số, vật phẩm trong game, vé sự kiện, tên miền…

Các hàm cốt lõi của ERC-721

function balanceOf(address owner) public view returns (uint256);
function ownerOf(uint256 tokenId) public view returns (address);
function safeTransferFrom(address from, address to, uint256 tokenId) public;
function approve(address to, uint256 tokenId) public;
function getApproved(uint256 tokenId) public view returns (address);

4.3 So sánh ERC-20 và ERC-721

Tiêu chíERC-20ERC-721
Loại tokenFungible (có thể thay thế)Non-Fungible (không thể thay thế)
Tính duy nhấtMọi token đều giống nhauMỗi token là duy nhất
Ví dụ thực tếTiền tệ, cổ phiếuNFT, nghệ thuật số, vật phẩm game
Hàm định danhbalanceOf(address)ownerOf(tokenId)
Ví dụ tokenUSDT, UNI, LINKCryptoPunks, BAYC


📝 50 Câu trắc nghiệm ôn tập


Phần 1: Smart Contract — Khái niệm & Lịch sử

Câu 1. Nick Szabo đưa ra khái niệm Hợp đồng thông minh vào năm nào?

  • A. 1989
  • B. 1994
  • C. 2008
  • D. 2015

Câu 2. Nick Szabo ví von Hợp đồng thông minh với thứ gì?

  • A. Hợp đồng giấy tờ công chứng
  • B. Máy tính lượng tử
  • C. Máy bán hàng tự động
  • D. Ngân hàng trung ương

Câu 3. Hợp đồng thông minh được định nghĩa chính thức là gì?

  • A. Hợp đồng pháp lý số hóa được lưu trên máy chủ trung tâm
  • B. Các chương trình máy tính lưu trên blockchain, tự động thực thi khi điều kiện được đáp ứng
  • C. Ứng dụng web3 kết nối với ngân hàng
  • D. Tài khoản người dùng trên Ethereum

Câu 4. Smart Contract về cơ bản là loại tài khoản nào?

  • A. Tài khoản được điều khiển bởi ngân hàng
  • B. Tài khoản được điều khiển bởi con người
  • C. Tài khoản được điều khiển bởi mã nguồn
  • D. Tài khoản ẩn danh

Câu 5. Đặc tính nào của Smart Contract đảm bảo rằng các quy tắc không thể bị một bên đơn phương thay đổi?

  • A. Self-executing
  • B. Transparent
  • C. Immutable
  • D. Disintermediated

Câu 6. Đặc tính nào của Smart Contract giúp loại bỏ sự cần thiết của bên trung gian?

  • A. Immutable
  • B. Disintermediated
  • C. Transparent
  • D. Compiled

Câu 7. Blockchain nào đầu tiên được thiết kế như một “Máy tính Thế giới” (World Computer) với khả năng lập trình Turing-complete?

  • A. Bitcoin
  • B. Litecoin
  • C. Ethereum
  • D. Solana

Phần 2: Solidity — Ngôn ngữ lập trình

Câu 8. Solidity chịu ảnh hưởng cú pháp từ những ngôn ngữ nào?

  • A. Java, Ruby, Swift
  • B. C++, Python, JavaScript
  • C. Go, Rust, Kotlin
  • D. PHP, Perl, Bash

Câu 9. Solidity là kiểu ngôn ngữ lập trình nào?

  • A. Thông dịch, hướng thủ tục
  • B. Biên dịch, hướng đối tượng
  • C. Thông dịch, hướng đối tượng
  • D. Biên dịch, hướng chức năng

Câu 10. Môi trường thực thi mà Solidity được thiết kế để hoạt động là gì?

  • A. JVM (Java Virtual Machine)
  • B. V8 Engine
  • C. EVM (Ethereum Virtual Machine)
  • D. WASM (WebAssembly)

Câu 11. Dòng pragma solidity ^0.8.20; có tác dụng gì?

  • A. Import thư viện Solidity
  • B. Khai báo tên hợp đồng
  • C. Khai báo phiên bản trình biên dịch
  • D. Định nghĩa hàm khởi tạo

Câu 12. Biến trạng thái (State Variable) trong Solidity được lưu trữ ở đâu?

  • A. RAM của node
  • B. Vĩnh viễn trên blockchain
  • C. Trên máy chủ của Ethereum Foundation
  • D. Trong bộ nhớ tạm thời

Câu 13. Hành động nào dưới đây tốn Gas nhiều nhất trong Solidity?

  • A. Gọi hàm view
  • B. Đọc một biến public
  • C. Thay đổi giá trị biến trạng thái
  • D. Gọi hàm pure

Câu 14. Từ khóa view trong hàm Solidity có nghĩa là gì?

  • A. Hàm có thể thay đổi trạng thái
  • B. Hàm chỉ đọc dữ liệu, không thay đổi trạng thái
  • C. Hàm được gọi nội bộ
  • D. Hàm nhận ETH

Câu 15. Hàm Write khác hàm Read ở điểm gì về cách thực thi?

  • A. Hàm Write chạy nhanh hơn
  • B. Hàm Write cần một giao dịch, được xác thực bởi toàn mạng lưới
  • C. Hàm Write không cần Gas
  • D. Hàm Write chỉ chạy trên một node duy nhất

Câu 16. Kiểu dữ liệu nào trong Solidity dùng để lưu địa chỉ Ethereum?

  • A. string
  • B. bytes32
  • C. address
  • D. uint160

Câu 17. Kiểu address có những thuộc tính đặc biệt nào?

  • A. .length.push()
  • B. .balance.transfer()
  • C. .name.symbol()
  • D. .owner.approve()

Câu 18. mapping(address => uint) trong Solidity tương đương với cấu trúc dữ liệu nào?

  • A. Mảng (Array)
  • B. Hàng đợi (Queue)
  • C. Hash table / Dictionary
  • D. Stack

Câu 19. struct trong Solidity dùng để làm gì?

  • A. Khai báo hàm
  • B. Tạo ra các kiểu dữ liệu phức tạp tùy chỉnh
  • C. Định nghĩa sự kiện (event)
  • D. Import thư viện

Câu 20. Visibility nào tương đương với protected trong các ngôn ngữ lập trình khác?

  • A. public
  • B. private
  • C. internal
  • D. external

Câu 21. Visibility nào KHÔNG thể được truy cập bởi hợp đồng con?

  • A. public
  • B. internal
  • C. private
  • D. external

Câu 22. Visibility nào tối ưu Gas nhất khi nhận dữ liệu lớn từ bên ngoài?

  • A. public
  • B. private
  • C. internal
  • D. external

Câu 23. Khi khai báo biến trạng thái public, Solidity tự động làm gì?

  • A. Tạo một hàm setter
  • B. Tạo một hàm getter
  • C. Mã hóa biến đó
  • D. Emit một event

Câu 24. Hàm nào dưới đây là ví dụ của hàm Write (thay đổi trạng thái)?

  • A. balanceOf()
  • B. ownerOf()
  • C. totalSupply()
  • D. transfer()

Câu 25. Kiểu dữ liệu bool trong Solidity nhận những giá trị nào?

  • A. 0 và 1
  • B. truefalse
  • C. yesno
  • D. nullundefined

Phần 3: Vòng đời Smart Contract

Câu 26. Bước đầu tiên trong vòng đời của một Smart Contract là gì?

  • A. Triển khai (Deploy)
  • B. Biên dịch (Compile)
  • C. Viết mã (Code)
  • D. Tương tác (Interact)

Câu 27. Kết quả của bước Biên dịch (Compile) là gì?

  • A. Token ERC-20 và ERC-721
  • B. Bytecode và ABI
  • C. Gas và Gwei
  • D. Block và Transaction

Câu 28. Bytecode là gì?

  • A. Mã Python đã được rút gọn
  • B. File JSON mô tả các hàm của hợp đồng
  • C. Mã máy cấp thấp mà EVM có thể hiểu và thực thi
  • D. Địa chỉ của hợp đồng trên blockchain

Câu 29. ABI (Application Binary Interface) là gì?

  • A. Mã máy cấp thấp cho EVM
  • B. File JSON mô tả các hàm của hợp đồng để bên ngoài tương tác
  • C. Địa chỉ public của hợp đồng
  • D. Ngôn ngữ lập trình thay thế Solidity

Câu 30. Khi triển khai (Deploy) Smart Contract, điều gì xảy ra?

  • A. Hợp đồng được lưu trên máy chủ của Infura
  • B. Bytecode được gửi lên Ethereum và một tài khoản hợp đồng mới được tạo ra
  • C. ABI được upload lên IPFS
  • D. Token ERC-20 được mint tự động

Câu 31. Sau khi triển khai, người dùng tương tác với Smart Contract bằng cách nào?

  • A. Gửi email đến nhà phát triển
  • B. Gửi giao dịch đến địa chỉ của hợp đồng
  • C. Gọi API REST truyền thống
  • D. Chỉnh sửa trực tiếp mã nguồn

Câu 32. Sau khi Smart Contract được triển khai, mã nguồn có thể bị thay đổi không?

  • A. Có, nếu người triển khai có private key
  • B. Có, nếu có đủ 51% node đồng ý
  • C. Không, mã nguồn không thể thay đổi sau khi triển khai (Immutable)
  • D. Có, thông qua ABI

Phần 4: Tiêu chuẩn ERC

Câu 33. ERC là viết tắt của gì?

  • A. Ethereum Research Community
  • B. Ethereum Request for Comment
  • C. Extended Request Contract
  • D. Ethereum Runtime Code

Câu 34. Tại sao cần có các tiêu chuẩn ERC?

  • A. Để thu phí Gas cho Ethereum Foundation
  • B. Để các hợp đồng, ví, sàn giao dịch có thể hiểu và tương tác với nhau
  • C. Để hạn chế số lượng token trên Ethereum
  • D. Để mã hóa dữ liệu người dùng

Câu 35. ERC-20 là tiêu chuẩn cho loại token nào?

  • A. Non-Fungible Token (NFT)
  • B. Fungible Token (Token có thể thay thế)
  • C. Governance Token
  • D. Soulbound Token

Câu 36. “Fungible” có nghĩa là gì?

  • A. Mỗi token là duy nhất
  • B. Mỗi đơn vị đều giống hệt nhau và có thể thay thế cho nhau
  • C. Token không thể chuyển nhượng
  • D. Token được mã hóa bằng ZK-proof

Câu 37. Token nào dưới đây là ví dụ của ERC-20?

  • A. CryptoPunks
  • B. Bored Ape Yacht Club
  • C. USDT
  • D. ENS Domain

Câu 38. Hàm totalSupply() trong ERC-20 trả về gì?

  • A. Số lượng người dùng đang giữ token
  • B. Tổng cung của token
  • C. Số dư token của một địa chỉ
  • D. Lượng Gas đã tiêu thụ

Câu 39. Hàm balanceOf(address account) trong ERC-20 làm gì?

  • A. Kiểm tra số ETH của một địa chỉ
  • B. Trả về số lượng token ERC-20 mà địa chỉ đó đang nắm giữ
  • C. Chuyển token từ địa chỉ này sang địa chỉ khác
  • D. Phê duyệt quyền chi tiêu

Câu 40. Hàm approve() trong ERC-20 dùng để làm gì?

  • A. Xác nhận giao dịch trên blockchain
  • B. Phê duyệt cho một địa chỉ khác (spender) được phép chi tiêu một lượng token nhất định
  • C. Tạo ra token mới
  • D. Khóa token trong smart contract

Câu 41. Hàm transferFrom() trong ERC-20 được dùng khi nào?

  • A. Người dùng tự chuyển token của mình
  • B. Một hợp đồng thứ ba chuyển token thay mặt người dùng, sau khi đã được approve
  • C. Mint token mới cho người dùng
  • D. Đốt (burn) token

Câu 42. ERC-721 là tiêu chuẩn cho loại token nào?

  • A. Fungible Token
  • B. Stablecoin
  • C. Non-Fungible Token (NFT)
  • D. Wrapped Token

Câu 43. “Non-Fungible” có nghĩa là gì?

  • A. Token có thể thay thế cho nhau
  • B. Mỗi token là duy nhất và không thể thay thế cho token khác
  • C. Token không thể giao dịch
  • D. Token cố định giá trị

Câu 44. Hàm đặc trưng nhất của ERC-721, phân biệt nó với ERC-20, là hàm nào?

  • A. balanceOf()
  • B. approve()
  • C. ownerOf(uint256 tokenId)
  • D. transfer()

Câu 45. Ứng dụng nào dưới đây phù hợp với ERC-721?

  • A. Tiền ổn định (Stablecoin) như USDT
  • B. Vé sự kiện độc nhất, tác phẩm nghệ thuật số
  • C. Token quản trị (Governance)
  • D. Token thanh khoản (LP Token)

Câu 46. Hàm safeTransferFrom() trong ERC-721 khác gì so với transfer() trong ERC-20?

  • A. safeTransferFrom() không tốn Gas
  • B. safeTransferFrom() bao gồm tokenId vì mỗi NFT là duy nhất, không chỉ chuyển một lượng
  • C. safeTransferFrom() chỉ hoạt động với ETH
  • D. Không có sự khác biệt

Câu 47. Trong ERC-20, allowance(owner, spender) trả về gì?

  • A. Số dư token của owner
  • B. Lượng token mà spender được phép dùng từ tài khoản của owner
  • C. Tổng cung token
  • D. Địa chỉ hợp đồng

Câu 48. Điểm khác biệt cơ bản nhất giữa ERC-20 và ERC-721 là gì?

  • A. ERC-20 dùng Solidity, ERC-721 dùng ngôn ngữ khác
  • B. ERC-20 là fungible (có thể thay thế), ERC-721 là non-fungible (độc nhất)
  • C. ERC-20 rẻ Gas hơn ERC-721
  • D. ERC-721 ra đời trước ERC-20

Phần 5: Tổng hợp & Nâng cao

Câu 49. Trong Solidity, hàm pure khác view ở điểm nào?

  • A. pure tốn Gas hơn view
  • B. pure không đọc cũng không thay đổi trạng thái blockchain
  • C. pure chỉ dùng cho ERC-721
  • D. pure không thể được gọi từ bên ngoài

Câu 50. Nếu muốn xây dựng một hệ thống điểm tích lũy (loyalty points) mà mỗi điểm có giá trị như nhau, bạn nên dùng tiêu chuẩn nào?

  • A. ERC-721
  • B. ERC-20
  • C. Cả hai đều được
  • D. Không dùng tiêu chuẩn nào

Câu 51. Tại sao khi gọi hàm view hoặc pure từ bên ngoài, người dùng không tốn Gas?

  • A. Vì Ethereum miễn phí cho hàm đọc
  • B. Vì không có thay đổi trạng thái nào được ghi lên blockchain, không cần sự đồng thuận của mạng lưới
  • C. Vì hàm view chạy offline
  • D. Vì Infura trả Gas thay cho người dùng

Câu 52. Để triển khai một Smart Contract, người triển khai cần gì?

  • A. Được phép từ Ethereum Foundation
  • B. Gửi một giao dịch đặc biệt chứa bytecode và trả Gas
  • C. Có ít nhất 32 ETH để staking
  • D. Chạy một Ethereum node đầy đủ

Câu 53. Trong vòng đời Smart Contract, bước nào tạo ra ABI?

  • A. Viết mã (Code)
  • B. Biên dịch (Compile)
  • C. Triển khai (Deploy)
  • D. Tương tác (Interact)

Câu 54. Mapping trong Solidity có nhược điểm gì so với Array?

  • A. Mapping tốn Gas hơn Array
  • B. Mapping không thể duyệt (iterate) qua tất cả phần tử
  • C. Mapping chỉ hỗ trợ kiểu uint làm key
  • D. Mapping không thể lưu dữ liệu vĩnh viễn

Câu 55. Smart Contract có thể nhận ETH không? Điều kiện là gì?

  • A. Không, Smart Contract không thể nhận ETH
  • B. Có, nhưng phải có hàm receive() hoặc fallback() được khai báo
  • C. Có, mọi contract đều tự động nhận ETH
  • D. Có, nhưng chỉ từ địa chỉ của người triển khai