@@ -23,7 +23,7 @@ Required:
2323
2424Options:
2525 --rpc-url <url> JSON-RPC endpoint (default: ${DEFAULT_RPC_URL} )
26- --from-block <n> Start block (default: 0 )
26+ --from-block <n> Start block (default: contract deployment block )
2727 --to-block <n> End block (default: latest)
2828 --json Emit a JSON array (default: one address per line)
2929 -h, --help Show this help
3737
3838ADDRESS=" "
3939RPC_URL=" $DEFAULT_RPC_URL "
40- FROM_BLOCK=" 0 "
40+ FROM_BLOCK=" "
4141TO_BLOCK=" latest"
4242JSON_OUTPUT=" false"
4343
@@ -66,6 +66,40 @@ for cmd in cast jq awk sort; do
6666 fi
6767done
6868
69+ # Binary-search for the smallest block N where eth_getCode(addr, N) != "0x".
70+ # That's the deployment block. Assumes code monotonicity (no SELFDESTRUCT).
71+ find_deploy_block () {
72+ local addr=" $1 "
73+ local rpc=" $2 "
74+ local latest lo hi mid code
75+
76+ latest=$( cast block-number --rpc-url " $rpc " )
77+ code=$( cast code " $addr " --block " $latest " --rpc-url " $rpc " )
78+ if [[ " $code " == " 0x" || -z " $code " ]]; then
79+ echo " Error: no contract code at $addr (checked block $latest )" >&2
80+ return 1
81+ fi
82+
83+ lo=0
84+ hi=" $latest "
85+ while (( lo < hi )) ; do
86+ mid=$(( (lo + hi) / 2 ))
87+ code=$( cast code " $addr " --block " $mid " --rpc-url " $rpc " )
88+ if [[ " $code " == " 0x" || -z " $code " ]]; then
89+ lo=$(( mid + 1 ))
90+ else
91+ hi=$mid
92+ fi
93+ done
94+
95+ echo " $lo "
96+ }
97+
98+ if [[ -z " $FROM_BLOCK " ]]; then
99+ FROM_BLOCK=$( find_deploy_block " $ADDRESS " " $RPC_URL " )
100+ echo " [info] auto-detected deployment block: $FROM_BLOCK " >&2
101+ fi
102+
69103# Fetch logs for one event signature and emit tab-separated records:
70104# <blockNumber>\t<logIndex>\t<label>\t<address>
71105# blockNumber and logIndex may be hex (0x...) or decimal depending on cast version;
0 commit comments