#!/usr/bin/env bash # Automated script to verify Ethereum Mainnet contracts using Standard JSON Input # This script uses Etherscan API directly for Standard JSON verification # Usage: ./verify-ethereum-mainnet-standard-json.sh [contract_address] set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" SOURCE_PROJECT="/home/intlc/projects/smom-dbis-138" DOCS_DIR="$PROJECT_ROOT/docs" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; } log_error() { echo -e "${RED}[✗]${NC} $1"; } log_step() { echo -e "${CYAN}[STEP]${NC} $1"; } # Load environment if [ -f "$SOURCE_PROJECT/.env" ]; then source "$SOURCE_PROJECT/.env" else log_error ".env file not found in $SOURCE_PROJECT" exit 1 fi # Required environment variables if [ -z "${ETHERSCAN_API_KEY:-}" ]; then log_error "ETHERSCAN_API_KEY not set in .env" exit 1 fi if [ -z "${ETHEREUM_MAINNET_RPC:-}" ]; then log_error "ETHEREUM_MAINNET_RPC not set in .env" exit 1 fi # Contract address (default or from argument) CONTRACT_ADDRESS="${1:-0x89dd12025bfCD38A168455A44B400e913ED33BE2}" CONTRACT_NAME="CCIPWETH9Bridge" STANDARD_JSON_FILE="$DOCS_DIR/CCIPWETH9Bridge_standard_json.json" CONSTRUCTOR_ARGS="0x00000000000000000000000080226fc0ee2b096224eeac085bb9a8cba1146f7d000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca" # Function to check verification status check_verification_status() { local address=$1 local api_key=$2 log_info "Checking verification status..." local response=$(curl -s "https://api.etherscan.io/api?module=contract&action=getsourcecode&address=${address}&apikey=${api_key}" 2>/dev/null || echo "") if [ -z "$response" ]; then return 1 fi # Check if SourceCode field exists and is not empty if echo "$response" | grep -q '"SourceCode":"{' || echo "$response" | grep -q '"SourceCode":"// SPDX'; then return 0 # Verified else return 1 # Not verified fi } # Function to verify using Etherscan API with Standard JSON verify_with_etherscan_api() { local address=$1 local contract_name=$2 local standard_json_file=$3 local constructor_args=$4 local api_key=$5 log_step "Submitting verification via Etherscan API..." if [ ! -f "$standard_json_file" ]; then log_error "Standard JSON file not found: $standard_json_file" return 1 fi # Read Standard JSON content and escape it properly for JSON local json_content=$(cat "$standard_json_file" | jq -c . 2>/dev/null || cat "$standard_json_file") # Use Python to properly encode the Standard JSON for the API local encoded_json=$(python3 </dev/null || echo "") if [ -z "$response" ]; then log_error "No response from Etherscan API" return 1 fi # Check response if echo "$response" | grep -q '"status":"1"'; then local guid=$(echo "$response" | grep -o '"result":"[^"]*"' | cut -d'"' -f4 || echo "") if [ -n "$guid" ] && [ "$guid" != "null" ]; then log_success "Verification submitted successfully!" log_info "GUID: $guid" log_info "Check status: https://etherscan.io/address/${address}#code" return 0 fi fi # Extract error message local error=$(echo "$response" | grep -o '"result":"[^"]*"' | cut -d'"' -f4 || echo "Unknown error") log_error "Verification failed: $error" log_info "Full response: $response" return 1 } # Function to check verification status after submission check_verification_loop() { local address=$1 local api_key=$2 local max_attempts=12 local attempt=0 log_info "Waiting for verification to complete..." while [ $attempt -lt $max_attempts ]; do sleep 5 attempt=$((attempt + 1)) if check_verification_status "$address" "$api_key"; then log_success "Contract is now verified!" return 0 fi log_info "Attempt $attempt/$max_attempts: Still processing..." done log_warn "Verification may still be processing. Check Etherscan manually." return 1 } # Main execution main() { log_info "=========================================" log_info "Ethereum Mainnet Contract Verification" log_info "Using Standard JSON Input Method" log_info "=========================================" log_info "" log_info "Contract: $CONTRACT_NAME" log_info "Address: $CONTRACT_ADDRESS" log_info "" # Check prerequisites log_step "Checking prerequisites..." if ! command -v cast &> /dev/null; then log_error "cast command not found. Please install Foundry." exit 1 fi if ! command -v curl &> /dev/null; then log_error "curl command not found. Please install curl." exit 1 fi if ! command -v python3 &> /dev/null; then log_error "python3 not found. Please install Python 3." exit 1 fi if ! command -v jq &> /dev/null; then log_warn "jq not found. Will use alternative JSON parsing." fi log_success "All prerequisites met" log_info "" # Step 1: Check if contract exists log_step "Step 1: Verifying contract exists on Ethereum Mainnet..." local code=$(cast code "$CONTRACT_ADDRESS" --rpc-url "$ETHEREUM_MAINNET_RPC" 2>/dev/null || echo "") if [ -z "$code" ] || [ "$code" = "0x" ]; then log_error "Contract not found on Ethereum Mainnet" exit 1 fi log_success "Contract exists (bytecode length: $((${#code} / 2 - 1)) bytes)" # Step 2: Check if already verified log_step "Step 2: Checking current verification status..." if check_verification_status "$CONTRACT_ADDRESS" "$ETHERSCAN_API_KEY"; then log_success "Contract is already verified on Etherscan!" log_info "View contract: https://etherscan.io/address/${CONTRACT_ADDRESS}#code" exit 0 fi log_info "Contract is not yet verified" # Step 3: Verify contract log_step "Step 3: Submitting verification request..." if verify_with_etherscan_api "$CONTRACT_ADDRESS" "$CONTRACT_NAME" "$STANDARD_JSON_FILE" "$CONSTRUCTOR_ARGS" "$ETHERSCAN_API_KEY"; then log_info "" log_step "Step 4: Monitoring verification status..." check_verification_loop "$CONTRACT_ADDRESS" "$ETHERSCAN_API_KEY" log_info "" log_success "Verification process completed!" log_info "View contract: https://etherscan.io/address/${CONTRACT_ADDRESS}#code" else log_error "" log_error "Verification submission failed." log_info "" log_info "Manual verification steps:" log_info "1. Go to: https://etherscan.io/address/${CONTRACT_ADDRESS}#code" log_info "2. Click 'Contract' tab → 'Verify and Publish'" log_info "3. Select 'Standard JSON Input'" log_info "4. Upload: $STANDARD_JSON_FILE" log_info "5. Enter constructor args: $CONSTRUCTOR_ARGS" log_info "6. Submit" exit 1 fi } # Run main function main "$@"