Khi làm việc với hợp đồng thông minh, tôi thấy việc hiểu rõ cấu trúc và bản chất của hợp đồng là rất cần thiết. Chính vì vậy, tôi viết bài này để làm rõ một số khái niệm quan trọng trong hợp đồng thông minh Ethereum, khác biệt so với mô hình phát triển web2.
Các Kiểu Dữ Liệu
Trong Solidity, kiểu contract là một cấu trúc tổ chức một tập hợp các hàm liên quan xoay quanh một mục đích duy nhất.
Kiểu address là địa chỉ Ethereum có kích thước 20 byte và được biểu diễn ở dạng thập lục phân bắt đầu bằng tiền tố 0x.
Bạn sẽ quen thuộc với hầu hết các kiểu dữ liệu khác nếu là một lập trình viên – bao gồm boolean, số nguyên, số dấu phẩy động cố định, mảng byte và ký tự.
Lưu Trữ Dữ Liệu
Trong Solidity, các giá trị dữ liệu tham chiếu có thể được lưu trữ dưới dạng storage, memory hoặc calldata tùy thuộc vào vai trò của dữ liệu được lưu trữ. Cụ thể:
- storage lưu trữ dữ liệu vĩnh viễn trên blockchain và cực kỳ tốn kém.
- Các giá trị memory chỉ được lưu trữ trong vòng đời thực thi của hợp đồng thông minh và có chi phí sử dụng thấp (chỉ tốn một lượng gas nhỏ).
- calldata là một vị trí dữ liệu đặc biệt chứa các đối số hàm và chỉ khả dụng cho các tham số gọi hàm bên ngoài.
Bộ Sửa Đổi Hàm
Các hàm tồn tại để lấy/đặt thông tin dựa trên các lệnh gọi được khởi tạo bởi các giao dịch bên ngoài. Cụ thể, một hợp đồng thông minh không bao giờ có thể chạy trừ khi được khởi tạo bởi một giao dịch bên ngoài – chúng không tự động thực thi.
Bộ sửa đổi truy cập bao gồm:
- public: Có thể được truy cập bởi tất cả các hàm hoặc người gọi.
- external: Chỉ có thể được truy cập bởi người gọi bên ngoài, không phải các hàm bên trong.
- internal: Chỉ có thể được truy cập bởi hợp đồng này hoặc các hợp đồng kế thừa từ nó.
- private: Chỉ có thể được truy cập từ chính hợp đồng này.
Các bộ sửa đổi khác bao gồm:
- view: Điều này đảm bảo rằng hàm sẽ không sửa đổi trạng thái dữ liệu của hợp đồng (hoặc dữ liệu trong storage).
- pure: Điều này đảm bảo rằng hàm sẽ không đọc cũng như không sửa đổi trạng thái dữ liệu của hợp đồng.
- payable: Các hàm và địa chỉ được khai báo payable có thể nhận ether vào hợp đồng của chúng.
Các Hàm và Biến Đặc Biệt
Có một số biến và hàm toàn cục mà bạn nên nhớ rằng bạn có quyền truy cập! Một số biến đặc biệt là:
- block.number (uint256): Số của khối gần đây nhất.
- block.timestamp (uint256): Dấu thời gian UNIX của khối gần đây nhất.
- block.gaslimit (uint256): Giới hạn gas của khối hiện tại.
- msg.sender (address payable): Người gửi giao dịch kích hoạt hợp đồng.
- msg.value (uint256): Số wei được chuyển cùng với thông báo.
Các hàm đặc biệt bao gồm:
- receive(): Hợp đồng chỉ có thể có một trong những hàm này được khai báo. Nó đóng vai trò là đích đến mặc định khi một hợp đồng được gửi Ether. Nó không thể có đối số, trả về bất kỳ thứ gì và phải là external và payable.
- fallback(): Hợp đồng chỉ có thể có một trong những hàm này được khai báo. Nó đóng vai trò là dự phòng nếu một lệnh gọi đến hợp đồng không khớp với bất kỳ hàm nào hoặc nếu không có dữ liệu nào được cung cấp và hàm receive() không được khai báo. Nó không thể có đối số, trả về bất kỳ thứ gì và phải là external.
Sự Kiện (Events)
Các sự kiện Solidity tương đương với việc ghi nhật ký trong các mô hình lập trình khác. Chúng được phát hành khi một hợp đồng được thực thi, được lưu trữ vĩnh viễn trên blockchain, nhưng không thể truy cập để sửa đổi/đọc bởi các hợp đồng thông minh.
Bạn có thể khai báo và phát hành một sự kiện như thế này:
event TestEvent (
uint256 date,
string value
);
emit TestEvent(block.timestamp,’My first event!”);
Các sự kiện có thể được truy cập theo nhiều cách khác nhau:
- Các sự kiện được lưu trữ trong biên lai của giao dịch và có thể được truy cập tại đó.
- Bạn có thể đăng ký một sự kiện bằng myContract.events.TestEvent([options][, callback])
- Bạn có thể yêu cầu các sự kiện trong quá khứ bằng cách gọi hàm myContract.getPastEvents(event[, options][, callback]).
Hy vọng bài viết này đã cung cấp cho bạn một cái nhìn tổng quan về các thành phần chính của một hợp đồng thông minh! Bạn có thể tìm thêm chi tiết trong Tài liệu Solidity được liên kết tại đây.