Nhảy đến nội dung chính

Hiểu hợp đồng thông minh token ERC-20

hợp đồng thông minh
tokens
Solidity
erc-20
Người mới bắt đầu
jdourlens
5 tháng 4, 2020
6 số phút đọc

Một trong những tiêu chuẩn hợp đồng thông minh quan trọng nhất trên Ethereum được gọi là ERC-20, đã nổi lên như một tiêu chuẩn kỹ thuật được sử dụng cho tất cả các hợp đồng thông minh trên chuỗi khối Ethereum để triển khai token có thể thay thế.

ERC-20 định nghĩa một danh sách các quy tắc chung mà tất cả các token Ethereum có thể thay thế phải tuân thủ. Do đó, tiêu chuẩn token này cho phép các nhà phát triển thuộc mọi loại dự đoán chính xác cách các token mới sẽ hoạt động trong hệ thống Ethereum lớn hơn. Điều này đơn giản hóa và giảm nhẹ các tác vụ của nhà phát triển, bởi vì họ có thể tiếp tục công việc của mình khi biết rằng mỗi dự án mới sẽ không cần phải làm lại mỗi khi một token mới được phát hành, miễn là token đó tuân theo các quy tắc.

Dưới đây là các hàm mà một ERC-20 phải triển khai, được trình bày dưới dạng một giao diện. Nếu bạn không chắc chắn giao diện là gì: hãy xem bài viết của chúng tôi về lập trình OOP trong Solidity (opens in a new tab).

1pragma solidity ^0.6.0;
2
3interface IERC20 {
4
5 function totalSupply() external view returns (uint256);
6 function balanceOf(address account) external view returns (uint256);
7 function allowance(address owner, address spender) external view returns (uint256);
8
9 function transfer(address recipient, uint256 amount) external returns (bool);
10 function approve(address spender, uint256 amount) external returns (bool);
11 function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
12
13
14 event Transfer(address indexed from, address indexed to, uint256 value);
15 event Approval(address indexed owner, address indexed spender, uint256 value);
16}
Hiện tất cả

Dưới đây là giải thích từng dòng về chức năng của mỗi hàm. Sau đây, chúng tôi sẽ trình bày một cách triển khai đơn giản của token ERC-20.

Các hàm getter

1function totalSupply() external view returns (uint256);

Trả về số lượng token đang tồn tại. Hàm này là một hàm getter và không sửa đổi trạng thái của hợp đồng. Lưu ý rằng không có kiểu dữ liệu số thực (float) trong Solidity. Do đó, hầu hết các token sử dụng 18 chữ số thập phân và sẽ trả về tổng nguồn cung cũng như các kết quả khác dưới dạng 1000000000000000000 cho 1 token. Không phải token nào cũng có 18 chữ số thập phân và đây là điều bạn thực sự cần lưu ý khi làm việc với các token.

1function balanceOf(address account) external view returns (uint256);

Trả về số lượng token thuộc sở hữu của một địa chỉ (account). Hàm này là một hàm getter và không sửa đổi trạng thái của hợp đồng.

1function allowance(address owner, address spender) external view returns (uint256);

Tiêu chuẩn ERC-20 cho phép một địa chỉ cấp quyền cho một địa chỉ khác để có thể lấy token từ đó. Hàm getter này trả về số lượng token còn lại mà spender sẽ được phép chi tiêu thay mặt cho owner. Hàm này là một hàm getter, không sửa đổi trạng thái của hợp đồng và sẽ trả về 0 theo mặc định.

Các hàm

1function transfer(address recipient, uint256 amount) external returns (bool);

Di chuyển số lượng token amount từ địa chỉ người gọi hàm (msg.sender) đến địa chỉ người nhận. Hàm này phát ra sự kiện Transfer được định nghĩa sau. Nó trả về true nếu việc chuyển có thể thực hiện được.

1function approve(address spender, uint256 amount) external returns (bool);

Đặt hạn mức (allowance) mà spender được phép chuyển từ số dư của người gọi hàm (msg.sender). Hàm này phát ra sự kiện Approval. Hàm trả về liệu hạn mức đã được đặt thành công hay chưa.

1function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

Di chuyển số lượng token amount từ sender đến recipient bằng cơ chế hạn mức. amount sau đó được trừ vào hạn mức của người gọi. Hàm này phát ra sự kiện Transfer.

Sự kiện

1event Transfer(address indexed from, address indexed to, uint256 value);

Sự kiện này được phát ra khi một lượng token (giá trị) được gửi từ địa chỉ from đến địa chỉ to.

Trong trường hợp đúc các token mới, việc chuyển thường là from địa chỉ 0x00..0000, trong khi trong trường hợp đốt token, việc chuyển là to 0x00..0000.

1event Approval(address indexed owner, address indexed spender, uint256 value);

Sự kiện này được phát ra khi số lượng token (value) được owner phê duyệt để spender sử dụng.

Một cách triển khai cơ bản của token ERC-20

Dưới đây là đoạn mã đơn giản nhất để bạn dựa vào đó tạo token ERC-20 của mình:

1pragma solidity ^0.8.0;
2
3interface IERC20 {
4
5 function totalSupply() external view returns (uint256);
6 function balanceOf(address account) external view returns (uint256);
7 function allowance(address owner, address spender) external view returns (uint256);
8
9 function transfer(address recipient, uint256 amount) external returns (bool);
10 function approve(address spender, uint256 amount) external returns (bool);
11 function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
12
13
14 event Transfer(address indexed from, address indexed to, uint256 value);
15 event Approval(address indexed owner, address indexed spender, uint256 value);
16}
17
18
19contract ERC20Basic is IERC20 {
20
21 string public constant name = "ERC20Basic";
22 string public constant symbol = "ERC";
23 uint8 public constant decimals = 18;
24
25
26 mapping(address => uint256) balances;
27
28 mapping(address => mapping (address => uint256)) allowed;
29
30 uint256 totalSupply_ = 10 ether;
31
32
33 constructor() {
34 balances[msg.sender] = totalSupply_;
35 }
36
37 function totalSupply() public override view returns (uint256) {
38 return totalSupply_;
39 }
40
41 function balanceOf(address tokenOwner) public override view returns (uint256) {
42 return balances[tokenOwner];
43 }
44
45 function transfer(address receiver, uint256 numTokens) public override returns (bool) {
46 require(numTokens <= balances[msg.sender]);
47 balances[msg.sender] = balances[msg.sender]-numTokens;
48 balances[receiver] = balances[receiver]+numTokens;
49 emit Transfer(msg.sender, receiver, numTokens);
50 return true;
51 }
52
53 function approve(address delegate, uint256 numTokens) public override returns (bool) {
54 allowed[msg.sender][delegate] = numTokens;
55 emit Approval(msg.sender, delegate, numTokens);
56 return true;
57 }
58
59 function allowance(address owner, address delegate) public override view returns (uint) {
60 return allowed[owner][delegate];
61 }
62
63 function transferFrom(address owner, address buyer, uint256 numTokens) public override returns (bool) {
64 require(numTokens <= balances[owner]);
65 require(numTokens <= allowed[owner][msg.sender]);
66
67 balances[owner] = balances[owner]-numTokens;
68 allowed[owner][msg.sender] = allowed[owner][msg.sender]-numTokens;
69 balances[buyer] = balances[buyer]+numTokens;
70 emit Transfer(owner, buyer, numTokens);
71 return true;
72 }
73}
Hiện tất cả

Một cách triển khai tuyệt vời khác của tiêu chuẩn token ERC-20 là cách triển khai ERC-20 của OpenZeppelin (opens in a new tab).

Lần cập nhật trang lần cuối: 21 tháng 8, 2025

Hướng dẫn này có hữu ích không?