π§ͺ Exbrid
April 1, 2025 Β· View on GitHub
Exbrid is an experiment exploring an alternate approach to message passing between Ethereum and Polkadot by embedding a Polkadot light client (Smoldot) directly inside an Ethereum node (Reth) using its plugin system ExEx.
Instead of relying on separate off-chain relayers, this prototype shows how finalized Ethereum block information can be captured from within the Ethereum node itself and submitted directly to a Polkadot-based Substrate chain (like Paseo) using Subxt, with Smoldot as the embedded client.
Initial Research
β Disclaimer: This is an early-stage prototype for research and exploration purposes only. It is not intended for production or secure cross-chain message passing.
The following questions are yet to be answered before it can be used safely:
- How will the Substrate/Polkadot runtime know that the message containing the finalized hash is actually correct?
- Can we get around the fact that two sides need to run an onchain light client of one another?
- Maybe other security or trust assumptions that we must validate. TBD.
π§ Project Overview
- Runs a full Ethereum node using Reth with a custom ExEx extension.
- Captures finalized Ethereum block numbers and hashes.
- Uses Smoldot to run a lightweight Polkadot client embedded in the same process.
- Uses Subxt to submit
system.remark_with_eventtransactions to a Substrate-based chain with the finalized Ethereum block info.
This allows Ethereum to directly push information to Polkadot with no external services or full Polkadot node dependencies.
π Structure
.
βββ src/
β βββ main.rs # Reth ExEx plugin + Subxt integration
βββ paseo_metadata.scale # Subxt metadata for Paseo chain
βββ paseo.raw.json # Chain spec for Smoldot light client
βββ Cargo.toml
βββ README.md
βοΈ Requirements
- Rust >= 1.73
- Subxt CLI to generate metadata
protocif compiling Smoldot from sourcecast(optional) to send test Ethereum transactions- OpenSSL (for generating JWT secrets when working with Holesky)
π¬ Running the Experiment Locally (Dev Mode)
π§Ή Optional Cleanup (Reset Dev Chain)
pkill -f reth
rm -rf "/Users/<username>/Library/Application Support/reth/dev"
rm -rf "/Users/<username>/Library/Caches/reth"
βΆοΈ Start the Node in Dev Mode
cargo run -- node --dev --http
This will:
- Start a Reth dev node
- Capture finalized Ethereum blocks
- Run Smoldot light client to connect to Paseo
- Submit finalized block data to Polkadot via
remark_with_event
β½ Trigger Block Production (in Dev Mode)
Dev mode only produces blocks when new transactions are submitted.
Use cast to send a dummy transaction and trigger block production:
cast send \
--private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \
--value 0 \
0x000000000000000000000000000000000000dEaD \
--rpc-url http://localhost:8545
Important: Only submit this transaction after you see this log in your terminal:
β Smoldot is readyThis indicates that the light client is fully synced and ready to submit transactions.
π End-to-End Flow Summary
Ethereum (Reth Node)
β
βββββΆ ExEx captures finalized block
β
βββββΆ Broadcasts (block_number, block_hash)
β
βΌ
Subxt + Smoldot light client
β
βββββΆ Submit remark to Polkadot chain
π§ͺ Holesky Testnet Setup (Optional)
This project can also be tested on Ethereum Holesky testnet instead of --dev mode.
1. Generate JWT Secret
openssl rand -hex 32 > /tmp/jwt/jwt.hex
2. Start Reth on Holesky
cargo run -- node \
--chain holesky \
--authrpc.jwtsecret /tmp/jwt/jwt.hex \
--http
3. Start Lighthouse for Beacon Node Sync
lighthouse bn \
--network holesky \
--purge-db \
--datadir /tmp/lighthouse-holesky \
--execution-endpoint http://localhost:8551 \
--execution-jwt /tmp/jwt/jwt.hex \
--checkpoint-sync-url https://holesky.beaconstate.info/
This setup allows finalized blocks from Holesky to be captured and relayed to a Substrate chain.
π Setup Notes
π₯ Download Paseo Chain Spec
curl -o paseo.raw.json https://paseo-r2.zondax.ch/chain-specs/paseo.raw.json
βοΈ Generate Subxt Metadata for Paseo
subxt codegen --url https://rpc.paseo.nodestake.top --output paseo_metadata.scale
π Key Management (Experimental Only)
The current prototype uses a hardcoded test mnemonic to sign transactions:
let phrase = Mnemonic::parse("girl run radar student point expect segment process ocean ability artwork ahead").unwrap();
β οΈ This is insecure and must be replaced with proper key management (e.g., remote signer, vault integration) if the approach is ever extended toward production usage.
π¨βπ¬ Purpose
This project is not intended to be a fully-featured bridge, but rather a proof-of-concept and a technical experiment that demonstrates:
- The feasibility of embedding a Polkadot light client into Ethereum
- Relaying finalized data across chains without external services
- Leveraging Rethβs ExEx system as a programmable Ethereum environment