def __init__(self, version, flag, tx_ins, tx_outs, tx_witnesses, lock_time): super().__init__() self.validate_bytes(version, 4) self.validate_bytes(lock_time, 4) if flag is not None: if flag != riemann.network.SEGWIT_TX_FLAG: raise ValueError('Invald segwit flag. ' 'Expected None or {}. Got: {}'.format( riemann.network.SEGWIT_TX_FLAG, flag)) if tx_witnesses is not None: if flag is None: raise ValueError('Got witnesses but no segwit flag.') if len(tx_witnesses) != len(tx_ins): raise ValueError('Witness and TxIn lists must be same length. ' 'Got {} inputs and {} witnesses.'.format( len(tx_ins), len(tx_witnesses))) for witness in tx_witnesses: if not isinstance(witness, InputWitness): raise ValueError( 'Invalid InputWitness. ' 'Expected instance of InputWitness. Got {}'.format( type(witness))) if min(len(tx_ins), len(tx_outs)) == 0: raise ValueError('Too few inputs or outputs. Stop that.') for tx_in in tx_ins: if not isinstance(tx_in, TxIn): raise ValueError('Invalid TxIn. ' 'Expected instance of TxIn. Got {}'.format( type(tx_in).__name__)) for tx_out in tx_outs: if not isinstance(tx_out, TxOut): raise ValueError('Invalid TxOut. ' 'Expected instance of TxOut. Got {}'.format( type(tx_out).__name__)) self += version if flag is not None: self += flag self += VarInt(len(tx_ins)) for tx_in in tx_ins: self += tx_in self += VarInt(len(tx_outs)) for tx_out in tx_outs: self += tx_out if tx_witnesses is not None: for witness in tx_witnesses: self += witness self += lock_time self.version = version self.flag = flag self.tx_ins_len = len(tx_ins) self.tx_ins = tuple(tx_in for tx_in in tx_ins) self.tx_outs_len = len(tx_outs) self.tx_outs = tuple(tx_out for tx_out in tx_outs) self.tx_witnesses_len = self.tx_ins_len self.tx_witnesses = \ tuple(wit for wit in tx_witnesses) if tx_witnesses is not None \ else None self.lock_time = lock_time if flag is not None: self.tx_id_le = utils.hash256(self.no_witness()) self.wtx_id_le = utils.hash256(self.to_bytes()) self.tx_id = utils.change_endianness(self.tx_id_le) self.wtx_id = utils.change_endianness(self.wtx_id_le) else: self.tx_id_le = utils.hash256(self.to_bytes()) self.tx_id = utils.change_endianness(self.tx_id_le) self.wtx_id = None self.wtx_le = None self._make_immutable()
def __init__(self, version, tx_ins, tx_outs, lock_time, expiry, tx_witnesses): super().__init__() self.validate_bytes(version, 4) self.validate_bytes(lock_time, 4) self.validate_bytes(expiry, 4) if min(len(tx_ins), len(tx_outs)) == 0: raise ValueError('Too few inputs or outputs. Stop that.') # if len(tx_witnesses) != len(tx_ins): # raise ValueError( # 'Witness and TxIn lists must be same length. ' # 'Got {} inputs and {} witnesses.' # .format(len(tx_ins), len(tx_witnesses))) for tx_in in tx_ins: if not isinstance(tx_in, DecredTxIn): raise ValueError( 'Invalid TxIn. ' 'Expected instance of DecredTxIn. Got {}'.format( type(tx_in).__name__)) for tx_out in tx_outs: if not isinstance(tx_out, DecredTxOut): raise ValueError( 'Invalid TxOut. ' 'Expected instance of DecredTxOut. Got {}'.format( type(tx_out).__name__)) for tx_witness in tx_witnesses: if not isinstance(tx_witness, DecredInputWitness): raise ValueError( 'Invalid TxWitness. ' 'Expected instance of DecredInputWitness. Got {}'.format( type(tx_witness).__name__)) self += version self += shared.VarInt(len(tx_ins)) for tx_in in tx_ins: self += tx_in self += shared.VarInt(len(tx_outs)) for tx_out in tx_outs: self += tx_out self += lock_time self += expiry self += shared.VarInt(len(tx_witnesses)) for tx_witness in tx_witnesses: self += tx_witness self.version = version self.tx_ins = tx_ins self.tx_outs = tx_outs self.lock_time = lock_time self.expiry = expiry self.tx_witnesses = tx_witnesses if len(self) > 100000: raise ValueError('Tx is too large. ' 'Expect less than 100kB. Got: {} bytes'.format( len(self))) # TODO: check this self.tx_id_le = self.prefix_hash() self.tx_id = utils.change_endianness(self.tx_id_le) # Ignoring this, as it's only used for in-block merkle trees # self.tx_id_full_le = utils.blake256(self.tx_id_le # + self.witness_hash()) # self.tx_id_full = utils.change_endianness(self.tx_id_full_le) self._make_immutable()