@@ -143,50 +143,45 @@ def __repr__(self):
143143 @staticmethod
144144 def from_raw (txinputrawhex : str , cursor : int = 0 , has_segwit : bool = False ):
145145 """
146- Imports a TxInput from a Transaction's hexadecimal data using struct for parsing.
146+ Imports a TxInput from a Transaction's hexadecimal data
147147
148- Args:
149- txinputrawhex (str): The hexadecimal raw string of the Transaction.
150- cursor (int): The position at which the algorithm will start to read the data.
151- has_segwit (bool): Indicates if the Tx Input is SegWit enabled.
152-
153- Returns:
154- tuple: (TxInput object, new cursor position)
155-
156- Raises:
157- Exception: If the transaction hash or script is malformed.
148+ Attributes
149+ ----------
150+ txinputrawhex : string (hex)
151+ The hexadecimal raw string of the Transaction
152+ cursor : int
153+ The cursor of which the algorithm will start to read the data
154+ has_segwit : boolean
155+ Is the Tx Input segwit or not
158156 """
159157 txinputraw = h_to_b (txinputrawhex )
160158
161- # Unpack transaction ID (hash) and output index
162- txid_format = "<32sI"
163- txid , vout = struct .unpack_from (txid_format , txinputraw , cursor )
164- txid = txid [::- 1 ].hex () # Reverse to match usual hexadecimal order
165- cursor += struct .calcsize (txid_format )
159+ # Unpack transaction ID (hash) in bytes and output index
160+ txid , vout = struct .unpack_from ('<32sI' , txinputraw , cursor )
161+ txid = txid [::- 1 ] # Reverse to match usual hexadecimal order
162+ cursor += 36 # 32 bytes for txid and 4 bytes for vout
166163
167164 # Read the unlocking script size using parse_compact_size
168- unlocking_script_size , size = parse_compact_size (txinputraw , cursor )
165+ unlocking_script_size , size = parse_compact_size (txinputraw [ cursor :] )
169166 cursor += size
170167
171- # Read the unlocking script
172- script_format = f"{ unlocking_script_size } s"
173- unlocking_script , = struct .unpack_from (script_format , txinputraw , cursor )
168+ # Read the unlocking script in bytes
169+ unlocking_script = struct .unpack_from (f'{ unlocking_script_size } s' , txinputraw , cursor )[0 ]
174170 cursor += unlocking_script_size
175171
176- # Read the sequence number
177- sequence_format = "<I"
178- sequence , = struct .unpack_from (sequence_format , txinputraw , cursor )
179- cursor += struct .calcsize (sequence_format )
172+ # Read the sequence number in bytes
173+ sequence , = struct .unpack_from ('<4s' , txinputraw , cursor )
174+ cursor += 4
180175
181- # If coinbase input, handle differently
182- if txid == 64 * "0" :
176+ # If coinbase input (utxo will be all zeros) , handle script differently
177+ if txid . hex () == '00' * 32 :
183178 script_sig = Script ([unlocking_script .hex ()]) # Treat as single element for coinbase
184179 else :
185180 script_sig = Script .from_raw (unlocking_script .hex (), has_segwit = has_segwit )
186181
187182 # Create the TxInput instance
188183 tx_input = TxInput (
189- txid = txid ,
184+ txid = txid . hex () ,
190185 txout_index = vout ,
191186 script_sig = script_sig ,
192187 sequence = sequence
@@ -306,13 +301,13 @@ def from_raw(txoutputrawhex: str, cursor: int = 0, has_segwit: bool = False):
306301 """
307302 txoutputraw = h_to_b (txoutputrawhex )
308303
309- # Unpack the output value (amount)
304+ # Unpack the amount of the TxOutput directly in bytes
310305 amount_format = "<Q" # Little-endian unsigned long long (8 bytes)
311306 amount , = struct .unpack_from (amount_format , txoutputraw , cursor )
312307 cursor += struct .calcsize (amount_format )
313308
314309 # Read the locking script size using parse_compact_size
315- lock_script_size , size = parse_compact_size (txoutputraw , cursor )
310+ lock_script_size , size = parse_compact_size (txoutputraw [ cursor :] )
316311 cursor += size
317312
318313 # Read the locking script
@@ -328,6 +323,7 @@ def from_raw(txoutputrawhex: str, cursor: int = 0, has_segwit: bool = False):
328323
329324 return tx_output , cursor
330325
326+
331327 def __str__ (self ) -> str :
332328 return str ({"amount" : self .amount , "script_pubkey" : self .script_pubkey })
333329
@@ -532,75 +528,72 @@ def __init__(
532528 @staticmethod
533529 def from_raw (rawtxhex : str ):
534530 """
535- Imports a Transaction from hexadecimal data
531+ Imports a Transaction from hexadecimal data.
536532
537533 Attributes
538534 ----------
539535 rawtxhex : string (hex)
540- The hexadecimal raw string of the Transaction
536+ The hexadecimal raw string of the Transaction.
541537 """
542538 rawtx = h_to_b (rawtxhex )
543- cursor = 0
544539
545- # Unpack version (4 bytes)
546- version , = struct . unpack_from ( '<I' , rawtx , cursor )
547- cursor + = 4
540+ # Read version (4 bytes)
541+ version = rawtx [ 0 : 4 ]
542+ cursor = 4
548543
549544 # Detect and handle SegWit
550- flag = None
551545 has_segwit = False
552- if rawtx [cursor ] == 0x00 and rawtx [cursor + 1 ] == 0x01 :
553- flag = rawtx [cursor + 1 ]
546+ if rawtx [cursor :cursor + 2 ] == b'\x00 \x01 ' :
554547 has_segwit = True
555- cursor += 2 # Skip past the marker and flag bytes
548+ cursor += 2 # Skipping past the marker and flag bytes
556549
557550 # Read the number of inputs
558- n_inputs , size = parse_compact_size (rawtx , cursor )
551+ n_inputs , size = parse_compact_size (rawtx [ cursor :] )
559552 cursor += size
560553 inputs = []
561554
562555 # Read inputs
563556 for _ in range (n_inputs ):
564- inp , cursor = TxInput .from_raw (rawtxhex , cursor , has_segwit )
557+ inp , cursor = TxInput .from_raw (rawtx . hex () , cursor , has_segwit )
565558 inputs .append (inp )
566559
567- # Read the number of outputs
568- n_outputs , size = parse_compact_size (rawtx , cursor )
560+ # Read the number of outputs using parse_compact_size
561+ n_outputs , size = parse_compact_size (rawtx [ cursor :] )
569562 cursor += size
570563 outputs = []
571564
572565 # Read outputs
573566 for _ in range (n_outputs ):
574- output , cursor = TxOutput .from_raw (rawtxhex , cursor , has_segwit )
567+ output , cursor = TxOutput .from_raw (rawtx . hex () , cursor , has_segwit )
575568 outputs .append (output )
576569
577570 # Handle witnesses if SegWit is enabled
578571 witnesses = []
579572 if has_segwit :
580573 for _ in range (n_inputs ):
581- n_items , size = parse_compact_size (rawtx , cursor )
574+ n_items , size = parse_compact_size (rawtx [ cursor :] )
582575 cursor += size
583- witness_stack = []
584- for __ in range (n_items ):
585- item_size , size = parse_compact_size (rawtx , cursor )
576+ witnesses_tmp = []
577+ for _ in range (n_items ):
578+ item_size , size = parse_compact_size (rawtx [ cursor :] )
586579 cursor += size
587580 witness_data = rawtx [cursor :cursor + item_size ]
588581 cursor += item_size
589- witness_stack .append (witness_data .hex ())
590- witnesses .append (TxWitnessInput (stack = witness_stack ))
582+ witnesses_tmp .append (witness_data .hex ())
583+ if witnesses_tmp :
584+ witnesses .append (TxWitnessInput (stack = witnesses_tmp ))
591585
592- # Unpack locktime (4 bytes)
593- locktime , = struct .unpack_from ('<I' , rawtx , cursor )
594- cursor += 4
586+ # Read locktime (4 bytes)
587+ locktime = rawtx [cursor :cursor + 4 ]
595588
596- # Construct and return the Transaction object
589+ #Returning the Transaction object
597590 return Transaction (
598- version = version ,
599591 inputs = inputs ,
600592 outputs = outputs ,
593+ version = version ,
601594 locktime = locktime ,
602595 has_segwit = has_segwit ,
603- witnesses = witnesses
596+ witnesses = witnesses ,
604597 )
605598
606599 def __str__ (self ) -> str :
0 commit comments