- vừa được xem lúc

Handle error trong Solidity với các hàm Require, Assert, Revert và Try/Catch

0 0 81

Người đăng: Đỗ Đức Hoàng

Theo Viblo Asia

Solidity được thiết kế để có khả năng reverting state nhằm ngăn chặn các sự cố có thể xảy ra. Bài viết này tập trung vào các sử dụng các hàm require, assertrevert . Ngoài ra cũng sẽ tái hiện các exceptions của assert và require .

Ví dụ: Solidity assert-type được tạo ra khi bạn truy cập một mảng với index âm hoặc quá lớn. Một ví dụ exception của require kích hoạt khi hợp đồng với từ khóa mới không kết thúc thành công.

Main Tips

  • Solidity xử lý các errors bằng cách trả lại các state vs exceptions
  • Solidity assertrequire là các hàm check điều kiện và trả lại exceptions
  • revert trigger exceptions và có thể trả về error string

Giải thích về Error Handling

Solidity quản lý các vấn đề bằng cách sử dụng state-reverting exceptions. Một exception như vậy sẽ hoàn tác tất cả các thay đổi được thực hiện đối với trạng thái trong cuộc gọi hiện tại (và tất cả các lệnh gọi con của nó) và gắn cờ lỗi cho người gọi.

Assert and Require

Hàm assertrequire có thể được sử dụng để kiểm tra các điều kiện và đưa ra một exception nếu điều kiện không được đáp ứng.

Hàm assert sẽ tạo ra lỗi kiểu Panic(uint256) ( hàm trong trình biên dịch ). Assert chỉ nên được sử dụng để kiểm tra các lỗi internal.

Sau đây là các trường hợp mà Solidity tạo ra các exception dạng assert

  • Nếu bạn gọi assert với một argument được đánh giá là false.
  • Khi bạn gọi một biến chưa được khởi tạo
  • Khi bạn convert một giá trị lớn hoặc âm thành kiểu enum
  • Khi chia cho 0
  • Khi truy cập vào array vs index âm hoặc quá lớn

Hàm require dùng để đảm bảo tính hợp lệ của các điều kiện không thể được phát hiện trước khi thực thi. Nó kiểm tra inputs, contract statereturn values từ việc call các external contract. Hàm này sẽ tạo ra lỗi kiểu Error(string)

Sau đây là các trường hợp mà Solidity tạo ra các exception dạng require

  • Khi bạn gọi require với một argument được đánh giá là false.
  • Khi bạn thực hiện một lệnh gọi đến một external funtion mà nó không chứa code.
  • Khi create contract với new keyword nhưng không kết thúc đúng cách
  • Khi contract của bạn nhận Ether trong hàm public không có payable bao gồm cả fallback function
  • Khi contract của bạn nhận Ether trong hàm public getter
  • Khi .transfer() lỗi

Ví dụ dưới đây thể hiện cách để yêu cầu Solidity xem qua các điều kiện đầu vào và thực hiện kiểm tra các lỗi internal.

pragma solidity >=0.5.0 <0.7.0; contract Sharer { function sendHalf(address payable addr) public payable returns (uint balance) { require(msg.value % 2 == 0, "Even value required."); uint balanceBeforeTransfer = address(this).balance; addr.transfer(msg.value / 2); // Since transfer throws an exception on failure and // cannot call back here, there should be no way for us to // still have half of the money. assert(address(this).balance == balanceBeforeTransfer - msg.value / 2); return address(this).balance; }
}

Chú ý assert sẽ sử dụng gas được cung cấp . require thì không sử dụng gas .

Revert

Hàm revert là một cách khác để kích hoạt các exception từ bên trong các code block khác để gắn cờ lỗi và revert current call. Đầu vào là một chuỗi chứa thông tin chi tiết về lỗi được chuyển lại cho người gọi và nó sẽ tạo ra Error(string) giống requires.

Dưới đây là một ví dụ về dùng revert giống như require

pragma solidity >=0.5.0 <0.7.0; contract VendingMachine { function buy(uint amount) public payable { if (amount > msg.value / 2 ether) revert("Not enough Ether provided."); // Alternative way to do it: require( amount <= msg.value / 2 ether, "Not enough Ether provided." ); // Perform the purchase. }
}

Trong ví dụ trên thì revert trả lại đoạn lỗi như sau

0x08c379a0 // Function selector for Error(string)
0x0000000000000000000000000000000000000000000000000000000000000020 // Data offset
0x000000000000000000000000000000000000000000000000000000000000001a // String length
0x4e6f7420656e6f7567682045746865722070726f76696465642e000000000000 // String data

try/catch

Lỗi trong việc gọi external có thể được phát hiện bằng cách sử dụng câu lệnh try / catch, như sau:

pragma solidity >=0.6.0 <0.9.0; interface DataFeed { function getData(address token) external returns (uint value); } contract FeedConsumer { DataFeed feed; uint errorCount; function rate(address token) public returns (uint value, bool success) { // Permanently disable the mechanism if there are // more than 10 errors. require(errorCount < 10); try feed.getData(token) returns (uint v) { return (v, true); } catch Error(string memory /*reason*/) { // This is executed in case // revert was called inside getData // and a reason string was provided. errorCount++; return (0, false); } catch (bytes memory /*lowLevelData*/) { // This is executed in case revert() was used. errorCount++; return (0, false); } }
}

Sau từ khóa try phải có một biểu thức gọi hàm external hoặc một contract creation (new ContractName()) . Phần returns (optional) theo sau là các kiểu trả về khớp với kiểu đc trả về bởi lệnh external call .

Tổng kết

  • Để handle error , Solidity undo các thay đổi có thể gây ra lỗi
  • Assert check các internal errors, require thì yêu cầu một điều kiện
  • Các exception mà Solidity revert có thể chứa error strings

Reference

Bình luận

Bài viết tương tự

- vừa được xem lúc

[Blockchain] Road to Bitcoin

. Chắc mọi người hẳn đã không còn xa lạ gì với anh chàng tỷ phú đã ném vỡ cửa kính ô tô nhà mình cùng với siêu năng lực điều khiển vật giá chỉ bằng lời nói, người đã đẩy định giá Bitcoin trên thị trường vượt ngưỡng 50K dolar/coin với những bài twitter để đời . .

0 0 44

- vừa được xem lúc

Khi Ethereum có chi phí giao dịch quá đắt đỏ - Tương lai cho layer2 ?

Với sự phát triển như vũ bão của Blockchain, ETH dường như đang quá tải và hệ quả là chi phí Gas đã lên đến 1000Gwei, phí để tạo những transaction phức tạp đã xấp xỉ 500$ . Và một giải pháp cứu cánh cho các sản phẩm Defi trên ETH chính là Layer2, và trong nhiệm vụ lần này Matic đang thể hiện khả năn

0 0 73

- vừa được xem lúc

Blockchain với Java - Tại sao không?

Cuộc cách mạng công nghiệp 4.0 ra đời kéo theo nhiều sự thay đổi và xu hướng mới được hình thành. Riêng đối với lĩnh vực CNTT cũng không nằm ngoài vùng ảnh hưởng mạnh mẽ. Chính làn sóng 4.

0 0 78

- vừa được xem lúc

Phân loại và tầm quan trọng của các node trong mạng blockchain

Trước khi đi vào phân loại và nêu rõ được tầm quan trọng của các node trọng mạng blockchain thì mình xin được trích dẫn khái niệm về blockchain từ Wikipedia như sau:. .

0 1 46

- vừa được xem lúc

Code Smart Contract bằng Assembly ?

Introduction. Hồi còn học trong ghế nhà trường bộ môn lập trình tốn nhiều não nhất của mình là code assembly. Nôm na thì bất cứ ngôn ngữ bậc cao nào như C , Go, Java,... được sinh ra để người dễ hiểu và dễ code , tuy nhiên chúng đều sẽ được compiled down xuống assembly một ngôn ngữ bậc thấp để máy h

0 0 43

- vừa được xem lúc

Dextool - Công cụ phân tích Decentralized Exchange tuyệt vời

. Trend Defi mặc dù đã bớt nhiệt nhưng những sản phẩm nổi bật của làn sóng này mang lại thì vẫn rất được người dùng ưa chuộng. Đặc biệt là các nền tảng Decentralized Exchange, tiêu biểu là Uniswap, SushiSwap, 1inch Exchange, FalconSwap,... Nhưng khi đã sử dụng các nền tảng DEx này mà không biết đến

0 0 92