コード例 #1
0
ファイル: car.py プロジェクト: ShawnXiao105/iotanet
def get_transfers(full_history, print_history=True):
    account_history_executing = True
    api = Iota(iota_node, seed)
    address_count = len(address_data)
    all_txn_hashes = []
    saved_txn_hashes = []
    new_txn_hashes = []
    i = 0

    while i < address_count:
        address = address_data[i]["address"]
        address_as_bytes = [bytes(address)]
        raw_transfers = api.find_transactions(addresses=address_as_bytes)
        transactions_to_check = raw_transfers["hashes"]

        for txn_hash in transactions_to_check:
            txn_hash = str(txn_hash)
            all_txn_hashes.append(txn_hash)
        i += 1

    for txn_hash in transfers_data:
        txn_hash = str(txn_hash['transaction_hash'])
        saved_txn_hashes.append(txn_hash)

    for txn_hash in all_txn_hashes:
        if txn_hash not in saved_txn_hashes:
            new_txn_hashes.append(txn_hash)

    if len(new_txn_hashes) > 0:
        print("Retreaving and saving transfer data from " +
              str(len(new_txn_hashes)) + " transaction(s)!\n"
              "Please wait...\n")
        for txn_hash in new_txn_hashes:
            txn_hash_as_bytes = bytes(txn_hash)
            li_result = api.get_latest_inclusion([
                txn_hash_as_bytes
            ])  # Needs to be integrated into new transactions as well
            is_confirmed = li_result['states'][txn_hash]
            print(li_result)

            gt_result = api.get_trytes([txn_hash_as_bytes])
            trytes = str(gt_result['trytes'][0])
            txn = Transaction.from_tryte_string(trytes)
            timestamp = str(txn.timestamp)
            tag = str(txn.tag)
            address = str(txn.address)
            message = "some message"  # Placeholder untill message decoding is added
            value = str(txn.value)
            bundle = str(txn.bundle_hash)

            write_transfers_data(txn_hash, is_confirmed, timestamp, tag,
                                 address, message, value, bundle)

    if full_history:
        print_transaction_history(full_history, print_history)

    elif not full_history:
        print_transaction_history(full_history, print_history)
コード例 #2
0
    def test_wireup(self):
        """
    Verify that the command is wired up correctly.

    The API method indeed calls the appropiate command.
    """
        with patch(
                'iota.commands.extended.get_latest_inclusion.GetLatestInclusionCommand.__call__',
                MagicMock(return_value='You found me!')) as mocked_command:

            api = Iota(self.adapter)

            # Don't need to call with proper args here.
            response = api.get_latest_inclusion('hashes')

            self.assertTrue(mocked_command.called)

            self.assertEqual(response, 'You found me!')
コード例 #3
0
class MyIOTA:
    def __init__(self, node, seed):
        self.node = node
        self.seed = seed
        self.api = False
        self._update = False
        self.transfers = []
        self._debug = False

        self.wallet = self.get_filename()

        self.addr_dict = {}

        self.min_weight_magnitude = 14

        self.api = Iota(self.node, self.seed)

        self.USED = True
        self.NOT_USED = False

    def Address(self, addr_string):
        return Address(addr_string)

    def get_addr_dict(self):
        return self.addr_dict

    def set_addr_dict(self, addr, value, used):
        self.addr_dict[addr] = (value, used)

    def s_addr(self, addr, n=3):
        s_addr = str(addr)
        l = len(s_addr)

        return s_addr[:n] + '...' + s_addr[l - n:]

    def get_filename(self):
        h = hashlib.sha256()
        h.update(self.seed)
        filename = h.hexdigest()[:20] + '.txt'

        return filename

    def init_wallet(self):
        filename = self.wallet

        # file exists
        if os.path.isfile(filename):
            filefd = open(filename, 'r+')

            self.debug(
                'Wallet file {0} exists. Opening it...'.format(filename))

            for line in filefd:
                line = line.rstrip('\n')

                addr, index, value, used = line.split(',')

                self.debug('reading from file: {0},{1},{2}'.format(
                    self.s_addr(addr, 3), value, used))

                used = used == 'True'

                addr = Address(addr, key_index=int(index), security_level=2)
                self.addr_dict[addr] = (int(index), int(value), used)

            filefd.close()
        else:
            filefd = open(filename, 'w')
            self.debug('Wallet file {0} doesnt exist. Creating it...'.format(
                filename))
            filefd.close()

    def is_empty_wallet(self):
        return len(self.addr_dict) == 0

    def get_fund_inputs(self, inputs):
        total_fund = 0

        for addr in inputs:
            index, value, used = self.addr_dict[addr]

            # TODO: abs. is this right?
            total_fund += abs(value)

        return total_fund

    def write_updates(self):
        filefd = open(self.wallet, 'w')

        self.debug('Writing (updating) wallet...')

        for addr in self.addr_dict:
            v = self.addr_dict[addr]

            line = 'Writing: {0},{1},{2},{3}\n'.format(self.s_addr(addr), v[0],
                                                       v[1], v[2])
            self.debug(line)

            filefd.write('{0},{1},{2},{3}\n'.format(addr, v[0], v[1], v[2]))

        filefd.close()

    def update_wallet(self, input_fund, inputs, change_addr):
        copy_dict = self.addr_dict.copy()

        for addr in inputs:
            v = self.addr_dict[addr]
            #self.debug('Spending {0} from input {1}'.format(self.s_addr(addr), v))

            # Negative fund and used address
            new_value = (v[0], -v[1], not v[2])

            self.debug('Updating input address {0} to: {1}'.format(
                self.s_addr(addr), new_value))

            self.addr_dict[addr] = new_value

        change_fund = self.get_fund_inputs(inputs) - input_fund

        v = self.addr_dict[change_addr]
        change_value = (v[0], change_fund, self.NOT_USED)

        self.debug('Updating change address {0} to: {1}'.format(
            self.s_addr(change_addr), change_value))

        self.addr_dict[change_addr] = change_value

        self.write_updates()

    def enable_debug(self):
        self._debug = True

    def debug(self, msg):
        if self._debug:
            print '[+] Debug: ', msg

    def get_node_info(self):
        return self.api.get_node_info()

    def make_addr_list(self, start_index, n):
        self.iota_assert(start_index >= 0 and n > 0,
                         'must be positive numbers. N should be at least 1.')

        result = self.api.get_new_addresses(index=start_index, count=n)
        addresses = result['addresses']

        for i in range(n):
            addr = addresses[i]
            value = self.get_addr_balance(addr)

            # TODO: Why always False
            self.addr_dict[addr] = (i, value, False)

        self.write_updates()

    def get_addr_balance(self, addr):
        # TODO: addr is a list with just one element
        result = self.api.get_balances([addr])

        balance = result['balances']

        return (balance[0])

    def prepare_transfer(self,
                         transfer_value,
                         dest_addr,
                         tag='DEFAULT',
                         msg='DEFAULT'):
        # TODO: verify address (checksum)
        # TODO: use mi, gi, etc

        msg = TryteString.from_string(msg)

        txn = ProposedTransaction(
            address=Address(dest_addr),
            message=msg,
            tag=Tag(tag),
            value=transfer_value,
        )

        return txn

    def find_transactions(self):
        addr_list = []
        for e in self.addr_dict.items():
            addr = e[0]

            addr_list.append(addr)

        return self.api.findTransactions(addresses=addr_list)['hashes']

    def get_bundle(self, trans):
        return self.api.getBundles(transaction=trans)

    def get_latest_inclusion(self, addrl):
        return self.api.get_latest_inclusion(hashes=addrl)

    def get_total_fund(self):
        total_fund = 0

        for addr in self.addr_dict.items():
            # key and value from dict
            k, v = addr

            index, value, used = v

            #if not used:
            total_fund += value

        return total_fund

    def get_number_of_address(self):
        return len(self.addr_dict)

    def is_all_addr_used(self):
        for addr in self.addr_dict:
            for e in self.addr_dict.items():
                addr, v = e
                index, value, used = v

                if used == False:
                    return True

    def get_more_addr(self, n=10):
        start_index = self.get_number_of_address()

        self.debug('Getting more addresses...please wait...')

        self.make_addr_list(start_index, n)

    def send_transfer(self,
                      input_fund,
                      inputs,
                      outputs,
                      change_addr,
                      savetofile=True):
        # TODO: How to send MANY transactions.
        self.debug('Sending {0} transactions, please wait...'.format(
            len(outputs)))

        self.api.send_transfer(inputs=inputs,
                               transfers=outputs,
                               depth=7,
                               change_address=change_addr,
                               min_weight_magnitude=self.min_weight_magnitude)

        self.debug('Sent.')
        if self.is_all_addr_used():
            # We do an update to wallet file here.
            self.get_more_addr(n=10)

        if savetofile:
            self.update_wallet(input_fund, inputs, change_addr)

    def get_bundles(self, hasht):
        return self.api.get_bundles(hasht)

    def get_trytes(self, hashl):
        return self.api.get_trytes(hashl)['trytes'][0]

    def get_transaction_from_trytes(self, trytes):
        txn = Transaction.from_tryte_string(trytes)

        return txn

    def get_transaction_fields(self, txn):
        #confirmed = str(txn.is_confirmed)
        timestamp = str(txn.timestamp)
        address = str(txn.address)
        value = str(txn.value)
        message = str(txn.signature_message_fragment)
        #message   = str(txn.message)
        tag = str(txn.tag)

        return (timestamp, address, value, tag, message)

    def get_info_transactions(self, transactions_hashes):
        txn_tuples = []

        for h in transactions_hashes:
            trytes = self.get_trytes([h])
            txn = self.get_transaction_from_trytes(trytes)

            # Get confirmed flag
            li_result = self.get_latest_inclusion([bytes(h)])
            confirmed_t = li_result['states'][h]

            (_, addr_t, value_t, tag_t,
             msg_t) = self.get_transaction_fields(txn)

            txn_tuples.append((confirmed_t, addr_t, value_t, tag_t, msg_t))

        return txn_tuples

    def get_any_valid_addr(self):
        #TODO: verify
        #return self.addr_dict.keys()[0]

        for e in self.addr_dict.items():
            addr, v = e
            index, value, used = v

            if not used:
                return addr

        return None

    def get_inputs(self, fund):
        # TODO: Zero fund
        fund_sum = 0
        addr_list = []
        change_addr = None

        # Zero fund transactions. We return any addr and any change_addr
        if fund == 0:
            # TODO: What if it conflicts with one another?
            addr_list.append(self.get_any_valid_addr())
            change_addr = self.get_any_valid_addr()

            return (addr_list, change_addr)

        for e in self.addr_dict.items():
            addr, v = e
            index, value, used = v

            if fund_sum < fund:
                #if value > 0 and not used:
                if value > 0 and used == self.NOT_USED:
                    fund_sum += value
                    self.debug(
                        'Found request: {0}. Found address {1} with fund {2}.'.
                        format(fund, self.s_addr(addr), value))
                    addr_list.append(addr)

        for e in self.addr_dict.items():
            addr, v = e
            index, value, used = v

            if used == self.NOT_USED and addr not in addr_list:
                change_addr = addr

                self.debug('Using {0} as change addr.'.format(
                    self.s_addr(addr)))
                break
        return (addr_list, change_addr)

        #else:
        #    # TODO
        #    self.iota_assert(True, 'No change addr available.')

    def iota_assert(self, condition, msg):
        if not condition:
            print 'Error: ', msg
            sys.exit(-1)
コード例 #4
0
class Wallet:
    """docstring for Wallet"""
    def __init__(self, uri: str, seed: Optional[str] = None) -> None:
        self._iota_api = Iota(uri, seed)
        self._account: _Account

    @property
    def account(self) -> _Account:
        try:
            return self._account
        except AttributeError:
            # We get an attibute error if we check this property before ever
            # calling refresh_account.
            self.refresh_account()
            return self._account

    @property
    def addresses(self) -> List[Address]:
        return self.account.addresses

    @property
    def balance(self) -> int:
        return self.account.balance

    @property
    def bundles(self) -> Dict[str, Iterable[Bundle]]:
        return {
            'confirmed': self.account.confirmed_bundles,
            'unconfirmed': self.account.unconfirmed_bundles,
            'duplicate': self.account.duplicate_bundles,
        }

    def _is_above_max_depth(self, transaction: Transaction) -> bool:
        current_millis = time.time() * 1000
        max_age = 11 * 60 * 1000  # 11 minutes
        diff = current_millis - cast(float, transaction.attachment_timestamp)
        return (0 < diff < max_age)

    def _is_promotable(self, bundle: Bundle) -> bool:
        return (self._is_above_max_depth(bundle.tail_transaction)
                and self._iota_api.helpers.is_promotable(
                    bundle.tail_transaction.hash))

    def _promote(self, bundle: Bundle) -> Bundle:
        tail_hash = bundle.tail_transaction.hash
        response = self._iota_api.get_latest_inclusion([tail_hash])
        if response['states'][tail_hash]:
            raise BundleAlreadyPromoted()

        response = self._iota_api.promote_transaction(transaction=tail_hash,
                                                      depth=DEPTH)
        return response['bundle']

    def _reattach(self, bundle: Bundle) -> Bundle:
        response = self._iota_api.replay_bundle(
            bundle.tail_transaction.hash,
            DEPTH,
        )
        return Bundle.from_tryte_strings(response['trytes'])

    def create_new_address(self) -> Address:
        response = self._iota_api.get_new_addresses(count=None)
        address = response['addresses'][0]

        # Attach the address
        self._iota_api.send_transfer(
            depth=DEPTH,
            transfers=[ProposedTransaction(address, value=0)],
        )

        return address

    def refresh_account(self) -> None:
        response = self._iota_api.get_account_data(inclusion_states=True)
        addresses = response['addresses']
        balance = response['balance']
        bundles = response['bundles']

        self._account = _Account(addresses, balance, bundles)

    def retry_unconfirmed_bundles(self, *bundles: Bundle) -> None:
        if len(bundles) == 0:
            bundles = tuple(self.bundles['unconfirmed'])
        for bundle in bundles:
            print(f'Retrying bundle: {bundle.hash}')
            if not self._is_promotable(bundle):
                bundle = self._reattach(bundle)
                while True:
                    time.sleep(2)
                    if self._is_promotable(bundle):
                        break
            for attempt in range(5):
                try:
                    promote_bundle = self._promote(bundle)
                except BundleAlreadyPromoted:
                    break
                else:
                    print(
                        f'Promotion attempt ({attempt}): Bundle {promote_bundle.hash}'
                    )

    def send(self, address: str, value: int) -> None:
        print(f'Sending {value} iota to {address}...')
        response = self._iota_api.send_transfer(
            depth=DEPTH,
            transfers=[ProposedTransaction(Address(address), value=value)])
        bundle = response['bundle']
        print(f'Iota sent! Bundle hash: {bundle.hash}')
コード例 #5
0
ファイル: model.py プロジェクト: averdier/py_iota_client
    def get_transfers(self, full_history, print_history=False):
        """
        Gets all associated transactions from the saved addresses and saves the transaction data in the account file

        :param full_history:
        :param print_history:
        :return:
        """
        self._account_history_executing = True
        api = Iota(self.iota_node, self._seed)
        address_count = len(self._data['account_data'][0]['address_data'])
        my_all_txn_hashes = {}
        all_txn_hashes = []
        saved_txn_hashes = []
        new_txn_hashes = []
        i = 0

        while i < address_count:
            address = self._data['account_data'][0]['address_data'][i][
                "address"]
            address_as_bytes = [address]
            raw_transfers = api.find_transactions(addresses=address_as_bytes)
            transactions_to_check = raw_transfers["hashes"]

            for txn_hash in transactions_to_check:
                str_txn_hash = str(txn_hash)
                all_txn_hashes.append(str_txn_hash)
                my_all_txn_hashes[str_txn_hash] = txn_hash
            i += 1

        for txn_hash in self._data['account_data'][0]['transfers_data']:
            txn_hash = str(txn_hash['transaction_hash'])
            saved_txn_hashes.append(txn_hash)

        for th in my_all_txn_hashes:
            if th not in saved_txn_hashes:
                new_txn_hashes.append(my_all_txn_hashes[th])

        if len(new_txn_hashes) > 0:
            self._logger.info("Retrieving and saving transfer data from " +
                              str(len(new_txn_hashes)) +
                              " transaction(s)! Please wait...")
            for txn_hash in new_txn_hashes:
                li_result = api.get_latest_inclusion([
                    txn_hash
                ])  # Needs to be integrated into new transactions as well
                is_confirmed = li_result['states'][txn_hash]

                gt_result = api.get_trytes([txn_hash])
                trytes = str(gt_result['trytes'][0])
                txn = Transaction.from_tryte_string(trytes)
                timestamp = str(txn.timestamp)
                tag = str(txn.tag)
                address = str(txn.address)
                message = "some message"  # Placeholder untill message decoding is added
                value = str(txn.value)
                bundle = str(txn.bundle_hash)

                self._write_transfers_data(str(txn_hash), is_confirmed,
                                           timestamp, tag, address, message,
                                           value, bundle)

                self.on_new_transaction_received(txn, is_confirmed)

        if print_history:
            if full_history:
                self.print_full_account_info()

            elif not full_history:
                self.print_standard_account_info()

        self._account_history_executing = False