16
16
import stat
17
17
import plyvel
18
18
19
+ from blockchain_parser .transaction import Transaction
20
+ from blockchain_parser .index import DBTransactionIndex
21
+ from blockchain_parser import utils
22
+ from binascii import unhexlify
23
+ from binascii import hexlify
19
24
from .block import Block
20
25
from .index import DBBlockIndex
21
26
from .utils import format_hash
@@ -146,7 +151,6 @@ def _index_confirmed(self, chain_indexes, num_confirmations=6):
146
151
if len (chain ) == num_confirmations :
147
152
return first_block .hash in chain
148
153
149
-
150
154
def get_ordered_blocks (self , index , start = 0 , end = None , cache = None ):
151
155
"""Yields the blocks contained in the .blk files as per
152
156
the heigt extract from the leveldb index present at path
@@ -168,8 +172,8 @@ def get_ordered_blocks(self, index, start=0, end=None, cache=None):
168
172
with open (cache , 'wb' ) as f :
169
173
pickle .dump (blockIndexes , f )
170
174
171
- # remove small forks that may have occured while the node was live.
172
- # Occassionally a node will receive two different solutions to a block
175
+ # remove small forks that may have occurred while the node was live.
176
+ # Occasionally a node will receive two different solutions to a block
173
177
# at the same time. The Leveldb index saves both, not pruning the
174
178
# block that leads to a shorter chain once the fork is settled without
175
179
# "-reindex"ing the bitcoind block data. This leads to at least two
@@ -217,3 +221,36 @@ def get_ordered_blocks(self, index, start=0, end=None, cache=None):
217
221
break
218
222
blkFile = os .path .join (self .path , "blk%05d.dat" % blkIdx .file )
219
223
yield Block (get_block (blkFile , blkIdx .data_pos ), blkIdx .height )
224
+
225
+ def get_transaction (self , txid , db ):
226
+ """Yields the transaction contained in the .blk files as a python
227
+ object, similar to
228
+ https://developer.bitcoin.org/reference/rpc/getrawtransaction.html
229
+ """
230
+
231
+ byte_arr = bytearray .fromhex (txid )
232
+ byte_arr .reverse ()
233
+ tx_hash = hexlify (b't' ).decode ('utf-8' ) + \
234
+ hexlify (byte_arr ).decode ('utf-8' )
235
+
236
+ tx_hash_fmtd = unhexlify (tx_hash )
237
+ raw_hex = db .get (tx_hash_fmtd )
238
+
239
+ tx_idx = DBTransactionIndex (utils .format_hash (tx_hash_fmtd ), raw_hex )
240
+ blk_file = os .path .join (self .path , "blk%05d.dat" % tx_idx .blockfile_no )
241
+ raw_hex = get_block (blk_file , tx_idx .file_offset )
242
+
243
+ offset = tx_idx .block_offset
244
+
245
+ transaction_data = raw_hex [80 :]
246
+ # Try from 1024 (1KiB) -> 1073741824 (1GiB) slice widths
247
+ for j in range (0 , 20 ):
248
+ try :
249
+ offset_e = offset + (1024 * 2 ** j )
250
+ transaction = Transaction .from_hex (
251
+ transaction_data [offset :offset_e ])
252
+ return transaction
253
+ except Exception :
254
+ continue
255
+
256
+ return None
0 commit comments