DILSHAD737's picture
Update app.py
a1c708d verified
Raw History Blame Contribute Delete
9.21 kB
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()