2024-05-07 04:18:02 +00:00
#!/bin/bash
set -e
if [ -n " $CERC_SCRIPT_DEBUG " ] ; then
set -x
fi
CERC_L1_CHAIN_ID = " ${ CERC_L1_CHAIN_ID :- ${ DEFAULT_CERC_L1_CHAIN_ID } } "
CERC_L1_RPC = " ${ CERC_L1_RPC :- ${ DEFAULT_CERC_L1_RPC } } "
CERC_L1_ACCOUNTS_CSV_URL = " ${ CERC_L1_ACCOUNTS_CSV_URL :- ${ DEFAULT_CERC_L1_ACCOUNTS_CSV_URL } } "
2024-09-03 09:42:08 +00:00
CERC_PROPOSER_AMOUNT = " ${ CERC_PROPOSER_AMOUNT :- ${ DEFAULT_CERC_PROPOSER_AMOUNT } } "
CERC_BATCHER_AMOUNT = " ${ CERC_BATCHER_AMOUNT :- ${ DEFAULT_CERC_BATCHER_AMOUNT } } "
2024-05-07 04:18:02 +00:00
export DEPLOYMENT_CONTEXT = " $CERC_L1_CHAIN_ID "
# Optional create2 salt for deterministic deployment of contract implementations
export IMPL_SALT = $( openssl rand -hex 32)
echo " Using L1 RPC endpoint ${ CERC_L1_RPC } "
# Exit if a deployment already exists (on restarts)
2024-09-03 09:42:08 +00:00
if [ -f " /l1-deployment/ $DEPLOYMENT_CONTEXT -deploy.json " ] ; then
2024-07-18 15:02:52 +00:00
echo " Deployment directory /l1-deployment/ $DEPLOYMENT_CONTEXT -deploy.json, checking OptimismPortal deployment "
2024-05-07 04:18:02 +00:00
2024-07-18 15:02:52 +00:00
OPTIMISM_PORTAL_ADDRESS = $( cat /l1-deployment/$DEPLOYMENT_CONTEXT -deploy.json | jq -r .OptimismPortal)
2024-05-07 04:18:02 +00:00
contract_code = $( cast code $OPTIMISM_PORTAL_ADDRESS --rpc-url $CERC_L1_RPC )
if [ -z " ${ contract_code #0x } " ] ; then
echo "Error: A deployment directory was found in the volume, but no contract code was found on-chain at the associated address. Please clear L1 deployment volume before restarting."
exit 1
else
echo "Deployment found, exiting (successfully)."
exit 0
fi
fi
wait_for_block( ) {
local block = " $1 " # Block to wait for
local timeout = " $2 " # Max time to wait in seconds
echo " Waiting for block $block . "
i = 0
loops = $(( $timeout / 10 ))
while [ -z " $block_result " ] && [ [ " $i " -lt " $loops " ] ] ; do
sleep 10
echo "Checking..."
block_result = $( cast block $block --rpc-url $CERC_L1_RPC | grep -E "(timestamp|hash|number)" || true )
i = $(( $i + 1 ))
done
}
# We need four accounts and their private keys for the deployment: Admin, Proposer, Batcher, and Sequencer
# If $CERC_L1_ADDRESS and $CERC_L1_PRIV_KEY have been set, we'll assign it to Admin and generate/fund the remaining three accounts from it
# If not, we'll assume the L1 is the stack's own fixturenet-eth and use the pre-funded accounts/keys from $CERC_L1_ACCOUNTS_CSV_URL
if [ -n " $CERC_L1_ADDRESS " ] && [ -n " $CERC_L1_PRIV_KEY " ] ; then
wallet1 = $( cast wallet new)
wallet2 = $( cast wallet new)
wallet3 = $( cast wallet new)
# Admin
ADMIN = $CERC_L1_ADDRESS
ADMIN_KEY = $CERC_L1_PRIV_KEY
# Proposer
PROPOSER = $( echo " $wallet1 " | awk '/Address:/{print $2}' )
PROPOSER_KEY = $( echo " $wallet1 " | awk '/Private key:/{print $3}' )
# Batcher
BATCHER = $( echo " $wallet2 " | awk '/Address:/{print $2}' )
BATCHER_KEY = $( echo " $wallet2 " | awk '/Private key:/{print $3}' )
# Sequencer
SEQ = $( echo " $wallet3 " | awk '/Address:/{print $2}' )
SEQ_KEY = $( echo " $wallet3 " | awk '/Private key:/{print $3}' )
echo "Funding accounts."
wait_for_block 1 300
2024-09-03 09:42:08 +00:00
cast send --from $ADMIN --rpc-url $CERC_L1_RPC --value $CERC_PROPOSER_AMOUNT $PROPOSER --private-key $ADMIN_KEY
cast send --from $ADMIN --rpc-url $CERC_L1_RPC --value $CERC_BATCHER_AMOUNT $BATCHER --private-key $ADMIN_KEY
2024-05-07 04:18:02 +00:00
else
curl -o accounts.csv $CERC_L1_ACCOUNTS_CSV_URL
# Admin
ADMIN = $( awk -F ',' 'NR == 1 {print $2}' accounts.csv)
ADMIN_KEY = $( awk -F ',' 'NR == 1 {print $3}' accounts.csv)
# Proposer
PROPOSER = $( awk -F ',' 'NR == 2 {print $2}' accounts.csv)
PROPOSER_KEY = $( awk -F ',' 'NR == 2 {print $3}' accounts.csv)
# Batcher
BATCHER = $( awk -F ',' 'NR == 3 {print $2}' accounts.csv)
BATCHER_KEY = $( awk -F ',' 'NR == 3 {print $3}' accounts.csv)
# Sequencer
SEQ = $( awk -F ',' 'NR == 4 {print $2}' accounts.csv)
SEQ_KEY = $( awk -F ',' 'NR == 4 {print $3}' accounts.csv)
fi
echo "Using accounts:"
echo -e " Admin: $ADMIN \nProposer: $PROPOSER \nBatcher: $BATCHER \nSequencer: $SEQ "
# These accounts will be needed by other containers, so write them to a shared volume
echo "Writing accounts/private keys to volume l2_accounts."
accounts_json = $( jq -n \
--arg Admin " $ADMIN " --arg AdminKey " $ADMIN_KEY " \
--arg Proposer " $PROPOSER " --arg ProposerKey " $PROPOSER_KEY " \
--arg Batcher " $BATCHER " --arg BatcherKey " $BATCHER_KEY " \
--arg Seq " $SEQ " --arg SeqKey " $SEQ_KEY " \
'{Admin: $Admin, AdminKey: $AdminKey, Proposer: $Proposer, ProposerKey: $ProposerKey, Batcher: $Batcher, BatcherKey: $BatcherKey, Seq: $Seq, SeqKey: $SeqKey}' )
echo " $accounts_json " > "/l2-accounts/accounts.json"
# Get a finalized L1 block to set as the starting point for the L2 deployment
# If the chain is a freshly created fixturenet-eth, a finalized block won't be available for many minutes; rather than wait, we can use block 1
echo "Checking L1 for finalized block..."
finalized = $( cast block finalized --rpc-url $CERC_L1_RPC | grep -E "(timestamp|hash|number)" || true )
config_build_script = "scripts/getting-started/config.sh"
if [ -z " $finalized " ] ; then
# assume fresh chain and use block 1 instead
echo "No finalized block. Using block 1 instead."
# wait for 20 or so blocks to be safe
wait_for_block 24 300
# Replace how block is calculated in the config building script
sed -i 's/block=.*/block=$(cast block 1 --rpc-url $L1_RPC_URL)/g' $config_build_script
fi
# Generate the deploy-config/getting-started.json file
2024-07-18 15:02:52 +00:00
GS_ADMIN_ADDRESS = $ADMIN \
GS_BATCHER_ADDRESS = $BATCHER \
GS_PROPOSER_ADDRESS = $PROPOSER \
GS_SEQUENCER_ADDRESS = $SEQ \
L1_RPC_URL = $CERC_L1_RPC \
L1_CHAIN_ID = $CERC_L1_CHAIN_ID \
L2_CHAIN_ID = 42069 \
2024-08-29 10:58:30 +00:00
L1_BLOCK_TIME = ${ CERC_L1_BLOCK_TIME :- $DEFAULT_CERC_L1_BLOCK_TIME } \
L2_BLOCK_TIME = ${ CERC_L2_BLOCK_TIME :- $DEFAULT_CERC_L2_BLOCK_TIME } \
2024-07-18 15:02:52 +00:00
$config_build_script
2024-05-07 04:18:02 +00:00
echo "Writing deployment config."
deploy_config_file = " deploy-config/ $DEPLOYMENT_CONTEXT .json "
cp deploy-config/getting-started.json $deploy_config_file
# Update generated config
# 1. Update L1 chain id
# 2. Add missing faultGameWithdrawalDelay field
# (see issue: https://github.com/ethereum-optimism/optimism/issues/9773#issuecomment-2080224969)
mkdir -p deployments/$DEPLOYMENT_CONTEXT
# Deployment requires the create2 deterministic proxy contract be published on L1 at address 0x4e59b44847b379578588920ca78fbf26c0b4956c
# See: https://github.com/Arachnid/deterministic-deployment-proxy
create2CodeSize = $( cast codesize 0x4e59b44847b379578588920cA78FbF26c0B4956C --rpc-url $CERC_L1_RPC )
if [ " $create2CodeSize " -eq 0 ] ; then
echo "Deploying create2 proxy contract..."
echo "Funding deployment signer address"
deployment_signer = "0x3fab184622dc19b6109349b94811493bf2a45362"
cast send --from $ADMIN --rpc-url $CERC_L1_RPC --value 0.5ether $deployment_signer --private-key $ADMIN_KEY
raw_bytes = "0xf8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222"
cast publish --rpc-url $CERC_L1_RPC $raw_bytes
fi
# Create the L2 deployment
2024-08-18 16:31:51 +00:00
# Writes out artifact to $OPTIMISM_ROOT/packages/contracts-bedrock/deployments/$DEPLOYMENT_CONTEXT-deploy.json
2024-05-07 04:18:02 +00:00
echo "Deploying L1 Optimism contracts..."
2024-08-22 04:37:43 +00:00
DEPLOY_CONFIG_PATH = $deploy_config_file forge script scripts/deploy/Deploy.s.sol:Deploy --private-key $ADMIN_KEY --broadcast --rpc-url $CERC_L1_RPC
2024-05-07 04:18:02 +00:00
echo "Done deploying contracts."
echo "Generating L2 genesis allocs..."
L2_CHAIN_ID = $( jq ".l2ChainID" $deploy_config_file )
2024-07-18 15:02:52 +00:00
DEPLOY_CONFIG_PATH = $deploy_config_file \
CONTRACT_ADDRESSES_PATH = deployments/$DEPLOYMENT_CONTEXT -deploy.json \
2024-08-23 01:47:58 +00:00
STATE_DUMP_PATH = allocs-l2.json \
forge script --chain-id $L2_CHAIN_ID scripts/L2Genesis.s.sol:L2Genesis --sig 'runWithStateDump()' --private-key $ADMIN_KEY
2024-05-07 04:18:02 +00:00
2024-07-18 15:02:52 +00:00
echo "Done."
2024-05-07 04:18:02 +00:00
echo "*************************************"
# Copy files needed by other containers to the appropriate shared volumes
echo "Copying deployment artifacts volume l1_deployment and deploy-config to volume l2_config"
2024-08-23 01:47:58 +00:00
cp /opt/optimism/packages/contracts-bedrock/deployments/$DEPLOYMENT_CONTEXT -deploy.json /l1-deployment
cp /opt/optimism/packages/contracts-bedrock/deploy-config/$DEPLOYMENT_CONTEXT .json /l2-config
2024-05-07 04:18:02 +00:00
cp allocs-l2.json /l2-config
2024-08-23 01:47:58 +00:00
echo "Deployment successful, exiting."