Receive

Một contract chỉ có thể có 1 hàm fallback, được khai báo với cú pháp sau:

receive() external payable {
 
}

Nó được thực thi khi có những lời gọi đến contract thông qua transfer, send hoặc call1 mà không có dữ liệu được gửi kèm (trường input ở trong transaction, được lưu trong thuộc tính msg.data).

Hàm này không nhận đối số, không trả về bất cứ thứ gì. Đồng thời, nó bắt buộc phải có visibility là external và state mutability là payable.

Ví dụ:

pragma solidity ^0.6.0;
 
contract Charity {
	receive() external payable {
		// React to receiving ether
	}
}

Hàm receive được khuyến khích sử dụng để nhận Ether hơn là hàm fallback.

Fallback

Một contract chỉ có thể có 1 hàm payable, được khai báo với cú pháp sau:

fallback() external [payable] {
 
}

Nó bắt buộc phải có visibility là external. Nếu muốn hàm này nhận Ether, ta có thể đánh dấu nó là payable.

Hàm fallback của một contract sẽ được thực thi nếu một trong số các trường hợp sau xảy ra:

  • Khi giá trị của msg.data khác rỗng.
  • Không có hàm receive ở trong contract.
  • Không có bất kỳ hàm nào match với function signature được gọi, caller có thể là các contract hoặc là các tài khoản ở bên ngoài.

Important

Nếu hàm receive hay hàm fallback (có modifier payable) đều không tồn tại ở trong contract thì nó sẽ không chấp nhận Ether được gửi thông qua hàm transfer hoặc hàm send và sẽ quăng lỗi.

Logic Tree

Sau đây là cây luận lý minh họa cho việc thực thi của hàm receivefallback2:

Which function is called, fallback() or receive()?  
  
          send Ether  
               |  
        msg.data is empty?  
              / \  
            yes  no  
            /     \  
receive() exists?  fallback()  
        /   \  
      yes   no  
      /       \  
 receive()   fallback()

Footnotes

  1. Xem thêm Solidity - Transfer Ether

  2. Tham khảo Sending Ether (transfer, send, call) | Solidity by Example | 0.8.17 (solidity-by-example.org)