Пример #1
0
 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()
Пример #2
0
 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()
Пример #3
0
    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()
Пример #4
0
 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()
Пример #5
0
    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()
Пример #6
0
    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)))
Пример #7
0
    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()
Пример #8
0
    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)))
Пример #9
0
    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)))