-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: bash scripts to deploy, generate allocs genesis file, and check it
- Loading branch information
1 parent
75db01b
commit 6dcf792
Showing
6 changed files
with
224 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
## Allocs | ||
|
||
These scripts are utilities for setting up the `genesis.json` file for a new chain. | ||
|
||
Developers write Forge script(s) that deploy and configure the contracts they wish to be pre-deployed on their chain. These scripts can then produce an `alloc` JSON file to input to `genesis.json`, which will setup those contracts with the correct code and storage slots. | ||
|
||
## Usage | ||
|
||
### Dependencies | ||
|
||
Install `heimdall` - instructions [here](https://github.com/Jon-Becker/heimdall-rs/tree/main?tab=readme-ov-file#installation--usage) | ||
|
||
Install `foundry` - instructions [here](https://book.getfoundry.sh/getting-started/installation) | ||
|
||
### Setup Scripts | ||
|
||
First, the developer must setup their `deploy-scripts.json` with the Forge scripts they want to run. | ||
|
||
Each script is represented in JSON with the following fields: | ||
- `relativePath`: the relative path to the repo containing the Forge script to run. | ||
- `deployFile`: the file name that contains the Forge script. | ||
- `deployContract`: the name of the contract in which the script is defined. | ||
- `deploySignature`: the function signature of the deploy script | ||
|
||
Using Uniswap's [Permit2](https://github.com/Uniswap/permit2/blob/main/script/DeployPermit2.s.sol) as an example, the JSON would look like this: | ||
``` | ||
{ | ||
"relativePath": "../permit2", | ||
"deployFile": "DeployPermit2.s.sol", | ||
"deployContract": "DeployPermit2", | ||
"deploySignature": "run" | ||
} | ||
``` | ||
|
||
### Deploy | ||
|
||
This bash script will run each of the deploy scripts within their respective repos, then output the addresses of every contract deployed: | ||
|
||
```shell | ||
$ ./allocs/deploy.sh $RPC_URL $PRIVATE_KEY | ||
``` | ||
|
||
### Generate Alloc | ||
|
||
This script will read from the outputs generated by the deploy script, then use `cast code` and `heimdall dump` to generate a complete `alloc` JSON: | ||
|
||
```shell | ||
$ ./allocs/generate-alloc.sh $ARCHIVE_RPC_URL | ||
``` | ||
|
||
NOTE: You MUST provide an archive RPC endpoint that supports `trace_replayBlockTransactions`, as `heimdall dump` relies on this endpoint. Unfortuntately, at the time of writing, `anvil` does not support this endpoint. | ||
|
||
### Check Alloc | ||
|
||
If you have an `alloc` JSON and you wish to check the storage slots against a deployed chain, you can run the following script: | ||
```shell | ||
$ ./allocs/check-alloc.sh $RPC_URL | ||
``` | ||
Note that a non-archive RPC endpoint is fine for this command. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# ./allocs/check-alloc.sh $RPC_URL | ||
|
||
rpc=$1 | ||
chainid=$(cast chain-id --rpc-url $rpc) | ||
|
||
# Pull the current alloc JSON | ||
contents=$(cat allocs/$chainid/alloc.json) | ||
|
||
# Get all addresses JSON | ||
addrs=$(echo $contents | jq -r '.alloc | keys[]') | ||
|
||
# For each contract, | ||
for addr in $addrs; do | ||
# Get the code using `cast` | ||
code=$(cast code $addr --rpc-url $rpc) | ||
# replace the value in the JSON with the queried code | ||
contents=$(echo $contents | jq --arg addy "$addr" --arg newCode "$code" '.alloc[$addy].code = $newCode') | ||
|
||
# Get the storage slots in the JSON | ||
slots=$(echo $contents | jq -r --arg addy "$addr" '.alloc[$addy].storage | select(. != null) | keys[]') | ||
for slot in $slots; do | ||
# Get the storage value using `cast` | ||
value=$(cast storage $addr $slot --rpc-url $rpc) | ||
# replace the value in the JSON with the queried storage value | ||
contents=$(echo $contents | jq --arg addy "$addr" --arg slot "$slot" --arg newValue "$value" '.alloc[$addy].storage[$slot] = $newValue') | ||
done | ||
done | ||
|
||
echo "$contents" > ./allocs/$chainid/alloc.json | ||
echo "Done - allocs re-written to alloc.json!" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
[ | ||
{ | ||
"relativePath": "../permit2", | ||
"deployFilePath": "script", | ||
"deployFile": "DeployPermit2.s.sol", | ||
"deployContract": "DeployPermit2", | ||
"deploySignature": "run" | ||
}, | ||
{ | ||
"relativePath": "../zenith", | ||
"deployFilePath": "script", | ||
"deployFile": "ZenithL2.s.sol", | ||
"deployContract": "L2Script", | ||
"deploySignature": "deploySystem" | ||
}, | ||
{ | ||
"relativePath": "../zenith", | ||
"deployFilePath": "script", | ||
"deployFile": "DeployGnosisSafe.s.sol", | ||
"deployContract": "GnosisScript", | ||
"deploySignature": "deployGnosis" | ||
}, | ||
{ | ||
"relativePath": "../stablecoin-evm", | ||
"deployFilePath": "scripts/deploy", | ||
"deployFile": "deploy-fiat-token.s.sol", | ||
"deployContract": "DeployFiatToken", | ||
"deploySignature": "run" | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# ./allocs/deploy.sh $RPC_URL $PRIVATE_KEY | ||
# NOTE: before running, setup the forge scripts that will run at `allocs/deploy-scripts.json` | ||
|
||
rpc=$1 | ||
privateKey=$2 | ||
|
||
# parse array of script commands `allocs/deploy-scripts.json`` | ||
scripts=$(cat allocs/deploy-scripts.json | jq -c '.[]') | ||
|
||
echo "$scripts" | while IFS= read -r script; do | ||
# pull the script vars | ||
relativePath=$(echo "$script" | jq -r '.relativePath') | ||
deployFilePath=$(echo "$script" | jq -r '.deployFilePath') | ||
deployFile=$(echo "$script" | jq -r '.deployFile') | ||
deployContract=$(echo "$script" | jq -r '.deployContract') | ||
deploySignature=$(echo "$script" | jq -r '.deploySignature') | ||
|
||
# cd to a new repo if necessary | ||
cd $relativePath | ||
|
||
# run the deploy script | ||
forge script $deployFilePath/${deployFile}:${deployContract} --sig $deploySignature --rpc-url $rpc --private-key $privateKey --broadcast | ||
done | ||
|
||
# write the addresses | ||
./allocs/write-output.sh $rpc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# ./allocs/generate.sh $ARCHIVE_RPC_URL | ||
|
||
rpc=$1 | ||
chainid=$(cast chain-id --rpc-url $rpc) | ||
|
||
# set empty allocs | ||
alloc="{}" | ||
|
||
# parse the JSON at `addresses.json` and get an array of addresses | ||
addresses=$(cat allocs/$chainid/addresses.json | jq -r '.[] | .contractAddress') | ||
fromBlock=$(printf "%d\n" $(cat allocs/$chainid/blocks.json | jq -r 'sort | .[0]')) | ||
toBlock=$(printf "%d\n" $(cat allocs/$chainid/blocks.json | jq -r 'sort | .[-1]')) | ||
|
||
# loop through addresses, | ||
for addr in $addresses; do | ||
# CODE | ||
# Get the code using `cast` | ||
code=$(cast code $addr --rpc-url $rpc --block $toBlock) | ||
# replace the value in the JSON with the queried code | ||
alloc=$(echo $alloc | jq --arg addy "$addr" --arg newCode "$code" '.alloc[$addy].code = $newCode') | ||
|
||
# STORAGE | ||
# Get the storage slots using heimdall | ||
echo "Dumping storage for $addr..." | ||
heimdall dump $addr --from-block $fromBlock --to-block $toBlock --rpc-url $rpc --output ./allocs/$chainid/$addr | ||
# parse the .csv output to json | ||
storage=$(awk -F, 'NR>1 {printf "\"%s\": \"%s\", ", $1, $2}' ./allocs/$chainid/$addr/dump.csv | sed 's/, $//') | ||
# replace the value in the JSON with the queried storage values | ||
alloc=$(echo $alloc | jq --arg addy "$addr" --argjson storage "{$storage}" '.alloc[$addy].storage = $storage') | ||
# remove the .csv files | ||
rm -rf ./allocs/$chainid/$addr/ | ||
done | ||
|
||
touch ./allocs/$chainid/alloc.json | ||
echo "$alloc" | jq '.' > ./allocs/$chainid/alloc.json | ||
echo "Done - generated allocs written to ./allocs/$chainid/alloc.json!" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# ./allocs/write-addresses.sh $RPC_URL | ||
# NOTE: before running, setup the forge scripts to inspect outputs from at `allocs/deploy-scripts.json` | ||
|
||
rpc=$1 | ||
chainid=$(cast chain-id --rpc-url $rpc) | ||
|
||
contracts="[]" | ||
blocks="[]" | ||
|
||
workingdir=$(pwd) | ||
mkdir -p ./allocs/$chainid | ||
|
||
# parse array of script commands `allocs/deploy-scripts.json`` | ||
scripts=$(cat allocs/deploy-scripts.json | jq -c '.[]') | ||
|
||
echo "$scripts" | while IFS= read -r script; do | ||
# pull the script vars | ||
relativePath=$(echo "$script" | jq -r '.relativePath') | ||
deployFile=$(echo "$script" | jq -r '.deployFile') | ||
deployContract=$(echo "$script" | jq -r '.deployContract') | ||
deploySignature=$(echo "$script" | jq -r '.deploySignature') | ||
|
||
# cd to the script repo | ||
cd $relativePath | ||
|
||
# get contracts deployed via CREATE or CREATE2 | ||
newContracts=$(cat broadcast/${deployFile}/${chainid}/${deploySignature}-latest.json | jq '[.transactions[] | select(.transactionType == ("CREATE", "CREATE2")) | {contractName, contractAddress}]') | ||
# get contracts deployed in sub-calls | ||
additionalContracts=$(cat broadcast/${deployFile}/${chainid}/${deploySignature}-latest.json | jq '[.transactions[].additionalContracts[] | {contractAddress: .address}]') | ||
# append all new contracts to the running total | ||
contracts=$(echo "$contracts" "$newContracts" "$additionalContracts" | jq -s '.[0] + .[1] + .[2]') | ||
# write addresses to file | ||
echo "$contracts" > $workingdir/allocs/$chainid/addresses.json | ||
|
||
# get blocks | ||
newBlocks=$(cat broadcast/${deployFile}/${chainid}/${deploySignature}-latest.json | jq '[.receipts[].blockNumber]') | ||
# append new blocks to the running total | ||
blocks=$(echo "$blocks" "$newBlocks" | jq -s '.[0] + .[1] | sort | unique') | ||
# write blocks to file | ||
echo "$blocks" > $workingdir/allocs/$chainid/blocks.json | ||
done | ||
|
||
echo "Done! Outputs written to ./allocs/$chainid/" |