示例#1
0
 def txid(self):
     self.deserialize()
     all_segwit = all(self.is_segwit_input(x) for x in self.inputs())
     if not all_segwit and not self.is_complete():
         return None
     ser = self.serialize_to_network(witness=False)
     return bh2u(sha256d(bfh(ser))[::-1])
示例#2
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)
示例#3
0
 def sign_txin(self,
               txin_index,
               privkey_bytes,
               *,
               bip143_shared_txdigest_fields=None) -> str:
     pre_hash = sha256d(
         bfh(
             self.serialize_preimage(
                 txin_index,
                 bip143_shared_txdigest_fields=bip143_shared_txdigest_fields
             )))
     privkey = ecc.ECPrivkey(privkey_bytes)
     sig = privkey.sign_transaction(pre_hash)
     sig = bh2u(sig) + '01'
     return sig
示例#4
0
    def update_signatures(self, signatures: Sequence[str]):
        """Add new signatures to a transaction

        `signatures` is expected to be a list of sigs with signatures[i]
        intended for self._inputs[i].
        This is used by the Trezor, KeepKey an Safe-T plugins.
        """
        if self.is_complete():
            return
        if len(self.inputs()) != len(signatures):
            raise Exception('expected {} signatures; got {}'.format(
                len(self.inputs()), len(signatures)))
        for i, txin in enumerate(self.inputs()):
            pubkeys, x_pubkeys = self.get_sorted_pubkeys(txin)
            sig = signatures[i]
            if sig in txin.get('signatures'):
                continue
            pre_hash = sha256d(bfh(self.serialize_preimage(i)))
            sig_string = ecc.sig_string_from_der_sig(bfh(sig[:-2]))
            for recid in range(4):
                try:
                    public_key = ecc.ECPubkey.from_sig_string(
                        sig_string, recid, pre_hash)
                except ecc.InvalidECPointException:
                    # the point might not be on the curve for some recid values
                    continue
                pubkey_hex = public_key.get_public_key_hex(compressed=True)
                if pubkey_hex in pubkeys:
                    try:
                        public_key.verify_message_hash(sig_string, pre_hash)
                    except Exception:
                        _logger.exception('')
                        continue
                    j = pubkeys.index(pubkey_hex)
                    _logger.info(f"adding sig {i} {j} {pubkey_hex} {sig}")
                    self.add_signature_to_txin(i, j, sig)
                    break
        # redo raw
        self.raw = self.serialize()
示例#5
0
 def wtxid(self):
     self.deserialize()
     if not self.is_complete():
         return None
     ser = self.serialize_to_network(witness=True)
     return bh2u(sha256d(bfh(ser))[::-1])