# Example: Cross-Chain Counter

Below we implement an example of incrementing a counter cross-chain--commonly used as the cross-chain "Hello World".

### Contracts and Patterns

The contracts are simple: a `SourceCounter` dispatches messages to a destination chain, specifying an `amount` to increment by. Then, `TargetCounter` increments by `amount` on the destination chain.

```solidity
pragma solidity 0.8.16;

import {ITelepathyRouter} from "src/amb/interfaces/ITelepathy.sol";
import {TelepathyHandler} from "src/amb/interfaces/TelepathyHandler.sol";

contract SourceCounter {
    ITelepathyRouter router;
    uint32 destinationChainId;

    constructor(address _router, uint32 _destinationChainId) {
        router = ITelepathyRouter(_router);
        destinationChainId = _destinationChainId;
    }

    // Increment counter on target chain by given amount
    function increment(uint256 _amount, address _destinationCounter) external virtual {
        bytes memory msgData = abi.encode(_amount);
        router.send(destinationChainId, _destinationCounter, msgData);
    }
}

contract TargetCounter is TelepathyHandler {
    uint256 public counter = 0;
    
    event Incremented(address incrementer, uint256 value);

    constructor(address _router) TelepathyHandler(_router) {}

    // Handle messages being sent and decoding
    function handleTelepathyImpl(
        uint32 _sourceChainId, address _sourceAddress, bytes memory _msgData
    ) internal override {
        (uint256 amount) = abi.decode(_msgData, (uint256));
        counter += amount;
        emit Incremented(_sourceAddress, counter);
    }
}
```

The `ITelepathyRouter` interface is used to send messages from source chain to destination chain. The `TelepathyHandler` interface is used to handle messages sent to a destination chain contract from the Telepathy [Router](https://docs.telepathy.xyz/telepathy-protocol/contracts#router).&#x20;

If we look closely at `SourceContract`, we see that incrementing is dispatched by a call to `router.send(...)`. We specify information about the destination chain, the sender, and the information we want to send using this call. The information we want to send across chains must be encoded bytes using `abi.encode(...)`.&#x20;

To handle messages sent to `TargetCounter`, it inherits from the `TelepathyHandler` contract and overrides the `handleTelepathyImpl(...)` method. This function is called by the `TelepathyRouter` after a message is relayed to it. The paramaters to `handleTelepathyImpl` contain the following information:

* `_sourceChainId` is the chain the message was sent on
* `_sourceAddress` is the message sender on the source chain. **Usually** receiving contracts should restrict who the `_sourceAddress` should be.&#x20;
* `_msgData` is the bytes of the message sent on the source chain

### Unit Testing

To read more about unit testing cross-chain contracts with Telepathy, please go to the [unit-testing](https://docs.telepathy.xyz/build-with-telepathy/interchain-messaging/unit-testing "mention") section.
