Skip to Content
Receiving Messages

Receiving Messages on Reactor

Blockchain applications that receive messages from Reactor will need to implement the execute function. The execute function is where application logic, like validating the message sender and source chain, takes place. It also responsible for parsing the data from the message’s payload and performing tasks based on the application’s use cases.

Execute Function

function execute( string calldata _sourceChainName, string calldata _sourceAddress, string calldata _action, bytes calldata _payload ) external;

Execute message parameters

  • _sourceChainName: Name of blockchain where message came from.
  • _sourceAddress: Address for the sender of the message on the source chain.
  • _action: Type of message that was received.
  • _payload: Encoded action-specific data for the message.

Source Chain Name

Source Chain Names are unique identifiers that conveys the sending chain of the message. This allows the receiving application to add checks to ensure that it process messages that originate on known blockchains.

Source Address

The address of the sender from the source chain. The receiving application can use the source address to further check via a whitelist to verify that a message is coming from a trusted source.

Action

Actions are the way that convey to Reactor the intent behind the message that is being received. This allows Reactor to be simple and flexible to cover the workflows required today while staying open to enable the emerging use cases in the future.

The following actions are currently supported:

  • cross_chain: Send data between blockchains.
  • web_request: Get or post data on a web resource (i.e. web service or API).

Although these are the only supported actions at the moment, receiving applications should anticipate new actions in the future. The choice is up to the implementer of the receiving application, but taking an approach that allows a receiving application to grow as more scenarios are enabled by Reactor allows the application to evolve to adapt to changing requirements.

Payload

On Reactor, any data that can be encoded into bytes can be delivered as the payload for a message. It is the job of the receiving application to parse the payload and extract the needed data. This can be as simple as decoding the payload via abi’s decode function or a custom decoding scheme that meets the requirements of the application. While cross_chain or web-to-chain messages can contain any byte-encoded data, messages like web_request will follow a predefined format. In the case of web_request messages, the payload received will be an ABI encoded value with the HTTP response code, the response body, and the names and values of the response headers as message parameters. An example of how to parse a web_request message is below.

Message Parameters

At times, there is a need to convey additional information related to a message between Reactor and the applications. In these scenarios, like request and response headers for web_request messages, Reactor payloads can be encoded with parameters.

// Example of web request with headers bytes memory web_request_payload = abi.encode("GET", "https://docs.reactor.network", ""); bytes memory payload = abi.encode(web_request_payload, ["header.NAME_1", "header.NAME_2"], ["VALUE_1", "VALUE_2"]);

For web_request messages, the payload delivered to the contract at the destination address on the destination chain will be encoded with parameters that include any response headers along with the HTTP response. Since any data that is delivered to the contracts will be persisted to the blockchain, it is important to handle sensitive data in a secure manner. For these cases, please contact the [Reactor Team] so that overrides can be added to remove any sensitive data before it is sent to contracts. In the future, there will be a self-service portal that will allow for the management of sensitive data like API keys, credentials, or other private information for messages coming into Reactor and going out of Reactor. This includes using this sensitive data in outgoing web_request messages.

Examples

Here’s are two basic examples of implementing the execute function for a message receiving contract:

Cross-Chain Message

// Example of receiving a cross_chain message function execute(string calldata _sourceChainName, string calldata _sourceAddress, string calldata _action, bytes calldata _payload) external { sourceChainName = _sourceChainName; sourceAddress = _sourceAddress; action = _action; payload = _payload; last_message = abi.decode(_payload, (string)); emit ExecutableCrossChainMessageReceiverSuccess(_sourceChainName, _sourceAddress, _action, keccak256(_payload)); }

Web Request Message

// Example of receiving a web_request message function execute(string calldata _sourceChainName, string calldata _sourceAddress, string calldata _action, bytes calldata _payload) external { sourceChainName = _sourceChainName; sourceAddress = _sourceAddress; action = _action; payload = _payload; (last_http_response_status_code,last_http_response_body, last_http_response_header_names, last_http_response_header_values) = abi.decode(_payload, (uint256, string, string[], string[])); emit ExecutableWebRequestReceiverSuccess(_sourceChainName, _sourceAddress, _action, keccak256(_payload)); }

Last updated on