Exemple #1
0
 def serialize_preimage(
     self,
     txin_index: int,
     *,
     bip143_shared_txdigest_fields: BIP143SharedTxDigestFields = None
 ) -> str:
     nVersion = int_to_hex(self.version, 4)
     nHashType = int_to_hex(1, 4)  # SIGHASH_ALL
     nLocktime = int_to_hex(self.locktime, 4)
     inputs = self.inputs()
     outputs = self.outputs()
     txin = inputs[txin_index]
     if self.is_segwit_input(txin):
         if bip143_shared_txdigest_fields is None:
             bip143_shared_txdigest_fields = self._calc_bip143_shared_txdigest_fields(
             )
         hashPrevouts = bip143_shared_txdigest_fields.hashPrevouts
         hashSequence = bip143_shared_txdigest_fields.hashSequence
         hashOutputs = bip143_shared_txdigest_fields.hashOutputs
         outpoint = self.serialize_outpoint(txin)
         preimage_script = self.get_preimage_script(txin)
         scriptCode = var_int(len(preimage_script) // 2) + preimage_script
         amount = int_to_hex(txin['value'], 8)
         nSequence = int_to_hex(txin.get('sequence', 0xffffffff - 1), 4)
         preimage = nVersion + hashPrevouts + hashSequence + outpoint + scriptCode + amount + nSequence + hashOutputs + nLocktime + nHashType
     else:
         txins = var_int(len(inputs)) + ''.join(
             self.serialize_input(
                 txin,
                 self.get_preimage_script(txin) if txin_index == k else '')
             for k, txin in enumerate(inputs))
         txouts = var_int(len(outputs)) + ''.join(
             self.serialize_output(o) for o in outputs)
         preimage = nVersion + txins + txouts + nLocktime + nHashType
     return preimage
Exemple #2
0
    def serialize_witness(self, txin, estimate_size=False):
        _type = txin['type']
        if not self.is_segwit_input(txin) and not txin['type'] == 'address':
            return '00'
        if _type == 'coinbase':
            return txin['witness']

        witness = txin.get('witness', None)
        if witness is None or estimate_size:
            if _type == 'address' and estimate_size:
                _type = self.guess_txintype_from_address(txin['address'])
            pubkeys, sig_list = self.get_siglist(txin, estimate_size)
            if _type in ['p2wpkh', 'p2wpkh-p2sh']:
                witness = construct_witness([sig_list[0], pubkeys[0]])
            elif _type in ['p2wsh', 'p2wsh-p2sh']:
                witness_script = multisig_script(pubkeys, txin['num_sig'])
                witness = construct_witness([0] + sig_list + [witness_script])
            else:
                witness = txin.get('witness', '00')

        if self.is_txin_complete(txin) or estimate_size:
            partial_format_witness_prefix = ''
        else:
            input_value = int_to_hex(txin['value'], 8)
            witness_version = int_to_hex(txin.get('witness_version', 0), 2)
            partial_format_witness_prefix = var_int(
                0xffffffff) + input_value + witness_version
        return partial_format_witness_prefix + witness
Exemple #3
0
 def serialize_input(self, txin, script):
     # Prev hash and index
     s = self.serialize_outpoint(txin)
     # Script length, script, sequence
     s += var_int(len(script) // 2)
     s += script
     s += int_to_hex(txin.get('sequence', 0xffffffff - 1), 4)
     return s
Exemple #4
0
 def serialize_to_network(self, estimate_size=False, witness=True):
     self.deserialize()
     nVersion = int_to_hex(self.version, 4)
     nLocktime = int_to_hex(self.locktime, 4)
     inputs = self.inputs()
     outputs = self.outputs()
     txins = var_int(len(inputs)) + ''.join(
         self.serialize_input(txin, self.input_script(txin, estimate_size))
         for txin in inputs)
     txouts = var_int(len(outputs)) + ''.join(
         self.serialize_output(o) for o in outputs)
     use_segwit_ser_for_estimate_size = estimate_size and self.is_segwit(
         guess_for_address=True)
     use_segwit_ser_for_actual_use = not estimate_size and \
                                     (self.is_segwit() or any(txin['type'] == 'address' for txin in inputs))
     use_segwit_ser = use_segwit_ser_for_estimate_size or use_segwit_ser_for_actual_use
     if witness and use_segwit_ser:
         marker = '00'
         flag = '01'
         witness = ''.join(
             self.serialize_witness(x, estimate_size) for x in inputs)
         return nVersion + marker + flag + txins + txouts + witness + nLocktime
     else:
         return nVersion + txins + txouts + nLocktime
Exemple #5
0
 def _calc_bip143_shared_txdigest_fields(
         self) -> BIP143SharedTxDigestFields:
     inputs = self.inputs()
     outputs = self.outputs()
     hashPrevouts = bh2u(
         sha256d(
             bfh(''.join(self.serialize_outpoint(txin)
                         for txin in inputs))))
     hashSequence = bh2u(
         sha256d(
             bfh(''.join(
                 int_to_hex(txin.get('sequence', 0xffffffff - 1), 4)
                 for txin in inputs))))
     hashOutputs = bh2u(
         sha256d(bfh(''.join(self.serialize_output(o) for o in outputs))))
     return BIP143SharedTxDigestFields(hashPrevouts=hashPrevouts,
                                       hashSequence=hashSequence,
                                       hashOutputs=hashOutputs)
Exemple #6
0
 def serialize_output(cls, output: TxOutput) -> str:
     s = int_to_hex(output.value, 8)
     script = cls.pay_script(output.type, output.address)
     s += var_int(len(script) // 2)
     s += script
     return s
Exemple #7
0
 def serialize_outpoint(self, txin):
     return bh2u(bfh(txin['prevout_hash'])[::-1]) + int_to_hex(
         txin['prevout_n'], 4)