# Simple Abstract Messenger Example

{% hint style="info" %}
If you have any questions or need assistance, please feel free to use our [contact form](https://entangle.zendesk.com/hc/en-us/requests/new) to connect with an expert on our team.
{% endhint %}

An effective implementation of blockchain interoperability is sending cross-chain messages. Traditionally, without UIP, this would be a challenging task. However, UIP makes this an easy and safe process. This guide walks you through building a simple dApp that utilises UIP to send cross-chain text messages with [EVM](https://ethereum.org/en/developers/docs/evm/) smart contracts.

For this guide, we won't need to worry about fees as we will deploy two smart contracts on the testnet — one on the Ethereum Sepolia testnet and the other on the Polygon Amoy network.&#x20;

## Prerequisites

Before you begin, you'll need to enure you're familiar with the concepts and have the tools we'll be using for this guide. If you're unsure about anything, we recommend reading more via the provided links.&#x20;

* The [Solidity](https://soliditylang.org/) programming language.
* The [Hardhat](https://hardhat.org/) development environment.

We will be using the following native tokens:

* [Ethereum Sepolia](https://www.alchemy.com/faucets/ethereum-sepolia)
* [Polygon Amoy](https://www.alchemy.com/faucets/polygon-amoy)

Click on the respective token to be taken to a public faucet and complete the steps to acquire the necessary funds in your wallet.

## Environment Setup

To begin with, let's setup the working environment. We'll initialize the Hardhat project and configure the environment file with the necessary information.

{% stepper %}
{% step %}
Clone the example project from GitHub.

```bash
git clone https://github.com/Entangle-Protocol/UIP-examples.git
```

{% endstep %}

{% step %}
Change your directory to the project folder.

```bash
cd UIP-examples/other/Messenger/EVM
```

{% endstep %}

{% step %}
Install the dependencies.

```bash
npm install
```

{% endstep %}

{% step %}
You can setup your wallet details using a mnemonic phrase (default) or a private key. Below we describe the configuration process for each type.

Since the same wallet can be used across multiple networks, there's no need to add separate wallets. However, if you're alternating between working on Testnet and Mainnet you have to make sure you update the *.env* file to specify wallet details for both.

{% tabs %}
{% tab title="Mnemonic Phrase" %}
{% hint style="warning" %}
Ensure spaces are included between words for your mnemonic phrase.&#x20;
{% endhint %}

The mnemonic phrase is configured in the *.env* file and is used by default. You may need to create this file in your root directory if it's missing.

Please specify details for Testnet and Mainnet individually as described below.

{% code title=".env" %}

```
TESTNET_MNEMONIC = ""
MAINNET_MNEMONIC = ""
```

{% endcode %}
{% endtab %}

{% tab title="Private Key" %}
By default the *hardhat.config.ts* file is configured to use the mnemonic phrase. Therefore, users who prefer to use the private key should make the changes described below.

Change the following variables:

* `process.env.TESTNET_MNEMONIC` to `process.env.TESTNET_PK`
* `process.env.MAINNET_MNEMONIC` to `process.env.MAINNET_PK`

For example:

{% code title="hardhat.config.ts" %}

```typescript
ethereum_sepolia: {
    url: "https://ethereum-sepolia-rpc.publicnode.com",
    accounts: [
        process.env.TESTNET_PK || ""
    ],
    chainId: 11155111
}
```

{% endcode %}

Next you need to configure the private key in the *.env* file. You may need to create this file in your root directory if it's missing.

Please specify details for Testnet and Mainnet individually as described below.

{% code title=".env" %}

```
TESTNET_PK = ""
MAINNET_PK = ""
```

{% endcode %}
{% endtab %}
{% endtabs %}
{% endstep %}
{% endstepper %}

## Deploying Contracts

Once the environment has been successfully setup we can begin deploying contracts. Before beginning, double check to make sure your environment variables are all correct.

Hardhat makes it easy to deploy contracts, simply run the commands below.

{% stepper %}
{% step %}
Deploy the Ethereum Sepolia contract.

```bash
npx hardhat run scripts/deployMessenger.ts --network ethereum_sepolia
```

{% endstep %}

{% step %}
Deploy the Polygon Amoy contract.

```bash
npx hardhat run scripts/deployMessenger.ts --network polygon_amoy
```

{% endstep %}
{% endstepper %}

<details>

<summary>Example Deployment Log</summary>

After deploying the contract using the Hardhat run command, a log will confirm the successful deployment. Some values have been shortened (indicated by "...") for readability.

```
Using network: mantle_sepolia

ChainID mantle_sepolia: 5003

Signer: 0xB3...AF
Signer native balance: 98.477296506288888787

Deploying MessengerProtocol
With args: 0xB3...AF,0x5C...FB

MessengerProtocol deployed to: 0xf6...28
MessengerProtocol implementation deployed to: 0x49...d7


Data successfully saved to ./addresses/mantle_sepolia/MessengerProtocol.json
```

The *MessengerProtocol* file will also be generated, containing the addresses mentioned in the log. You can find it in the following directory:

```
EVM/addresses/ethereum_sepolia/MessengerProtocol.json
```

The deployment address is required for sending messages using Hardhat in the next section of this guide, so it's recommended to note or save the *MessengerProtocol* deployment address.

</details>

## Sending and Receiving Messages

In this section, we'll take a look at sending and receiving messages.

### Sending Messages

{% hint style="info" %}
The Chain ID specifies that the message is being sent to the Polygon Amoy chain. For a complete list of chain IDs, you can refer to [ChainList](https://chainlist.org/). Make sure to check the "Include Testnets" box to show testnet chains.&#x20;
{% endhint %}

To send a message from the source chain (Ethereum Sepolia) to the destination chain (Polygon Amoy) copy the below command, update the address of the deployed contract on Polygon Amoy and run it.

```
npx hardhat sendMessage --destchainid 80002 --destaddress <address of deployed contract on polygon amoy> --message "hello" --network ethereum_sepolia
```

By default, we use our recommended transmitter settings when sending messages. If you are familiar with the [customizable message transmission options](https://docs.entangle.fi/universal-interoperability-protocol/developer-guides/customizable-message-transmission-options) and prefer manual configuration, your command will include two additional arguments:

```
npx hardhat sendMessage --destchainid <destination_chain_id> --destaddress <destination_address> --message <message> --finalization <block_finalization_option> --gaslimit <custom_gas_limit> --network <network_name>
```

<details>

<summary>Example Transaction Log</summary>

```
Using network: polygon_amoy
signer: <your sender wallet address>
Deployment address loaded from
        ./addresses/polygon_amoy/MessengerProtocol.json

===============================================
ContractTransactionReceipt {
  provider: HardhatEthersProvider {
    _hardhatProvider: LazyInitializationProviderAdapter {
      _providerFactory: [AsyncFunction (anonymous)],
      _emitter: [EventEmitter],
      _initializingPromise: [Promise],
      provider: [BackwardsCompatibilityProviderAdapter]
    },
    _networkName: 'polygon_amoy',
    _blockListeners: [],
    _transactionHashListeners: Map(0) {},
    _eventListeners: [],
    _isHardhatNetworkCached: false,
    _transactionHashPollingTimeout: undefined
  },
  to: <address of deployed contract on polygon amoy>,
  from: <your sender wallet address>,
  contractAddress: null,
  hash: '0x183c0b7d69511c556e171347fe28c1b96b5980623d1959d7845a395617c94401',
  index: 1,
  blockHash: '0xccf0a95c60edc064e3499b80562719b1f3606041fbcd4005783b6e587bc0f0cf',
  blockNumber: 14901297,
  logsBloom: '0x0000400000000000001000000400000000000000000000000000000000000000000000000000000000000010000000000010a000000000000000000000000000000000000000000000000000010000800020000000000000100100000020000000000200000000000000000000000000040000000000000080000000000000000000000000000000000000000000000000000000000000000000000001000000200000000000000000000000000000000000000000040000000000000000004000400000000000000001000000000020000002000000800000108000000000000000001000000000000000000000000000000000400000000000000000100000',
  gasUsed: 56902n,
  blobGasUsed: undefined,
  cumulativeGasUsed: 211811n,
  gasPrice: 50284800008n,
  blobGasPrice: undefined,
  type: 2,
  status: 1,
  root: undefined
}
===============================================
Operation proposed to chain 11155111 to address 0x1091029fCF0fa1d67037c6D84206c796A967cF7F with message: "hello"
```

</details>

### Receiving Messages

To read the last message on the destination chain (in this example it's Polygon Amoy) copy the below command, update your sender wallet address and run it.

```
npx hardhat getLastMessage --sender <your sender wallet address> --network polygon_amoy
```

<details>

<summary>Expected Result</summary>

```
Last message from address <your sender wallet address> is: "hello"
```

</details>

## Conclusion

In this guide we created a DApp utilising EVM contracts to facilitate in cross-chain text messaging between the [Ethereum Sepolia](https://www.alchemy.com/faucets/ethereum-sepolia) and [Polygon Amoy](https://www.alchemy.com/faucets/polygon-amoy) chains.
