Skip to content
All essays
CraftMarch 27, 202613 min

Cross-Chain Bridges: Connecting Blockchains

Understand cross-chain bridges and enable interoperability between blockchains

Ü
Ümit Uz
Mobile & Full Stack Developer

Cross-chain bridges enable assets and data to move between different blockchains, unlocking interoperability in the multi-chain ecosystem.

How Bridges Work

Bridges lock assets on one chain and mint equivalent tokens on another:

Ethereum (Source)          Polygon (Destination)
     │                            │
     ├─ Lock 1 ETH               ├─ Mint 1 ETH
     │                            │
     ▼                            ▼
[Smart Contract]          [Smart Contract]

Bridge Types

Trusted Bridges

solidity
// Trusted bridge with centralized validator
contract TrustedBridge {
    address public validator;
    mapping(address => uint256) public lockedBalances;
    
    event Locked(address indexed user, uint256 amount, address targetChain);
    event Minted(address indexed user, uint256 amount, bytes32 txHash);
    
    function lock(uint256 amount, address targetChain, address recipient) external {
        require(amount > 0, "Amount must be positive");
        require(
            IERC20(USDC).transferFrom(msg.sender, address(this), amount),
            "Transfer failed"
        );
        
        lockedBalances[msg.sender] += amount;
        emit Locked(msg.sender, amount, targetChain);
    }
    
    function mint(
        address recipient,
        uint256 amount,
        bytes32 sourceTxHash
    ) external {
        require(msg.sender == validator, "Only validator");
        
        // Mint equivalent tokens on this chain
        BridgedToken token = BridgedToken(BRIDGED_USDC);
        token.mint(recipient, amount);
        
        emit Minted(recipient, amount, sourceTxHash);
    }
}

Trustless Bridges

solidity
// Trustless bridge with relayers and signatures
contract TrustlessBridge {
    uint256 public constant THRESHOLD = 3;
    address[] public relayers;
    mapping(address => bool) public isRelayer;
    
    struct Proposal {
        bytes32 dataHash;
        uint256 signaturesCollected;
        mapping(address => bool) hasSigned;
    }
    
    mapping(bytes32 => Proposal) public proposals;
    
    constructor(address[] memory _relayers) {
        relayers = _relayers;
        for (uint i = 0; i < _relayers.length; i++) {
            isRelayer[_relayers[i]] = true;
        }
    }
    
    function proposeMint(
        address recipient,
        uint256 amount,
        bytes32 sourceTxHash
    ) external {
        bytes32 proposalId = keccak256(abi.encodePacked(recipient, amount, sourceTxHash));
        Proposal storage proposal = proposals[proposalId];
        
        require(
            proposal.dataHash == bytes32(0) || 
            proposal.dataHash == keccak256(abi.encodePacked(recipient, amount)),
            "Proposal mismatch"
        );
        
        proposal.dataHash = keccak256(abi.encodePacked(recipient, amount));
        proposal.signaturesCollected++;
        proposal.hasSigned[msg.sender] = true;
        
        if (proposal.signaturesCollected >= THRESHOLD) {
            // Execute mint
            BridgedToken(BRIDGED_TOKEN).mint(recipient, amount);
            delete proposals[proposalId];
        }
    }
}
typescript
// Chainlink CCIP integration
import { ethers } from 'ethers';
import CCIPAbi from './abi/CCIP.json';

const CCIP_ADDRESS = '0x...';

async function crossChainTransfer(
    amount: string,
    destinationChain: bigint,
    recipient: string
) {
    const provider = new ethers.JsonRpcProvider('RPC_URL');
    const wallet = new ethers.Wallet('PRIVATE_KEY', provider);
    
    const ccip = new ethers.Contract(CCIP_ADDRESS, CCIPAbi, wallet);
    
    // Approve CCIP to spend tokens
    const token = new ethers.Contract(
        TOKEN_ADDRESS,
        ['function approve(address,uint256) returns (bool)'],
        wallet
    );
    await token.approve(CCIP_ADDRESS, ethers.parseEther(amount));
    
    // Send cross-chain message
    const tx = await ccip.ccipSend({
        sourceChainSelector: SOURCE_CHAIN_SELECTOR,
        destinationChainSelector: destinationChain,
        receiver: recipient,
        data: ethers.toUtf8Bytes('Cross-chain transfer'),
        tokenAmounts: [{
            token: TOKEN_ADDRESS,
            amount: ethers.parseEther(amount)
        }]
    });
    
    await tx.wait();
    console.log('Cross-chain transfer initiated:', tx.hash);
}

Security Considerations

Bridge Monitoring

typescript
class BridgeMonitor {
    private alerts: AlertService;
    
    async monitorBridge() {
        // Check bridge balance
        const balance = await this.getBridgeBalance();
        const expected = await this.getExpectedBalance();
        
        if (balance < expected) {
            await this.alerts.send({
                severity: 'CRITICAL',
                message: 'Bridge balance mismatch!',
                balance,
                expected
            });
        }
        
        // Monitor unusual activity
        const volume = await this.get24hVolume();
        const avgVolume = await this.getAvg24hVolume();
        
        if (volume > avgVolume * 3) {
            await this.alerts.send({
                severity: 'WARNING',
                message: 'Unusually high bridge volume',
                volume,
                avgVolume
            });
        }
    }
}

Best Practices

  1. 1Use audited bridges when possible
  2. 2Monitor bridge activity continuously
  3. 3Diversify bridge usage
  4. 4Understand bridge security model
  5. 5Consider bridge slippage
  6. 6Keep informed of bridge hacks

Conclusion

Cross-chain bridges enable the multi-chain future. Use them carefully, understand the risks, and monitor activity continuously.

Enjoyed this essay? Share it.

Related essays

Next essay
Layer 2 Blockchain Solutions: Scaling Ethereum