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])
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)
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
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()
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])