Building A Cross-Chain Atomic Swap On Celo And Ethereum

Introduction

In this blog post, we will explore the concept of cross-chain atomic swaps and build a simple implementation to perform an atomic swap between Celo and Ethereum. Cross-chain atomic swaps allow users to exchange cryptocurrencies between different blockchains while maintaining full control of their assets. This is possible by utilizing smart contracts, cryptographic hash functions, and time locks.

Prerequisites

  • Basic understanding of Solidity and Celo
  • Node.js and Truffle installed on your machine

Atomic Swap

An atomic swap is an atomic operation that simultaneously transfers funds between two participants. It relies on Hashed Timelock Contracts (HTLCs), which use a combination of time locks and cryptographic hash functions to ensure atomicity.

Here's how an atomic swap works:

  1. Alice and Bob agree on a trade and share their respective hashed secrets
  2. Alice deploys an HTLC contract on Celo and sends her funds to the contract
  3. Bob deploys an HTLC contract on Ethereum and sends his funds to the contract
  4. Both of them reveal their secrets
  5. Alice redeems her funds from Bob's contract on Ethereum
  6. Bob redeems his funds from Alice's contract on Celo

Step 1: Creating the HTLC Smart Contract

We will be using Solidity to create our HTLC smart contracts for both Celo and Ethereum.

pragma solidity ^0.8.0; contract HashedTimelock { bytes32 public hashlock; uint256 public timelock; uint256 public amount; address public sender; address public recipient; bool public withdrawn; constructor(address _recipient, bytes32 _hashlock, uint256 _timelock) payable { sender = msg.sender; recipient = _recipient; hashlock = _hashlock; timelock = _timelock; amount = msg.value; } function withdraw(bytes32 _preimage) public { require(msg.sender == recipient, "Only recipient can withdraw"); require(keccak256(abi.encodePacked(_preimage)) == hashlock, "Invalid preimage"); require(block.timestamp <= timelock, "Time has expired"); withdrawn = true; payable(recipient).transfer(amount); } function refund() public { require(msg.sender == sender, "Only sender can refund"); require(block.timestamp > timelock, "Time has not expired"); payable(sender).transfer(amount); } }

Step 2: Deploying the Smart Contracts

Use Truffle and the following networks configuration to deploy the smart contracts on Celo and Ethereum networks.

// truffle-config.js module.exports = { networks: { celo: { ... }, ethereum: { ... }, }, ... };

Step 3: Implementing the Atomic Swap

Use Web3.js to deploy the HTLC contracts on both networks and interact with them.

const Web3 = require('web3'); const htlcContract = require('./HashedTimelock.json'); async function main() { const web3Celo = new Web3('<CELO_RPC_URL>'); const web3Eth = new Web3('<ETHEREUM_RPC_URL>'); // Perform the atomic swap here... const gasEstimate = await htlcCelo.methods.refund().estimateGas(); await htlcCelo.methods.refund().send({ from: aliceAddress, gas: gasEstimate }); } main();

Conclusion

In this blog post, we learned about cross-chain atomic swaps and implemented a simple swap between Celo and Ethereum using smart contracts. This is just the beginning, and there are various applications and improvements that can be built on top of this concept to enable a more connected and seamless blockchain ecosystem.