HelloHOP
is an example implementation designed to demonstrate the capabilities of VIA Labs technology in facilitating cross-chain message passing. This sample contract illustrates the use of the VIA Labs package for enabling messages to traverse multiple blockchain networks via a predefined sequence of chain IDs. It serves primarily as a technical showcase, highlighting the mechanics of cross-chain communication without external bridges in a multi-chain environment.
- Multi-Hop Messages: Facilitates the passage of messages across multiple blockchain networks in a sequential manner.
- Cross-Chain Functionality: Demonstrates the ability to conduct cross-chain interactions using the underlying capabilities of the VIA Labs framework.
- VIA Labs Integration: Implements the VIA Labs package, showcasing its utility in cross-chain messaging.
Before you begin, ensure you have the following installed:
- Node.js and npm (Node Package Manager)
- A text editor such as VSCode for editing
.sol
and.ts
files - GIT installed
- Testnet Tokens
Please visit node documentation link and the git install documentation for more information.
Please open a terminal to run the following commands. You can use any terminal of your choice, including the built in terminal in vscode (Terminal -> New Terminal)
-
Clone the Repository:
git clone https://github.com/VIALabs-io/hello-hop.git
After cloning the repository, if using vscode or a similar IDE, you can now open the hello-hop folder in your IDE of choice.
-
Install Dependencies:
npm install
-
Set Up Environment Variables: Create a new
.env
file to set your EVM private key for contract deployment or copy and edit the existing.env.example
to.env
PRIVATE_KEY=0000000000000000000000000000
Deploy the HelloHOP contract to your desired networks. This must be done for each network you wish to operate on. You can see a list of our networks in the Package documentation
- Ethereum Sepolia Deployment:
npx hardhat --network ethereum-sepolia deploy
- Polygon Testnet Deployment:
npx hardhat --network polygon-amoy deploy
- Avalanche Testnet Deployment:
npx hardhat --network avalanche-testnet deploy
- Ethereum Holesky Testnet Deployment:
npx hardhat --network ethereum-holesky deploy
Edit the networks.ts
file and include all of the networks the contract is deployed on.
[
"avalanche-testnet",
"ethereum-holesky",
"ethereum-sepolia",
"polygon-amoy"
]
Once all contracts are deployed across the desired networks and listed in networks.ts
, configure them using the provided script. Remember, if a new network is added later, all contracts must be reconfigured.
- Ethereum Sepolia Configuration:
npx hardhat --network ethereum-sepolia configure
- Polygon Testnet Configuration:
npx hardhat --network polygon-amoy configure
- Avalanche Testnet Configuration:
npx hardhat --network avalanche-testnet configure
- Ethereum Holesky Testnet Configuration:
npx hardhat --network ethereum-holesky configure
To start a message off, the go()
method is called on any of the networks the contract is deployed on, and the path desired is set with the --path
parameter followed by a comma seperated list of Chain IDs. Chain IDs can be looked up in the Package documentation.
npx hardhat --network ethereum-sepolia go --path 80002,43113,17000
The HelloHOP
contract is a Solidity implementation designed for demonstrating cross-chain message passing using the VIA Labs framework. It allows messages to be sent sequentially across multiple blockchain networks.
pragma solidity =0.8.17;
import "@vialabs-io/contracts/message/MessageClient.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract HelloHOP is MessageClient, Ownable {
event Go();
event Completed(uint _startChainId, uint hops);
event NextHop(uint startChainId, uint hops);
/**
* Kicks off the initial message, which will then be sent from chain to chain, following
* the path set in _chainlist which is a comma seperated list of chain ids
*
*/
function go(uint[] calldata _chainlist) external onlyOwner {
// create cross chain message
bytes memory _data = abi.encode(block.chainid, 1, _chainlist);
// send message
_sendMessage(_chainlist[0], _data);
emit Go();
}
/**
* This is where we handle the received message from the sending chain, and if there
* are still more hops to follow, execute another message to the next chain.
*
*/
function messageProcess(uint, uint _sourceChainId, address _sender, address, uint, bytes calldata _data) external override onlySelf(_sender, _sourceChainId) {
// decode message
(uint _startChainId, uint _hop, uint[] memory _chainlist) = abi.decode(_data, (uint, uint, uint[]));
if(_hop >= _chainlist.length) {
emit Completed(_startChainId, _hop);
} else {
// create cross chain message
bytes memory _newData = abi.encode(_startChainId, _hop+1, _chainlist);
// send message
_sendMessage(_chainlist[_hop], _newData);
emit NextHop(_startChainId, _hop+1);
}
}
}
- Inheritance:
MessageClient
: Inherits from the VIA Labs'MessageClient
for handling cross-chain messages.Ownable
: Inherits from OpenZeppelin'sOwnable
, restricting certain functions to the contract owner.
Go
: Emitted when the message passing process is initiated.Completed
: Emitted when the message has traversed all the specified chains.NextHop
: Emitted on each hop to the next chain in the sequence.
function go(uint[] calldata _chainlist) external onlyOwner
- Purpose: Initiates the message passing process.
- Parameters:
_chainlist
- an array of chain IDs representing the path for the message. - Functionality:
- Encodes the current chain ID, hop number (starting at 1), and the chain list into a byte array
_data
. - Sends the message to the first chain in the list using
_sendMessage
. - Triggers the
Go
event.
- Encodes the current chain ID, hop number (starting at 1), and the chain list into a byte array
function messageProcess(uint, uint _sourceChainId, address _sender, address, uint, bytes calldata _data) external override onlySelf(_sender, _sourceChainId)
- Purpose: Handles incoming messages and forwards them if there are more hops to follow.
- Parameters:
_sourceChainId
: Chain ID of the message sender._sender
: Address of the message sender._data
: Encoded data containing the start chain ID, hop count, and chain list.
- Functionality:
- Decodes
_data
to extract the start chain ID, hop count, and chain list. - If the current hop is the last one, emits the
Completed
event. - Otherwise, increments the hop count, encodes a new message, and sends it to the next chain in the list.
- Emits the
NextHop
event for each successful hop to the next chain.
- Decodes
onlyOwner
Modifier (fromOwnable
): Restricts the execution of thego
function to the contract owner.onlySelf
Modifier: Ensures that themessageProcess
function is only callable by the contract itself, as part of the cross-chain message handling.