Kiểm toán hợp đồng thông minh: làm gì, đọc thế nào
Nội dung bài9 phần
Độ khó: Trung cấp
Hợp đồng thông minh giữ tiền thật và gần như không thể sửa sau khi triển khai, nên một lỗi nhỏ cũng có thể thành khoản mất lớn. Kiểm toán là bước thuê chuyên gia đọc mã trước khi dự án chạy để tìm lỗi. Bài này giải thích kiểm toán gồm những gì, cách đọc một báo cáo và những điều báo cáo không bảo đảm.
Nội dung chỉ nhằm giải thích kiến thức, không phải khuyến nghị đầu tư.
Điểm chính
- Kiểm toán là một lượt rà soát mã của người ngoài, không phải bảo hành an toàn.
- Báo cáo gắn với một phiên bản mã cụ thể; sửa mã sau đó là mã chưa được kiểm.
- Đọc phần lỗi nghiêm trọng và trạng thái đã sửa hay chưa, không chỉ đọc dòng "đạt".
- Ethereum.org nêu rõ kiểm toán không bắt được mọi lỗi.
Kiểm toán làm những gì
Nhóm kiểm toán đọc mã nguồn (thường là Solidity) và chạy công cụ tự động để tìm chỗ sai logic, chỗ cho phép rút tiền trái phép và chỗ tốn gas không cần thiết. Họ không đảm bảo dự án có lãi hay đội ngũ đáng tin, chỉ nhận xét về mã.
Nguyên tắc cốt lõi: hợp đồng đã triển khai rất khó sửa, nên phải tìm lỗi trước khi có tiền trong đó.
Quy trình thường gặp
Bước | Việc làm | Sản phẩm |
|---|---|---|
1. Chốt phạm vi | Xác định hợp đồng nào, phiên bản mã nào được kiểm | Danh sách tệp và mã băm phiên bản |
2. Rà soát thủ công | Chuyên gia đọc từng hàm, vẽ luồng tiền | Ghi chú lỗi |
3. Kiểm tra tự động | Chạy công cụ phân tích và kiểm thử | Danh sách cảnh báo |
4. Báo cáo nháp | Đội dự án xem và phản hồi từng lỗi | Bản nháp kèm trạng thái |
5. Sửa và kiểm lại | Dự án sửa, auditor xác nhận lỗi đã đóng | Báo cáo cuối công bố |

Bước 1 quyết định giá trị của cả báo cáo: chỉ phần mã nằm trong phạm vi mới được kiểm.
Ví dụ lỗi hay bị bắt: reentrancy
Reentrancy (gọi lại) là lỗi kinh điển. Hàm withdraw() gửi ETH cho người dùng rồi mới đặt số dư của họ về 0. Hợp đồng của kẻ tấn công nhận tiền, rồi gọi lại withdraw() ngay trong lúc nhận, khi số dư vẫn chưa về 0.

Ví dụ số: hợp đồng giữ 10 ETH, kẻ tấn công gửi vào 1 ETH. Mỗi lần gọi lại hợp đồng trả thêm 1 ETH vì số dư chưa bị trừ; lặp 10 lần là rút sạch 10 ETH. Cách chữa được Ethereum.org nêu: cập nhật số dư trước khi gửi tiền (checks-effects-interactions), dùng khoá chặn gọi đệ quy, hoặc để người dùng tự rút.
Vụ The DAO năm 2016 là bản lớn của lỗi cùng họ: Ethereum Foundation gọi đó là "lỗ hổng gọi đệ quy", và Ethereum.org ghi 3,6 triệu ETH bị lấy.
Mức nghiêm trọng trong báo cáo
Mỗi lỗi trong báo cáo có một mức, mỗi bên kiểm toán đặt tên hơi khác nhau nhưng khung chung như sau:
Mức | Ý nghĩa thực tế |
|---|---|
Nghiêm trọng (Critical) | Có thể mất tiền của người dùng hoặc dự án |
Cao (High) | Có thể gây thiệt hại lớn trong điều kiện nhất định |
Trung bình (Medium) | Gây sai lệch hoạt động, khó khai thác trực tiếp |
Thấp (Low) | Sai sót nhỏ, ít ảnh hưởng |
Thông tin (Informational) | Gợi ý viết mã tốt hơn |
Mỗi lỗi còn có trạng thái: đã sửa, đã ghi nhận nhưng chưa sửa, hoặc không sửa kèm lý do. Lỗi nghiêm trọng "chưa sửa" là dấu hiệu cần dừng lại.
Hai ví dụ: sửa mã là rủi ro mới
Uranium Finance, 28/04/2021. Theo phân tích của Immunefi, kẻ tấn công lấy hơn 50 triệu USD trên 26 cặp giao dịch. Uranium sao chép logic hoán đổi của Uniswap V2 nhưng đổi hệ số phí sang giá trị 10000 mà phép so sánh bất biến (K) vẫn dùng 1000. Kết quả là phép kiểm tra lỏng hơn 100 lần, cho phép rút cạn quỹ bằng lượng vào rất nhỏ.
Bài học: mã gốc được dùng rộng rãi vẫn có thể thành lỗ hổng chỉ vì một hằng số bị đổi ở bản sao.
Compound, Proposal 62, 29/09/2021. Đề xuất này tách phần thưởng COMP cho bên gửi và bên vay, và theo Compound đã đưa vào một lỗi khiến người dùng ở một số thị trường nhận COMP nhiều hơn dự định. Theo Compound, 163 nghìn COMP bị nhận sai đã được trả lại kho cộng đồng, 130 nghìn COMP còn nằm trong Comptroller có thể bị nhận sai, và khoảng 200 nghìn COMP phân bổ nhầm còn chưa hoàn lại tại thời điểm bản tin viết. Cộng đồng sau đó cam kết kiểm thử và mô phỏng kỹ hơn trước các đề xuất sau.
Bài học: một nâng cấp mã trên giao thức lớn vẫn là mã mới, và mã mới cần được kiểm như mã mới.
Cách làm: đọc báo cáo trước
- Tìm báo cáo trên trang của dự án hoặc của bên kiểm toán; không có báo cáo công khai là một dấu hiệu cần tính đến.
- Xem ngày kiểm toán và phiên bản mã. So với mã đang chạy trên chuỗi.
- Đọc phần lỗi mức nghiêm trọng và cao, xem trạng thái đã sửa chưa.
- Xem phạm vi: hợp đồng bạn tương tác có nằm trong báo cáo không.
- Kiểm tra dự án có chương trình bug bounty (thưởng báo lỗi) tương xứng số tiền đang giữ, theo khuyến nghị của Ethereum.org.
- Đối chiếu thêm các dấu hiệu ở bài cách phát hiện dự án DeFi lừa đảo và rủi ro rug pull.
Điều kiểm toán không bảo đảm
- Không bắt hết lỗi: Ethereum.org nêu rõ kiểm toán không phải viên đạn bạc.
- Không bao phủ mã đổi sau đó.
- Không đánh giá khoá quản trị, người giữ quyền nâng cấp hay thiết kế kinh tế.
- Không chứng minh toán học là mã đúng. Phương pháp chứng minh nằm ở bài formal verification hợp đồng thông minh.

Về các lỗ hổng cụ thể, xem lỗ hổng bảo mật cầu nối chuỗi.
Học tiếp trong khoá Crypto
Các bài học liên quan trong Khoá học Crypto của HODL.VN:
Câu hỏi thường gặp
Mã đã kiểm toán có an toàn tuyệt đối không?
Không. Kiểm toán giảm rủi ro nhưng không loại bỏ; Ethereum.org nói rõ nó không bắt được mọi lỗi. Mã đổi sau kiểm toán cũng nằm ngoài báo cáo.
Kiểm toán khác bug bounty thế nào?
Kiểm toán là một nhóm được thuê rà soát trong thời gian nhất định. Bug bounty mời nhiều nhà nghiên cứu bên ngoài báo lỗi liên tục và trả thưởng khi tìm thấy.
Nên tin báo cáo của bên nào?
Không có bảng xếp hạng chung. Hãy đọc nội dung báo cáo: phạm vi, lỗi nghiêm trọng, trạng thái sửa, thay vì chỉ nhìn tên bên kiểm toán.
Dự án không có kiểm toán thì sao?
Đó là mức rủi ro cao hơn vì chưa ai ngoài đội phát triển rà mã. Người dùng nên đánh giá khoản tiền mình sẵn sàng mất.
Kiểm toán một lần có đủ không?
Chỉ đủ cho phiên bản mã đã kiểm. Mỗi lần nâng cấp lớn cần kiểm lại, như bài học từ các nâng cấp gây lỗi ở trên.
Duyệt bởi Ban biên tập HODL.VN · Cập nhật 09/11/2026
Ứng dụng HODL
Tải app HODL
Bảng giá, cảnh báo giá và bài phân tích ngay trên điện thoại.