28 May, 2025 by
Smartcontract: Bộ đếm on-chain với Hardhat
Bạn có thể tăng tốc quá trình phát triển Web App với Javascript/NextJS, Web Server với Rust/Rocket.rs, Mobile App với Dash/Flutter, và cùng nguyên tắc đó ta có phát triển smartcontract với Solidity/Hardhat.
Khởi tạo dự án
Tạo folder dự án cs01
và cài đặt hardhat
:
Khởi tạo hardhat. Lưu ý, chúng ta phải chọn Create a TypeScript project (with Viem)
và y
cho tất cả các cài đặt còn lại.
Sau khi hoàn tất, ta được cấu trúc thư mục như bên dưới:
Trong đó hardhat.config.ts
là cài đặt Hardhat, thư mục contracts
chứa code solidity, thư mục ignition
chứa scripts triển khai contracts, và thư mục test
để kiểm thử contracts.
Chạy thử lệnh npx hardhat compile
,
Quan hệ giữa Smartcontract, Solidity, và ABI
Bạn sẽ phát triển smartcontract bằng Solidity và biên dịch ra mã máy bằng Solidity Compiler. Blockchain sẽ lưu trữ và thực thi mã máy này. Tuy nhiên để tương tác với smartcontract thông qua các ngôn ngữ lập trình như Javascript, Python,... chúng ta cần định nghĩa lại interface của contract một cách thủ công. Điều này được chuẩn hoá bởi Solidity Compiler bằng cách tạo ra một sản phẩm phụ mang tên ABI (Application Binary Interface) trong quá trình biên dịch. Với ABI, các ngôn ngữ lập trình có thể nhanh chóng hiểu và tương tác với smartcontract.
Sản phẩm của Solidity Compiler. Nguồn ảnh: https://medium.com/coinmonks/smart-contract-and-its-compilation-process-34868abccb69
Bộ đếm on-chain
Có thể xoá contracts mẫu của hardhat,
contracts/Lock.sol
.
Chúng ta sẽ viết một smartcontract đơn giản với biến counter
được khởi tạo bằng 0
và một hàm increase
để tăng +1
cho mỗi lần gọi. Đối với hàm increase
, ta chỉ cho phép owner
truy cập và emit một sự kiện Increase
cho mỗi lần gọi thành công.
Đối với logic contract đã được chuẩn hoá cao như Ownership
, token ERC20
, thư viện toán MathSafe
,... thay vì phải viết lại cho mỗi lần phát triển dự án, sẽ an toàn hơn khi ta sử dụng @openzeppelin/contracts
.
@openzeppelin/contracts
là một tập hợp các contracts mẫu mực đã được kiểm thử và nâng cấp nhiều lần từ cộng đồng cũng như các công ty đầu ngành. Hiện nay, các contracts phổ biến trong @openzeppelin/contracts
có độ tin cậy và an toàn cao.
Với contract Counter.sol
bên trên, ta kế thừa lại login của Ownable.sol
. Điều này cho phép ta có thể quản lý chủ của (owner
) contract và thiết lập quyền cho các hàm mong muốn (ví dụ như increase
).
ABI
Nếu chạy thử pnpm build
ta sẽ nhận ra một thư mục artifacts
chứa các sản phẩm bytecode
và abi
. Vì ABI sẽ được tái sử dụng nhiều và cho cả SDK, chúng ta nên cần một thư mục riêng để chứa các ABI này.
Thêm cài đặt cho hardhat.config.ts
,
Thiết lập các câu lệnh làm việc
Trong scrips
của package.json
, thay (hoặc thêm mới) 2 lệnh build
và test
.
Chạy thử lệnh build
,
Đồng thời, ta sẽ được folder abi
chứa tất cả các ABI cần thiết. Lưu ý, vì abi
là sản phẩm của quá trình build
nên hãy thêm nó vào .gitignore
.
Phụ lục
Tại sao chúng ta phải tạo các file ts
cho ABI?
Để viem
có thể suy diễn được interface
của contract, viem
cần const assertion. Đó là lý do tại sao ta có as const
ở cuối các file ts
cho ABI. Các bạn có thể bắt gặp công dụng của nó ở bài Triển khai SDK.
VSC Plugins
🪖 Solidity by Nomic Foundation
🎨 Prettier - Code formatter by Prettier
Autoformat trong VSC
❓ How do you format code on save in VS Code - Stackoverflow