add_privkey(CBitcoinSecret.from_secret_bytes(secret, False)) add_privkey(CBitcoinSecret.from_secret_bytes(secret, True)) logging.info('Added %d known passphrases' % n) known_txids = set() while True: mempool_txids = set(rpc.getrawmempool()) new_txids = mempool_txids.difference(known_txids) known_txids.update(mempool_txids) burn_txs = [] for new_txid in new_txids: try: new_tx = rpc.getrawtransaction(new_txid) except IndexError: continue burn_txs.extend(scan_tx_for_spendable_outputs(new_tx, new_txid)) for burn_tx in burn_txs: try: txid = rpc.sendrawtransaction(burn_tx) logging.info('Sent burn tx %s' % b2lx(txid)) except bitcoin.rpc.JSONRPCException as err: logging.info('Got error %s while sending %s' % (err, b2x(burn_tx.serialize()))) logging.info('Sleeping %f seconds' % args.delay) time.sleep(args.delay)
rpc = bitcoin.rpc.Proxy() try: args.txid = lx(args.txid) except ValueError as err: parser.error('Invalid txid: %s' % str(err)) if len(args.txid) != 32: parser.error('Invalid txid: Wrong length.') try: rpc.gettransaction(args.txid) except IndexError as err: parser.exit('Invalid txid: Not in wallet.') txinfo = rpc.getrawtransaction(args.txid, True) tx = CMutableTransaction.from_tx(txinfo['tx']) if 'confirmations' in txinfo and txinfo['confirmations'] > 0: parser.exit("Transaction already mined; %d confirmations." % txinfo['confirmations']) # Find a txout that was being used for change change_txout = None for vout in tx.vout: try: addr = CBitcoinAddress.from_scriptPubKey(vout.scriptPubKey) except ValueError: continue if rpc.validateaddress(addr)['ismine']:
rpc = bitcoin.rpc.Proxy() try: args.txid = lx(args.txid) except ValueError as err: parser.error('Invalid txid: %s' % str(err)) if len(args.txid) != 32: parser.error('Invalid txid: Wrong length.') try: rpc.gettransaction(args.txid) except IndexError as err: parser.exit('Invalid txid: Not in wallet.') txinfo = rpc.getrawtransaction(args.txid, True) tx = CMutableTransaction.from_tx(txinfo['tx']) if 'confirmations' in txinfo and txinfo['confirmations'] > 0: parser.exit("Transaction already mined; %d confirmations." % txinfo['confirmations']) # Find a txout that was being used for change change_txout = None for vout in tx.vout: try: addr = CBitcoinAddress.from_scriptPubKey(vout.scriptPubKey) except ValueError: continue if rpc.validateaddress(addr)['ismine']: change_txout = vout
add_privkey(CBitcoinSecret.from_secret_bytes(secret, False)) add_privkey(CBitcoinSecret.from_secret_bytes(secret, True)) logging.info('Added %d known passphrases' % n) known_txids = set() while True: mempool_txids = set(rpc.getrawmempool()) new_txids = mempool_txids.difference(known_txids) known_txids.update(mempool_txids) burn_txs = [] for new_txid in new_txids: try: new_tx = rpc.getrawtransaction(new_txid) except IndexError: continue # The scriptSigs might not sign vout, in which case we can replace the # whole thing with OP_RETURN. if not (len(new_tx.vout) == 1 and new_tx.vout[0].nValue == 0 and new_tx.vout[0].scriptPubKey == CScript([OP_RETURN])): to_fees_tx = CTransaction(new_tx.vin, [CTxOut(0, CScript([OP_RETURN]))], nLockTime=new_tx.nLockTime, nVersion=new_tx.nVersion) try: to_fees_txid = rpc.sendrawtransaction(to_fees_tx, True)
if vin.nSequence < 0xFFFFFFFF-1: return True return False tx1 = None if args.prev_txid is not None: try: args.prev_txid = lx(args.prev_txid) except ValueError as err: parser.error('Invalid txid: %s' % str(err)) if len(args.prev_txid) != 32: parser.error('Invalid txid: Wrong length.') tx1 = rpc.getrawtransaction(args.prev_txid) elif not args.no_reuse: # Try to find an unconfirmed transaction with full-RBF enabled and a change # output > amount txids_seen = set() for unspent in rpc.listunspent(0,0): txid = unspent['outpoint'].hash if txid not in txids_seen: unspent_tx = rpc.getrawtransaction(txid) # FIXME: this still fails if amount doesn't leave enough for fees if unspent_tx.vout[0].nValue < args.amount: continue if check_full_rbf_optin(unspent_tx):
import os import json import base64 import argparse import binascii from dotenv import load_dotenv from blockchain_parser.block import Block from blockchain_parser.transaction import Transaction import bitcoin.rpc import tna load_dotenv() btc_conf_file = os.path.expanduser(os.getenv("BTC_CONF_FILE")) parser = argparse.ArgumentParser(description="render a tx with tna") parser.add_argument("--txid", type=str, required=True, help="txid to look up") args = parser.parse_args() rpc = bitcoin.rpc.RawProxy(btc_conf_file=btc_conf_file) raw_tx_json = rpc.getrawtransaction(args.txid, 1) raw_block_json = rpc.getblock(raw_tx_json['blockhash']) raw_block = binascii.unhexlify(rpc.getblock(raw_tx_json['blockhash'], False)) block = Block(raw_block, raw_block_json['height']) tx = Transaction.from_hex(binascii.unhexlify(raw_tx_json['hex'])) res = tna.extract(block, tx) print(json.dumps(res, sort_keys=True, indent=4))
def updateDatabase(currentBlockHeight): ''' Updates the database with the latest blocks from the blockchain :param currentBlockHeight: the latest block height in the database, one to start from :return: nothing ''' # Run RPC and get latest block height print("Updating database") print("Using mainnet") bitcoin.SelectParams("mainnet") print("Creating RPC connection") rpc = rpcConnection() print("Getting the latest block from the network") latestBlock = int(rpc.getblockcount()) print("Latest block is : " + str(latestBlock)) # print stuff if currentBlockHeight == "None": currentBlockHeight = -1 print("Collecting blocks from range " + str(currentBlockHeight) + " to " + str(latestBlock)) for blockHeight in range(int(currentBlockHeight) + 1, latestBlock + 1, 1): print("Block " + str(blockHeight) + "/" + str(latestBlock)) objects = [] rpc = rpcConnection() block = rpc.getblock(rpc.getblockhash(blockHeight)) #block = rpc.getblock(str(blockHeight)) previousblockhash = "" if "previousblockhash" in block.keys(): previousblockhash = block["previousblockhash"] nextblockhash = "" if "nextblockhash" in block.keys(): nextblockhash = block["nextblockhash"] databaseBlock = table_classes.Blocks( height=block["height"], tx_hash=block["hash"], size=block["size"], version=block["version"], merkleroot=block["merkleroot"], tx=list(block["tx"]), time=block["time"], nonce=block["nonce"], difficulty=block["difficulty"], chainwork=block["chainwork"], previousblockhash=previousblockhash, nextblockhash=nextblockhash, ) objects.append(databaseBlock) #print("Will add block once we have all transactions") # do the same for transactions # print(str(len(block["tx"])) +" transactions found in block") for tx_hash in block["tx"]: skip = 0 rpc = rpcConnection() try: tx = rpc.getrawtransaction(tx_hash, 1) except bitcoin.rpc.InvalidAddressOrKeyError: print("Could not find TX, no information") print("Setting value to False") skip = 1 if skip: transaction = table_classes.Transactions( tx_hash=tx_hash, version=0, size=0, vsize=0, locktime=0, blockhash=block["hash"], time=0, blocktime=0) objects.append(transaction) continue else: transaction = table_classes.Transactions( tx_hash=tx_hash, tx_id=tx["txid"], version=tx["version"], size=tx["size"], vsize=tx["vsize"], locktime=tx["locktime"], blockhash=tx["blockhash"], tx_hex=tx["hex"], time=tx["time"], blocktime=tx["blocktime"], tx_in_count=len(tx["vin"]), tx_out_count=len(tx["vout"])) objects.append(transaction) # now check the values to see if its a coingen, vin, vout and vjoinsplit fieldssss if len(tx["vin"]): for val in tx["vin"]: if "coinbase" in val.keys(): # we found a coingen transaction, create the object and add it coingen = table_classes.Coingen( tx_hash=tx_hash, coinbase=val["coinbase"], sequence=val["sequence"]) objects.append(coingen) else: # else its a normal vin duh vin = table_classes.Vin(tx_hash=tx_hash, prevout_hash=val["txid"], prevout_n=val["vout"], sequence=val["sequence"]) objects.append(vin) if len(tx["vout"]): for val in tx["vout"]: pubkey = [] if "addresses" in val["scriptPubKey"]: pubkey = val["scriptPubKey"]["addresses"] vout = table_classes.Vout(tx_hash=tx_hash, value=val["value"], tx_n=val["n"], pubkey=pubkey #script = ) objects.append(vout) dbLib.addObjects(objects) # print("Block complete") print("Processed all blocks. Closing program")
if vin.nSequence < 0xFFFFFFFF - 1: return True return False tx1 = None if args.prev_txid is not None: try: args.prev_txid = lx(args.prev_txid) except ValueError as err: parser.error('Invalid txid: %s' % str(err)) if len(args.prev_txid) != 32: parser.error('Invalid txid: Wrong length.') tx1 = rpc.getrawtransaction(args.prev_txid) elif not args.no_reuse: # Try to find an unconfirmed transaction with full-RBF enabled and a change # output > amount txids_seen = set() for unspent in rpc.listunspent(0, 0): txid = unspent['outpoint'].hash if txid not in txids_seen: unspent_tx = rpc.getrawtransaction(txid) # FIXME: this still fails if amount doesn't leave enough for fees if unspent_tx.vout[0].nValue < args.amount: continue if check_full_rbf_optin(unspent_tx):