Beispiel #1
0
 def invoke(firstarg='0.0.0.0',
            sport='8787',
            upnp_str=None,
            addr_str=None):
     bindhost, *extrahosts = firstarg.split(',')
     if len(extrahosts) > 1:
         raise Exception("too many hosts")
     elif len(extrahosts) == 1:
         [
             announcehost,
         ] = extrahosts
     else:
         announcehost = None
     port = int(sport)
     pnp = get_upnp() if upnp_str == 'upnp' else None
     if not pnp and not addr_str:
         # third arg may be addr_str, so swap the args
         addr_str = upnp_str
         upnp_str = None
     addr = None
     if addr_str:
         assert Address.is_valid(
             addr_str), "Invalid donation address specified"
         addr = Address.from_string(addr_str)
     return self.start_fusion_server(network,
                                     bindhost,
                                     port,
                                     upnp=pnp,
                                     announcehost=announcehost,
                                     donation_address=addr)
Beispiel #2
0
 def donation_address(self, window) -> Optional[Tuple[str, Address]]:
     ''' Plugin API: Returns a tuple of (description, Address) or None. This
     is the donation address that we as a client got from the remote server
     (as opposed to the donation address we announce if we are a server). '''
     if self.remote_donation_address and Address.is_valid(
             self.remote_donation_address):
         return (self.fullname() + " " + _("Server") + ": " +
                 self.get_server()[0],
                 Address.from_string(self.remote_donation_address))
Beispiel #3
0
 def delete_history(self, address: Address) -> None:
     if isinstance(address, str) and Address.is_valid(address):
         address = Address.from_string(address)
     storage = self.parent.wallet.storage if self.parent.wallet else None
     if storage:
         if True:  #with self.lock:
             addrstr = address.to_storage_string()
             k = 'contact_history_%s' % (addrstr)
             storage.put(k, None)
             self.print_error("Deleted %s" % addrstr)
Beispiel #4
0
 def get_history(self, address: Address) -> list:
     ret = list()
     if isinstance(address, str) and Address.is_valid(address):
         address = Address.from_string(address)
     storage = self.parent.wallet.storage if self.parent.wallet else None
     if storage:
         addrstr = address.to_storage_string()
         k = 'contact_history_%s' % (addrstr)
         hdict = storage.get(k)
         if hdict:
             ret = list(hdict.values())
             ret.sort(key=lambda x: x[1], reverse=True)
     return ret
Beispiel #5
0
 def _open_internal_link(self, target):
     ''' accepts either a str txid, str address, or a QUrl which should be
     of the bare form "txid" and/or "address" -- used by the clickable
     links in the inputs/outputs QTextBrowsers'''
     if isinstance(target, QUrl):
         target = target.toString(QUrl.None_)
     assert target
     if Address.is_valid(target):
         # target was an address, open address dialog
         self.main_window.show_address(Address.from_string(target), parent=self)
     else:
         # target was a txid, open new tx dialog
         self.main_window.do_process_from_txid(txid=target, parent=self)
Beispiel #6
0
 def doReloadForKey(self, key: Any) -> Any:
     t0 = time.time()
     hist = list()
     unk = False
     duped = ''
     if isinstance(key, (type(None), list)):
         # the common case, 'None' or [Address]
         hist = get_history(domain=key)
     # contacts entires
     elif isinstance(key, contacts.ContactsEntry):
         hist = get_contact_history(key.address)
     elif isinstance(key, Address):
         # support for list-less single Address.. call self again with the proper format
         hist = self.get([key])
         duped = ' (duped) '
     elif isinstance(key, str):
         # support for string addresses or tx_hashes.. detect which and act accordingly
         if Address.is_valid(key):
             hist = self.get(
                 [Address.from_string(key)]
             )  # recursively call self with propery list data type, which will end up calling get_history (it's ok -- this is to cache results uniformly!)
             duped = ' (duped) '
         elif gui.ElectrumGui.gui.wallet and gui.ElectrumGui.gui.wallet.transactions.get(
                 key, None):
             fullHist = self.get(
                 None
             )  # recursively call self to get a full history (will be cached so it's ok!)
             try:
                 hentry = fullHist.get_by_txid(key)
                 hist.append(hentry)
             except KeyError:
                 pass
         else:
             unk = True
     else:
         unk = True
     dstr = str(key) if not isinstance(
         key, contacts.ContactsEntry
     ) else '[ContactsEntry: ' + key.address_str + ']'
     if unk:
         utils.NSLog(
             "HistoryMgr: failed to retrieve any data for unknown domain=%s, returning empty list",
             dstr[:80])
     else:
         time_taken = time.time() - t0
         utils.NSLog(
             "HistoryMgr: refresh %d entries for domain=%s in %f ms%s (hist result type=%s)",
             len(hist), dstr[:80], time_taken * 1e3, duped,
             ''.join(list(str(type(hist)))[-19:-2]))
         gui.ElectrumGui.gui.refresh_cost('history', time_taken)
     return hist
Beispiel #7
0
    def doConversion_(self, text) -> bool:
        self.cash.text = ""
        self.legacy.text = ""
        self.cpyCashBut.enabled = False
        self.cpyLegBut.enabled = False
        self.qrButShowCash.enabled = False
        self.qrButShowLegacy.enabled = False
        text = text.strip()

        addy = None

        try:
            addy = Address.from_string(text)
        except:
            pass

        if addy:
            self.cash.text = addy.to_full_string(Address.FMT_CASHADDR)
            self.legacy.text = addy.to_full_string(Address.FMT_LEGACY)
            self.cpyCashBut.enabled = True
            self.cpyLegBut.enabled = True
            self.qrButShowCash.enabled = True
            self.qrButShowLegacy.enabled = True

            return True
        return False
    def doVerify(self) -> None:
        addrtf = self.tf
        address_str = str(addrtf.text).strip()
        message = str(self.topTvDel.text)
        signature = str(self.botTvDel.text).strip()

        if not signature:
            parent().show_message(
                _("Please provide both a signature and a message to verify"))
            return

        try:
            address = Address.from_string(address_str)
        except:
            parent().show_error(_('Invalid Ergon address.'))
            return
        message = message.encode('utf-8')
        try:
            # This can raise on invalid base64
            sig = base64.b64decode(signature)
            verified = bitcoin.verify_message(
                address, sig, message)  # this raises too on failure
        except:
            verified = False

        if verified:
            parent().show_message(_("Signature verified"), title=_("Success"))
        else:
            parent().show_error(_("Wrong signature"))
Beispiel #9
0
    def on_edited(self, item, column, prior_value):
        contact = item.data(0, self.DataRoles.Contact)
        if column == 2:  # Label
            label_key = contact.address
            try:
                label_key = Address.from_string(label_key).to_storage_string()
            except:
                pass
            self.wallet.set_label(label_key, item.text(2))
            self.update(
            )  # force refresh in case 2 contacts use the same address
            return
        # else.. Name
        typ = contact.type
        was_cur, was_sel = bool(self.currentItem()), item.isSelected()
        name, value = item.text(1), item.text(3)
        del item  # paranoia

        # On success, parent.set_contact returns the new key (address text)
        # if 'cashacct'.. or always the same key for all other types.
        key = self.parent.set_contact(name, value, typ=typ, replace=contact)

        if key:
            # Due to deferred updates, on_update will actually be called later.
            # So, we have to save the edited item's "current" and "selected"
            # status here. 'on_update' will look at this tuple and clear it
            # after updating.
            self._edited_item_cur_sel = (key, was_cur, was_sel)
Beispiel #10
0
 def make_unsigned_transaction(self, amount, fee, all_inputs, outputs,
                               changes):
     ''' make unsigned transaction '''
     dust = self.dust_threshold(
     )  # always 546 for now, but this call is here in case something more sophisticated happens in the future
     coins = {}
     tx_inputs = []
     amounts = {}
     try:
         for player in all_inputs:
             inputs_coins = self.get_coins(all_inputs[player])
             # if there are no coins on input it terminates the process
             if inputs_coins:
                 coins[player] = inputs_coins
             else:
                 return None
     except BaseException as e:
         self.print_error('make_unsigned_transaction:', repr(e))
         return None
     for player, pubkey_utxos in coins.items():
         amounts[player] = 0
         for pubkey, utxos in pubkey_utxos.items():
             for utxo in utxos:
                 utxo['type'] = 'p2pkh'
                 utxo['address'] = Address.from_pubkey(pubkey)
                 utxo['pubkeys'] = [pubkey]
                 utxo['x_pubkeys'] = [pubkey]
                 utxo['prevout_hash'] = utxo['tx_hash']
                 utxo['prevout_n'] = utxo['tx_pos']
                 utxo['signatures'] = [None]
                 utxo['num_sig'] = 1
                 tx_inputs.append(utxo)
                 amounts[player] += utxo['value']
     tx_inputs.sort(key=lambda x: x['prevout_hash'] + str(x["tx_pos"]))
     tx_outputs = [(TYPE_ADDRESS, Address.from_string(output), int(amount))
                   for output in outputs]
     transaction = Transaction.from_io(tx_inputs,
                                       tx_outputs,
                                       sign_schnorr=False)
     tx_changes = [
         (TYPE_ADDRESS, Address.from_string(changes[player]),
          int(amounts[player] - amount - fee)) for player in sorted(changes)
         if Address.is_valid(changes[player]) and int(amounts[player] -
                                                      amount - fee) >= dust
     ]
     transaction.add_outputs(tx_changes)
     return transaction
Beispiel #11
0
 def view_addr_link_activated(addr):
     if isinstance(parent, ElectrumWindow):
         try:
             address = Address.from_string(addr)
             parent.show_address(address,
                                 parent=parent.top_level_window())
         except Exception as e:
             parent.print_error(repr(e))
Beispiel #12
0
def decodeAddress(addr: str) -> Address:
    ret = None
    if addr:
        try:
            # re-encode addr in case they went to/from cashaddr
            ret = Address.from_string(addr)
        except BaseException as e:
            utils.NSLog("Caught exception decoding address %s: %s", addr,
                        str(e))
    return ret
Beispiel #13
0
 def open_link(link):
     if Address.is_valid(link):
         addr = Address.from_string(link)
         if wallet.is_mine(addr):
             parent.show_address(addr)
         else:
             addr_URL = web.BE_URL(parent.config, 'addr', addr)
             if addr_URL:
                 webopen(addr_URL)
         return
     if link.startswith('http'):
         webopen(link)
     elif len(link) == 64:  # 64 character txid
         tx = wallet.transactions.get(link)
         if tx:
             parent.show_transaction(tx, tx_desc=wallet.get_label(link))
         else:
             parent.do_process_from_txid(txid=link,
                                         tx_desc=wallet.get_label(link))
         return
Beispiel #14
0
 def getaddressunspent(self, address):
     """Returns the UTXO list of any address. Note: This
     is a walletless server query, results are not checked by SPV.
     """
     if not isinstance(address, Address):
         try:
             address = Address.from_string(address)
         except AddressError:
             return None
     sh = address.to_scripthash_hex()
     return self.network.synchronous_get(
         ('blockchain.scripthash.listunspent', [sh]))
Beispiel #15
0
 def get_full_contacts(self, include_pseudo: bool = True) -> List[Contact]:
     ''' Returns all the contacts, with the "My CashAcct" pseudo-contacts
     clobbering dupes of the same type that were manually added.
     Client code should scan for type == 'cashacct' and type == 'cashacct_W' '''
     if include_pseudo:
         # filter out cachaccts that are "Wallet", as they will be added
         # at the end as pseudo contacts if they also appear in real contacts
         real_contacts = [
             contact
             for contact in self.parent.contacts.get_all(nocopy=True)
             if contact.type !=
             'cashacct'  # accept anything that's not cashacct
             or not Address.is_valid(
                 contact.address
             )  # or if it is, it can have invalid address as it's clearly 'not mine"
             or not self.wallet.is_mine(  # or if it's not mine
                 Address.from_string(contact.address))
         ]
         return real_contacts + self._make_wallet_cashacct_pseudo_contacts()
     else:
         return self.parent.contacts.get_all(nocopy=True)
Beispiel #16
0
    def check_inputs_for_sufficient_funds_and_return_total(
            self, inputs, amount):
        """
        This function check on blockchain for sufficient funds.

        inputs is a dict with bitcoin pubkeys as a keys
        and list of utxo hashes as values.

        the sum of all utxo values should be greater then amount

        it does as follows:
        1. check utxo list for every pubkey in the dict
        2. check if utxo from inputs are in the utxo list on blockchain for these pubkeys
            2.a return None if there is a utxo from list not in utxo set from blockchain
            2.b return None if utxo in list is not confirmed
        3. return True, total_amt if summary values of utxos are greater then amount and False, None otherwise
           returns None,None on blockchain communication error
        """
        assert amount > 0, "Amount must be > 0!"

        def _utxo_name(x):
            return x['tx_hash'] + ":" + str(x['tx_pos'])

        total = 0
        try:
            for public_key, pk_inputs in inputs.items():
                try:
                    address = Address.from_pubkey(public_key)
                except AddressError:
                    # refuse to accept something that doesn't parse as a pubkey
                    return False, None
                unspent_list = self.getaddressunspent(address)
                utxos = {
                    _utxo_name(utxo): utxo['value']
                    for utxo in unspent_list if utxo.get('height', -1) >
                    0  # all inputs must have at least 1 confirmation
                }
                for utxo in pk_inputs:
                    val = utxos.get(utxo)
                    if val is None:
                        return False, None  # utxo does not exist or was spent
                    total += val
            answer = total >= amount
            if answer:
                return True, total
            return False, total

        except BaseException as e:
            #import traceback
            #traceback.print_exc()
            self.print_error("check_inputs_for_sufficient_funds: ", repr(e))
        return None, None
Beispiel #17
0
 def load_shuffle_change_shared_with_others(wallet):
     ''' Modifies wallet instance and adds _shuffle_change_shared_with_others
     retrieving it from storage. _shuffle_patched_ need not be set. '''
     wallet._shuffle_change_shared_with_others = set()
     tmpadrs = wallet.storage.get(
         ConfKeys.PerWallet.CHANGE_SHARED_WITH_OTHERS, [])
     if isinstance(tmpadrs, (list, tuple, set)):
         for a in tmpadrs:
             try:
                 a = Address.from_string(a)
                 if not wallet.get_address_history(
                         a
                 ):  # no need to re-add to set if it has a history since it won't be shared anyway with the network if it's been used. This set is used only to not cross over shuffled out addresses with change addresses for unused addrs when shuffling
                     wallet._shuffle_change_shared_with_others.add(a)
             except (AddressError, TypeError):
                 pass
Beispiel #18
0
def tx_from_components(all_components, session_hash):
    """ Returns the tx and a list of indices matching inputs with components"""
    input_indices = []
    assert len(session_hash) == 32
    if Protocol.FUSE_ID is None:
        prefix = []
    else:
        assert len(Protocol.FUSE_ID) == 4
        prefix = [4, *Protocol.FUSE_ID]
    inputs = []
    outputs = [
        (TYPE_SCRIPT,
         ScriptOutput(bytes([OpCodes.OP_RETURN, *prefix, 32]) + session_hash),
         0)
    ]
    for i, compser in enumerate(all_components):
        comp = pb.Component()
        comp.ParseFromString(compser)
        ctype = comp.WhichOneof('component')
        if ctype == 'input':
            inp = comp.input
            if len(inp.prev_txid) != 32:
                raise FusionError("bad component prevout")
            inputs.append(
                dict(address=Address.from_P2PKH_hash(hash160(inp.pubkey)),
                     prevout_hash=inp.prev_txid[::-1].hex(),
                     prevout_n=inp.prev_index,
                     num_sig=1,
                     signatures=[None],
                     type='p2pkh',
                     x_pubkeys=[inp.pubkey.hex()],
                     pubkeys=[inp.pubkey.hex()],
                     sequence=0xffffffff,
                     value=inp.amount))
            input_indices.append(i)
        elif ctype == 'output':
            out = comp.output
            atype, addr = get_address_from_output_script(out.scriptpubkey)
            if atype != TYPE_ADDRESS:
                raise FusionError("bad component address")
            outputs.append((TYPE_ADDRESS, addr, out.amount))
        elif ctype != 'blank':
            raise FusionError("bad component")
    tx = Transaction.from_io(inputs, outputs, locktime=0, sign_schnorr=True)
    tx.version = 1
    return tx, input_indices
Beispiel #19
0
    def _make_wallet_cashacct_pseudo_contacts(self,
                                              exclude_contacts=[]
                                              ) -> List[Contact]:
        ''' Returns a list of 'fake' contacts that come from the wallet's
        own registered Cash Accounts.  These contacts do not exist in the
        wallet.contacts object but are created on-the-fly from the
        wallet.cashacct list of registered & verified Cash Accounts.

        The creation of this list is relatively cheap and scales as the lookups
        are O(logN) in the cashaccts caches.

        This is a convenience so that the Contacts tab shows "my" cash accounts
        after registration as well as external Cash Accounts. Note that the
        "mine" entries won't be shown if the user explicitly added his own as
        "external"... '''
        try:
            excl_chk = set((c.name, Address.from_string(c.address))
                           for c in exclude_contacts if c.type == 'cashacct')
        except:
            # Hmm.. invalid address?
            excl_chk = set()
        wallet_cashaccts = []
        v_txids = set()
        # Add the [Mine] pseudo-contacts
        for ca_info in self.wallet.cashacct.get_wallet_cashaccounts():
            v_txids.add(ca_info.txid)
            name = self.wallet.cashacct.fmt_info(ca_info, emoji=False)
            if (name, ca_info.address) in excl_chk:
                continue
            wallet_cashaccts.append(
                Contact(name=name,
                        address=ca_info.address.to_ui_string(),
                        type='cashacct_W'))
        # Add the [Pend] pseudo-contacts
        for txid, tup in self._ca_pending_conf.copy().items():
            if txid in v_txids or self.wallet.cashacct.is_verified(txid):
                self._ca_pending_conf.pop(txid, None)
                continue
            if tup in excl_chk:
                continue
            name, address = tup
            wallet_cashaccts.append(
                Contact(name=name,
                        address=address.to_ui_string(),
                        type='cashacct_T'))
        return wallet_cashaccts
Beispiel #20
0
 def doReloadForKey(self, key: Any) -> Any:
     if key is None:
         a = AddressData(gui.ElectrumGui.gui)
         a.refresh()
         utils.NSLog("AddressMgr refresh (full)")
         return a
     elif key and isinstance(key, (str, Address)):
         if isinstance(key, str):
             key = Address.from_string(key)
         a = self.get(
             None
         )  # recursive call to self to get cached 'all' or rebuild 'all' if not cached
         if a:
             entries = a.master[0][0]
             for entry in entries:
                 if entry.address == key:
                     return entry
     return None
Beispiel #21
0
    def do_send(self):
        if not Address.is_valid(self.str_recipient):
            print(_('Invalid Bitcoin address'))
            return
        try:
            amount = int(PyDecimal(self.str_amount) * COIN)
        except Exception:
            print(_('Invalid Amount'))
            return
        try:
            fee = int(PyDecimal(self.str_fee) * COIN)
        except Exception:
            print(_('Invalid Fee'))
            return

        if self.wallet.has_password():
            password = self.password_dialog()
            if not password:
                return
        else:
            password = None

        c = ""
        while c != "y":
            c = input("ok to send (y/n)?")
            if c == "n": return

        try:
            tx = self.wallet.mktx([(TYPE_ADDRESS, self.str_recipient, amount)],
                                  password, self.config, fee)
        except Exception as e:
            print(str(e))
            return

        if self.str_description:
            self.wallet.labels[tx.txid()] = self.str_description

        print(_("Please wait..."))
        status, msg = self.network.broadcast_transaction(tx)

        if status:
            print(_('Payment sent.'))
        else:
            print(_('Error'))
Beispiel #22
0
 def get_coins(self, inputs):
     coins = {}
     for public_key, utxos in inputs.items():
         address = Address.from_pubkey(public_key)
         coins[public_key] = [
         ]  # FIXME: Should probably use a defaultdict here but maybe we want calling code to fail on KeyError ?
         unspent_list = self.getaddressunspent(address)
         utxo_dicts = {
             "{}:{}".format(utxo["tx_hash"], utxo["tx_pos"]): utxo
             for utxo in unspent_list
         }
         for utxo in utxos:
             utxo_dict = utxo_dicts.get(utxo)
             if utxo_dict:
                 coins[public_key].append(utxo_dict)
             else:
                 # uh-oh.. not found. may have been double-spent in the meantimg or buggy Player peer.
                 return None
     return coins
Beispiel #23
0
    def getUnusedAddress(self) -> None:
        wallet = parent().wallet
        if not wallet: return
        # hide receive tab if no receive requests available
        b = len(wallet.receive_requests) > 0
        #self.setVisible(b)
        #self.parent.receive_requests_label.setVisible(b)
        #if not b:
        #    self.parent.expires_label.hide()
        #    self.parent.expires_combo.show()

        domain = wallet.get_addresses()
        if self.addrStr:
            # update the receive address if necessary
            current_address = Address.from_string(self.addrStr)
            addr = wallet.get_unused_address()
            if not current_address in domain and addr:
                self.setReceiveAddress_(addr.to_ui_string())
                current_address = addr.to_ui_string()
Beispiel #24
0
    def on_update(self):
        self.chkVisible()

        # update the receive address if necessary
        current_address_string = self.parent.receive_address_e.text().strip()
        current_address = Address.from_string(current_address_string) if len(
            current_address_string) else None
        domain = self.wallet.get_receiving_addresses()
        addr = self.wallet.get_unused_address()
        if current_address not in domain and addr:
            self.parent.set_receive_address(addr)

        # clear the list and fill it again
        item = self.currentItem()
        prev_sel = item.data(0, Qt.UserRole) if item else None
        self.clear()
        for req in self.wallet.get_sorted_requests(self.config):
            address = req['address']
            if address not in domain:
                continue
            timestamp = req.get('time', 0)
            amount = req.get('amount')
            expiration = req.get('exp', None)
            message = req.get('memo', '')
            date = format_time(timestamp)
            status = req.get('status')
            signature = req.get('sig')
            requestor = req.get('name', '')
            amount_str = self.parent.format_amount(amount) if amount else ""
            item = QTreeWidgetItem([
                date,
                address.to_ui_string(), '', message, amount_str,
                _(pr_tooltips.get(status, ''))
            ])
            item.setData(0, Qt.UserRole, address)
            if signature is not None:
                item.setIcon(2, QIcon(":icons/seal.svg"))
                item.setToolTip(2, 'signed by ' + requestor)
            if status is not PR_UNKNOWN:
                item.setIcon(6, QIcon(pr_icons.get(status)))
            self.addTopLevelItem(item)
            if prev_sel == address:
                self.setCurrentItem(item)
Beispiel #25
0
    def doSign(self) -> None:
        addrtf = self.tf
        address = str(addrtf.text).strip()
        message = str(self.topTvDel.text)
        signatureTvDel = self.botTvDel
        try:
            print("address = ", address)
            addr = Address.from_string(address)
        except:
            parent().show_error(_('Invalid Ergon address.'))
            return
        if addr.kind != addr.ADDR_P2PKH:
            msg_sign = _("Signing with an address actually means signing with the corresponding "
                        "private key, and verifying with the corresponding public key. The "
                        "address you have entered does not have a unique public key, so these "
                        "operations cannot be performed.") + '\n\n' + \
                       _('The operation is undefined. Not just in Oregano, but in general.')
            parent().show_message(
                _('Cannot sign messages with this type of address.') + '\n\n' +
                msg_sign)
            return
        if not parent().wallet:
            return
        if parent().wallet.is_watching_only():
            parent().show_message(_('This is a watching-only wallet.'))
            return
        if not parent().wallet.is_mine(addr):
            parent().show_message(_('Address not in wallet.'))
            return

        def onPw(password: str) -> None:
            try:
                signed = parent().wallet.sign_message(addr, message, password)
            except:
                parent().show_error(str(sys.exc_info()[1]))
                return
            signatureTvDel.text = base64.b64encode(signed).decode('ascii')
            parent().show_message(_(
                "The signature for the provided message has been pasted into the signature text box."
            ),
                                  title=_("Success"))

        parent().prompt_password_if_needed_asynch(onPw, vc=self)
Beispiel #26
0
 def __init__(self, window, wallet, network_settings,
              period = 10.0, logger = None, password=None, timeout=60.0,
              typ=Messages.DEFAULT  # NB: Only DEFAULT is currently supported
              ):
     super().__init__()
     cls = type(self)
     self.daemon = True
     self.timeout = timeout
     self.version = cls.PROTOCOL_VERSION + (1 if networks.net.TESTNET else 0)
     self.type = typ
     assert self.type == Messages.DEFAULT, "BackgroundShufflingThread currently only supports DEFAULT shuffles"
     cls.latest_shuffle_settings = cls.ShuffleSettings(self.type, Messages.TYPE_NAME_DICT[self.type], self.version, 0, 0, self.FEE)
     # set UPPER_BOUND and LOWER_BOUND from config keys here. Note all instances will see these changes immediately.
     cls.update_lower_and_upper_bound_from_config()
     self.period = period
     self.logger = logger
     self.wallet = wallet
     self.window = window
     self.host = network_settings.get("host", None)
     self.info_port = network_settings.get("info", None)
     self.port = 1337  # default value -- will get set to real value from server's stat port in run() method
     self.poolSize = 3  # default value -- will get set to real value from server's stat port in run() method
     self.banScore = 0  # comes from stats port -- our own personal ban score
     self.banned = False  # comes from stats port. True if our IP is banned (default ban duration: 30 mins)
     self.ssl = network_settings.get("ssl", None)
     self.lock = threading.RLock()
     self.password = password
     self.threads = {scale:None for scale in self.scales}
     self.shared_chan = Channel(switch_timeout=None)  # threads write a 3-tuple here: (killme_flg, thr, msg)
     self.stop_flg = threading.Event()
     self.last_idle_check = 0.0  # timestamp in seconds unix time
     self.done_utxos = dict()
     self._paused = False
     self._coins_busy_shuffling = set()  # 'prevout_hash:n' (name) set of all coins that are currently being shuffled by a ProtocolThread. Both wallet locks should be held to read/write this.
     self._last_server_check = 0.0  # timestamp in seconds unix time
     self._dummy_address = Address.from_pubkey(EC_KEY(number_to_string(1337, generator_secp256k1.order())).get_public_key())  # dummy address
     # below 4 vars are related to the "delayed unreserve address" mechanism as part of the bug #70 & #97 workaround and the complexity created by it..
     self._delayed_unreserve_addresses = dict()  # dict of Address -> time.time() timestamp when its shuffle ended
     self._last_delayed_unreserve_check = 0.0  # timestamp in seconds unix time
     self._delayed_unreserve_check_interval = 60.0  # check these addresses every 60 seconds.
     self._delayed_unreserve_timeout = 600.0  # how long before the delayed-unreserve addresses expire; 10 minutes
Beispiel #27
0
def check_input_electrumx(network, inpcomp):
    """ Check an InputComponent against electrumx service. This can be a bit slow
    since it gets all utxos on that address.

    Returns normally if the check passed. Raises ValidationError if the input is not
    consistent with blockchain (according to server), and raises other exceptions if
    the server times out or gives an unexpected kind of response.
    """
    address = Address.from_pubkey(inpcomp.pubkey)
    prevhash = inpcomp.prev_txid[::-1].hex()
    prevn = inpcomp.prev_index
    sh = address.to_scripthash_hex()
    u = network.synchronous_get(('blockchain.scripthash.listunspent', [sh]), timeout=5)
    for item in u:
        if prevhash == item['tx_hash'] and prevn == item['tx_pos']:
            break
    else:
        raise ValidationError('missing or spent or scriptpubkey mismatch')

    check(item['height'] > 0, 'not confirmed')
    check(item['value'] == inpcomp.amount, 'amount mismatch')
Beispiel #28
0
    def do_send(self):
        if not Address.is_valid(self.str_recipient):
            self.show_message(_('Invalid Bitcoin address'))
            return
        try:
            amount = int(PyDecimal(self.str_amount) * COIN)
        except Exception:
            self.show_message(_('Invalid Amount'))
            return
        try:
            fee = int(PyDecimal(self.str_fee) * COIN)
        except Exception:
            self.show_message(_('Invalid Fee'))
            return

        if self.wallet.has_password():
            password = self.password_dialog()
            if not password:
                return
        else:
            password = None
        try:
            tx = self.wallet.mktx([(TYPE_ADDRESS, self.str_recipient, amount)],
                                  password, self.config, fee)
        except Exception as e:
            self.show_message(str(e))
            return

        if self.str_description:
            self.wallet.labels[tx.txid()] = self.str_description

        self.show_message(_("Please wait..."), getchar=False)
        status, msg = self.network.broadcast_transaction(tx)

        if status:
            self.show_message(_('Payment sent.'))
            self.do_clear()
            #self.update_contacts_tab()
        else:
            self.show_message(_('Error'))
Beispiel #29
0
 def viewWillDisappear_(self, animated: bool) -> None:
     send_super(__class__,
                self,
                'viewWillDisappear:',
                animated,
                argtypes=[c_bool])
     parent().cash_addr_sig.disconnect(self)
     data = utils.nspy_get_byname(self, 'data')
     if not data: data = DialogData(None, None)
     text = self.tf.text.strip()
     if self.mode == SignVerify:
         try:
             address = Address.from_string(text)
             data = utils.set_namedtuple_field(data, 'address', address)
         except:
             pass
     elif self.mode == EncryptDecrypt:
         data = utils.set_namedtuple_field(data, 'pubkey', text)
     utils.nspy_put_byname(self, data, 'data')
     if self.kbas:
         utils.unregister_keyboard_autoscroll(self.kbas)
         self.kbas = None
Beispiel #30
0
 def parse_address(self, line):
     r = line.strip()
     m = re.match(RE_ALIAS, r)
     address = m.group(2) if m else r
     return Address.from_string(address)