Exemple #1
0
    def finalize(self):
        # type: () -> None
        """
    Finalizes the bundle, preparing it to be attached to the Tangle.
    """
        if self.hash:
            raise RuntimeError('Bundle is already finalized.')

        if not self:
            raise ValueError('Bundle has no transactions.')

        # Quick validation.
        balance = self.balance

        if balance < 0:
            if self.change_address:
                self.add_transaction(
                    ProposedTransaction(
                        address=self.change_address,
                        value=-balance,
                        tag=self.tag,
                    ))
            else:
                raise ValueError(
                    'Bundle has unspent inputs (balance: {balance}); '
                    'use ``send_unspent_inputs_to`` to create '
                    'change transaction.'.format(balance=balance, ), )
        elif balance > 0:
            raise ValueError(
                'Inputs are insufficient to cover bundle spend '
                '(balance: {balance}).'.format(balance=balance, ), )

        # Generate bundle hash.
        sponge = Curl()
        last_index = len(self) - 1

        for (i,
             txn) in enumerate(self):  # type: Tuple[int, ProposedTransaction]
            txn.current_index = i
            txn.last_index = last_index

            sponge.absorb(txn.get_signature_validation_trytes().as_trits())

        bundle_hash_trits = [0] * HASH_LENGTH  # type: MutableSequence[int]
        sponge.squeeze(bundle_hash_trits)

        # Copy bundle hash to individual transactions.
        bundle_hash = BundleHash.from_trits(bundle_hash_trits)
        for txn in self:
            txn.bundle_hash = bundle_hash

            # Initialize signature/message fragment.
            txn.signature_message_fragment = Fragment(txn.message or b'')
Exemple #2
0
    def calc_hash(self, bundle):
        Trxn_HASH_Trytes = 81
        HASH_LENGTH = Trxn_HASH_Trytes * 3  # Trits conversion

        # Generate bundle hash. (taken from python API client)
        while True:
            sponge = Kerl()
            last_index = len(bundle) - 1

            for i, txn in enumerate(bundle):
                txn.current_index = i
                txn.last_index = last_index

                sponge.absorb(txn.get_bundle_essence_trits())

            bundle_hash_trits = [0] * HASH_LENGTH
            sponge.squeeze(bundle_hash_trits)

            bundle_hash = BundleHash.from_trits(
                bundle_hash_trits)  # Convert trits to ascii Trytes
            bundle.bundle_hash = bundle_hash
            # Check that we generated a secure bundle hash.
            # https://github.com/iotaledger/iota.py/issues/84
            if any(13 in part for part in normalize(bundle_hash)):
                # Increment the legacy tag and try again.
                bundle.tail_transaction.increment_legacy_tag()
            else:
                break

        # Copy bundle hash to individual transactions.
        for txn in bundle:
            txn.bundle_hash = bundle_hash

            # Initialize signature/message fragment.
            if not txn.value_trxn:
                # Put dummy message in fragment.
                # txn.signature_message_fragment = Fragment('9' * 2187) # Fragment Length
                txn.signature_message_fragment = Fragment(
                    TryteString.from_string(
                        'IOTA is cool! This is a meta transaction!')
                )  # Fragment Length
            else:
                # Generate signature for bundle transaction
                txn.signature_message_fragment = self.genSig(
                    bundleHash=bundle_hash)
                bundle.data_payload = self.name + " (" + str(
                    bundle.outputTrxn.value
                ) + ") ->" + bundle.outputTrxn.recName

        return self.conductPOW(bundle)
Exemple #3
0
    def finalize(self):
        # type: () -> None
        """
    Finalizes the bundle, preparing it to be attached to the Tangle.
    """
        if self.hash:
            raise RuntimeError('Bundle is already finalized.')

        if not self:
            raise ValueError('Bundle has no transactions.')

        # Quick validation.
        balance = self.balance

        if balance < 0:
            if self.change_address:
                self.add_transaction(
                    ProposedTransaction(
                        address=self.change_address,
                        value=-balance,
                        tag=self.tag,
                    ))
            else:
                raise ValueError(
                    'Bundle has unspent inputs (balance: {balance}); '
                    'use ``send_unspent_inputs_to`` to create '
                    'change transaction.'.format(balance=balance, ), )
        elif balance > 0:
            raise ValueError(
                'Inputs are insufficient to cover bundle spend '
                '(balance: {balance}).'.format(balance=balance, ), )

        # Generate bundle hash.
        while True:
            sponge = Kerl()
            last_index = len(self) - 1

            for (i, txn
                 ) in enumerate(self):  # type: Tuple[int, ProposedTransaction]
                txn.current_index = i
                txn.last_index = last_index

                sponge.absorb(txn.get_signature_validation_trytes().as_trits())

            bundle_hash_trits = [0] * HASH_LENGTH  # type: MutableSequence[int]
            sponge.squeeze(bundle_hash_trits)

            bundle_hash = BundleHash.from_trits(bundle_hash_trits)

            # Check that we generated a secure bundle hash.
            # https://github.com/iotaledger/iota.lib.py/issues/84
            if any(13 in part for part in normalize(bundle_hash)):
                # Increment the legacy tag and try again.
                tail_transaction = self.tail_transaction  # type: ProposedTransaction
                tail_transaction.increment_legacy_tag()
            else:
                break

        # Copy bundle hash to individual transactions.
        for txn in self:
            txn.bundle_hash = bundle_hash

            # Initialize signature/message fragment.
            txn.signature_message_fragment = Fragment(txn.message or b'')
Exemple #4
0
    def finalize(self):
        # type: () -> None
        """
        Finalizes the bundle, preparing it to be attached to the Tangle.

        This operation includes checking if the bundle has zero balance,
        generating the bundle hash and updating the transactions with it,
        furthermore to initialize signature/message fragment fields.

        Once this method is invoked, no new transactions may be added to the
        bundle.

        :raises RuntimeError: if bundle is already finalized.
        :raises ValueError:
            - if bundle has no transactions.
            - if bundle has unspent inputs (there is no ``change_address``
              attribute specified.)
            - if inputs are insufficient to cover bundle spend.
        """
        if self.hash:
            raise RuntimeError('Bundle is already finalized.')

        if not self:
            raise ValueError('Bundle has no transactions.')

        # Quick validation.
        balance = self.balance

        if balance < 0:
            if self.change_address:
                self.add_transaction(
                    ProposedTransaction(
                        address=self.change_address,
                        value=-balance,
                        tag=self.tag,
                    ))
            else:
                raise ValueError(
                    'Bundle has unspent inputs (balance: {balance}); '
                    'use ``send_unspent_inputs_to`` to create '
                    'change transaction.'.format(balance=balance, ), )
        elif balance > 0:
            raise ValueError(
                'Inputs are insufficient to cover bundle spend '
                '(balance: {balance}).'.format(balance=balance, ), )

        # Generate bundle hash.
        while True:
            sponge = Kerl()
            last_index = len(self) - 1

            for i, txn in enumerate(self):
                txn.current_index = i
                txn.last_index = last_index

                sponge.absorb(txn.get_signature_validation_trytes().as_trits())

            bundle_hash_trits = [0] * HASH_LENGTH
            sponge.squeeze(bundle_hash_trits)

            bundle_hash = BundleHash.from_trits(bundle_hash_trits)

            # Check that we generated a secure bundle hash.
            # https://github.com/iotaledger/iota.py/issues/84
            if any(13 in part for part in normalize(bundle_hash)):
                # Increment the legacy tag and try again.
                tail_transaction = (self.tail_transaction
                                    )  # type: ProposedTransaction
                tail_transaction.increment_legacy_tag()
            else:
                break

        # Copy bundle hash to individual transactions.
        for txn in self:
            txn.bundle_hash = bundle_hash

            # Initialize signature/message fragment.
            txn.signature_message_fragment = Fragment(txn.message or b'')
Exemple #5
0
  def finalize(self):
    # type: () -> None
    """
    Finalizes the bundle, preparing it to be attached to the Tangle.
    """
    if self.hash:
      raise RuntimeError('Bundle is already finalized.')

    if not self:
      raise ValueError('Bundle has no transactions.')

    # Quick validation.
    balance = self.balance

    if balance < 0:
      if self.change_address:
        self.add_transaction(ProposedTransaction(
          address = self.change_address,
          value   = -balance,
          tag     = self.tag,
        ))
      else:
        raise ValueError(
          'Bundle has unspent inputs (balance: {balance}); '
          'use ``send_unspent_inputs_to`` to create '
          'change transaction.'.format(
            balance = balance,
          ),
        )
    elif balance > 0:
      raise ValueError(
        'Inputs are insufficient to cover bundle spend '
        '(balance: {balance}).'.format(
          balance = balance,
        ),
      )

    # Generate bundle hash.
    while True:
      sponge      = Kerl()
      last_index  = len(self) - 1

      for (i, txn) in enumerate(self): # type: Tuple[int, ProposedTransaction]
        txn.current_index = i
        txn.last_index    = last_index

        sponge.absorb(txn.get_signature_validation_trytes().as_trits())

      bundle_hash_trits = [0] * HASH_LENGTH # type: MutableSequence[int]
      sponge.squeeze(bundle_hash_trits)

      bundle_hash = BundleHash.from_trits(bundle_hash_trits)

      # Check that we generated a secure bundle hash.
      # https://github.com/iotaledger/iota.lib.py/issues/84
      if any(13 in part for part in normalize(bundle_hash)):
        # Increment the legacy tag and try again.
        tail_transaction = self.tail_transaction # type: ProposedTransaction
        tail_transaction.increment_legacy_tag()
      else:
        break

    # Copy bundle hash to individual transactions.
    for txn in self:
      txn.bundle_hash = bundle_hash

      # Initialize signature/message fragment.
      txn.signature_message_fragment = Fragment(txn.message or b'')