#!/usr/bin/env bash # On-chain check: thirdweb deployer 0xB2dE... can use EIP-2470 singleton # 0x4e59b448... on Chain 138 (deploy(bytes) + minimal initcode; eth_call + gas estimate). # Does not send a real tx (use cast send with PRIVATE_KEY only if you need a live deploy). # Usage: ./scripts/verify/verify-eip-2470-singleton-thirdweb-deployer-chain138.sh [--rpc URL] # Default RPC: Thirdweb public 138, then 2103 if set in env. # # Ref: docs/04-configuration/RPC_ENDPOINTS_MASTER.md (Thirdweb / CREATE2 path) # Re-broadcast / large calldata dry-run: scripts/verify/dry-run-thirdweb-singleton-2103.sh set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true # Canonical addresses (see EIP-2470, MULTI_CHAIN_EXECUTION_DETERMINISTIC_DEPLOYMENT.md) SINGLETON=0x4e59b44847b379578588920cA78FbF26c0B4956C DEPLOYER=0xB2dEA0e264ddfFf91057A3415112e57A1a5Eac14 # Minimal create bytecode that deploys empty runtime (standard test pattern for factories) TEST_INIT=0x600a600c6000396000f3fe CHAIN_WANT=138 RPC_2103="http://192.168.11.217:8545" RPC_PUBLIC="https://138.rpc.thirdweb.com" while [[ $# -gt 0 ]]; do case "$1" in --rpc) RPC_OVERRIDE="$2"; shift 2 ;; *) echo "Unknown arg: $1" >&2; exit 2 ;; esac done if [[ -n "${RPC_OVERRIDE:-}" ]]; then RPCS=("$RPC_OVERRIDE") elif [[ -n "${TEST_RPC_138:-}" ]]; then RPCS=("$TEST_RPC_138") else RPCS=("$RPC_PUBLIC" "$RPC_2103") fi ok() { echo "[OK] $*"; } fail() { echo "[FAIL] $*" >&2; exit 1; } any_ok=0 for RPC in "${RPCS[@]}"; do echo "━━━━━━━━ RPC: $RPC" if ! out=$(cast chain-id -r "$RPC" 2>&1); then echo "[SKIP] unreachable: $out" continue fi cid="$out" if [[ "$cid" != "$CHAIN_WANT" ]]; then fail "chainId $cid (expected $CHAIN_WANT)" fi ok "chainId = $cid" code=$(cast code "$SINGLETON" -r "$RPC" 2>/dev/null || true) [[ -n "$code" && "$code" != "0x" && ${#code} -gt 4 ]] || fail "no runtime code at singleton $SINGLETON" ok "singleton has code (len $(((${#code}-2)/2)) bytes)" calldata=$(cast calldata "deploy(bytes)" "$TEST_INIT") sel=${calldata:0:10} if [[ "$sel" != "0x00774360" ]]; then echo "[WARN] deploy(bytes) selector is $sel (expected 0x00774360); continuing anyway" >&2 fi if ! result=$(cast call -r "$RPC" --from "$DEPLOYER" "$SINGLETON" "$calldata" 2>&1); then fail "eth_call deploy(bytes) failed: $result" fi if [[ ${#result} -eq 42 && "$result" == 0x* ]]; then addr="$result" else addr=0x${result: -40} fi if [[ ! "$addr" =~ ^0x[0-9a-fA-F]{40}$ ]]; then fail "unexpected eth_call return: $result" fi ok "eth_call (from $DEPLOYER) returns address $addr (CREATE2 precompute; not mined until a tx is sent)" if ! gas=$(cast estimate -r "$RPC" --from "$DEPLOYER" "$SINGLETON" "$calldata" 2>&1); then fail "eth_estimateGas failed: $gas" fi ok "eth_estimateGas = $gas" bal=$(cast balance "$DEPLOYER" -r "$RPC" -e 2>/dev/null || echo "?") echo " deployer balance (est. ETH): $bal (needs >= gas*price to broadcast a real tx)" echo "" any_ok=1 done if [[ "$any_ok" -eq 0 ]]; then fail "no RPC succeeded (check --rpc or network)" fi echo "All reached RPCs passed. No transaction was sent." echo "To broadcast a minimal test deploy (optional, uses same calldata as this check):" echo " calldata=\$(cast calldata 'deploy(bytes)' $TEST_INIT)" echo " cast send -r $RPC_2103 --private-key \"\$PRIVATE_KEY\" $SINGLETON \"\$calldata\""