Menu
CoddyTech

Cheat sheet Solidity

Cấu trúc contract

Mỗi tệp bắt đầu bằng giấy phép và pragma; contract là đơn vị để triển khai.

Cú phápÝ nghĩa
// SPDX-License-Identifier: MITChú thích giấy phép mà trình biên dịch yêu cầu ở dòng 1
pragma solidity ^0.8.0;Phiên bản trình biên dịch mà tệp được viết cho
contract Counter { ... }Khai báo contract (state và hàm)
constructor(uint start) { count = start; }Chạy một lần, lúc triển khai
import "./Token.sol";Import một tệp khác
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";Import một package thư viện
interface IToken { function balanceOf(address a) external view returns (uint); }Khai báo interface (không có thân hàm)
library Math { function min(uint a, uint b) internal pure returns (uint) { ... } }Thư viện gồm các hàm dùng lại được

Kiểu giá trị

Số nguyên có kích thước cố định và không có phần thập phân; 0.8 sẽ revert khi tràn số.

KiểuGiá trị chứa được
uint256 / uintSố nguyên không dấu, từ 0 đến 2^256 - 1 (uint là uint256)
uint8, uint16, ... uint128Số nguyên không dấu nhỏ hơn, theo bước 8 bit
int256 / intSố nguyên có dấu (cho phép số âm)
booltrue hoặc false
addressĐịa chỉ tài khoản hoặc contract dài 20 byte
address payableĐịa chỉ có thể nhận Ether qua transfer/send
bytes32, bytes1...Mảng byte có kích thước cố định
enum Status { Open, Closed }Tập hằng số có tên, lưu dưới dạng uint8
1 ether, 1 gwei, 1 weiĐơn vị Ether: 1 ether = 10^18 wei
1 days, 2 hours, 30 minutesĐơn vị thời gian, tính bằng giây

Kiểu tham chiếu và vị trí dữ liệu

Mảng, chuỗi, bytes, struct và mapping nằm ở storage, memory hoặc calldata.

Cú phápÝ nghĩa
string memory nameChuỗi UTF-8 động (một bản sao tạm thời)
bytes memory dataMảng byte động
uint[] public scores;Mảng động trong storage
uint[3] fixed;Mảng cố định 3 phần tử
uint[] memory tmp = new uint[](5);Cấp phát một mảng trong memory
scores.push(42);Thêm phần tử vào mảng storage
scores.pop();Xóa phần tử cuối
scores.lengthSố phần tử
storageLưu lâu dài trên chuỗi, ghi tốn phí cao
memoryTạm thời, chỉ tồn tại trong một lần gọi
calldataĐầu vào chỉ đọc của hàm external, rẻ nhất

Mapping và struct

Mapping là bảng băm không có độ dài và không duyệt được; struct gom các trường lại với nhau.

Cú phápÝ nghĩa
mapping(address => uint) public balances;Kho khóa và giá trị, mọi khóa đều tồn tại (mặc định là 0)
balances[msg.sender] += 1;Đọc/ghi theo khóa
mapping(address => mapping(address => uint)) allowance;Mapping lồng nhau
struct User { string name; uint age; bool active; }Định nghĩa struct
User memory u = User("Ada", 36, true);Tạo struct trong memory
User memory u = User({name: "Ada", age: 36, active: true});Tạo theo tên trường
users[msg.sender] = u;Lưu struct vào mapping
users[msg.sender].age = 37;Cập nhật một trường trong storage
delete users[msg.sender];Đặt lại về giá trị mặc định

Hàm và visibility

Mỗi hàm khai báo ai được gọi nó và nó đọc hay ghi state.

Cú phápÝ nghĩa
function add(uint a, uint b) public pure returns (uint) { return a + b; }Hàm có tham số và giá trị trả về
publicGọi được từ mọi nơi (bên trong lẫn bên ngoài)
externalChỉ gọi được từ bên ngoài contract
internalContract này và các contract kế thừa nó
privateChỉ contract này
viewĐọc state, không bao giờ ghi
pureKhông đọc state nào cả
payableCó thể nhận Ether cùng lời gọi
returns (uint sum, bool ok)Nhiều giá trị trả về có tên
(uint s, bool ok) = f();Phân rã nhiều giá trị trả về
uint public count;Biến state public tự có hàm getter count()

Modifier, hằng số và kế thừa

Dùng lại các bước kiểm tra bằng modifier; cố định giá trị bằng constant và immutable.

Cú phápÝ nghĩa
modifier onlyOwner() { require(msg.sender == owner, "Not owner"); _; }Định nghĩa modifier (_ = chạy thân hàm)
function withdraw() public onlyOwner { ... }Áp dụng modifier
uint public constant MAX = 100;Hằng số lúc biên dịch
address public immutable owner;Gán một lần trong constructor, sau đó cố định
contract Token is ERC20, Ownable { ... }Kế thừa từ các contract khác
function f() public virtual { ... }Cho phép ghi đè
function f() public override { ... }Ghi đè hàm của contract cha
super.f();Gọi phần cài đặt của contract cha
abstract contract Base { function f() public virtual; }Contract có các hàm chưa cài đặt

Luồng điều khiển

Các câu lệnh quen thuộc của họ ngôn ngữ C; không có switch, và mỗi lần lặp đều tốn gas.

Cú phápÝ nghĩa
if (x > 5) { ... } else if (x > 2) { ... } else { ... }Rẽ nhánh theo điều kiện
for (uint i = 0; i < n; i++) { ... }Vòng lặp đếm
while (x < 10) { x++; }Lặp khi điều kiện còn đúng
do { ... } while (cond);Chạy ít nhất một lần
break; / continue;Thoát vòng lặp / bỏ qua sang lần lặp tiếp theo
x > 0 ? a : bBiểu thức ba ngôi
a / bChia lấy phần nguyên (bỏ phần dư)
a % bPhần dư
a ** 2Lũy thừa
unchecked { x++; }Bỏ qua kiểm tra tràn số (tiết kiệm gas, dùng cẩn thận)

Lỗi: require, revert, assert

Một bước kiểm tra thất bại sẽ hoàn tác toàn bộ giao dịch và hoàn lại phần gas chưa dùng.

Cú phápÝ nghĩa
require(amount > 0, "Amount must be positive");Kiểm tra đầu vào hoặc state; revert kèm thông báo
revert("Not allowed");Hủy ngay vô điều kiện
error Insufficient(uint available, uint requested);Khai báo lỗi tùy chỉnh (rẻ hơn dùng chuỗi)
revert Insufficient(balance, amount);Revert bằng lỗi tùy chỉnh
assert(total == a + b);Kiểm tra một bất biến không bao giờ được sai
try token.transfer(to, amt) returns (bool ok) { ... } catch { ... }Xử lý lời gọi bên ngoài bị lỗi

Event

Event ghi log để các ứng dụng ngoài chuỗi đăng ký theo dõi; contract không đọc được event.

Cú phápÝ nghĩa
event Transfer(address indexed from, address indexed to, uint value);Khai báo event
emit Transfer(msg.sender, to, amount);Phát event
indexedTham số lọc được (tối đa 3 tham số mỗi event)
event Log(string message);Ghi log được mọi kiểu ABI

Ether, địa chỉ và biến toàn cục

Ngữ cảnh giao dịch lấy từ msg, block và tx.

Cú phápÝ nghĩa
msg.senderĐịa chỉ đã gọi hàm này
msg.valueSố wei gửi kèm lời gọi (cần payable)
block.timestampThời gian của block hiện tại (số giây tính từ epoch)
block.numberChiều cao block hiện tại
tx.originTài khoản sở hữu bên ngoài đã khởi tạo giao dịch (tránh dùng để xác thực)
address(this).balanceSố dư Ether của contract này
payable(to).transfer(1 ether);Gửi Ether, revert khi thất bại
(bool ok, ) = to.call{value: amt}("");Gửi ở mức thấp, trả về cờ thành công
receive() external payable {}Chạy khi nhận Ether chuyển thẳng
fallback() external payable {}Chạy khi không có hàm nào khớp
keccak256(abi.encodePacked(a, b))Tính giá trị băm
abi.encode(x), abi.decode(data, (uint))Mã hóa / giải mã dữ liệu ABI

Mọi cú pháp Solidity bạn hay dùng, gom trong một trang. Cheat sheet Solidity này là bảng tra cứu nhanh cho ngôn ngữ smart contract của Ethereum và mọi chuỗi EVM: khai báo contract, chọn kiểu dữ liệu, lưu dữ liệu trong mapping và struct, viết hàm với visibility và mutability phù hợp, rồi bảo vệ chúng bằng require, modifier và event.

Cú pháp ở đây là Solidity 0.8, phiên bản mặc định kiểm tra tràn số học và dùng được với Remix, Hardhat và Foundry. Sao chép phần bạn cần, hoặc thử ngay trong playground Solidity: viết contract, biên dịch rồi chạy trên EVM ngay trong trình duyệt.

Solidity cheat sheet FAQ

Is this Solidity cheat sheet free?

Yes. This cheat sheet is free to use, with no sign-up required. Bookmark it and come back any time you need a quick reference.

Is this cheat sheet good for beginners?

Yes. It is organized by topic so you can find what you need at any level, and each entry links back to Coddy's free interactive Solidity course when you want to go deeper.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học Solidity cùng Coddy

Bắt đầu