def witness_signing(self): data = DecredByteData() data += self.version[:2] data += b'\x03\x00' # Serialization type 3 (witness signing) data += shared.VarInt(len(self.tx_witnesses)) for tx_witness in self.tx_witnesses: data += shared.VarInt(tx_witness.script_len) data += tx_witness.script_sig return data.to_bytes()
def prefix(self): data = DecredByteData() data += self.version[:2] data += b'\x01\x00' # Serialization type 1 (prefix only) data += shared.VarInt(len(self.tx_ins)) for tx_in in self.tx_ins: data += tx_in data += shared.VarInt(len(self.tx_outs)) for tx_out in self.tx_outs: data += tx_out data += self.lock_time data += self.expiry return data.to_bytes()
def __init__(self, value, height, index, stack_script, redeem_script): super().__init__() self.validate_bytes(value, 8) self.validate_bytes(height, 4) self.validate_bytes(index, 4) self.validate_bytes(stack_script, None) self.validate_bytes(redeem_script, None) self += value self += height self += index self += shared.VarInt(len(stack_script) + len(redeem_script)) self += stack_script self += redeem_script self.value = value self.height = height self.index = index self.script_len = len(stack_script + redeem_script) self.stack_script = stack_script self.redeem_script = redeem_script self.script_sig = self.stack_script + self.redeem_script self._make_immutable()
def witness(self): data = DecredByteData() data += self.version[:2] data += b'\x02\x00' # Serialization type 2 (witness only) data += shared.VarInt(len(self.tx_witnesses)) for tx_witness in self.tx_witnesses: data += tx_witness return data.to_bytes()
def __init__(self, value, version, output_script): super().__init__() self.validate_bytes(value, 8) self.validate_bytes(version, 2) self.validate_bytes(output_script, None) self += value self += version self += shared.VarInt(len(output_script)) self += output_script self.value = value self.version = version self.output_script_len = len(output_script) self.output_script = output_script self._make_immutable()
def __init__(self, tx_ins, tx_outs, lock_time, expiry_height, value_balance, tx_shielded_spends, tx_shielded_outputs, tx_joinsplits, joinsplit_pubkey, joinsplit_sig, binding_sig): super().__init__() if 'sapling' not in riemann.get_current_network_name(): raise ValueError( 'SaplingTx not supported by network {}.' .format(riemann.get_current_network_name())) self.validate_bytes(lock_time, 4) self.validate_bytes(expiry_height, 4) self.validate_bytes(value_balance, 8) if utils.le2i(expiry_height) > 499999999: raise ValueError('Expiry time too high.' 'Expected <= 499999999. Got {}' .format(utils.le2i(expiry_height))) if (len(tx_shielded_spends) + len(tx_shielded_outputs) == 0 and value_balance != b'\x00' * 8): raise ValueError('If no shielded inputs or outputs, value balance ' 'must be 8 0-bytes. Got {}' .format(value_balance.hex())) elif binding_sig is not None: self.validate_bytes(binding_sig, 64) for tx_in in tx_ins: if not isinstance(tx_in, TxIn): raise ValueError( 'Invalid TxIn. ' 'Expected instance of TxOut. 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__)) if len(tx_joinsplits) > 5: raise ValueError('Too many joinsplits. Stop that.') for shielded_spend in tx_shielded_spends: if not isinstance(shielded_spend, SaplingShieldedSpend): raise ValueError( 'Invalid shielded spend. ' 'Expected instance of SaplingShieldedSpend. Got {}' .format(type(shielded_spend).__name__)) for shielded_output in tx_shielded_outputs: if not isinstance(shielded_output, SaplingShieldedOutput): raise ValueError( 'Invalid shielded output. ' 'Expected instance of SaplingShieldedOutput. Got {}' .format(type(shielded_output).__name__)) for tx_joinsplit in tx_joinsplits: if not isinstance(tx_joinsplit, SaplingJoinsplit): raise ValueError( 'Invalid Joinsplit. ' 'Expected instance of SaplingJoinsplit. Got {}' .format(type(tx_joinsplit).__name__)) if len(tx_joinsplits) != 0: self.validate_bytes(joinsplit_pubkey, 32) self.validate_bytes(joinsplit_sig, 64) if len(tx_joinsplits) + len(tx_ins) + len(tx_shielded_spends) == 0: raise ValueError('Transaction must have some input value.') self += b'\x04\x00\x00\x00' # Sapling is always v4 self += b'\x85\x20\x2f\x89' # Sapling version group id 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_height self += value_balance self += shared.VarInt(len(tx_shielded_spends)) if len(tx_shielded_spends) != 0: for shielded_spend in tx_shielded_spends: self += shielded_spend self += shared.VarInt(len(tx_shielded_outputs)) if len(tx_shielded_outputs) != 0: for shielded_output in tx_shielded_outputs: self += shielded_output self += shared.VarInt(len(tx_joinsplits)) if len(tx_joinsplits) != 0: for tx_joinsplit in tx_joinsplits: self += tx_joinsplit self += joinsplit_pubkey self += joinsplit_sig if len(tx_shielded_outputs) + len(tx_shielded_spends) != 0: self += binding_sig self.binding_sig = binding_sig self.header = b'\x04\x00\x00\x80' # Sapling is always v4 self.group_id = b'\x85\x20\x2f\x89' # Sapling version group id self.tx_ins = tuple(tx_in for tx_in in tx_ins) self.tx_outs = tuple(tx_out for tx_out in tx_outs) self.lock_time = lock_time self.expiry_height = expiry_height self.value_balance = value_balance if len(tx_shielded_spends) != 0: self.tx_shielded_spends = tuple(ss for ss in tx_shielded_spends) else: self.tx_shielded_spends = tuple() if len(tx_shielded_outputs) != 0: self.tx_shielded_outputs = tuple(so for so in tx_shielded_outputs) else: self.tx_shielded_outputs = tuple() if len(tx_joinsplits) != 0: self.tx_joinsplits = tuple(js for js in tx_joinsplits) self.joinsplit_pubkey = joinsplit_pubkey self.joinsplit_sig = joinsplit_sig # Zcash spec 5.4.1.4 Hsig hash function self.hsigs = (tuple(self._hsig(i) for i in range(len(self.tx_joinsplits)))) self.primary_inputs = (tuple(self._primary_input(i) for i in range(len(self.tx_joinsplits)))) else: self.tx_joinsplits = tuple() self.joinsplit_pubkey = None self.joinsplit_sig = None self.hsigs = tuple() self.primary_inputs = tuple() if len(tx_shielded_outputs) + len(tx_shielded_spends) != 0: self.binding_sig = binding_sig else: self.binding_sig = None self.tx_id_le = self.tx_id_le = utils.hash256(self.to_bytes()) self.tx_id = self.tx_id_le[::-1] self._make_immutable() if len(self) > 100000: raise ValueError( # pragma: no cover 'Tx is too large. ' 'Expect less than 100kB. Got: {} bytes'.format(len(self)))
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()
def __init__(self, version, tx_ins, tx_outs, lock_time, tx_joinsplits, joinsplit_pubkey, joinsplit_sig): super().__init__() if 'sprout' not in riemann.get_current_network_name(): raise ValueError('SproutTx not supported by network {}.'.format( riemann.get_current_network_name())) self.validate_bytes(version, 4) self.validate_bytes(lock_time, 4) for tx_in in tx_ins: if not isinstance(tx_in, TxIn): raise ValueError('Invalid TxIn. ' 'Expected instance of TxOut. 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__)) if utils.le2i(version) == 1: if tx_joinsplits is not None and len(tx_joinsplits) != 0: raise ValueError('Joinsplits not allowed in version 1 txns.') if tx_ins is None or len(tx_ins) == 0: raise ValueError('Version 1 txns must have at least 1 input.') if utils.le2i(version) == 2: if len(tx_joinsplits) > 5: raise ValueError('Too many joinsplits. Stop that.') for tx_joinsplit in tx_joinsplits: if not isinstance(tx_joinsplit, z.SproutJoinsplit): raise ValueError( 'Invalid Joinsplit. ' 'Expected instance of SproutJoinsplit. Got {}'.format( type(tx_joinsplit).__name__)) self.validate_bytes(joinsplit_pubkey, 32) if joinsplit_sig is not None and joinsplit_sig != b'': self.validate_bytes(joinsplit_sig, 64) if utils.le2i(version) not in [1, 2]: raise ValueError('Version must be 1 or 2. ' 'Got: {}'.format(utils.le2i(version))) 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 if version == utils.i2le_padded(2, 4): self += shared.VarInt(len(tx_joinsplits)) for tx_joinsplit in tx_joinsplits: self += tx_joinsplit self += joinsplit_pubkey self += joinsplit_sig self.version = version self.tx_ins = tuple(tx_in for tx_in in tx_ins) self.tx_outs = tuple(tx_out for tx_out in tx_outs) self.tx_joinsplits = tuple(js for js in tx_joinsplits) self.lock_time = lock_time if version == utils.i2le_padded(2, 4): self.joinsplit_pubkey = joinsplit_pubkey self.joinsplit_sig = joinsplit_sig # Zcash spec 5.4.1.4 Hsig hash function self.hsigs = (tuple( self._hsig(i) for i in range(len(self.tx_joinsplits)))) self.primary_inputs = (tuple( self._primary_input(i) for i in range(len(self.tx_joinsplits)))) else: self.joinsplit_pubkey = None self.joinsplit_sig = None self.hsigs = None self.primary_inputs = None self.tx_id_le = utils.hash256(self.to_bytes()).hex() self.tx_id = utils.hash256(self.to_bytes())[::-1].hex() self._make_immutable() if len(self) > 100000: raise ValueError( # pragma: no cover 'Tx is too large. ' 'Expect less than 100kB. Got: {} bytes'.format(len(self)))
def __init__(self, tx_ins, tx_outs, lock_time, expiry_height, tx_joinsplits, joinsplit_pubkey, joinsplit_sig): super().__init__() if 'overwinter' not in riemann.get_current_network_name(): raise ValueError( 'OverwinterTx not supported by network {}.' .format(riemann.get_current_network_name())) self.validate_bytes(lock_time, 4) self.validate_bytes(expiry_height, 4) if utils.le2i(expiry_height) > 499999999: raise ValueError('Expiry time too high.' 'Expected <= 499999999. Got {}' .format(utils.le2i(expiry_height))) 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__)) if len(tx_joinsplits) > 5: raise ValueError('Too many joinsplits. Stop that.') for tx_joinsplit in tx_joinsplits: if not isinstance(tx_joinsplit, z.SproutJoinsplit): raise ValueError( 'Invalid Joinsplit. ' 'Expected instance of SproutJoinsplit. Got {}' .format(type(tx_joinsplit).__name__)) if len(tx_joinsplits) != 0: self.validate_bytes(joinsplit_pubkey, 32) self.validate_bytes(joinsplit_sig, 64) if len(tx_joinsplits) == 0 and len(tx_ins) == 0: raise ValueError('Transaction must have tx_ins or joinsplits.') self += b'\x03\x00\x00\x80' # Version 3 + fOverwintered self += b'\x70\x82\xc4\x03' # Overwinter Group ID 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_height self += shared.VarInt(len(tx_joinsplits)) if len(tx_joinsplits) != 0: for tx_joinsplit in tx_joinsplits: self += tx_joinsplit self += joinsplit_pubkey self += joinsplit_sig self.header = b'\x03\x00\x00\x80' self.group_id = b'\x70\x82\xc4\x03' self.version = b'\x03\x00' self.tx_ins = tuple(tx_in for tx_in in tx_ins) self.tx_outs = tuple(tx_out for tx_out in tx_outs) self.lock_time = lock_time self.expiry_height = expiry_height if len(tx_joinsplits) != 0: self.tx_joinsplits = tuple(js for js in tx_joinsplits) self.joinsplit_pubkey = joinsplit_pubkey self.joinsplit_sig = joinsplit_sig # Zcash spec 5.4.1.4 Hsig hash function self.hsigs = (tuple(self._hsig(i) for i in range(len(self.tx_joinsplits)))) self.primary_inputs = (tuple(self._primary_input(i) for i in range(len(self.tx_joinsplits)))) else: self.tx_joinsplits = tuple() self.joinsplit_pubkey = None self.joinsplit_sig = None self.hsigs = tuple() self.primary_inputs = tuple() self.tx_id_le = self.tx_id_le = utils.hash256(self.to_bytes()) self.tx_id = self.tx_id_le[::-1] self._make_immutable() if len(self) > 100000: raise ValueError( # pragma: no cover 'Tx is too large. ' 'Expect less than 100kB. Got: {} bytes'.format(len(self)))