Esempio n. 1
0
 def compose_tx_spec(self, op_tx_spec):
     targets_by_color = group_targets_by_color(op_tx_spec.get_targets(), self.__class__)
     uncolored_targets = targets_by_color.pop(UNCOLORED_MARKER.color_id, [])
     # get inputs for each color
     colored_inputs = []
     colored_targets = []
     for color_id, targets in targets_by_color.items():
         color_def = targets[0].get_colordef()
         needed_sum = ColorTarget.sum(targets)
         inputs, total = op_tx_spec.select_coins(needed_sum)
         change = total - needed_sum
         if change > 0:
             targets.append(
                 ColorTarget(op_tx_spec.get_change_addr(color_def), change))
         colored_inputs += inputs
         colored_targets += targets
     uncolored_needed = ColorTarget.sum(uncolored_targets)
     fee = op_tx_spec.get_required_fee(250 * (len(colored_inputs) + 1))
     uncolored_inputs, uncolored_total = op_tx_spec.select_coins(uncolored_needed + fee)
     uncolored_change = uncolored_total - uncolored_needed - fee
     if uncolored_change > op_tx_spec.get_dust_threshold():
         uncolored_targets.append(
             ColorTarget(op_tx_spec.get_change_addr(UNCOLORED_MARKER),
                         uncolored_change))
     txins = colored_inputs + uncolored_inputs
     txouts = [txspec.ComposedTxSpec.TxOut(target.get_satoshi(),
                                           target.get_address())
               for target in (colored_targets + uncolored_targets)]
     return txspec.ComposedTxSpec(txins, txouts)
Esempio n. 2
0
 def compose_tx_spec(self, op_tx_spec):
     targets_by_color = group_targets_by_color(op_tx_spec.get_targets(),
                                               self.__class__)
     uncolored_targets = targets_by_color.pop(UNCOLORED_MARKER.color_id, [])
     # get inputs for each color
     colored_inputs = []
     colored_targets = []
     for color_id, targets in targets_by_color.items():
         color_def = targets[0].get_colordef()
         needed_sum = ColorTarget.sum(targets)
         inputs, total = op_tx_spec.select_coins(needed_sum)
         change = total - needed_sum
         if change > 0:
             targets.append(
                 ColorTarget(op_tx_spec.get_change_addr(color_def), change))
         colored_inputs += inputs
         colored_targets += targets
     uncolored_needed = ColorTarget.sum(uncolored_targets)
     fee = op_tx_spec.get_required_fee(250 * (len(colored_inputs) + 1))
     uncolored_inputs, uncolored_total = op_tx_spec.select_coins(
         uncolored_needed + fee)
     uncolored_change = uncolored_total - uncolored_needed - fee
     if uncolored_change > 0:
         uncolored_targets.append(
             ColorTarget(op_tx_spec.get_change_addr(UNCOLORED_MARKER),
                         uncolored_change))
     txins = colored_inputs + uncolored_inputs
     txouts = [
         txspec.ComposedTxSpec.TxOut(target.get_satoshi(),
                                     target.get_address())
         for target in (colored_targets + uncolored_targets)
     ]
     return txspec.ComposedTxSpec(txins, txouts)
Esempio n. 3
0
 def compose_tx_spec(self, op_tx_spec):
     targets_by_color = group_targets_by_color(op_tx_spec.get_targets(), self.__class__)
     uncolored_targets = targets_by_color.pop(UNCOLORED_MARKER.color_id, [])
     composed_tx_spec = op_tx_spec.make_composed_tx_spec()
     # get inputs for each color
     for color_id, targets in targets_by_color.items():
         color_def = targets[0].get_colordef()
         needed_sum = ColorTarget.sum(targets)
         inputs, total = op_tx_spec.select_coins(needed_sum)
         change = total - needed_sum           
         if change > 0:
             targets.append(
                 ColorTarget(op_tx_spec.get_change_addr(color_def), change))
         composed_tx_spec.add_txins(inputs)
         for target in targets:
             composed_tx_spec.add_txout(value=target.get_value(),
                                        target=target)
     uncolored_needed = ColorTarget.sum(uncolored_targets)
     uncolored_inputs, uncolored_total = op_tx_spec.select_coins(uncolored_needed, composed_tx_spec)
     composed_tx_spec.add_txins(uncolored_inputs)
     fee = composed_tx_spec.estimate_required_fee()
     uncolored_change = uncolored_total - uncolored_needed - fee
     if uncolored_change > op_tx_spec.get_dust_threshold():
         composed_tx_spec.add_txout(value=uncolored_change,
                                    target_addr=op_tx_spec.get_change_addr(UNCOLORED_MARKER),
                                    is_fee_change=True)
     return composed_tx_spec
Esempio n. 4
0
 def compose_tx_spec(self, op_tx_spec):
     targets_by_color = group_targets_by_color(op_tx_spec.get_targets(),
                                               self.__class__)
     uncolored_targets = targets_by_color.pop(UNCOLORED_MARKER.color_id, [])
     composed_tx_spec = op_tx_spec.make_composed_tx_spec()
     # get inputs for each color
     for color_id, targets in targets_by_color.items():
         color_def = targets[0].get_colordef()
         needed_sum = ColorTarget.sum(targets)
         inputs, total = op_tx_spec.select_coins(needed_sum)
         change = total - needed_sum
         if change > 0:
             targets.append(
                 ColorTarget(op_tx_spec.get_change_addr(color_def), change))
         composed_tx_spec.add_txins(inputs)
         for target in targets:
             composed_tx_spec.add_txout(value=target.get_value(),
                                        target=target)
     uncolored_needed = ColorTarget.sum(uncolored_targets)
     uncolored_inputs, uncolored_total = op_tx_spec.select_coins(
         uncolored_needed, composed_tx_spec)
     composed_tx_spec.add_txins(uncolored_inputs)
     fee = composed_tx_spec.estimate_required_fee()
     uncolored_change = uncolored_total - uncolored_needed - fee
     if uncolored_change > op_tx_spec.get_dust_threshold():
         composed_tx_spec.add_txout(
             value=uncolored_change,
             target_addr=op_tx_spec.get_change_addr(UNCOLORED_MARKER),
             is_fee_change=True)
     return composed_tx_spec
Esempio n. 5
0
    def compose_tx_spec(self, op_tx_spec):
        # group targets by color
        targets_by_color = defaultdict(list)
        # group targets by color
        for target in op_tx_spec.get_targets():
            color_def = target.get_colordef()
            if color_def == UNCOLORED_MARKER \
                    or isinstance(color_def, POBColorDefinition):
                targets_by_color[color_def.color_id].append(target)
            else:
                raise InvalidColorError('incompatible color definition')
        uncolored_targets = targets_by_color.pop(UNCOLORED_MARKER.color_id, [])

        # get inputs for each color
        colored_inputs = []
        colored_targets = []
        for color_id, targets in targets_by_color.items():
            color_def = targets[0].get_colordef()
            needed_sum = ColorTarget.sum(targets)
            inputs, total = op_tx_spec.select_coins(needed_sum)
            change = total - needed_sum
            if change > 0:
                targets.append(ColorTarget(
                        op_tx_spec.get_change_addr(color_def), change))
            colored_inputs += inputs
            colored_targets += targets

        # we also need some amount of extra "uncolored" coins
        # for padding purposes, possibly
        padding_needed = (len(colored_targets) - len(colored_inputs)) \
            * self.PADDING
        uncolored_needed = ColorTarget.sum(uncolored_targets) \
            + SimpleColorValue(colordef=UNCOLORED_MARKER, value=padding_needed)
        fee = op_tx_spec.get_required_fee(250 * (len(colored_inputs) + 1))
        amount_needed = uncolored_needed + fee
        zero = SimpleColorValue(colordef=UNCOLORED_MARKER, value=0)
        if amount_needed == zero:
            uncolored_change = zero
            uncolored_inputs = []
        else:
            uncolored_inputs, uncolored_total = op_tx_spec.select_coins(amount_needed)
            uncolored_change = uncolored_total - amount_needed
        if uncolored_change > zero:
            uncolored_targets.append(
                ColorTarget(op_tx_spec.get_change_addr(UNCOLORED_MARKER),
                 uncolored_change))

        # compose the TxIn and TxOut elements
        txins = colored_inputs + uncolored_inputs
        txouts = [
            txspec.ComposedTxSpec.TxOut(target.get_satoshi(),
                                        target.get_address())
            for target in colored_targets]
        txouts += [txspec.ComposedTxSpec.TxOut(target.get_satoshi(),
                                               target.get_address())
                   for target in uncolored_targets]
        return txspec.ComposedTxSpec(txins, txouts)
Esempio n. 6
0
 def compose_genesis_tx_spec(self, op_tx_spec):
     targets = op_tx_spec.get_targets()[:]
     if len(targets) != 1:
         raise InvalidTargetError(
             'genesis transaction spec needs exactly one target')
     target = targets[0]
     if target.get_colordef() != GENESIS_OUTPUT_MARKER:
         raise InvalidColorError(
             'genesis transaction target should use -1 color_id')
     fee = op_tx_spec.get_required_fee(300)
     uncolored_value = SimpleColorValue(colordef=UNCOLORED_MARKER,
                                        value=target.get_value())
     colorvalue = fee + uncolored_value
     inputs, total = op_tx_spec.select_coins(colorvalue)
     change = total - fee - uncolored_value
     if change > 0:
         targets.append(
             ColorTarget(op_tx_spec.get_change_addr(UNCOLORED_MARKER),
                         change))
     txouts = [
         txspec.ComposedTxSpec.TxOut(target.get_satoshi(),
                                     target.get_address())
         for target in targets
     ]
     return txspec.ComposedTxSpec(inputs, txouts)
Esempio n. 7
0
 def compose_tx_spec(self, op_tx_spec):
     targets_by_color = defaultdict(list)
     uncolored_targets = []
     # group targets by color
     for target in op_tx_spec.get_targets():
         color_def = target.get_colordef()
         if color_def == UNCOLORED_MARKER:
             uncolored_targets.append(target)
         elif isinstance(color_def, OBColorDefinition):
             targets_by_color[color_def.color_id].append(target)
         else:
             raise InvalidColorError('incompatible color definition')
     # get inputs for each color
     colored_inputs = []
     colored_targets = []
     for color_id, targets in targets_by_color.items():
         color_def = targets[0].get_colordef()
         needed_sum = ColorTarget.sum(targets)
         inputs, total = op_tx_spec.select_coins(needed_sum)
         change = total - needed_sum
         if change > 0:
             targets.append(
                 ColorTarget(op_tx_spec.get_change_addr(color_def), change))
         colored_inputs += inputs
         colored_targets += targets
     uncolored_needed = ColorTarget.sum(uncolored_targets)
     fee = op_tx_spec.get_required_fee(250 * (len(colored_inputs) + 1))
     uncolored_inputs, uncolored_total = op_tx_spec.select_coins(uncolored_needed + fee)
     uncolored_change = uncolored_total - uncolored_needed - fee
     if uncolored_change > 0:
         uncolored_targets.append(
             ColorTarget(op_tx_spec.get_change_addr(UNCOLORED_MARKER),
                         uncolored_change))
     txins = colored_inputs + uncolored_inputs
     txouts = [txspec.ComposedTxSpec.TxOut(target.get_satoshi(),
                                           target.get_address())
               for target in (colored_targets + uncolored_targets)]
     return txspec.ComposedTxSpec(txins, txouts)
Esempio n. 8
0
    def compose_tx_spec(self, op_tx_spec):
        targets_by_color = group_targets_by_color(op_tx_spec.get_targets(), self.__class__)
        uncolored_targets = targets_by_color.pop(UNCOLORED_MARKER.color_id, [])
        colored_txins = []
        colored_txouts = []
        if uncolored_targets:
            uncolored_needed = ColorTarget.sum(uncolored_targets)
        else:
            uncolored_needed = SimpleColorValue(colordef=UNCOLORED_MARKER,
                                                value=0)

        dust_threshold = op_tx_spec.get_dust_threshold().get_value()

        inputs_by_color = dict()

        min_padding = 0
        # step 1: get inputs, create change targets, compute min padding
        for color_id, targets in targets_by_color.items():
            color_def = targets[0].get_colordef()
            needed_sum = ColorTarget.sum(targets)
            inputs, total = op_tx_spec.select_coins(needed_sum)
            inputs_by_color[color_id] = inputs
            change = total - needed_sum
            if change > 0:
                targets.append(
                    ColorTarget(op_tx_spec.get_change_addr(color_def), change))
            for target in targets:
                padding_needed = dust_threshold - target.get_value() 
                if padding_needed > min_padding:
                    min_padding = padding_needed

        tag = self.Tag(self.Tag.closest_padding_code(min_padding), False)
        padding = tag.get_padding()

        # step 2: create txins & txouts, compute uncolored requirements
        for color_id, targets in targets_by_color.items():
            color_def = targets[0].get_colordef()
            for inp in inputs_by_color[color_id]:
                colored_txins.append(inp)
                uncolored_needed -= SimpleColorValue(colordef=UNCOLORED_MARKER,
                                               value=inp.value)
                print uncolored_needed
            for target in targets:
                svalue = target.get_value() + padding
                colored_txouts.append(
                    txspec.ComposedTxSpec.TxOut(svalue,
                                                target.get_address()))
                uncolored_needed += SimpleColorValue(colordef=UNCOLORED_MARKER,
                                               value=svalue)
                print uncolored_needed

        fee = op_tx_spec.get_required_fee(250 * (len(colored_txins) + 1))

        uncolored_txouts = []
        uncolored_inputs = []
        uncolored_change = None

        if uncolored_needed + fee > 0:
            uncolored_inputs, uncolored_total = op_tx_spec.select_coins(uncolored_needed + fee)
            uncolored_txouts = [txspec.ComposedTxSpec.TxOut(target.get_satoshi(),
                                                            target.get_address())
                                for target in uncolored_targets]
            uncolored_change = uncolored_total - uncolored_needed - fee
        else:
            uncolored_change =  (- uncolored_needed) - fee
            
        if uncolored_change > op_tx_spec.get_dust_threshold():
            uncolored_txouts.append(txspec.ComposedTxSpec.TxOut(
                    uncolored_change.get_value(), 
                    op_tx_spec.get_change_addr(UNCOLORED_MARKER)))

        all_inputs = colored_txins + uncolored_inputs

        all_inputs[0].set_nSequence(tag.to_nSequence())

        return txspec.ComposedTxSpec(all_inputs,
                                     colored_txouts + uncolored_txouts)
Esempio n. 9
0
    def compose_tx_spec(self, op_tx_spec):
        targets_by_color = group_targets_by_color(op_tx_spec.get_targets(),
                                                  self.__class__)
        uncolored_targets = targets_by_color.pop(UNCOLORED_MARKER.color_id, [])
        colored_txins = []
        colored_txouts = []
        if uncolored_targets:
            uncolored_needed = ColorTarget.sum(uncolored_targets)
        else:
            uncolored_needed = SimpleColorValue(colordef=UNCOLORED_MARKER,
                                                value=0)

        dust_threshold = op_tx_spec.get_dust_threshold().get_value()

        inputs_by_color = dict()

        min_padding = 0
        # step 1: get inputs, create change targets, compute min padding
        for color_id, targets in targets_by_color.items():
            color_def = targets[0].get_colordef()
            needed_sum = ColorTarget.sum(targets)
            inputs, total = op_tx_spec.select_coins(needed_sum)
            inputs_by_color[color_id] = inputs
            change = total - needed_sum
            if change > 0:
                targets.append(
                    ColorTarget(op_tx_spec.get_change_addr(color_def), change))
            for target in targets:
                padding_needed = dust_threshold - target.get_value()
                if padding_needed > min_padding:
                    min_padding = padding_needed

        tag = self.Tag(self.Tag.closest_padding_code(min_padding), False)
        padding = tag.get_padding()

        # step 2: create txins & txouts, compute uncolored requirements
        for color_id, targets in targets_by_color.items():
            color_def = targets[0].get_colordef()
            for inp in inputs_by_color[color_id]:
                colored_txins.append(inp)
                uncolored_needed -= SimpleColorValue(colordef=UNCOLORED_MARKER,
                                                     value=inp.value)
                print uncolored_needed
            for target in targets:
                svalue = target.get_value() + padding
                colored_txouts.append(
                    txspec.ComposedTxSpec.TxOut(svalue, target.get_address()))
                uncolored_needed += SimpleColorValue(colordef=UNCOLORED_MARKER,
                                                     value=svalue)
                print uncolored_needed

        fee = op_tx_spec.get_required_fee(250 * (len(colored_txins) + 1))

        uncolored_txouts = []
        uncolored_inputs = []
        uncolored_change = None

        if uncolored_needed + fee > 0:
            uncolored_inputs, uncolored_total = op_tx_spec.select_coins(
                uncolored_needed + fee)
            uncolored_txouts = [
                txspec.ComposedTxSpec.TxOut(target.get_satoshi(),
                                            target.get_address())
                for target in uncolored_targets
            ]
            uncolored_change = uncolored_total - uncolored_needed - fee
        else:
            uncolored_change = (-uncolored_needed) - fee

        if uncolored_change > 0:
            uncolored_txouts.append(
                txspec.ComposedTxSpec.TxOut(
                    uncolored_change.get_value(),
                    op_tx_spec.get_change_addr(UNCOLORED_MARKER)))

        all_inputs = colored_txins + uncolored_inputs

        all_inputs[0].set_nSequence(tag.to_nSequence())

        return txspec.ComposedTxSpec(all_inputs,
                                     colored_txouts + uncolored_txouts)
Esempio n. 10
0
    def compose_tx_spec(self, op_tx_spec):
        targets_by_color = group_targets_by_color(op_tx_spec.get_targets(), self.__class__)
        uncolored_targets = targets_by_color.pop(UNCOLORED_MARKER.color_id, [])
        composed_tx_spec = op_tx_spec.make_composed_tx_spec()
        if uncolored_targets:
            uncolored_needed = ColorTarget.sum(uncolored_targets)
        else:
            uncolored_needed = SimpleColorValue(colordef=UNCOLORED_MARKER,
                                                value=0)
        dust_threshold = op_tx_spec.get_dust_threshold().get_value()
        inputs_by_color = dict()
        min_padding = 0

        # step 1: get inputs, create change targets, compute min padding
        for color_id, targets in targets_by_color.items():
            color_def = targets[0].get_colordef()
            needed_sum = ColorTarget.sum(targets)
            inputs, total = op_tx_spec.select_coins(needed_sum)
            inputs_by_color[color_id] = inputs
            change = total - needed_sum
            if change > 0:
                targets.append(
                    ColorTarget(op_tx_spec.get_change_addr(color_def), change))
            for target in targets:
                padding_needed = dust_threshold - target.get_value() 
                if padding_needed > min_padding:
                    min_padding = padding_needed

        tag = self.Tag(self.Tag.closest_padding_code(min_padding), False)
        padding = tag.get_padding()

        # step 2: create txins & txouts, compute uncolored requirements
        for color_id, targets in targets_by_color.items():
            color_def = targets[0].get_colordef()
            for inp in inputs_by_color[color_id]:
                composed_tx_spec.add_txin(inp)
                uncolored_needed -= SimpleColorValue(colordef=UNCOLORED_MARKER,
                                               value=inp.value)
            for target in targets:
                svalue = target.get_value() + padding
                composed_tx_spec.add_txout(value=svalue,
                                           target=target)
                uncolored_needed += SimpleColorValue(colordef=UNCOLORED_MARKER,
                                               value=svalue)
                print uncolored_needed

        composed_tx_spec.add_txouts(uncolored_targets)
        fee = composed_tx_spec.estimate_required_fee()

        uncolored_change = None

        if uncolored_needed + fee > 0:
            uncolored_inputs, uncolored_total = op_tx_spec.select_coins(uncolored_needed, composed_tx_spec)
            composed_tx_spec.add_txins(uncolored_inputs)
            fee = composed_tx_spec.estimate_required_fee()
            uncolored_change = uncolored_total - uncolored_needed - fee
        else:
            uncolored_change =  (- uncolored_needed) - fee
            
        if uncolored_change > op_tx_spec.get_dust_threshold():
            composed_tx_spec.add_txout(value=uncolored_change,
                                       target_addr=op_tx_spec.get_change_addr(UNCOLORED_MARKER),
                                       is_fee_change=True)

        composed_tx_spec.txins[0].set_nSequence(tag.to_nSequence())

        return composed_tx_spec
Esempio n. 11
0
    def compose_tx_spec(self, op_tx_spec):
        targets_by_color = group_targets_by_color(op_tx_spec.get_targets(),
                                                  self.__class__)
        uncolored_targets = targets_by_color.pop(UNCOLORED_MARKER.color_id, [])
        composed_tx_spec = op_tx_spec.make_composed_tx_spec()
        if uncolored_targets:
            uncolored_needed = ColorTarget.sum(uncolored_targets)
        else:
            uncolored_needed = SimpleColorValue(colordef=UNCOLORED_MARKER,
                                                value=0)
        dust_threshold = op_tx_spec.get_dust_threshold().get_value()
        inputs_by_color = dict()
        min_padding = 0

        # step 1: get inputs, create change targets, compute min padding
        for color_id, targets in targets_by_color.items():
            color_def = targets[0].get_colordef()
            needed_sum = ColorTarget.sum(targets)
            inputs, total = op_tx_spec.select_coins(needed_sum)
            inputs_by_color[color_id] = inputs
            change = total - needed_sum
            if change > 0:
                targets.append(
                    ColorTarget(op_tx_spec.get_change_addr(color_def), change))
            for target in targets:
                padding_needed = dust_threshold - target.get_value()
                if padding_needed > min_padding:
                    min_padding = padding_needed

        tag = self.Tag(self.Tag.closest_padding_code(min_padding), False)
        padding = tag.get_padding()

        # step 2: create txins & txouts, compute uncolored requirements
        for color_id, targets in targets_by_color.items():
            color_def = targets[0].get_colordef()
            for inp in inputs_by_color[color_id]:
                composed_tx_spec.add_txin(inp)
                uncolored_needed -= SimpleColorValue(colordef=UNCOLORED_MARKER,
                                                     value=inp.value)
            for target in targets:
                svalue = target.get_value() + padding
                composed_tx_spec.add_txout(value=svalue, target=target)
                uncolored_needed += SimpleColorValue(colordef=UNCOLORED_MARKER,
                                                     value=svalue)
                print uncolored_needed

        composed_tx_spec.add_txouts(uncolored_targets)
        fee = composed_tx_spec.estimate_required_fee()

        uncolored_change = None

        if uncolored_needed + fee > 0:
            uncolored_inputs, uncolored_total = op_tx_spec.select_coins(
                uncolored_needed, composed_tx_spec)
            composed_tx_spec.add_txins(uncolored_inputs)
            fee = composed_tx_spec.estimate_required_fee()
            uncolored_change = uncolored_total - uncolored_needed - fee
        else:
            uncolored_change = (-uncolored_needed) - fee

        if uncolored_change > op_tx_spec.get_dust_threshold():
            composed_tx_spec.add_txout(
                value=uncolored_change,
                target_addr=op_tx_spec.get_change_addr(UNCOLORED_MARKER),
                is_fee_change=True)

        composed_tx_spec.txins[0].set_nSequence(tag.to_nSequence())

        return composed_tx_spec