Skip to main content
Version: Endpoint V1

Receive Messages

Destination contracts must implement lzReceive() to handle incoming messages

The code snippet explains how the message will be received.

To receive a message, your User Application contract must implement the ILayerZeroReceiver interface and override the lzReceive() function

pragma solidity >=0.5.0;

interface ILayerZeroReceiver {
// @notice LayerZero endpoint will invoke this function to deliver the message on the destination
// @param _srcChainId - the source endpoint identifier
// @param _srcAddress - the source sending contract address from the source chain
// @param _nonce - the ordered message nonce
// @param _payload - the signed payload is the UA bytes has encoded to be sent
function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;
}

Below is a snippet that shows an implementation of lzReceive(). Here we demonstrate how to extract an address out of the payload and increment a counter each time this contract receives any message.

UAs should authenticate the received messages with:

  • the caller is the known LayerZero endpoint
  • the srcAddress is a trusted known address on the _srcChain. If the application will connect non-evm chains, the UA should use bytes to store addresses.
mapping(address => uint) public addrCounter;
mapping(uint16 => bytes) public trustedRemoteLookup;

// override from ILayerZeroReceiver.sol
function lzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) override external {
require(msg.sender == address(endpoint));
require(keccak256(_srcAddress) == keccak256(trustedRemoteLookup[_srcChainId]);
address fromAddress;
assembly {
fromAddress := mload(add(_srcAddress, 20))
}
addrCounter[fromAddress] += 1;
}

Check the CounterMock for examples.