SafeMath
Là một thư viện1 cung cấp các thao tác toán học cơ bản chẳng hạn như cộng, trừ, nhân, chia và giúp đảm bảo các arithmetic vulnerability sẽ không xảy ra.
Ví dụ bên dưới sử dụng thư viện SafeMath cho kiểu uint256:
using SafeMath for uint256;
uint256 a = 5;
uint256 b = a.add(3); // 5 + 3 = 8
uint256 c = a.mul(2); // 5 * 2 = 10Có thể thấy, ta thay thế toán tử + và * thành hàm add và mul của thư viện.
Về bản chất, hai hàm này đều có hai tham số, nhưng lúc gọi ta chỉ truyền vào có một đối số. Đối số còn lại chính là biến gọi thực thi hàm. Cụ thể:
function add(uint256 a, uint256 b) internal pure returns (bool, uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
assert(c / a == b);
return c;
}Trong hai hàm trên, các câu lệnh assert được dùng để kiểm tra overflow. Câu lệnh assert sẽ quăng lỗi nếu biểu thức truyền vào có giá trị là false.
Sự khác nhau giữa require và assert là require sẽ trả lại tiền cho user nếu như biểu thức truyền vào nó thỏa điều kiện.
Attention
Kiểu dữ liệu của các tham số trong hàm
addvàmullàuint256. Điều này có nghĩa là chúng ta chỉ có thể sử dụng thư viện với kiểu dữ liệu làuint256. Nếu muốn áp dụng cho các kiểu dữ liệu số nguyên khác, ta cần phải sao chép lại một thư viện mới có kiểu dữ liệu của các tham số làuint32hayuint64, etc.
Note
Kể từ phiên bản 0.8.0 trở đi, integer overflow/underflow đã được Solidity compiler kiểm tra nên SafeMath không còn được sử dụng nữa.
unchecked Keyword
Trong trường hợp ta vẫn muốn integer overflow/underflow xảy ra thì có thể bọc thao tác toán học trong khối lệnh của từ khóa uncheked. Khi đó, compiler sẽ không kiểm tra.
uint8 public bigNumber = 255;
function add() public {
unchecked {
bigNumber = bigNumber + 1;
}
}Info
Việc sử dụng
uncheckedcó thể làm giảm gas mà smart contract cần để thực thi.
Resources
Footnotes
-
Xem thêm Solidity - Libraries. ↩