import os import time import hashlib import hmac import sys import multiprocessing from mnemonic import Mnemonic import coincurve from eth_utils import keccak, to_checksum_address from web3 import Web3 # ============================================================ # šŸ› ļø APNI SETTINGS YAHAN SET KAREIN # ============================================================ CSV_FILE = "14262022_addresses.csv" NUM_PHRASES = 1800000 SCAN_MODE = "File" ACC_START = 0 ACC_END = 29 ADDR_START = 0 ADDR_END = 29 SHOW_ALL = False PASSPHRASE = "" NUM_WORKERS = 48 # ============================================================ # Web3 Setup alchemy_api_key = "Rjey8KWIGjKik1qfZ4vdU" alchemy_url = f"https://eth-mainnet.g.alchemy.com/v2/{alchemy_api_key}" web3_eth = Web3(Web3.HTTPProvider(alchemy_url, request_kwargs={"timeout": 10})) bsc_url = "https://bsc-dataseed.binance.org/" web3_bsc = Web3(Web3.HTTPProvider(bsc_url, request_kwargs={"timeout": 10})) def get_balances(address): eth_float, bnb_float = 0.0, 0.0 eth_str, bnb_str = "0.0", "0.0" try: eth_wei = web3_eth.eth.get_balance(Web3.to_checksum_address(address)) eth_float = float(Web3.from_wei(eth_wei, 'ether')) if eth_float > 0: eth_str = f"{eth_float:.6f}" except Exception: pass try: bnb_wei = web3_bsc.eth.get_balance(Web3.to_checksum_address(address)) bnb_float = float(Web3.from_wei(bnb_wei, 'ether')) if bnb_float > 0: bnb_str = f"{bnb_float:.6f}" except Exception: pass return eth_float, bnb_float, eth_str, bnb_str # ============================================================ # Global Variables for Workers # ============================================================ KNOWN_ADDRESSES = None _MNEMONIC = None def init_worker(known_addresses): global KNOWN_ADDRESSES KNOWN_ADDRESSES = known_addresses _get_mnemonic() def _get_mnemonic(): global _MNEMONIC if _MNEMONIC is None: _MNEMONIC = Mnemonic("english") return _MNEMONIC # ============================================================ # Crypto Logic # ============================================================ _SECP256K1_N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 _HARDENED = 0x80000000 def _bip32_derive_child_priv(parent_priv, parent_chain, index): if index >= _HARDENED: data = b'\x00' + parent_priv + index.to_bytes(4, 'big') else: pub = coincurve.PrivateKey(parent_priv).public_key.format(compressed=True) data = pub + index.to_bytes(4, 'big') I = hmac.new(parent_chain, data, hashlib.sha512).digest() child_int = (int.from_bytes(I[:32], 'big') + int.from_bytes(parent_priv, 'big')) % _SECP256K1_N if child_int == 0: raise ValueError("Invalid child key") return child_int.to_bytes(32, 'big'), I[32:] def seed_to_privkey_hd(seed, account_idx=0, address_idx=0): I = hmac.new(b"Bitcoin seed", seed, hashlib.sha512).digest() key, chain = I[:32], I[32:] for idx in [44 + _HARDENED, 60 + _HARDENED, account_idx + _HARDENED, 0, address_idx]: key, chain = _bip32_derive_child_priv(key, chain, idx) return key def phrase_to_seed(phrase, passphrase=""): return _get_mnemonic().to_seed(phrase, passphrase=passphrase) # ============================================================ # Worker Function # ============================================================ def process_phrase_worker(phrase): global KNOWN_ADDRESSES seed = phrase_to_seed(phrase, PASSPHRASE) matches_found = [] paths_checked = 0 for acc_idx in range(ACC_START, ACC_END + 1): for addr_idx in range(ADDR_START, ADDR_END + 1): paths_checked += 1 try: priv = seed_to_privkey_hd(seed, acc_idx, addr_idx) pub = coincurve.PrivateKey(priv).public_key.format(compressed=False)[1:] addr = to_checksum_address(keccak(pub)[-20:]) except Exception: continue if SCAN_MODE == "File": norm_addr = addr[2:].lower() if addr.startswith("0x") else addr.lower() if norm_addr in KNOWN_ADDRESSES: match_details = ( f"\n{'šŸŽÆ'*20}\n" f"šŸŽÆ FILE MATCH FOUND!\n" f"Phrase: {phrase}\n" f"Path: m/44'/60'/{acc_idx}'/0/{addr_idx}\n" f"Private Key: {priv.hex()}\n" f"Address: {addr}\n" f"{'šŸŽÆ'*20}\n" ) matches_found.append(match_details) else: eth_float, bnb_float, eth_str, bnb_str = get_balances(addr) if eth_float > 0 or bnb_float > 0: match_details = ( f"\n{'šŸŽ‰'*20}\n" f"šŸŽ‰ MATCH WITH BALANCE!\n" f"Phrase: {phrase}\n" f"Path: m/44'/60'/{acc_idx}'/0/{addr_idx}\n" f"Private Key: {priv.hex()}\n" f"Address: {addr}\n" f"ETH: {eth_str}\n" f"BNB: {bnb_str}\n" f"{'šŸŽ‰'*20}\n" ) matches_found.append(match_details) return paths_checked, matches_found # ============================================================ # CSV File Setup # ============================================================ def load_addresses_from_csv(path): if not os.path.exists(path): return None print(f"ā³ Loading CSV: {path}") start = time.time() addresses = set() with open(path, "r", encoding="utf-8", errors="replace") as f: for line in f: a = line.strip().strip('"').strip("'").lstrip("\ufeff").lower() if a.startswith("0x"): a = a[2:] if a and len(a) == 40: addresses.add(a) elapsed = time.time() - start print(f"āœ… Loaded {len(addresses):,} addresses in {elapsed:.1f} seconds.\n") return addresses # ============================================================ # Generator for phrases # ============================================================ def phrase_generator(): mnemo = _get_mnemonic() for _ in range(NUM_PHRASES): yield mnemo.generate(strength=128) # ============================================================ # Main # ============================================================ def main(): global_start = time.time() known_addresses = None if SCAN_MODE == "File": known_addresses = load_addresses_from_csv(CSV_FILE) if not known_addresses: print(f"āŒ CSV File nahi mili ya khali hai: {CSV_FILE}") return print("=" * 60) print(f"šŸ” HD Wallet Scanner (Parallel: {NUM_WORKERS} Cores)") print("=" * 60) print(f"šŸ› ļø Scan Mode: {SCAN_MODE} | Account: {ACC_START}-{ACC_END} | Address: {ADDR_START}-{ADDR_END}") print(f"šŸ“ Total Phrases to scan: {NUM_PHRASES}\n") total_phrases = NUM_PHRASES phrases_checked = 0 total_paths_checked = 0 total_matches = 0 last_percentage_printed = -1 print(f"šŸš€ Starting {NUM_WORKERS} workers on your Dual-Socket Xeon...\n") try: with multiprocessing.Pool( processes=NUM_WORKERS, initializer=init_worker, initargs=(known_addresses,) ) as pool: for paths, matches in pool.imap_unordered(process_phrase_worker, phrase_generator(), chunksize=2): phrases_checked += 1 total_paths_checked += paths for match in matches: print(f"\n{match}") total_matches += 1 # āœ… Sirf 10% par progress print karein current_pct = int((phrases_checked / total_phrases) * 100) if current_pct >= last_percentage_printed + 10: print(f"ā³ Scanning Progress: {current_pct}% ({phrases_checked}/{total_phrases})") last_percentage_printed = current_pct # Print 100% if it skipped due to loop limits if last_percentage_printed < 100: print(f"ā³ Scanning Progress: 100% ({phrases_checked}/{total_phrases})") print() except KeyboardInterrupt: print("\n\nšŸ›‘ Script ruk gayi (Ctrl+C).") pool.terminate() pool.join() global_elapsed = time.time() - global_start print("=" * 60) print("šŸ RUN SUMMARY") print("=" * 60) print(f"šŸ“ Phrases checked in THIS run: {phrases_checked}") print(f"šŸ”‘ Private Keys generated in THIS run: {total_paths_checked:,}") print(f"šŸ“¬ Addresses checked in THIS run: {total_paths_checked:,}") print(f"šŸŽÆ Matches found in THIS run: {total_matches}") print("-" * 60) print(f"ā±ļø Total time to complete process: {global_elapsed:.2f} seconds") print("=" * 60) if __name__ == "__main__": main()