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
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
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
def construct_witness(items: Sequence[Union[str, int, bytes]]) -> str: """Constructs a witness from the given stack items.""" witness = var_int(len(items)) for item in items: if type(item) is int: item = bitcoin.script_num_to_hex(item) elif type(item) is bytes: item = bh2u(item) witness += bitcoin.witness_push(item) return witness
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
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