Skip to content

Commit

Permalink
Contract code verification using Blockscout (#33)
Browse files Browse the repository at this point in the history
* Fix json filename

* Adapt deployment script to support contract verification using Blockscout

* Update readme
  • Loading branch information
matjazv committed Feb 6, 2024
1 parent a23f3eb commit 4716830
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 26 deletions.
27 changes: 20 additions & 7 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,33 @@ L1_STANDARD_BRIDGE_ADDR=0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1
# L1 RPC URL, e.g. Infura, Alchemy, or your own node
L1_RPC_URL=https://sepolia.infura.io/v3/YOUR_INFURA_KEY

# RPC URL of the L1 network from which a private L1 test network is forked if a private test network is used, e.g. Infura, Alchemy
L1_FORK_RPC_URL=https://sepolia.infura.io/v3/YOUR_INFURA_KEY

# L2 RPC URL, e.g. Infura, Alchemy, or your own node
L2_RPC_URL=https://optimism-sepolia.infura.io/v3/YOUR_INFURA_KEY

# RPC URL of the L2 network from which a private L2 test network is forked if a private test network is used, e.g. Infura, Alchemy
L2_FORK_RPC_URL=https://optimism-sepolia.infura.io/v3/YOUR_INFURA_KEY
# *************** SMART CONTRACT VERIFICATION ***************

# Contract verifier - blockscout or etherscan. If not provided, verification will be skipped.
CONTRACT_VERIFIER=blockscout

# Verifier URL for smart contracts deployed on L1 network
L1_VERIFIER_URL=https://eth-sepolia.blockscout.com/api\?

# Verifier URL for smart contracts deployed on L2 network
L2_VERIFIER_URL=https://sepolia-blockscout.lisk.com/api\?

# L1 Etherscan API key (needed for contract verification, if not provided, verification will be skipped)
# L1 Etherscan API key
L1_ETHERSCAN_API_KEY=

# L2 Etherscan API key (needed for contract verification, if not provided, verification will be skipped)
# L2 Etherscan API key
L2_ETHERSCAN_API_KEY=

# *************** PRIVATE TESTNET ***************

# RPC URL of the L1 network from which a private L1 test network is forked if a private test network is used, e.g. Infura, Alchemy
L1_FORK_RPC_URL=https://sepolia.infura.io/v3/YOUR_INFURA_KEY

# RPC URL of the L2 network from which a private L2 test network is forked if a private test network is used, e.g. Infura, Alchemy
L2_FORK_RPC_URL=https://optimism-sepolia.infura.io/v3/YOUR_INFURA_KEY

# Test network default mnemonic
TEST_NETWORK_MNEMONIC="test test test test test test test test test test test junk"
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ git submodule update --init --recursive
**NOTE**: To successfully deploy all smart contracts and execute the required transactions, the deployer (specified by `PRIVATE_KEY` in the `.env` file) must have funds available in its address on the respective networks. For a private test network, you can use a any private key from the list provided by `anvil` when the network is created, or choose another private key with sufficient funds on both forked networks.

Private L1 and L2 test networks are established using the `anvil` tool, and the smart contracts are deployed using the `forge script` tool. To run private networks and deploy the smart contracts, follow these steps:
1. Create `.env` file and set the vars `PRIVATE_KEY`, `NETWORK`, `L1_TOKEN_OWNER_ADDRESS`, `L2_CLAIM_OWNER_ADDRESS`, `DAO_ADDRESS`, `DETERMINISTIC_ADDRESS_SALT`, `L1_STANDARD_BRIDGE_ADDR`, `L1_RPC_URL`, `L1_FORK_RPC_URL`, `L2_RPC_URL`, `L2_FORK_RPC_URL` and `TEST_NETWORK_MNEMONIC`. You can copy and rename the `.env.example` file if the default values provided in `.env.example` are satisfactory. `L1_RPC_URL` should be set to `http://127.0.0.1:8545` and `L2_RPC_URL` should be set to `http://127.0.0.1:8546` if no changes are made in the `./runL1TestNetwork.sh` or `./runL2TestNetwork.sh` script files.
1. Create `.env` file and set the vars `PRIVATE_KEY`, `NETWORK`, `L1_TOKEN_OWNER_ADDRESS`, `L2_CLAIM_OWNER_ADDRESS`, `DAO_ADDRESS`, `DETERMINISTIC_ADDRESS_SALT`, `L1_STANDARD_BRIDGE_ADDR`, `L1_RPC_URL`, `L2_RPC_URL`, `L1_FORK_RPC_URL`, `L2_FORK_RPC_URL` and `TEST_NETWORK_MNEMONIC`. You can copy and rename the `.env.example` file if the default values provided in `.env.example` are satisfactory. `L1_RPC_URL` should be set to `http://127.0.0.1:8545` and `L2_RPC_URL` should be set to `http://127.0.0.1:8546` if no changes are made in the `./runL1TestNetwork.sh` or `./runL2TestNetwork.sh` script files.
2. Navigate to the `script` directory.
3. Place the `accounts.json` and `merkle-root.json` files in the correct folder (`data/devnet`, `data/testnet`, or `data/mainnet`) corresponding to the previously set `NETWORK` environment variable. Example files for `accounts.json` and `merkle-root.json` may be found inside `data/devnet` directory.
4. To create and launch a private test L1 network, execute the script: `./runL1TestNetwork.sh`
Expand All @@ -75,11 +75,12 @@ Private L1 and L2 test networks are established using the `anvil` tool, and the

**NOTE**: To successfully deploy all smart contracts and execute the required transactions, the deployer (specified by `PRIVATE_KEY` in the `.env` file) must have funds available in its address. This implies that a private key with a sufficient balance on both public test networks is required.

To deploy smart contracts on both L1 and L2 public networks, you will need to provide for each network an URL for a public node from a RPC provider, such as Alchemy or Infura. Additionally, in order to verify smart contracts on Etherscan Block Explorer during the deployment process, it is necessary to provide an Etherscan API key. Follow these steps to deploy the smart contracts:
1. Create `.env` file and set the vars `PRIVATE_KEY`, `NETWORK`, `L1_TOKEN_OWNER_ADDRESS`, `L2_CLAIM_OWNER_ADDRESS`, `DAO_ADDRESS`, `DETERMINISTIC_ADDRESS_SALT`, `L1_STANDARD_BRIDGE_ADDR`, `L1_RPC_URL`, `L2_RPC_URL`, `L1_ETHERSCAN_API_KEY` and `L2_ETHERSCAN_API_KEY`. You can copy and rename the `.env.example` file if the default values provided in `.env.example` are satisfactory. `L1_ETHERSCAN_API_KEY` and `L2_ETHERSCAN_API_KEY` may be empty to skip smart contracts verification process on Etherscan Block Explorer.
2. Navigate to the `script` directory.
3. Place the `accounts.json` and `merkle-root.json` files in the correct folder (`data/devnet`, `data/testnet`, or `data/mainnet`) corresponding to the previously set `NETWORK` environment variable. Example files for `accounts.json` and `merkle-root.json` may be found inside `data/devnet` directory.
4. To deploy all smart contracts, execute the script: `./deployContracts.sh`
To deploy smart contracts on both L1 and L2 public networks, you will need to provide for each network an URL for a public node from a RPC provider, such as Alchemy or Infura. Additionally, in order to verify smart contracts on Blockscout or Etherscan Block Explorers during the deployment process, it is necessary to provide verifier name along with additional information (URL and API key). Follow these steps to deploy the smart contracts:
1. Create `.env` file and set the vars `PRIVATE_KEY`, `NETWORK`, `L1_TOKEN_OWNER_ADDRESS`, `L2_CLAIM_OWNER_ADDRESS`, `DAO_ADDRESS`, `DETERMINISTIC_ADDRESS_SALT`, `L1_STANDARD_BRIDGE_ADDR`, `L1_RPC_URL`, `L2_RPC_URL` and `CONTRACT_VERIFIER`. You can copy and rename the `.env.example` file if the default values provided in `.env.example` are satisfactory. `CONTRACT_VERIFIER` may be empty to skip smart contracts verification process on Blockscout or Etherscan Block Explorers.
2. When `CONTRACT_VERIFIER` is configured as either `blockscout` or `etherscan`, there are specific additional variables that must be defined. For `blockscout`, it is necessary to set `L1_VERIFIER_URL` and `L2_VERIFIER_URL`. Conversely, for `etherscan`, it is necessary to set `L1_ETHERSCAN_API_KEY` and `L2_ETHERSCAN_API_KEY`.
3. Navigate to the `script` directory.
4. Place the `accounts.json` and `merkle-root.json` files in the correct folder (`data/devnet`, `data/testnet`, or `data/mainnet`) corresponding to the previously set `NETWORK` environment variable. Example files for `accounts.json` and `merkle-root.json` may be found inside `data/devnet` directory.
5. To deploy all smart contracts, execute the script: `./deployContracts.sh`

## Tips & Tricks

Expand Down
4 changes: 2 additions & 2 deletions script/Utils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ contract Utils is Script {
function readL2AddressesFile() external view returns (L2AddressesConfig memory) {
string memory network = getNetworkType();
string memory root = vm.projectRoot();
string memory addressPath = string.concat(root, "/deployment/", network, "/ll2addresses.json");
string memory addressPath = string.concat(root, "/deployment/", network, "/l2addresses.json");
string memory addressJson = vm.readFile(addressPath);
bytes memory addressRaw = vm.parseJson(addressJson);
return abi.decode(addressRaw, (L2AddressesConfig));
Expand All @@ -99,7 +99,7 @@ contract Utils is Script {
vm.serializeAddress(json, "L2ClaimContract", cfg.L2ClaimContract);
vm.serializeAddress(json, "L2ClaimImplementation", cfg.L2ClaimImplementation);
string memory finalJson = vm.serializeAddress(json, "L2LiskToken", cfg.L2LiskToken);
finalJson.write(string.concat("deployment/", network, "/ll2addresses.json"));
finalJson.write(string.concat("deployment/", network, "/l2addresses.json"));
}

/// @notice This function reads MerkleRoot from JSON file.
Expand Down
43 changes: 32 additions & 11 deletions script/deployContracts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,51 @@ else
fi
echo "Done."

echo "Deploying L1LiskToken smart contract..."
if [ -z "$L1_ETHERSCAN_API_KEY" ]
echo "Deploying and if enabled verifying L1LiskToken smart contract..."
if [ -z "$CONTRACT_VERIFIER" ]
then
forge script --rpc-url="$L1_RPC_URL" --broadcast -vvvv script/L1LiskToken.s.sol:L1LiskTokenScript
else
forge script --rpc-url="$L1_RPC_URL" --broadcast --verify --etherscan-api-key="$L1_ETHERSCAN_API_KEY" -vvvv script/L1LiskToken.s.sol:L1LiskTokenScript
if [ $CONTRACT_VERIFIER = "blockscout" ]
then
forge script --rpc-url="$L1_RPC_URL" --broadcast --verify --verifier blockscout --verifier-url $L1_VERIFIER_URL -vvvv script/L1LiskToken.s.sol:L1LiskTokenScript
fi
if [ $CONTRACT_VERIFIER = "etherscan" ]
then
forge script --rpc-url="$L1_RPC_URL" --broadcast --verify --verifier etherscan --etherscan-api-key="$L1_ETHERSCAN_API_KEY" -vvvv script/L1LiskToken.s.sol:L1LiskTokenScript
fi
fi
echo "Done."

echo "Deploying L2LiskToken smart contract..."
if [ -z "$L2_ETHERSCAN_API_KEY" ]
echo "Deploying and if enabled verifying L2LiskToken smart contract..."
if [ -z "$CONTRACT_VERIFIER" ]
then
forge script --rpc-url="$L2_RPC_URL" --broadcast -vvvv script/L2LiskToken.s.sol:L2LiskTokenScript
forge script --rpc-url="$L2_RPC_URL" --broadcast -vvvv script/L2LiskToken.s.sol:L2LiskTokenScript
else
forge script --rpc-url="$L2_RPC_URL" --broadcast --verify --etherscan-api-key="$L2_ETHERSCAN_API_KEY" -vvvv script/L2LiskToken.s.sol:L2LiskTokenScript
if [ $CONTRACT_VERIFIER = "blockscout" ]
then
forge script --rpc-url="$L2_RPC_URL" --broadcast --verify --verifier blockscout --verifier-url $L2_VERIFIER_URL -vvvv script/L2LiskToken.s.sol:L2LiskTokenScript
fi
if [ $CONTRACT_VERIFIER = "etherscan" ]
then
forge script --rpc-url="$L2_RPC_URL" --broadcast --verify --verifier etherscan --etherscan-api-key="$L2_ETHERSCAN_API_KEY" -vvvv script/L2LiskToken.s.sol:L2LiskTokenScript
fi
fi
echo "Done."

echo "Deploying L2Claim smart contract..."
if [ -z "$L2_ETHERSCAN_API_KEY" ]
echo "Deploying and if enabled verifying L2Claim smart contract..."
if [ -z "$CONTRACT_VERIFIER" ]
then
forge script --rpc-url="$L2_RPC_URL" --broadcast -vvvv script/L2Claim.s.sol:L2ClaimScript
forge script --rpc-url="$L2_RPC_URL" --broadcast -vvvv script/L2Claim.s.sol:L2ClaimScript
else
forge script --rpc-url="$L2_RPC_URL" --broadcast --verify --etherscan-api-key="$L2_ETHERSCAN_API_KEY" -vvvv script/L2Claim.s.sol:L2ClaimScript
if [ $CONTRACT_VERIFIER = "blockscout" ]
then
forge script --rpc-url="$L2_RPC_URL" --broadcast --verify --verifier blockscout --verifier-url $L2_VERIFIER_URL -vvvv script/L2Claim.s.sol:L2ClaimScript
fi
if [ $CONTRACT_VERIFIER = "etherscan" ]
then
forge script --rpc-url="$L2_RPC_URL" --broadcast --verify --verifier etherscan --etherscan-api-key="$L2_ETHERSCAN_API_KEY" -vvvv script/L2Claim.s.sol:L2ClaimScript
fi
fi
echo "Done."

Expand Down

0 comments on commit 4716830

Please sign in to comment.