Next scheduled rescrape ... never
Version 1
Last scraped
Edited on 12/08/2025, 04:59:03 UTC
This Python script generates a fully signed raw Bitcoin transaction that can be used with the MARA Slipstream service (or any other broadcast method). Accepts any type of destination address: Legacy (P2PKH), SegWit (P2WPKH), or Taproot (P2TR).
Supports private keys in WIF (Wallet Import Format).

Automatically:
Fetches UTXOs (unspent outputs) from mempool.space

Code:
import base58
import requests
import ecdsa
from bitcoin import *
import hashlib

def decode_wif(wif):
    b = base58.b58decode(wif)
    if len(b) == 38 and b[-5] == 0x01:
        return b[1:-5], True  # compressed
    elif len(b) == 37:
        return b[1:-1], False  # uncompressed
    raise ValueError("Invalid WIF format")

def get_pubkey(priv_bytes, compressed=True):
    sk = ecdsa.SigningKey.from_string(priv_bytes, curve=ecdsa.SECP256k1)
    vk = sk.get_verifying_key()
   if compressed: x = vk.pubkey.point.x()
       xy = vk.pubkey.point.xy()
      return ('02' if y % 2 = vk.pubkey.point.y(= 0 else '03') + f"{x:064x}"  # Always compressed
        return ('02' if y % 2 == 0 else '03') + f"{x:064x}"
    elsedef get_address(pubkey):
       return '04' + vkpubkey_bytes = bytes.to_stringfromhex(pubkey).hex()
    pubkey_hash = hash160(pubkey_bytes)
def get_address    return pubkey_to_address(pubkey, compressed):  # Always compressed P2PKH
    pubkey_bytes = bytes.fromhex(pubkey)
    if compresseddef is_legacy_address(address):
       pubkey_hash = hash160return address.startswith(pubkey_bytes'1')
        return pubkey_to_address(pubkey)  # P2PKH
    elsedef fetch_utxos(address):
       return pubkey_to_addressif not is_legacy_address(pubkeyaddress)  # P2PKH uncompressed:
        raise ValueError("Only legacy addresses (starting with '1') are supported")
def address_type(address):    
   if address.startswith('1') try:
       return 'p2pkh' url = f"https://mempool.space/api/address/{address}/utxo"
   elif address     r = requests.startswithget('3'url):
       return 'p2sh' r.raise_for_status()
   elif address     return r.startswithjson('bc1q'):
       return 'p2wpkh'except Exception as e:
   elif address.startswith     print('bc1p')"Failed to fetch UTXOs:", e)
        return 'p2tr'[]
    else:
        raise ValueErrordef estimate_fee("Unknown address type"num_inputs, num_outputs, fee_rate):
    # Legacy transaction size estimation with compressed pubkeys
def fetch_utxos(address):    input_size = 148  # Standard for P2PKH with compressed pubkey
   try: output_size = 34   # P2PKH output size
       urltotal_size = f"https://mempool.space/api/address/{address}/utxo"10 + num_inputs * input_size + num_outputs * output_size
       r = requests.get(url)return total_size * fee_rate
        r.raise_for_status()
        return r.jsondef create_transaction(wif, to_address, amount_btc, fee_rate):
   except Exception as e: # Validate addresses are legacy
       printif not is_legacy_address("Failed to fetch UTXOs:", eto_address):
       return [] raise ValueError("Only legacy addresses (starting with '1') are supported for recipient")
    
def estimate_fee(num_inputs    priv_bytes, num_outputs, fee_rate, compressed, out_types_ = decode_wif(wif):  
   # estimate size based on input/output types pubkey = get_pubkey(priv_bytes)
   input_size from_address = 108 if compressed else 148get_address(pubkey)
   output_size = sum(43 if t == 'p2wpkh' else 34 for t in out_types) 
   total_size = 10 + num_inputs * input_size + output_size if not is_legacy_address(from_address):
   return total_size * fee_rate     raise ValueError("Only legacy addresses (starting with '1') are supported for sender")

def create_transaction    utxos = fetch_utxos(wif, to_address, amount_btc, fee_ratefrom_address):
   priv_bytes, compressed = decode_wif(wif) if not utxos:
   pubkey = get_pubkey     raise RuntimeError(priv_bytes, compressed"No UTXOs available")
    from_address = get_address(pubkey, compressed)
   to_type = address_type # Sort UTXOs by value (to_addressdescending) to minimize number of inputs
    utxos.sort(key=lambda x: x['value'], reverse=True)
    utxos = fetch_utxos(from_address)
   if not utxos: inputs = []
       raise RuntimeError("No UTXOs available")total = 0
    for utxo in utxos:
        inputs = .append({'output': f"{utxo['txid']}:{utxo['vout']}", 'value': utxo['value']})
        total += 0utxo['value']
   for utxo in utxos     if total >= int(amount_btc * 1e8) + estimate_fee(len(inputs), 2, fee_rate):
       inputs.append({'output': f"{utxo['txid']}:{utxo['vout']}", 'value': utxo['value']})     break  # We have enough including fees
        total += utxo['value']
       if total >= int(amount_btc * 1e8)= 0: break
        raise RuntimeError("No UTXOs available")
    if total == 0:
       raise RuntimeErrorsend_amount = int("Not enough inputs to cover amount"amount_btc * 1e8)
    fee = estimate_fee(len(inputs), 2, fee_rate)
    send_amount = int(amount_btc * 1e8)
    if total < send_amount + fee = estimate_fee(len(inputs), 2, fee_rate, compressed, [to_type, 'p2pkh']):
        raise RuntimeError(f"Insufficient funds. Need {send_amount + fee} satoshis, have {total}")
    if total < send_amount + fee:
       raise RuntimeError("Insufficient funds")change = total - send_amount - fee
    outputs = [{'address': to_address, 'value': send_amount}]
    if change = total - send_amount - fee> 546:  # Minimum dust amount
        outputs = [.append({'address': to_addressfrom_address, 'value': send_amountchange}])
   if elif change > 0:
       outputs.append({'address': from_address, 'value': fee += change})  # Add remaining change to fee if it's too small

    tx = mktx(inputs, outputs)
    for i in range(len(inputs)):
        tx = sign(tx, i, wif)
    return tx

# === Example Usage ===
if __name__ == "__main__":
    WIF = "<wif_private_key>"
    TO_ADDRESS = "1YourLegacyAddressHere"  # worksmust start with '1..., 3..., bc1q..., bc1p...'
    AMOUNT_BTC = 6.70013241
    FEE_RATE = 20  # sats/vB

    try:
        raw_tx = create_transaction(WIF, TO_ADDRESS, AMOUNT_BTC, FEE_RATE)
        print("Raw Transaction:", raw_tx)
   except Exception as e:     
        # To broadcast the transaction (uncomment to use)
        # broadcast_url = "https://mempool.space/api/tx"
        # response = requests.post(broadcast_url, data=raw_tx)
        #
print("Broadcast response:", response.text)
    except Exception as e:
        print("
Error:", e)

Example script output

Quote
Raw Transaction: 0100000005b3138da741af259146ca2c4895bac7e0c08147679f88ce3302fb4db0584bf312050000100000002b3138da741af259146ca2c4895bac7e0c08147679f88ce3302fb4db0584bf31205000 0006b483045022100fcc29e303b33016113a6ec23553187c0589859f0ba576e2dc09990fa29c61a0006b4830450221009131a350b98aab71d77f5a9a94dd5bac9a5602e2b761a2dc605ba03cb996df cb02205a200c482ab1d4901853b47a62ec57cdfa87e8908e6e3204c1d5dbe7c14efb77012102122ff0220480b53128af0cf7c9b74fa8d625e2a9d143d15fdaa2fd24e421d4d0d29c1532201210279b 09f5ec514a1580a2937bd833979d933199fc230e204c6cdc58872b7d46f75ffffffff15cda65f1ee667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ffffffff6441384445 46982fc082b15c8dbb60985d12a7e60b0c742263608cc9349f3808460000006b483045022100967a0f426ee689e2532e41fc6947dda41558026b80f5b1dfd7c58455d130000006a473044022032ccf 4dce2352f28d8ea52866a2cecbe153e6f9da0f228b0a5ceb7a2afa2a5cc78022045af0952718f04651486b1055ea188d95645dc61329e9fa89a18b33417d33dc0aa61484d602206bbb8e8cf1b2a6e8 e0f5c1dade18cc6f9309951d5025c3f9597af0e5c27e5afcde01210212209f5ec514a1580a2937bea64f78f7d7625d05014f593c76438c7127d5e2b147d971601210279be667ef9dcbbac55a06295c d833979d933199fc230e204c6cdc58872b7d46f75ffffffff5e24638c73bbff287f002d3035ac13e870b07029bfcdb2dce28d959f2815b16f81798ffffffff023997ef27000000001976a914751e76 d43b373bed0470a8425b92ed7f601409b3000000006b483045022100d7acede82875fc6025d28a2e8199196d454941c45d1b3a323f1433bd688acafb2f501000000001976a914f6f5431d25bbf7b12 c7464a29b198ee477adcf0fbb7ac5bf1fc6b52b340220414620d32b062afef07773d90d958ad599 1bf06f3ff0720839c5f6e8364ec35901210212209f5ec514a1580a2937bd833979d933199fc230e 204c6cdc58872b7d46f75ffffffff10d650ec671f51e730c36da55623e6c9ae1f1803ea3cbb4cf8 2edc1f3e066358000000006b483045022100e55a20c9e40518ce4b9bbd3640350ae7d10ad7d86b0 bbfb3cac7dd778300ea0102203c54c9cd9d7fc8894b6d1f16b5558687047701e31e58257ea4b528 e14d86a58601210212209f5ec514a1580a2937bd833979d933199fc230e204c6cdc58872b7d46f7 5ffffffff6441384445a0f426ee689e2532e41fc6947dda41558026b80f5b1dfd7c58455d130000 006a47304402202dea305bc23b33c291aabde55273836b45c3f7a207cd138279133281a1e5094c0 22060a78ae12f61dee3ed8ae328a05c785957154e18abcd2d6893b4193eb2ed3ae601210212209f 5ec514a1580a2937bd833979d933199fc230e204c6cdc58872b7d46f75ffffffff023997ef27000 000001976a914f6f5431d25bbf7b12e8add9af5e3475c44a0a5b888aca1086202000000001976a9 14f6f5431d25bbf7b12e8add9af5e3475c44a0a5b888ac00000000e8add9af5e3475c44a0a5b888ac00000000


Cheers Grin
Original archived Re: Bitcoin puzzle transaction ~32 BTC prize to who solves it
Scraped on 05/08/2025, 04:59:19 UTC
This Python script generates a fully signed raw Bitcoin transaction that can be used with the MARA Slipstream service (or any other broadcast method). Accepts any type of destination address: Legacy (P2PKH), SegWit (P2WPKH), or Taproot (P2TR).
Supports private keys in WIF (Wallet Import Format).

Automatically:
Fetches UTXOs (unspent outputs) from mempool.space

Code:
import base58
import requests
import ecdsa
from bitcoin import *
import hashlib

def decode_wif(wif):
    b = base58.b58decode(wif)
    if len(b) == 38 and b[-5] == 0x01:
        return b[1:-5], True  # compressed
    elif len(b) == 37:
        return b[1:-1], False  # uncompressed
    raise ValueError("Invalid WIF format")

def get_pubkey(priv_bytes, compressed):
    sk = ecdsa.SigningKey.from_string(priv_bytes, curve=ecdsa.SECP256k1)
    vk = sk.get_verifying_key()
    if compressed:
        x = vk.pubkey.point.x()
        y = vk.pubkey.point.y()
        return ('02' if y % 2 == 0 else '03') + f"{x:064x}"
    else:
        return '04' + vk.to_string().hex()

def get_address(pubkey, compressed):
    pubkey_bytes = bytes.fromhex(pubkey)
    if compressed:
        pubkey_hash = hash160(pubkey_bytes)
        return pubkey_to_address(pubkey)  # P2PKH
    else:
        return pubkey_to_address(pubkey)  # P2PKH uncompressed

def address_type(address):
    if address.startswith('1'):
        return 'p2pkh'
    elif address.startswith('3'):
        return 'p2sh'
    elif address.startswith('bc1q'):
        return 'p2wpkh'
    elif address.startswith('bc1p'):
        return 'p2tr'
    else:
        raise ValueError("Unknown address type")

def fetch_utxos(address):
    try:
        url = f"https://mempool.space/api/address/{address}/utxo"
        r = requests.get(url)
        r.raise_for_status()
        return r.json()
    except Exception as e:
        print("Failed to fetch UTXOs:", e)
        return []

def estimate_fee(num_inputs, num_outputs, fee_rate, compressed, out_types):
    # estimate size based on input/output types
    input_size = 108 if compressed else 148
    output_size = sum(43 if t == 'p2wpkh' else 34 for t in out_types)
    total_size = 10 + num_inputs * input_size + output_size
    return total_size * fee_rate

def create_transaction(wif, to_address, amount_btc, fee_rate):
    priv_bytes, compressed = decode_wif(wif)
    pubkey = get_pubkey(priv_bytes, compressed)
    from_address = get_address(pubkey, compressed)
    to_type = address_type(to_address)

    utxos = fetch_utxos(from_address)
    if not utxos:
        raise RuntimeError("No UTXOs available")

    inputs = []
    total = 0
    for utxo in utxos:
        inputs.append({'output': f"{utxo['txid']}:{utxo['vout']}", 'value': utxo['value']})
        total += utxo['value']
        if total >= int(amount_btc * 1e8): break

    if total == 0:
        raise RuntimeError("Not enough inputs to cover amount")

    send_amount = int(amount_btc * 1e8)
    fee = estimate_fee(len(inputs), 2, fee_rate, compressed, [to_type, 'p2pkh'])

    if total < send_amount + fee:
        raise RuntimeError("Insufficient funds")

    change = total - send_amount - fee
    outputs = [{'address': to_address, 'value': send_amount}]
    if change > 0:
        outputs.append({'address': from_address, 'value': change})

    tx = mktx(inputs, outputs)
    for i in range(len(inputs)):
        tx = sign(tx, i, wif)
    return tx

# === Example Usage ===
if __name__ == "__main__":
    WIF = "<wif_private_key>"
    TO_ADDRESS = "1YourLegacyAddressHere"  # works with 1..., 3..., bc1q..., bc1p...
    AMOUNT_BTC = 6.70013241
    FEE_RATE = 20  # sats/vB

    try:
        raw_tx = create_transaction(WIF, TO_ADDRESS, AMOUNT_BTC, FEE_RATE)
        print("Raw Transaction:", raw_tx)
    except Exception as e:
        print("Error:", e)

Example script output

Quote
Raw Transaction: 0100000005b3138da741af259146ca2c4895bac7e0c08147679f88ce3302fb4db0584bf31205000 0006b483045022100fcc29e303b33016113a6ec23553187c0589859f0ba576e2dc09990fa29c61a cb02205a200c482ab1d4901853b47a62ec57cdfa87e8908e6e3204c1d5dbe7c14efb77012102122 09f5ec514a1580a2937bd833979d933199fc230e204c6cdc58872b7d46f75ffffffff15cda65f1e 46982fc082b15c8dbb60985d12a7e60b0c742263608cc9349f3808460000006b483045022100967 4dce2352f28d8ea52866a2cecbe153e6f9da0f228b0a5ceb7a2afa2a5cc78022045af0952718f04 e0f5c1dade18cc6f9309951d5025c3f9597af0e5c27e5afcde01210212209f5ec514a1580a2937b d833979d933199fc230e204c6cdc58872b7d46f75ffffffff5e24638c73bbff287f002d3035ac13 d43b373bed0470a8425b92ed7f601409b3000000006b483045022100d7acede82875fc6025d28a2 c7464a29b198ee477adcf0fbb7ac5bf1fc6b52b340220414620d32b062afef07773d90d958ad599 1bf06f3ff0720839c5f6e8364ec35901210212209f5ec514a1580a2937bd833979d933199fc230e 204c6cdc58872b7d46f75ffffffff10d650ec671f51e730c36da55623e6c9ae1f1803ea3cbb4cf8 2edc1f3e066358000000006b483045022100e55a20c9e40518ce4b9bbd3640350ae7d10ad7d86b0 bbfb3cac7dd778300ea0102203c54c9cd9d7fc8894b6d1f16b5558687047701e31e58257ea4b528 e14d86a58601210212209f5ec514a1580a2937bd833979d933199fc230e204c6cdc58872b7d46f7 5ffffffff6441384445a0f426ee689e2532e41fc6947dda41558026b80f5b1dfd7c58455d130000 006a47304402202dea305bc23b33c291aabde55273836b45c3f7a207cd138279133281a1e5094c0 22060a78ae12f61dee3ed8ae328a05c785957154e18abcd2d6893b4193eb2ed3ae601210212209f 5ec514a1580a2937bd833979d933199fc230e204c6cdc58872b7d46f75ffffffff023997ef27000 000001976a914f6f5431d25bbf7b12e8add9af5e3475c44a0a5b888aca1086202000000001976a9 14f6f5431d25bbf7b12e8add9af5e3475c44a0a5b888ac00000000


Cheers Grin