| runme | ||||
|---|---|---|---|---|
|
This repository represents an example of using a Chainlink product or service. It is provided to help you understand how to interact with Chainlink’s systems so that you can integrate them into your own. This template is provided "AS IS" without warranties of any kind, has not been audited, and may be missing key checks or error handling to make the usage of the product more clear. Take everything in this repository as an example and not something to be copy pasted into a production ready service.
Demonstrating how to use Chainlink Cross-Chain Interoperobility Protocol (CCIP) and Avalanche Interchain Messaging (ICM) to send a message from Ethereum Sepolia to Avalanche Fuji (via CCIP), then forwarding that message from Avalanche Fuji to Dispatch L1 (via ICM).
In the next section you can see how to send data from one chain to another. But before that, you need to set up some environment variables, install dependencies, setup environment variables, and compile contracts.
yarn && makeRun the command below, then update the .env PRIVATE_KEY and ETHERSCAN_API_KEY variables.
if [ -f .env ]; then
echo "We will use the .env your have already created."
else
if [ -z "${DOTENV}" ]; then
echo "Creating and setting .env"
cp .env.example .env && source .env
echo "Set your PRIVATE_KEY and ETHERSCAN_API_KEY in .env"
fi
fiTo create a new wallet that is stored in a keystore, issue the following command, which will prompt you to secure the private key with a password.
# Grabs the PRIVATE_KEY from the .env file.
PRIVATE_KEY=$(grep PRIVATE_KEY .env | cut -d '=' -f2)
if [ -f keystore/secret ]; then
echo "Found keystore in workspace"
else
if [ -z "${DOTENV}" ]; then
echo "Creating and setting keystore"
mkdir keystore
cast wallet import --private-key $PRIVATE_KEY -k keystore secret
echo "keystore/secret created"
fi
fi
For ease use of the keystore we already configured a environment variable called KEYSTORE pointing to the keystore file in the working directory.
You can use the wallet stored in the keystore by adding the --keystore flag instead of the --private-key flag. Run the command below to confirm your wallet address is stored accurately.
KEYSTORE=$(grep KEYSTORE .env | cut -d '=' -f2)
cast wallet address --keystore $KEYSTOREBefore we proceed with deployment, it is best practice to run tests, which can be executed as follows:
forge test --match-contract SenderTest -vvforge test --match-contract BrokerTest -vvforge test --match-contract ReceiverTest -vvIn order to interact with our contracts, we first need to deploy them, which is simplified in the script/Deploy.s.sol smart contract, so let's deploy each contract applying the deployment script for each of the following commands.
forge script ./script/Deploy.s.sol:DeploySender -vvv --broadcast --rpc-url ethereumSepoliaUpdate MESSAGE_SENDER_ADDRESS stored in your .env, then make sure to verify the deployment by running the following command:
export MESSAGE_SENDER_ADDRESS=$(grep MESSAGE_SENDER_ADDRESS .env | cut -d '=' -f2)
forge verify-contract $MESSAGE_SENDER_ADDRESS src/MessageSender.sol:MessageSender \
--rpc-url 'https://eth-sepolia.public.blastapi.io' \
--verifier blockscout \
--verifier-url 'https://eth-sepolia.blockscout.com/api/'
echo "Verified MessageSender contract may be found here: https://eth-sepolia.blockscout.com/address/$MESSAGE_SENDER_ADDRESS?tab=contract"Finally, since the MessageSender requires funds to pay for fees, we will load up the contract programatically, as follows with 0.05 ETH:
KEYSTORE=$(grep KEYSTORE .env | cut -d '=' -f2)
cast send $MESSAGE_SENDER_ADDRESS --rpc-url ethereumSepolia --value 0.05ether --keystore $KEYSTOREforge script ./script/Deploy.s.sol:DeployBroker -vvv --broadcast --rpc-url avalancheFujiUpdate MESSAGE_BROKER_ADDRESS stored in your .env, then make sure to verify the deployment by running the following command:
export MESSAGE_BROKER_ADDRESS=$(grep MESSAGE_BROKER_ADDRESS .env | cut -d '=' -f2)
forge verify-contract $MESSAGE_BROKER_ADDRESS src/MessageBroker.sol:MessageBroker \
--rpc-url 'https://api.avax-test.network/ext/bc/C/rpc' \
--verifier-url 'https://api.routescan.io/v2/network/testnet/evm/43113/etherscan' \
--etherscan-api-key "verifyContract"
echo "Verified MessageBroker contract may be found here: https://testnet.snowtrace.io/address/$MESSAGE_BROKER_ADDRESS/contract/43113/code"forge script ./script/Deploy.s.sol:DeployReceiver -vvv --broadcast --rpc-url dispatchTestnetUpdate MESSAGE_RECEIVER_ADDRESS stored in your .env, then make sure to verify the deployment by running the following command:
export MESSAGE_RECEIVER_ADDRESS=$(grep MESSAGE_RECEIVER_ADDRESS .env | cut -d '=' -f2)
forge verify-contract $MESSAGE_RECEIVER_ADDRESS src/MessageReceiver.sol:MessageReceiver --etherscan-api-key 'verifyContract' \
&& orge verify-contract $MESSAGE_RECEIVER_ADDRESS src/MessageReceiver.sol:MessageReceiver \
--rpc-url 'https://subnets.avax.network/dispatch/testnet/rpc' \
--verifier-url 'https://api.routescan.io/v2/network/testnet/evm/779672/etherscan' \
echo "Verified MessageReceiver contract may be found here: https://779672.testnet.snowtrace.io/address/$MESSAGE_RECEIVER_ADDRESS/contract/779672/code"Before proceeding, please ensure you have completed the steps outlined in the Setup Messaging Scenario section above.
Run the following to send a message to Fuji from Sepolia via the SendMessage functionality coded in Send.s.sol:
export CUSTOM_MESSAGE=""
if [ -z "${CUSTOM_MESSAGE}" ]; then
echo "No custom message provided"
else
echo "Sending \`$CUSTOM_MESSAGE\` to Avalanche"
fi
forge script ./script/Send.s.sol:SendMessage -vvv --broadcast --rpc-url ethereumSepolia --sig "run(string)" -- "$CUSTOM_MESSAGE"
# https://ccip.chain.link/#/side-drawer/msg/0x30917345c2214ca9a26631f24f30e67b0f7d3aef2285c4ec108a124d944886f1Once the message is finalized on the broker chain (Fuji), you may see the details about the latest message via the BrokerMessage functionality coded in Broker.s.sol. After you have confirmed the latest message you received looks good, you may proceed with running the following script to broker the message to Dispatch:
MESSAGE_BROKER_ADDRESS=$(grep MESSAGE_BROKER_ADDRESS .env | cut -d '=' -f2)
MESSAGE_RECEIVER_ADDRESS=$(grep MESSAGE_RECEIVER_ADDRESS .env | cut -d '=' -f2)
KEYSTORE=$(grep KEYSTORE .env | cut -d '=' -f2)
cast send $MESSAGE_BROKER_ADDRESS --rpc-url avalancheFuji --keystore $KEYSTORE "brokerMessage(address)" $MESSAGE_RECEIVER_ADDRESSAfter running the script above to broker the message from Fuji to Dispatch, you may confirm the message was received by running the following script:
forge script ./script/Receive.s.sol:ReceiveMessage -vvv --broadcast --rpc-url dispatchTestnet