Build Omnichain Fungible Token (OFTs) on Rootstock with Layerzero
Rootstock now integrates with LayerZero, a cross-chain messaging protocol. This integration enables the seamless movement of Bitcoin-backed assets from Rootstock to other blockchains, allowing developers to build omnichain applications (OApps) that interact across multiple chains as if they were one. Users can now move their Bitcoin across different DeFi ecosystems without complicated bridges, high fees, or slow transactions.
This tutorial demonstrates how to implement cross-chain token transfers using OFT (Omnichain Fungible Token) between Rootstock Testnet and Ethereum Sepolia Testnet via LayerZero's OFT V2 protocol.
What you'll learn
- Set up Hardhat for cross-chain deployments
- Deploy an OFT contract for token transfers between chains
- Configure LayerZero endpoints for cross-chain communication
- Execute transfers between Rootstock and Ethereum Sepolia testnets using the crosschain transfer feature.
Prerequisites
To complete this tutorial, you'll need:
- Node.js: v18.18.0+
- RPC Providers (Rootstock, Alchemy)
- Etherscan API Key
- Sign up to get an API Key. This will be used for verifying the contracts.
- Metamask: Install and connect to Ethereum Sepolia and Rootstock Testnet
- Test Funds: Sepolia ETH and Rootstock rBTC
Important: Ensure you have sufficient test tokens on both networks.
Benefits of building cross-chain dApps on Rootstock
- Simplified Cross-Chain Asset Transfers: Eliminate the need for cumbersome and often risky bridging mechanisms. rBTC and RIF can flow freely between Rootstock and other supported chains.
- Enhanced Capital Efficiency: Lower transaction costs and faster confirmation times, driven by LayerZero and Stargate, optimize capital utilization and improve the user experience.
- Expanded DeFi Accessibility: Unlock Bitcoin's liquidity and security for use across a wide range of DeFi protocols on major chains like Ethereum, Base, Arbitrum, and beyond.
- Unified Liquidity: Aggregate liquidity across multiple chains, creating deeper pools and improving trading efficiency.
- Atomic Transactions: Facilitate secure and reliable cross-chain transactions with LayerZero's guaranteed message delivery.
- Programmable Cross-Chain Logic: Construct complex, multi-chain workflows and applications with LayerZero's flexible messaging framework.
Use cases for building cross-chain dApps on Rootstock
The integration with Layerzero opens up a vast array of innovative use cases, extending beyond simple asset transfers.
Developers can now build sophisticated applications that leverage Bitcoin's security and Rootstock's EVM compatibility across multiple chains:
- Decentralized Exchanges (DEXs) with Cross-Chain Liquidity Pools: Build DEXs that aggregate liquidity from various chains, enabling seamless trading of rBTC and other assets.
- Cross-Chain Lending and Borrowing Protocols: Allow users to lend and borrow rBTC and other assets across different chains, maximizing capital utilization.
- Omnichain Governance Systems: Enable decentralized governance models that span multiple chains, allowing token holders to participate in decision-making regardless of their preferred blockchain.
- Cross-Chain Yield Aggregators: Develop yield optimization platforms that automatically allocate rBTC and other assets to the most profitable opportunities across multiple chains.
- NFT Marketplaces with Cross-Chain Interoperability: Create NFT marketplaces that allow users to buy, sell, and transfer NFTs across different chains, leveraging Bitcoin's security.
Getting started
Clone and cd into the Layerzero Starter Kit project, and run npm install
.
git clone https://github.com/rsksmart/rsk-layerzero-xERC20.git
cd rsk-layerzero-xERC20
Set up environment variables
Rename the .env.example
file to .env
and update the environment variables with your own values.
MNEMONIC=
EVM_PRIVATE_KEY=
RPC_URL_SEPOLIA=
RPC_URL_ROOTSTOCK_TESTNET=
ETHERSCAN_API_KEY=
Choose either Mnemonic or the Private Key as your preferred value and set only one. Note to ensure the wallet has ETH and test rBTC. See the prerequisites section. By default, the examples support both mnemonic-based and private key-based authentication. Setup RPC url’s for Sepolia and Rootstock using Alchemy and the Rootstock RPC API. To verify the contracts from the Sepolia explorer, use the Etherscan API key. Note: Do not share these variables with third parties as you risk losing your real assets.
Configure chains
To configure the kit to deploy to your preferred chains, go to hardhat.config.ts
file and replace the code below in the networks section.
Note: For better performance and reliability, use a custom RPC endpoint as suggested in the prerequisites section.
networks: {
'sepolia-testnet': {
eid: EndpointId.SEPOLIA_V2_TESTNET,
url: process.env.RPC_URL_SEPOLIA || 'https://ethereum-sepolia-rpc.publicnode.com',
accounts,
},
'rootstock-testnet': {
eid: EndpointId.ROOTSTOCK_V2_TESTNET,
url: process.env.RPC_URL_ROOTSTOCK_TESTNET || 'https://public-node.testnet.rsk.co',
accounts,
}
}
Deploying contracts
After adding your PRIVATE_KEY
to the .env
file and adding networks in your hardhat.config.ts, run the command to deploy your LayerZero contracts:
npx hardhat lz:deploy
We will specify the target chains for our OFT deployment. This action will generate a /deployments
folder containing the necessary deployment assets.
Use the default networks provided. To select other options, see the instructions above.
- Use the default script provided. Press Enter to proceed.
During this step, the deployer and the token contract address will be requested. Enter y to confirm.
Save the deployer address and contract address, as this will be used later in this tutorial to verify the contracts.
Verifying Contracts
You can verify your contracts by running the following command:
npx hardhat verify --network <network> <endpoint-address> <deployer address> <contract address> <constructor-arguments>
Replace <endpoint-address>
with the LayerZero contract address for the respective network and <owner-address>
with your deployer address saved earlier.
For example, to verify the MyOFT
contract on Rootstock Testnet, you would run:
npx hardhat verify --network rootstock-testnet 0x5659E38A754C96D20fA4F08Acd9A6Cb5982149C6 "MyOFT" "MOFT" 0x6C7Ab2202C98C4227C5c46f1417D81144DA716Ff 0x5659E38A754C96D20fA4F08Acd9A6Cb5982149C6
Response:
Successfully submitted source code for contract
contracts/MyOFT.sol:MyOFT at 0xa3725eAC59776F075dC5bb02D2997a7feb326595
for verification on the block explorer. Waiting for verification result...
Successfully verified contract MyOFT on Sourcify.
https://repo.sourcify.dev/contracts/full_match/11155111/0xa3725eAC59776F075dC5bb02D2997a7feb326595/
Configuring the Omni-chain App (OApp)
LayerZero configures and validates communication between smart contracts across different blockchains. This is done by defining a connection pathway that sets the required send and receive libraries, message verification settings (DVNs and Executors), and execution parameters (like gas and value limits). These configurations ensure that the contracts can securely and reliably send and receive messages, allowing for seamless cross-chain interoperability.
Initialize your OApp configurations by running
npx hardhat lz:oapp:config:init --contract-name MyOFT --oapp-config layerzero.config.ts
Once the command is executed, you will be prompted to select the chain set up in your layerzero.config.ts
file.
Each section contains a config, containing multiple configuration structs for changing how your OApp sends and receives messages, specifically for the chain your OApp is sending from: