def get_transaction(self, txid, db): """Yields the transaction contained in the .blk files as a python object, similar to https://developer.bitcoin.org/reference/rpc/getrawtransaction.html """ byte_arr = bytearray.fromhex(txid) byte_arr.reverse() tx_hash = hexlify(b't').decode('utf-8') + \ hexlify(byte_arr).decode('utf-8') tx_hash_fmtd = unhexlify(tx_hash) raw_hex = db.get(tx_hash_fmtd) tx_idx = DBTransactionIndex(utils.format_hash(tx_hash_fmtd), raw_hex) blk_file = os.path.join(self.path, "blk%05d.dat" % tx_idx.blockfile_no) raw_hex = get_block(blk_file, tx_idx.file_offset) offset = tx_idx.block_offset transaction_data = raw_hex[80:] # Try from 1024 (1KiB) -> 1073741824 (1GiB) slice widths for j in range(0, 20): try: offset_e = offset + (1024 * 2**j) transaction = Transaction.from_hex( transaction_data[offset:offset_e]) return transaction except Exception: continue return None
async def handle(self): global current_block_count msg = await self.zmqSubSocket.recv_multipart() topic = msg[0] body = msg[1] sequence = "Unknown" if len(msg[-1]) == 4: msgSequence = struct.unpack('<I', msg[-1])[-1] sequence = str(msgSequence) if topic == b"rawblock": try: block = Block(body, current_block_count + 1) current_block_count += 1 documents = [] d_txids = [] for tx in block.transactions: res = tna.extract(block, tx) #print(json.dumps(res, indent=4)) documents.append(res) d_txids.append(tx.hash) print("height={} inserted={}".format( block.height, len(db.confirmed.insert_many(documents).inserted_ids))) db.meta.update({'column': 'last_block'}, {"height": block.height}, upsert=True) for txid in d_txids: db.unconfirmed.delete_one({'tx': {'h': txid}}) except AssertionError: print('error: rawblock') elif topic == b"rawtx": try: tx = Transaction.from_hex(body) res = tna.extract(None, tx) db.unconfirmed.insert_one(res) print('inserted tx: {}'.format(tx.hash)) except: print('error: rawtx') # schedule to receive next message asyncio.ensure_future(self.handle())
action="store_true", help="show json from tna") args = parser.parse_args() rpc = bitcoin.rpc.RawProxy(btc_conf_file=btc_conf_file) mongo = pymongo.MongoClient(os.getenv('MONGO_URL')) db = mongo[os.getenv('MONGO_NAME')] if not args.dry: print('deleted {} txs from unconfirmed'.format( db.unconfirmed.delete_many({}).deleted_count)) documents = [] transactions = rpc.getrawmempooltxs() total_transactions = len(transactions) for txdata_index, txdata in enumerate(transactions): tx = Transaction.from_hex(binascii.unhexlify(txdata)) res = tna.extract(None, tx) if args.verbose: print(json.dumps(res, indent=4)) documents.append(res) print("{}%\t{}/{}".format( round((txdata_index / total_transactions) * 100, 2), txdata_index, total_transactions)) if not args.dry: inserted = len(db.unconfirmed.insert_many(documents).inserted_ids) print("inserted={}".format(inserted))
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))