Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZK-611: contract deployment environments #47

Merged
merged 20 commits into from
Dec 12, 2024
21 changes: 14 additions & 7 deletions .github/workflows/_check-vars-and-secrets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ jobs:
if [[ \
-z '${{ vars.SHIELDER_CONTRACT_ADDRESS }}' || \
-z '${{ vars.KUSTOMIZE_VERSION }}' || \
-z '${{ vars.CI_TESTNET_ALICE_PUBLIC_KEY }} }}' || \
-z '${{ vars.CI_TESTNET_BOB_PUBLIC_KEY }} }}' || \
-z '${{ vars.CI_TESTNET_CHARLIE_PUBLIC_KEY }} }}' || \
-z '${{ vars.CI_TESTNET_TS_SDK_PUBLIC_KEY }} }}' || \
-z '${{ vars.CI_TESTNET_RELAYER_SIGNER_ADDRESSES }} }}' || \
-z '${{ vars.CI_TESTNET_FEE_DESTINATION }} }}'
Comment on lines -18 to -23
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was NOT working

-z '${{ vars.CI_TESTNET_ALICE_PUBLIC_KEY }}' || \
-z '${{ vars.CI_TESTNET_BOB_PUBLIC_KEY }}' || \
-z '${{ vars.CI_TESTNET_CHARLIE_PUBLIC_KEY }}' || \
-z '${{ vars.CI_TESTNET_TS_SDK_PUBLIC_KEY }}' || \
-z '${{ vars.CI_TESTNET_RELAYER_SIGNER_ADDRESSES }}' || \
-z '${{ vars.CI_TESTNET_FEE_DESTINATION }}' || \
-z '${{ vars.CI_TESTNET_STAGE_OWNER_ADDRESS }}' || \
-z '${{ vars.MAINNET_PROD_OWNER_ADDRESS }}'
]]; then
echo '!!! Some repository variables are either missing or empty.'
echo '!!! Please check either repository or organization settings.'
Expand Down Expand Up @@ -52,10 +54,15 @@ jobs:
-z '${{ secrets.NPM_PUBLISHING_KEY }}' || \
-z '${{ secrets.CONTRACTS_ZKOS_ADDRESSES_TESTNET_DEV_RW_AWS_ACCESS_KEY_ID }}' || \
-z '${{ secrets.CONTRACTS_ZKOS_ADDRESSES_TESTNET_DEV_RW_AWS_SECRET_ACCESS_KEY }}' || \
-z '${{ secrets.CONTRACTS_ZKOS_ADDRESSES_TESTNET_STAGE_RW_AWS_ACCESS_KEY_ID }}' || \
-z '${{ secrets.CONTRACTS_ZKOS_ADDRESSES_TESTNET_STAGE_RW_AWS_SECRET_ACCESS_KEY }}' || \
-z '${{ secrets.CONTRACTS_ZKOS_ADDRESSES_MAINNET_PROD_RW_AWS_ACCESS_KEY_ID }}' || \
-z '${{ secrets.CONTRACTS_ZKOS_ADDRESSES_MAINNET_PROD_RW_AWS_SECRET_ACCESS_KEY }}' || \
-z '${{ secrets.CONTRACTS_S3BUCKET_REGION }}' || \
-z '${{ secrets.CONTRACTS_S3BUCKET_NAME }}' || \
-z '${{ secrets.CONTRACTS_ZKOS_ARTIFACTS_RW_AWS_ACCESS_KEY_ID }}' || \
-z '${{ secrets.CONTRACTS_ZKOS_ARTIFACTS_RW_AWS_SECRET_ACCESS_KEY }}'
-z '${{ secrets.CONTRACTS_ZKOS_ARTIFACTS_RW_AWS_SECRET_ACCESS_KEY }}' || \
-z '${{ secrets.CI_MAINNET_DEPLOYER_PRIVATE_KEY }}'
]]; then
echo '!!! Some repository secrets are either missing or empty.'
echo '!!! Please check either repository or organization settings.'
Expand Down
161 changes: 161 additions & 0 deletions .github/workflows/manual-deploy-contract.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
---
name: "Manually Deploy contracts"

on:
workflow_dispatch:
inputs:
environment:
description: "Environment to deploy to"
required: true
default: "dev"
type: choice
options:
- "dev"
- "stage"
- "prod"

jobs:
deploy-contracts:
name: Deploy contracts on ${{ github.event.inputs.environment }}
runs-on: [self-hosted, Linux, X64, medium]
steps:
- name: GIT | Checkout
uses: actions/checkout@v4

- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 18

- name: Prepare Rust env
uses: ./.github/actions/prepare-rust-env
with:
poseidon-gadget-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
zkos-circuits-private-key: ${{ secrets.ZKOS_CIRCUITS_SSH_PRIVATE_KEY }}

- name: Install Foundry
uses: foundry-rs/[email protected]
with:
cache-key: custom-seed-coverage-${{ github.ref_name }}
cache-restore-keys: |-
contract-suite
version: nightly-31dd1f77fd9156d09836486d97963cec7f555343

- name: Install deps
run: make deps

# for "dev" we use default owner address, as it's not important
- name: Set environment-specific variables
run: |
if [ "${{ github.event.inputs.environment }}" == "dev" ]; then
echo "PRIVATE_KEY=${{ secrets.CI_TESTNET_DEPLOYER_PRIVATE_KEY }}" >> $GITHUB_ENV
echo "NETWORK=https://rpc.alephzero-testnet.gelato.digital" >> $GITHUB_ENV
echo "EXPLORER_URL=https://evm-explorer-testnet.alephzero.org/api" >> $GITHUB_ENV
elif [ "${{ github.event.inputs.environment }}" == "stage" ]; then
echo "OWNER_ADDRESS=${{ vars.CI_TESTNET_STAGE_OWNER_ADDRESS }}" >> $GITHUB_ENV
echo "PRIVATE_KEY=${{ secrets.CI_TESTNET_DEPLOYER_PRIVATE_KEY }}" >> $GITHUB_ENV
echo "NETWORK=https://rpc.alephzero-testnet.gelato.digital" >> $GITHUB_ENV
echo "EXPLORER_URL=https://evm-explorer-testnet.alephzero.org/api" >> $GITHUB_ENV
elif [ "${{ github.event.inputs.environment }}" == "prod" ]; then
echo "OWNER_ADDRESS=${{ vars.MAINNET_PROD_OWNER_ADDRESS }}" >> $GITHUB_ENV
echo "PRIVATE_KEY=${{ secrets.CI_MAINNET_DEPLOYER_PRIVATE_KEY }}" >> $GITHUB_ENV
echo "NETWORK=https://rpc.alephzero.raas.gelato.cloud" >> $GITHUB_ENV
echo "EXPLORER_URL=https://evm-explorer.alephzero.org/api" >> $GITHUB_ENV
else
echo "Invalid environment selected!" >&2
exit 1
fi

- name: Compile eth contracts
run: make compile-contracts

- name: Deploy contracts
run: |
make deploy-contracts

- name: Verify Shielder contract
run: ./scripts/verify-shielder.sh

- name: Upload Shielder abi to artifacts
uses: actions/upload-artifact@v4
with:
name: shielder_abi
path: artifacts/Shielder.sol/Shielder.json
include-hidden-files: true
retention-days: 14

- name: Upload Shielder contract address to artifacts
uses: actions/upload-artifact@v4
with:
name: shielder_address
path: shielder_address.txt
include-hidden-files: true
retention-days: 14

- name: Create a JSON with address
run: |
echo -n $(cat shielder_address.txt | xargs) | jq -Rs '{ shielder: . }' \
> evm_addresses.json

- name: Prepare contract_spec JSON
uses: Cardinal-Cryptography/github-actions/generate-contract-spec@v6
with:
src-files: |-
evm_addresses.json|evm_
dst-file: contract_spec.json
spec-version: "0.1"
contract-version: "${{ github.sha }}"

- name: Add block numbers to contract_spec JSON
shell: bash
run: |
cat contract_spec.json | \
jq ".start_blocks = { evm: \"$(cat shielder_block_number.txt)\" }" \
> contract_spec_with_block_numbers.json

cat contract_spec_with_block_numbers.json

# yamllint disable rule:line-length
- name: Store addresses in S3 bucket (dev)
if: ${{ inputs.environment == 'dev' }}
shell: bash
env:
AWS_REGION: ${{ secrets.CONTRACTS_S3BUCKET_REGION }}
AWS_ACCESS_KEY_ID: ${{ secrets.CONTRACTS_ZKOS_ADDRESSES_TESTNET_DEV_RW_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.CONTRACTS_ZKOS_ADDRESSES_TESTNET_DEV_RW_AWS_SECRET_ACCESS_KEY }}
run: |
aws s3 cp contract_spec_with_block_numbers.json s3://${{ secrets.CONTRACTS_S3BUCKET_NAME }}/zkos/addresses/testnet/dev.json
aws s3 cp broadcast/Shielder.s.sol/2039/run-latest.json s3://${{ secrets.CONTRACTS_S3BUCKET_NAME }}/zkos/addresses/testnet/dev-broadcast.json

# yamllint disable rule:line-length
- name: Store addresses in S3 bucket (stage)
if: ${{ inputs.environment == 'stage' }}
shell: bash
env:
AWS_REGION: ${{ secrets.CONTRACTS_S3BUCKET_REGION }}
AWS_ACCESS_KEY_ID: ${{ secrets.CONTRACTS_ZKOS_ADDRESSES_TESTNET_STAGE_RW_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.CONTRACTS_ZKOS_ADDRESSES_TESTNET_STAGE_RW_AWS_SECRET_ACCESS_KEY }}
run: |
aws s3 cp contract_spec_with_block_numbers.json s3://${{ secrets.CONTRACTS_S3BUCKET_NAME }}/zkos/addresses/testnet/stage.json
aws s3 cp broadcast/Shielder.s.sol/2039/run-latest.json s3://${{ secrets.CONTRACTS_S3BUCKET_NAME }}/zkos/addresses/testnet/stage-broadcast.json

# yamllint disable rule:line-length
- name: Store addresses in S3 bucket (prod)
if: ${{ inputs.environment == 'prod' }}
shell: bash
env:
AWS_REGION: ${{ secrets.CONTRACTS_S3BUCKET_REGION }}
AWS_ACCESS_KEY_ID: ${{ secrets.CONTRACTS_ZKOS_ADDRESSES_MAINNET_PROD_RW_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.CONTRACTS_ZKOS_ADDRESSES_MAINNET_PROD_RW_AWS_SECRET_ACCESS_KEY }}
run: |
aws s3 cp contract_spec_with_block_numbers.json s3://${{ secrets.CONTRACTS_S3BUCKET_NAME }}/zkos/addresses/mainnet/prod.json
aws s3 cp broadcast/Shielder.s.sol/41455/run-latest.json s3://${{ secrets.CONTRACTS_S3BUCKET_NAME }}/zkos/addresses/mainnet/prod-broadcast.json

- name: Store artifact in S3 bucket
shell: bash
env:
AWS_ACCESS_KEY_ID: ${{ secrets.CONTRACTS_ZKOS_ARTIFACTS_RW_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.CONTRACTS_ZKOS_ARTIFACTS_RW_AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ${{ secrets.CONTRACTS_S3BUCKET_REGION }}
run: |
aws s3 cp artifacts/Shielder.sol/Shielder.json s3://${{ secrets.CONTRACTS_S3BUCKET_NAME }}/zkos/artifacts/${{ github.sha }}/eth_shielder/
105 changes: 0 additions & 105 deletions .github/workflows/manual-testnet-deploy-contract.yml

This file was deleted.

5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
NETWORK ?= anvil
PRIVATE_KEY ?= 0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 # pkey of the dev account `0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E` prefunded with ETH on all networks
OWNER_ADDRESS ?= $(shell cast wallet address $(PRIVATE_KEY))

.PHONY: help
help: # Show help for each of the Makefile recipes.
Expand Down Expand Up @@ -50,9 +51,9 @@ deploy-contracts: # Deploy solidity contracts
deploy-contracts:
ifeq ($(NETWORK),anvil)
$(eval PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80) \
PRIVATE_KEY=$(PRIVATE_KEY) forge script DeployShielderScript --broadcast --rpc-url anvil --sender $(shell cast wallet address $(PRIVATE_KEY))
PRIVATE_KEY=$(PRIVATE_KEY) OWNER_ADDRESS=$(OWNER_ADDRESS) forge script DeployShielderScript --broadcast --rpc-url anvil --sender $(shell cast wallet address $(PRIVATE_KEY))
else
PRIVATE_KEY=$(PRIVATE_KEY) forge script DeployShielderScript --broadcast --rpc-url $(NETWORK) --sender $(shell cast wallet address $(PRIVATE_KEY))
PRIVATE_KEY=$(PRIVATE_KEY) OWNER_ADDRESS=$(OWNER_ADDRESS) forge script DeployShielderScript --broadcast --rpc-url $(NETWORK) --sender $(shell cast wallet address $(PRIVATE_KEY))
endif

.PHONY: generate-poseidon-contracts
Expand Down
9 changes: 6 additions & 3 deletions scripts/Shielder.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ contract DeployShielderScript is Script {
function run() external {
uint256 privateKey = vm.envUint("PRIVATE_KEY");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we could rename it to DEPLOYER_PRIVATE_KEY for consistency with the Actions env vars?


address owner = vm.addr(privateKey);
console2.log("Using", owner, "as broadcaster");
address owner = vm.envAddress("OWNER_ADDRESS");
address broadcaster = vm.addr(privateKey);
console2.log("Using", broadcaster, "as broadcaster");

vm.startBroadcast(privateKey);

Expand All @@ -34,7 +35,9 @@ contract DeployShielderScript is Script {
Shielder shielder = Shielder(proxy);

console2.log("Shielder deployed at:", address(shielder));
shielder.unpause();
if (owner == broadcaster) {
shielder.unpause();
}

vm.stopBroadcast();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@

set -euo pipefail

LIBRARIES=$(cat broadcast/Shielder.s.sol/2039/run-latest.json | jq -r '.libraries | map("--libraries " + .) | join(" ")')
IMPL_CONTRACT_ADDRESS=$(cat broadcast/Shielder.s.sol/2039/run-latest.json \
CHAIN_ID=$(cast chain-id --rpc-url ${NETWORK})

LIBRARIES=$(cat broadcast/Shielder.s.sol/${CHAIN_ID}/run-latest.json | jq -r '.libraries | map("--libraries " + .) | join(" ")')
IMPL_CONTRACT_ADDRESS=$(cat broadcast/Shielder.s.sol/${CHAIN_ID}/run-latest.json \
| jq -r '.transactions | .[] | select(.transactionType=="CREATE") | select(.contractName=="Shielder") | .contractAddress')
PROXY_CONTRACT_ADDRESS=$(cat broadcast/Shielder.s.sol/2039/run-latest.json \
PROXY_CONTRACT_ADDRESS=$(cat broadcast/Shielder.s.sol/${CHAIN_ID}/run-latest.json \
| jq -r '.transactions | .[] | select(.transactionType=="CREATE") | select(.contractName=="ERC1967Proxy") | .contractAddress')
PROXY_DEPLOYMENT_TX_HASH=$(cat broadcast/Shielder.s.sol/2039/run-latest.json \
PROXY_DEPLOYMENT_TX_HASH=$(cat broadcast/Shielder.s.sol/${CHAIN_ID}/run-latest.json \
| jq '.transactions | .[] | select(.transactionType=="CREATE") | select(.contractName=="ERC1967Proxy") | .hash')
PROXY_BLOCK_NUMBER=$(cast to-dec $(cat broadcast/Shielder.s.sol/2039/run-latest.json \
PROXY_BLOCK_NUMBER=$(cast to-dec $(cat broadcast/Shielder.s.sol/${CHAIN_ID}/run-latest.json \
| jq -r ".receipts | .[] | select(.transactionHash==${PROXY_DEPLOYMENT_TX_HASH}) | .blockNumber"))

echo ${PROXY_CONTRACT_ADDRESS} > shielder_address.txt
echo ${PROXY_BLOCK_NUMBER} > shielder_block_number.txt

forge verify-contract --rpc-url https://rpc.alephzero-testnet.gelato.digital \
--verifier blockscout --verifier-url https://evm-explorer-testnet.alephzero.org/api \
forge verify-contract --rpc-url ${NETWORK} \
--verifier blockscout --verifier-url ${EXPLORER_URL} \
${LIBRARIES} \
${IMPL_CONTRACT_ADDRESS} \
contracts/Shielder.sol:Shielder
4 changes: 3 additions & 1 deletion tooling-e2e-tests/utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ mtzero() {
####################################################################################################
deploy_contracts() {
SHIELDER_CONTRACT_ADDRESS=$(
PRIVATE_KEY="${DEPLOYER_PRIVATE_KEY}" forge script DeployShielderScript \
PRIVATE_KEY="${DEPLOYER_PRIVATE_KEY}" \
OWNER_ADDRESS="$(cast wallet address ${DEPLOYER_PRIVATE_KEY})" \
forge script DeployShielderScript \
--rpc-url "${NODE_RPC_URL}" \
--broadcast \
--non-interactive \
Expand Down