예제 #1
0
 def hash_prevouts(self):
     if self._hash_prevouts is None:
         all_prevouts = b''
         all_sequence = b''
         for tx_in in self.tx_ins:
             all_prevouts += tx_in.prev_tx[::-1] + int_to_little(
                 tx_in.prev_index, 4)
             all_sequence += int_to_little(tx_in.sequence, 4)
         self._hash_prevouts = hash256(all_prevouts)
         self._hash_sequence = hash256(all_sequence)
     return self._hash_prevouts
예제 #2
0
 def serialize(self):
     '''Returns the byte serialization of the transaction input'''
     # serialize prev_tx, little endian
     result = self.prev_tx[::-1]
     # serialize prev_index, 4 bytes, little endian
     result += int_to_little(self.prev_index, 4)
     # serialize the script_sig
     result += self.script_sig.serialize()
     # serialize sequence, 4 bytes, little endian
     result += int_to_little(self.sequence, 4)
     return result
예제 #3
0
 def serialize(self):
     '''Returns the byte serialization of the transaction output'''
     # serialize amount, 8 bytes, little endian
     result = int_to_little(self.amount, 8)
     # serialize the script_pubkey
     result += self.script_pubkey.serialize()
     return result
예제 #4
0
 def serialize_legacy(self):
     '''Returns the byte serialization of the transaction'''
     # serialize version (4 bytes, little endian)
     result = int_to_little(self.version, 4)
     # encode_varint on the number of inputs
     result += encode_varint(len(self.tx_ins))
     # iterate inputs
     for tx_in in self.tx_ins:
         # serialize each input
         result += tx_in.serialize()
     # encode_varint on the number of outputs
     result += encode_varint(len(self.tx_outs))
     # iterate outputs
     for tx_out in self.tx_outs:
         # serialize each output
         result += tx_out.serialize()
     # serialize locktime (4 bytes, little endian)
     result += int_to_little(self.locktime, 4)
     return result
예제 #5
0
 def serialize_segwit(self):
     result = int_to_little(self.version, 4)
     result += b'\x00\x01'
     result += encode_varint(len(self.tx_ins))
     for tx_in in self.tx_ins:
         result += tx_in.serialize()
     result += encode_varint(len(self.tx_outs))
     for tx_out in self.tx_outs:
         result += tx_out.serialize()
     # Witness
     for tx_in in self.tx_ins:
         result += int_to_little(len(tx_in.witness), 1)
         for item in tx_in.witness:
             if type(item) == int:
                 result += int_to_little(item, 1)
             else:
                 result += encode_varint(len(item)) + item
     result += int_to_little(self.locktime, 4)
     return result
예제 #6
0
 def sig_hash(self, idx, sighash_type=SIGHASH_ALL, redeem_script=None):
     '''Returns the integer representation of the hash that needs to get
     signed for index idx'''
     # start the serialization with version
     # use int_to_little in 4 bytes
     s = int_to_little(self.version, 4)
     # add how many inputs there are using encode_varint
     s += encode_varint(len(self.tx_ins))
     # loop through each input using enumerate, so we have the input index
     for i, tx_in in enumerate(self.tx_ins):
         # if the input index is the one we're signing
         if i == idx:
             # if the RedeemScript was passed in, that's the ScriptSig
             if redeem_script:
                 script_sig = redeem_script
             # otherwise the previous tx's ScriptPubkey is the ScriptSig
             else:
                 script_sig = tx_in.script_pubkey(self.testnet)
         # Otherwise, the ScriptSig is empty
         else:
             script_sig = None
         # add the serialization of the input with the ScriptSig we want
         s += TxIn(
             prev_tx=tx_in.prev_tx,
             prev_index=tx_in.prev_index,
             script_sig=script_sig,
             sequence=tx_in.sequence,
         ).serialize()
     # add how many outputs there are using encode_varint
     s += encode_varint(len(self.tx_outs))
     # add the serialization of each output
     for tx_out in self.tx_outs:
         s += tx_out.serialize()
     # add the locktime using int_to_little in 4 bytes
     s += int_to_little(self.locktime, 4)
     # add SIGHASH_ALL using int_to_little in 4 bytes
     s += int_to_little(sighash_type, 4)
     # hash256 the serialization
     h256 = hash256(s)
     # convert the result to an integer using int.from_bytes(x, 'big')
     return int.from_bytes(h256, 'big')
예제 #7
0
 def get_path_bytes(self):
     ''' returns path as concatenated bytes'''
     levels = self.path.split("/")
     path_bytes = b""
     for lev in levels:
         i = 0
         if lev[-1] == "'":
             i = SOFT_CAP
             lev = lev[:-1]
         i += int(lev)
         path_bytes += int_to_little(i, 4)
     return path_bytes
예제 #8
0
 def raw_serialize(self):
     # initialize what we'll send back
     result = b''
     # go through each cmd
     for cmd in self.cmds:
         # if the cmd is an integer, it's an opcode
         if type(cmd) == int:
             # turn the cmd into a single byte integer using int_to_little
             result += int_to_little(cmd, 1)
         else:
             # otherwise, this is an element
             # get the length in bytes
             length = len(cmd)
             # for large lengths, we have to use a pushdata opcode
             if length < 75:
                 # turn the length into a single byte integer
                 result += int_to_little(length, 1)
             elif length > 75 and length < 0x100:
                 # 76 is pushdata1
                 result += int_to_little(76, 1)
                 result += int_to_little(length, 1)
             elif length >= 0x100 and length <= 520:
                 # 77 is pushdata2
                 result += int_to_little(77, 1)
                 result += int_to_little(length, 2)
             else:
                 raise ValueError('too long a cmd')
             if type(cmd) == str:
                 print(cmd)
             result += cmd
     return result
예제 #9
0
 def sig_hash_bip143(self,
                     idx,
                     redeem_script=None,
                     witness_script=None,
                     sighash_type=SIGHASH_ALL):
     '''Returns the integer representation of the hash that needs to get
     signed for index idx'''
     tx_in = self.tx_ins[idx]
     # per BIP143 spec
     s = int_to_little(self.version, 4)
     s += self.hash_prevouts() + self.hash_sequence()
     s += tx_in.prev_tx[::-1] + int_to_little(tx_in.prev_index, 4)
     if witness_script:
         script_code = witness_script.serialize()
     elif redeem_script:
         script_code = p2pkh_script(redeem_script.cmds[1]).serialize()
     else:
         script_code = p2pkh_script(
             tx_in.script_pubkey(self.testnet).cmds[1]).serialize()
     s += script_code
     s += int_to_little(tx_in.value(), 8)
     s += int_to_little(tx_in.sequence, 4)
     s += self.hash_outputs()
     s += int_to_little(self.locktime, 4)
     s += int_to_little(sighash_type, 4)
     return int.from_bytes(hash256(s), 'big')
예제 #10
0
	def add_sighash_type(self, idx, sighash):
		self.psbt.maps["inputs"][idx][IN_SIGHASH_TYPE] = int_to_little(n=sighash, length=4)