@@ -541,15 +541,20 @@ def p2ms(cls, m: int, pubkey: typing.List[PubKey]) -> bytearray:
541541
542542
543543class HashType :
544+ # HashType represents the signature hash type used in bitcoin transactions to control which parts of the
545+ # transaction are signed. It determines what can be modified without invalidating the signature.
546+ # See: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki
547+ # See: https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki
548+
544549 def __init__ (self , n : int ) -> None :
545550 assert n in [
546- sighash_default ,
547- sighash_all ,
548- sighash_none ,
549- sighash_single ,
550- sighash_anyone_can_pay | sighash_all ,
551- sighash_anyone_can_pay | sighash_none ,
552- sighash_anyone_can_pay | sighash_single ,
551+ sighash_default , # 0x00: Default for Taproot (equivalent to ALL)
552+ sighash_all , # 0x01: Sign all inputs and outputs
553+ sighash_none , # 0x02: Sign all inputs, no outputs
554+ sighash_single , # 0x03: Sign all inputs, only the output at the same index
555+ sighash_anyone_can_pay | sighash_all , # 0x81: Sign only this input, all outputs
556+ sighash_anyone_can_pay | sighash_none , # 0x82: Sign only this input, no outputs
557+ sighash_anyone_can_pay | sighash_single , # 0x83: Sign only this input, only corresponding output
553558 ]
554559 self .i = n & sighash_anyone_can_pay
555560 self .o = n & 0x3
@@ -558,40 +563,46 @@ def __init__(self, n: int) -> None:
558563
559564
560565class OutPoint :
561- def __init__ (self , txid : bytearray , vout : int ) -> None :
566+ # A combination of a transaction hash and an index n into its vout.
567+
568+ def __init__ (self , txid : bytearray , n : int ) -> None :
562569 assert len (txid ) == 32
563- assert vout >= 0
564- assert vout <= 0xffffffff
570+ assert n >= 0
571+ assert n <= 0xffffffff
565572 self .txid = txid
566- self .vout = vout
573+ self .n = n
567574
568575 def __eq__ (self , other ) -> bool :
569576 return all ([
570577 self .txid == other .txid ,
571- self .vout == other .vout ,
578+ self .n == other .n ,
572579 ])
573580
574581 def __repr__ (self ) -> str :
575582 return json .dumps (self .json ())
576583
577584 def copy (self ) -> OutPoint :
578- return OutPoint (self .txid .copy (), self .vout )
585+ return OutPoint (self .txid .copy (), self .n )
579586
580587 def json (self ) -> typing .Dict :
581588 return {
582589 'txid' : self .txid .hex (),
583- 'vout ' : self .vout ,
590+ 'n ' : self .n ,
584591 }
585592
586- def load (self ):
587- rpcret = pabtc .rpc .get_tx_out (self .txid [::- 1 ].hex (), self .vout )
593+ def load (self ) -> TxOut :
594+ # Load the tx out referenced by this out point via rpc.
595+ rpcret = pabtc .rpc .get_tx_out (self .txid [::- 1 ].hex (), self .n )
588596 script_pubkey = bytearray .fromhex (rpcret ['scriptPubKey' ]['hex' ])
589597 amount = rpcret ['value' ] * pabtc .denomination .bitcoin
590598 amount = int (amount .to_integral_exact ())
591599 return TxOut (amount , script_pubkey )
592600
593601
594602class TxIn :
603+ # An input of a transaction. It contains the location of the previous transaction's output that it claims and a
604+ # signature that matches the output's public key.
605+
595606 def __init__ (
596607 self ,
597608 out_point : OutPoint ,
@@ -630,6 +641,8 @@ def json(self) -> typing.Dict:
630641
631642
632643class TxOut :
644+ # An output of a transaction. It contains the public key that the next input must be able to sign with to claim it.
645+
633646 def __init__ (self , value : int , script_pubkey : bytearray ) -> None :
634647 assert value >= 0
635648 assert value <= 0xffffffffffffffff
@@ -658,6 +671,7 @@ def json(self) -> typing.Dict:
658671class Transaction :
659672 # Referring to the design of Bitcoin core.
660673 # See: https://github.com/bitcoin/bitcoin/blob/master/src/primitives/transaction.h
674+
661675 def __init__ (self , version : int , vin : typing .List [TxIn ], vout : typing .List [TxOut ], locktime : int ) -> None :
662676 self .version = version
663677 self .vin = vin
@@ -716,7 +730,7 @@ def digest_segwit_v0(self, i: int, hash_type: int, script_code: bytearray) -> by
716730 snap = bytearray ()
717731 for e in self .vin :
718732 snap .extend (e .out_point .txid )
719- snap .extend (e .out_point .vout .to_bytes (4 , 'little' ))
733+ snap .extend (e .out_point .n .to_bytes (4 , 'little' ))
720734 hash = hash256 (snap )
721735 data .extend (hash )
722736 # Append hash sequence.
@@ -729,7 +743,7 @@ def digest_segwit_v0(self, i: int, hash_type: int, script_code: bytearray) -> by
729743 data .extend (hash )
730744 # Append outpoint.
731745 data .extend (self .vin [i ].out_point .txid )
732- data .extend (self .vin [i ].out_point .vout .to_bytes (4 , 'little' ))
746+ data .extend (self .vin [i ].out_point .n .to_bytes (4 , 'little' ))
733747 # Append script code of the input.
734748 data .extend (script_code )
735749 # Append value of the output spent by this input.
@@ -775,7 +789,7 @@ def digest_segwit_v1(self, i: int, hash_type: int, script_code: bytearray) -> by
775789 snap = bytearray ()
776790 for e in self .vin :
777791 snap .extend (e .out_point .txid )
778- snap .extend (e .out_point .vout .to_bytes (4 , 'little' ))
792+ snap .extend (e .out_point .n .to_bytes (4 , 'little' ))
779793 data .extend (bytearray (hashlib .sha256 (snap ).digest ()))
780794 # Append the SHA256 of the serialization of all input amounts.
781795 snap = bytearray ()
@@ -808,7 +822,7 @@ def digest_segwit_v1(self, i: int, hash_type: int, script_code: bytearray) -> by
808822 data .append (spend_type )
809823 if ht .i == sighash_anyone_can_pay :
810824 data .extend (self .vin [i ].out_point .txid )
811- data .extend (self .vin [i ].out_point .vout .to_bytes (4 , 'little' ))
825+ data .extend (self .vin [i ].out_point .n .to_bytes (4 , 'little' ))
812826 utxo = self .vin [i ].out_point .load ()
813827 data .extend (utxo .value .to_bytes (8 , 'little' ))
814828 data .extend (pabtc .compact_size .encode (len (utxo .script_pubkey )))
@@ -857,7 +871,7 @@ def serialize_legacy(self) -> bytearray:
857871 data .extend (pabtc .compact_size .encode (len (self .vin )))
858872 for i in self .vin :
859873 data .extend (i .out_point .txid )
860- data .extend (i .out_point .vout .to_bytes (4 , 'little' ))
874+ data .extend (i .out_point .n .to_bytes (4 , 'little' ))
861875 data .extend (pabtc .compact_size .encode (len (i .script_sig )))
862876 data .extend (i .script_sig )
863877 data .extend (i .sequence .to_bytes (4 , 'little' ))
@@ -877,7 +891,7 @@ def serialize_segwit(self) -> bytearray:
877891 data .extend (pabtc .compact_size .encode (len (self .vin )))
878892 for i in self .vin :
879893 data .extend (i .out_point .txid )
880- data .extend (i .out_point .vout .to_bytes (4 , 'little' ))
894+ data .extend (i .out_point .n .to_bytes (4 , 'little' ))
881895 data .extend (pabtc .compact_size .encode (len (i .script_sig )))
882896 data .extend (i .script_sig )
883897 data .extend (i .sequence .to_bytes (4 , 'little' ))
0 commit comments