Deploy a Bitcoin Appchain (L3)
In this guide, we will walk through the process of deploying a Bitcoin Appchain (L3) on Citrea using the OP Stack, with Celestia as the data availability layer.
The following steps are appropriately modified from the Optimism documentation.
Prerequisites
We recommend to open a separate folder in your filesystem for the rest of this guide.
Appchains require strong hardware to function properly. For demo purposes, we used a machine with AMD EPYC 9124 @ 3.71GHz and 128 GB of RAM.
Step 1: Install & Run Celestia Light Node
Step 1.1 Install Celestia Light Node
Follow the steps here to install Celestia Light Node. You may install the latest version.
Step 1.2 Run Celestia Light Node
Run the following to start a Celestia Mocha Light Node:
celestia light init --p2p.network mocha
celestia light start --core.ip rpc-mocha.pops.one --p2p.network mocha
Step 1.3 Get funds to your address
To write data into Celestia, you will need an address & funds. Please follow the steps here.
Step 2: DA Server Setup
Step 2.1 Build DA Server
Let's clone the op-plasma-celestia
repository first and build the da-server
:
git clone https://github.com/celestiaorg/op-plasma-celestia
cd op-plasma-celestia
make da-server
This will form the da-server
binary in the bin
folder.
Step 2.2 Run DA Server
Then, let's create a namespace:
export NAMESPACE=00000000000000000000000000000000000000$(openssl rand -hex 10)
Lastly, let's get the Celestia auth token for the light node and put it into AUTH_TOKEN
env variable to start the DA server:
export AUTH_TOKEN=$(celestia light auth admin --p2p.network mocha)
./da-server --generic-commitment=true --celestia.server=http://localhost:26658 --celestia.auth-token=$AUTH_TOKEN --celestia.namespace=$NAMESPACE --addr=127.0.0.1 --port=3100
This will start the DA server.
Step 3: Setup Optimism repositories and configure environment
Step 3.1: Clone repositories
Clone op-geth
and Optimism mono-repository, then checkout to v1.9.2
for development purposes:
git clone https://github.com/ethereum-optimism/op-geth.git
git clone https://github.com/ethereum-optimism/optimism.git
cd optimism
git checkout v1.9.2
Step 3.2: Setup environment
Then, let's setup our environment using the .envrc
file (alternatively you can set them in your shell):
##################################################
# Getting Started #
##################################################
# Admin account
export GS_ADMIN_ADDRESS=[YOUR_CITREA_ADDRESS]
export GS_ADMIN_PRIVATE_KEY=[YOUR_CITREA_PRIVATE_KEY]
# Batcher account
export GS_BATCHER_ADDRESS=[YOUR_CITREA_ADDRESS]
export GS_BATCHER_PRIVATE_KEY=[YOUR_CITREA_PRIVATE_KEY]
# Proposer account
export GS_PROPOSER_ADDRESS=[YOUR_CITREA_ADDRESS]
export GS_PROPOSER_PRIVATE_KEY=[YOUR_CITREA_PRIVATE_KEY]
# Sequencer account
export GS_SEQUENCER_ADDRESS=[YOUR_CITREA_ADDRESS]
export GS_SEQUENCER_PRIVATE_KEY=[YOUR_CITREA_PRIVATE_KEY]
##################################################
# op-node Configuration #
##################################################
# The kind of RPC provider, used to inform optimal transactions receipts
# fetching. Valid options: alchemy, quicknode, infura, parity, nethermind,
# debug_geth, erigon, basic, any.
export L1_RPC_KIND=any
##################################################
# Contract Deployment #
##################################################
# RPC URL for the L1 network to interact with
export L1_RPC_URL=https://rpc.testnet.citrea.xyz
# Salt used via CREATE2 to determine implementation addresses
# NOTE: If you want to deploy contracts from scratch you MUST reload this
# variable to ensure the salt is regenerated and the contracts are
# deployed to new addresses (otherwise deployment will fail)
export IMPL_SALT=$(openssl rand -hex 32)
# Name for the deployed network
export DEPLOYMENT_CONTEXT=getting-started
# Optional Tenderly details for simulation link during deployment
export TENDERLY_PROJECT=
export TENDERLY_USERNAME=
# Optional Etherscan API key for contract verification
export ETHERSCAN_API_KEY=
# Private key to use for contract deployments, you don't need to worry about
# this for the Getting Started guide.
export PRIVATE_KEY=
export L1_CHAIN_ID=5115
export L2_CHAIN_ID=511551155115
export L1_BLOCK_TIME=2
export L2_BLOCK_TIME=2
Step 3.3: Run configuration scripts
Navigate to the op-node
directory and generate the configuration:
cd packages/contracts-bedrock
./scripts/getting-started/config.sh
Later in the same folder, let's run the deployment script using forge
to deploy the necessary contracts on Citrea:
forge install
DEPLOY_CONFIG_PATH=./deploy-config/getting-started.json forge script scripts/deploy/Deploy.s.sol:Deploy --private-key $GS_ADMIN_PRIVATE_KEY --broadcast --rpc-url $L1_RPC_URL
And also run the L3 genesis configuration script:
DEPLOY_CONFIG_PATH=./deploy-config/getting-started.json CONTRACT_ADDRESSES_PATH=./deployments/5115-deploy.json forge script scripts/L2Genesis.s.sol:L2Genesis --sig "runWithStateDump()"
Step 4: Generate node configurations
Navigate to the op-node
and generate the configuration for the L3 node:
cd ../../op-node
go run cmd/main.go genesis l2 --deploy-config ../packages/contracts-bedrock/deploy-config/getting-started.json --l1-deployments ../packages/contracts-bedrock/deployments/5115-deploy.json --outfile.l2 genesis.json --l2-allocs ../packages/contracts-bedrock/state-dump-511551155115-fjord.json --outfile.rollup rollup.json --l1-rpc $L1_RPC_URL
openssl rand -hex 32 > jwt.txt
cp genesis.json ../op-geth
cp jwt.txt ../op-geth
Step 5: Initialize and start op-geth
Navigate to the op-geth
directory and initialize the genesis configuration:
cd ../../op-geth
mkdir datadir
make geth
build/bin/geth init --state.scheme=hash --datadir=datadir genesis.json
Then, start the op-geth
:
./build/bin/geth --datadir ./datadir --http --http.corsdomain="*" --http.vhosts="*" --http.addr=0.0.0.0 --http.api=web3,debug,eth,txpool,net,engine --ws --ws.addr=0.0.0.0 --ws.port=8546 --ws.origins="*" --ws.api=debug,eth,txpool,net,engine --syncmode=full --gcmode=archive --nodiscover --maxpeers=0 --networkid=511551155115 --authrpc.vhosts="*" --authrpc.addr=0.0.0.0 --authrpc.port=8551 --authrpc.jwtsecret=./jwt.txt --rollup.disabletxpoolgossip=true
Step 6: Add DA-config to op-node
Navigate to op-node
folder and add the following to the rollup.json
:
cd ../optimism/op-node
"alt_da": {
"da_commitment_type": "GenericCommitment",
"da_challenge_contract_address": "0x0000000000000000000000000000000000000000",
"da_challenge_window": 1000,
"da_resolve_window": 2000
}
Step 7: Run op-node
Go back to the main optimism
directory, and build op-node
:
cd ..
make op-node
Then let's run the node:
cd op-node
./bin/op-node --l2=http://localhost:8551 --l2.jwt-secret=./jwt.txt --sequencer.enabled --sequencer.l1-confs=5 --verifier.l1-confs=4 --rollup.config=./rollup.json --rpc.addr=0.0.0.0 --p2p.disable --rpc.enable-admin --p2p.sequencer.key=$GS_SEQUENCER_PRIVATE_KEY --l1=$L1_RPC_URL --l1.rpckind=$L1_RPC_KIND --altda.enabled=true --altda.da-service=true --l1.beacon=$L1_RPC_URL --l1.beacon.ignore=true --altda.da-server=http://localhost:3100 --l1.trustrpc=true --l1.http-poll-interval=2s
Step 8: Run op-batcher
Go back to the main optimism
directory, and build the op-batcher
:
cd ..
make op-batcher
Then let's run the batcher:
cd op-batcher
./bin/op-batcher --l2-eth-rpc=http://localhost:8545 --rollup-rpc=http://localhost:9545 --poll-interval=1s --sub-safety-margin=6 --num-confirmations=1 --safe-abort-nonce-too-low-count=3 --resubmission-timeout=30s --rpc.addr=0.0.0.0 --rpc.port=8548 --rpc.enable-admin --max-channel-duration=25 --l1-eth-rpc=$L1_RPC_URL --private-key=$GS_BATCHER_PRIVATE_KEY --altda.enabled=true --altda.da-service=true --altda.da-server=http://localhost:3100
Step 9: Run op-proposer
Go back to optimism main folder, and build the op-proposer:
cd ..
make op-proposer
Then let's run the proposer:
cd op-proposer
./bin/op-proposer --poll-interval=2s --rpc.port=8560 --rollup-rpc=http://localhost:9545 --l2oo-address=$(cat ../packages/contracts-bedrock/deployments/5115-deploy.json | jq -r .L2OutputOracleProxy) --private-key=$GS_PROPOSER_PRIVATE_KEY --l1-eth-rpc=$L1_RPC_URL
That’s it! Enjoy your Bitcoin Appchain on Citrea!
Last updated
Was this helpful?