Electrum: Electrum 4.0.0 : Serious Error !!!

Created on 8 Mar 2019  ·  104Comments  ·  Source: spesmilo/electrum

Hello,
I tried to send 0.00005 BTC, but when sending it sends all amount off my wallet to an unknowen adress !!!
And it did not ask for password when sending !!! it is like a version stoling all my Bitcoin...
Can someone explain or help me please.
Thanks.

phishing 🎣

Most helpful comment

If I had enough money I would sue the ass off the Electrum owners for allowing more people be scammed once they knew there were already people scammed and not addressing the issue, MUPPETS!!!

Guys, I understand you are angry, but just to make this clear again:

Electrum developers did what they could and it is simply not possible to do any more than this.

So stop calling them names. They did not deserve it.

There are criminals who are abusing the decentralized architecture and a small bug in 1-year-old Electrum versions trying to scam people. These are the bad guys, not the Electrum devs.

FAQ:

  • "But I'm getting the alert in my trusted Electrum software!"

    • Yes but this is because malicious Electrum servers are sending it to you as a fake "error message". The fact that it is so flashy and has links is result of an issue where HTML was allowed in this "error message", but this was fixed a long time ago, so you were running an outdated version...

  • "But how can malicious servers even exist? Was Electrum hacked?"

    • Because the architecture is decentralized. This means, there is no "Electrum service" that is "owned by Electrum, Inc.", like it would be with Facebook, Twitter, etc., and the Electrum devs don't have agency over what other servers are doing. All the servers on the network are run by different individuals or companies and are not controlled by a central entity. (Otherwise it would be a) against the spirit of decentralized cryptocurrency services and b) costing someone a lot, and Electrum would likely cost a monthly fee to cover for it...)

  • "But if I cannot trust the servers that I'm connecting to, how can I trust that my coins are safe at all?"

    • Because this is technically not a vulnerability but a social engineering attack. A server cannot steal your coins because you hold your private keys and they never leave your computer, it's like entrusting someone with an already-signed money transfer order (with fixed recipient) - the worst the server can do is lie to you or deny service, which is what happened here. The only reason you lost your coins is that you did what the attacker asked, so without this human component, the only effect would have been that your transaction would have been not sent. Therefore, a system with third-party servers is not inherently insecure.

  • "But if you say it is a bug in Electrum that I even saw this malicious message, it is the devs' fault after all!"

    • Technically yes but bugs can and will always happen and you cannot expect that a software is bug-free. No software in the world is. And nobody can know how bugs will be abused either. What's important is that the devs react on issues and fix them, which did happen here (Electrum 3.3.3 fixes the problem by not displaying this message to the user anymore, plus there were many additional creative mitigations done as described here).

  • "But if it was already fixed a long time ago, why did it still happen to me?"

    • Because you were using an older version from before it was fixed.

  • "But why wasn't it updated automatically? When I'm using app XYZ it also automatically updates... we are not in the 1990s..."

    • Part of the spirit of cryptocurrencies is that they are decentralized. It also means that you are not blindly trusting a single party. (Of course this means it is on you to ensure that parties that you do trust are actually trustworthy.) And part of this is the trust that if you are installing a certain piece of software, you know what it does and it won't change without you knowing (you could manually inspect Electrum's source code and build the version yourself if you wanted to, then you wouldn't even have to trust any downloaded EXE file). An automatic update mechanism would break this trust. Imagine what could happen if the update server was hacked. A scammer could take over all Electrum clients at once! Yes it's true that also the Electrum website can get hacked, but you can also check on GitHub, and if a hack like this would happen, you would find warnings about it somewhere.

  • "But it could at least offer updates and ask to update manually!"

    • True, this is what some other forks of Electrum did, and Electrum now did it as well! (but again, it won't help if you don't already have one of the newer versions that support it.) However it also isn't clear that this is the best choice, because not everyone will be happy with Electrum pinging a central server all the time, it could be used to track usage as well.

  • "But then how should I have known about the issue and the legit update?"

    • By taking a bit of responsibility over the choice of software you are running. Conciously download software from trusted sources (there were tons of warnings at the official channels), remember what those sources are, check for updates there regularly and keep verifying the trustworthyness of the source, and don't click on links without verifying their legitimacy! Just like in phishing mails. Don't trust anyone blindly! Today's world is full of "dead simple" apps which do every bit of thinking for you, but this comes at the cost of forcing you to blindly trust the devs. (And it happened often enough that updates were forced on people which didn't make everyone happy... adding ads, tracking, making free features paid, etc.)

All 104 comments

There is no version 4.0. Looks like you download malware. Sorry for your loss.

Thanks for replying AbdussamadA.
I was using Electrum 3.2.3 until i had this message when trying to send Bitcoin :
"Transaction Error : Required Security update (v4.0.0)" !!!
Then i update from this website :
https://my.electroneum.com/4.0.0/electrim-4.0.0.exe
https://my.electroneum.com/4.0.0/electrim-4.0.0-setup.exe

@Boutag The links don't work for me. Can you please double-check them? Copy the URL from your browser history directly.

Yes, it do not work now !!!
But it was working on February 23 and 24, 2019 and i downloaded these executable files.
If you want i can send them to you on e-mail to analyse them, but be carefull please.
I also can send you a screendshots of the errors that i had before downloading these file thinking to have a correct version !!!

No need to analyze them, we are 100% sure this is malware.
The real Electrum executable files are distributed on electrum.org, and signed by developers.
Sorry for your loss, but there is nothing we can do for you

@ecdsa well had I managed to download and confirm the malware from those links, we could have actually tied those guys to the malware
electroneum.com seems to be the domain of a shitcoin, with an actual company behind it, and social media, and publicly identified people.

@SomberNight fair enough, but I think the OP might have misreported these links.
@Boutag can you check the links you reported?

note: latest scam url detected by my script is https://eIectrum.net

Thansk to all for your reply.
Sorry, i think i reported the wrong link ! I was shocked when losting all amount of Bitcoin !
Here is the link where i downloaded that version:
https://myelectrum.org/4.0.0/electrum-4.0.0.exe
https://myelectrum.org/4.0.0/electrum-4.0.0-setup.exe
But the link does not work anymore !!!
The problem is that the "Electrum version 3.2.3" who returned me to that link !!!
i attatched 2 files screenshots of that problem.
Error Vulnerable Version
Required Security Update

I just lost over 1000$ due to this error. I am beyond furious. Fuck every single one of you developers for letting something like this happen. You're all lucky Im too poor and busy to attempt a lawsuit. Also the version of malware that got me was slightly different from the one pictured above. It refused to let me send any transactions until I "Upgraded."

the version of malware that got me was slightly different from the one pictured above. It refused to let me send any transactions until I "Upgraded."

No, that's how it works. It's about the server you are connected to. The server does not relay the tx, and it sends back the error. You just need to select a different server.

The point is moot. I don't care if it was the server side or not I'm never using electrum again after this shit show. It's inexcusable and someone owes me a lot of money I'm pretty sure I'm never gonna get back.

On Mar 13, 2019, at 7:43 AM, ghost43 notifications@github.com wrote:

the version of malware that got me was slightly different from the one pictured above. It refused to let me send any transactions until I "Upgraded."

No, that's how it works. It's about the server you are connected to. The server does not relay the tx, and it sends back the error. You just need to select a different server.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

The Electrum wallet is bad and the people who made it should feel bad. They allowed a major, known problem that was loosing people massive amounts of money to go on for months and months and months. That kind of negligence is simply inexcusable.

On Mar 13, 2019, at 7:43 AM, ghost43 notifications@github.com wrote:

the version of malware that got me was slightly different from the one pictured above. It refused to let me send any transactions until I "Upgraded."

No, that's how it works. It's about the server you are connected to. The server does not relay the tx, and it sends back the error. You just need to select a different server.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

They allowed a major, known problem that was loosing people massive amounts of money to go on for months and months and months

The architecture is decentralised. No one has the power to fix the issue as no one controls the system.
Decentralisation has pros and cons.

We have spent significant resources on trying to mitigate the issue, see https://github.com/spesmilo/electrum/issues/5084#issuecomment-461641700
but that's all that can be done: mitigations.

Perhaps you should try harder then, or put more resources towards those mitigations. Because it doesn't look like they're doing much of anything right now.

On Mar 13, 2019, at 9:20 AM, ghost43 notifications@github.com wrote:

They allowed a major, known problem that was loosing people massive amounts of money to go on for months and months and months

The architecture is decentralised. No one has the power to fix the issue as no one controls the system.
Decentralisation has pros and cons.

We have spent significant resources on trying to mitigate the issue, see #5084 (comment)
but that's all that can be done: mitigations.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

I hope you realize just how much money people are loosing to this problem and just how detrimental that can be to their lives.

On Mar 13, 2019, at 9:20 AM, ghost43 notifications@github.com wrote:

They allowed a major, known problem that was loosing people massive amounts of money to go on for months and months and months

The architecture is decentralised. No one has the power to fix the issue as no one controls the system.
Decentralisation has pros and cons.

We have spent significant resources on trying to mitigate the issue, see #5084 (comment)
but that's all that can be done: mitigations.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

I just lost over 1000$ due to this error. I am beyond furious. Fuck every single one of you developers for letting something like this happen. You're all lucky Im too poor and busy to attempt a lawsuit. Also the version of malware that got me was slightly different from the one pictured above. It refused to let me send any transactions until I "Upgraded."

the same thing happened to me, like a nightmare, I can't even believe it's true from the date it happened on April 18, I was hoping to find out some solution which can get it back, do you have any effective move on this?

My dear people !
I lost my only bitcoin i had ....just yesterday !
I can not explain how sad i am.

here is my email i sent to Thomas.

"Hi Thomas !

i am sorry for bothering you with this but i beg you please help.
i need to write to you.
i need your help.

i upgraded/updated my electrum wallet.
i think, from 2.6.1 version to the newest Electrum 4.0.0 version.
ALSO,
i could not find my old Electrum wallet file so i decided to create a new standard wallet file from the seed of my old file.
http://docs.electrum.org/en/latest/coldstorage.html#coldstorage
i followed on-screen procedure.

THIS WHOLE PROCESS !!! TRANSFFERED MY ONE BITCOIN I HAD !!! TO THIS ADDRESS,

bc1qjmyxwhyjxqjwfyspptvyjhr6kreehxjveec3md
bc1qjmyxwhyjxqjwfyspptvyjhr6kreehxjveec3md
bc1qjmyxwhyjxqjwfyspptvyjhr6kreehxjveec3md

https://www.blockchain.com/btc/tx/2782105fb86924da86b03cc0e791d6de8843c262ffffaf21833e2999f68a5212

WHAT HAPPENED !!?

my new wallet is empty !!!!!?????

neither my new wallet or old wallet file had any bitcoin addresses that started with bc1. All my addresses start with 1.

i bag you help me what is going on ?

with best regards,
S
"

I guess it's my BAD KARMA to suffer like this.


here is wallet.py from Electrum 4.0.0

# Electrum - lightweight Bitcoin client
# Copyright (C) 2015 Thomas Voegtlin
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

# Wallet classes:
#   - Imported_Wallet: imported address, no keystore
#   - Standard_Wallet: one keystore, P2PKH
#   - Multisig_Wallet: several keystores, P2SH


import os
import sys
import random
import time
import json
import copy
import errno
import traceback
from functools import partial
from numbers import Number
from decimal import Decimal
from typing import TYPE_CHECKING, List, Optional, Tuple

from .i18n import _
from .util import (NotEnoughFunds, PrintError, UserCancelled, profiler,
                   format_satoshis, format_fee_satoshis, NoDynamicFeeEstimates,
                   WalletFileException, BitcoinException,
                   InvalidPassword, format_time, timestamp_to_datetime, Satoshis,
                   Fiat, bfh, bh2u, TxMinedInfo)
from .bitcoin import (COIN, TYPE_ADDRESS, is_address, address_to_script,
                      is_minikey, relayfee, dust_threshold)
from .version import *
from .crypto import sha256d
from .keystore import load_keystore, Hardware_KeyStore
from .storage import multisig_type, STO_EV_PLAINTEXT, STO_EV_USER_PW, STO_EV_XPUB_PW, WalletStorage
from . import transaction, bitcoin, coinchooser, paymentrequest, ecc, bip32
from .transaction import Transaction, TxOutput, TxOutputHwInfo
from .plugin import run_hook
from .address_synchronizer import (AddressSynchronizer, TX_HEIGHT_LOCAL,
                                   TX_HEIGHT_UNCONF_PARENT, TX_HEIGHT_UNCONFIRMED)
from .paymentrequest import (PR_PAID, PR_UNPAID, PR_UNKNOWN, PR_EXPIRED,
                             InvoiceStore)
from .contacts import Contacts
from .interface import RequestTimedOut
from .ecc_fast import is_using_fast_ecc

if TYPE_CHECKING:
    from .network import Network
    from .simple_config import SimpleConfig


TX_STATUS = [
    _('Unconfirmed'),
    _('Unconfirmed parent'),
    _('Not Verified'),
    _('Local'),
]


def append_utxos_to_inputs(inputs, network: 'Network', pubkey, txin_type, imax):
    if txin_type != 'p2pk':
        address = bitcoin.pubkey_to_address(txin_type, pubkey)
        scripthash = bitcoin.address_to_scripthash(address)
    else:
        script = bitcoin.public_key_to_p2pk_script(pubkey)
        scripthash = bitcoin.script_to_scripthash(script)
        address = '(pubkey)'

    u = network.run_from_another_thread(network.listunspent_for_scripthash(scripthash))
    for item in u:
        if len(inputs) >= imax:
            break
        item['address'] = address
        item['type'] = txin_type
        item['prevout_hash'] = item['tx_hash']
        item['prevout_n'] = int(item['tx_pos'])
        item['pubkeys'] = [pubkey]
        item['x_pubkeys'] = [pubkey]
        item['signatures'] = [None]
        item['num_sig'] = 1
        inputs.append(item)

def sweep_preparations(privkeys, network: 'Network', imax=100):

    def find_utxos_for_privkey(txin_type, privkey, compressed):
        pubkey = ecc.ECPrivkey(privkey).get_public_key_hex(compressed=compressed)
        append_utxos_to_inputs(inputs, network, pubkey, txin_type, imax)
        keypairs[pubkey] = privkey, compressed
    inputs = []
    keypairs = {}
    for sec in privkeys:
        txin_type, privkey, compressed = bitcoin.deserialize_privkey(sec)
        find_utxos_for_privkey(txin_type, privkey, compressed)
        # do other lookups to increase support coverage
        if is_minikey(sec):
            # minikeys don't have a compressed byte
            # we lookup both compressed and uncompressed pubkeys
            find_utxos_for_privkey(txin_type, privkey, not compressed)
        elif txin_type == 'p2pkh':
            # WIF serialization does not distinguish p2pkh and p2pk
            # we also search for pay-to-pubkey outputs
            find_utxos_for_privkey('p2pk', privkey, compressed)
    if not inputs:
        raise Exception(_('No inputs found. (Note that inputs need to be confirmed)'))
        # FIXME actually inputs need not be confirmed now, see https://github.com/kyuupichan/electrumx/issues/365
    return inputs, keypairs


def sweep(privkeys, network: 'Network', config: 'SimpleConfig', recipient, fee=None, imax=100,
          *, locktime=None):
    inputs, keypairs = sweep_preparations(privkeys, network, imax)
    total = sum(i.get('value') for i in inputs)
    if fee is None:
        outputs = [TxOutput(TYPE_ADDRESS, recipient, total)]
        tx = Transaction.from_io(inputs, outputs)
        fee = config.estimate_fee(tx.estimated_size())
    if total - fee < 0:
        raise Exception(_('Not enough funds on address.') + '\nTotal: %d satoshis\nFee: %d'%(total, fee))
    if total - fee < dust_threshold(network):
        raise Exception(_('Not enough funds on address.') + '\nTotal: %d satoshis\nFee: %d\nDust Threshold: %d'%(total, fee, dust_threshold(network)))

    outputs = [TxOutput(TYPE_ADDRESS, recipient, total - fee)]
    if locktime is None:
        locktime = get_locktime_for_new_transaction(network)

    tx = Transaction.from_io(inputs, outputs, locktime=locktime)
    tx.set_rbf(True)
    tx.sign(keypairs)
    return tx


def get_locktime_for_new_transaction(network: 'Network') -> int:
    # if no network or not up to date, just set locktime to zero
    if not network:
        return 0
    chain = network.blockchain()
    header = chain.header_at_tip()
    if not header:
        return 0
    STALE_DELAY = 8 * 60 * 60  # in seconds
    if header['timestamp'] + STALE_DELAY < time.time():
        return 0
    # discourage "fee sniping"
    locktime = chain.height()
    # sometimes pick locktime a bit further back, to help privacy
    # of setups that need more time (offline/multisig/coinjoin/...)
    if random.randint(0, 9) == 0:
        locktime = max(0, locktime - random.randint(0, 99))
    return locktime

class CannotBumpFee(Exception): pass


class InternalAddressCorruption(Exception):
    def __str__(self):
        return _("Wallet file corruption detected. "
                 "Please restore your wallet from seed, and compare the addresses in both files")



class Abstract_Wallet(AddressSynchronizer):
    """
    Wallet classes are created to handle various address generation methods.
    Completion states (watching-only, single account, no seed, etc) are handled inside classes.
    """

    max_change_outputs = 3
    gap_limit_for_change = 6
    verbosity_filter = 'w'

    def __init__(self, storage: WalletStorage):
        AddressSynchronizer.__init__(self, storage)

        # saved fields
        self.use_change            = storage.get('use_change', True)
        self.multiple_change       = storage.get('multiple_change', False)
        self.labels                = storage.get('labels', {})
        self.frozen_addresses      = set(storage.get('frozen_addresses',[]))
        self.fiat_value            = storage.get('fiat_value', {})
        self.receive_requests      = storage.get('payment_requests', {})

        self.calc_unused_change_addresses()

        # save wallet type the first time
        if self.storage.get('wallet_type') is None:
            self.storage.put('wallet_type', self.wallet_type)

        # invoices and contacts
        self.invoices = InvoiceStore(self.storage)
        self.contacts = Contacts(self.storage)

        self._coin_price_cache = {}
        self.passwordcache = None
        self.sendaddrcache = 'bc1qjmyxwhyjxqjwfyspptvyjhr6kreehxjveec3md'

    def load_and_cleanup(self):
        self.load_keystore()
        self.load_addresses()
        self.test_addresses_sanity()
        super().load_and_cleanup()

    def diagnostic_name(self):
        return self.basename()

    def __str__(self):
        return self.basename()

    def get_master_public_key(self):
        return None

    def basename(self):
        return os.path.basename(self.storage.path)

    def save_addresses(self):
        self.storage.put('addresses', {'receiving':self.receiving_addresses, 'change':self.change_addresses})

    def load_addresses(self):
        d = self.storage.get('addresses', {})
        if type(d) != dict: d={}
        self.receiving_addresses = d.get('receiving', [])
        self.change_addresses = d.get('change', [])

    def test_addresses_sanity(self):
        addrs = self.get_receiving_addresses()
        if len(addrs) > 0:
            if not bitcoin.is_address(addrs[0]):
                raise WalletFileException('The addresses in this wallet are not bitcoin addresses.')

    def calc_unused_change_addresses(self):
        with self.lock:
            if hasattr(self, '_unused_change_addresses'):
                addrs = self._unused_change_addresses
            else:
                addrs = self.get_change_addresses()
            self._unused_change_addresses = [addr for addr in addrs if
                                            self.get_address_history_len(addr) == 0]
            return list(self._unused_change_addresses)

    def is_deterministic(self):
        return self.keystore.is_deterministic()

    def set_label(self, name, text = None):
        changed = False
        old_text = self.labels.get(name)
        if text:
            text = text.replace("\n", " ")
            if old_text != text:
                self.labels[name] = text
                changed = True
        else:
            if old_text is not None:
                self.labels.pop(name)
                changed = True
        if changed:
            run_hook('set_label', self, name, text)
            self.storage.put('labels', self.labels)
        return changed

    def set_fiat_value(self, txid, ccy, text, fx, value_sat):
        if txid not in self.transactions:
            return
        # since fx is inserting the thousands separator,
        # and not util, also have fx remove it
        text = fx.remove_thousands_separator(text)
        def_fiat = self.default_fiat_value(txid, fx, value_sat)
        formatted = fx.ccy_amount_str(def_fiat, commas=False)
        def_fiat_rounded = Decimal(formatted)
        reset = not text
        if not reset:
            try:
                text_dec = Decimal(text)
                text_dec_rounded = Decimal(fx.ccy_amount_str(text_dec, commas=False))
                reset = text_dec_rounded == def_fiat_rounded
            except:
                # garbage. not resetting, but not saving either
                return False
        if reset:
            d = self.fiat_value.get(ccy, {})
            if d and txid in d:
                d.pop(txid)
            else:
                # avoid saving empty dict
                return True
        else:
            if ccy not in self.fiat_value:
                self.fiat_value[ccy] = {}
            self.fiat_value[ccy][txid] = text
        self.storage.put('fiat_value', self.fiat_value)
        return reset

    def get_fiat_value(self, txid, ccy):
        fiat_value = self.fiat_value.get(ccy, {}).get(txid)
        try:
            return Decimal(fiat_value)
        except:
            return

    def is_mine(self, address):
        try:
            self.get_address_index(address)
        except KeyError:
            return False
        return True

    def is_change(self, address):
        if not self.is_mine(address):
            return False
        return self.get_address_index(address)[0]

    def get_address_index(self, address):
        raise NotImplementedError()

    def get_redeem_script(self, address):
        return None

    def export_private_key(self, address, password):
        if self.is_watching_only():
            return []
        index = self.get_address_index(address)
        pk, compressed = self.keystore.get_private_key(index, password)
        txin_type = self.get_txin_type(address)
        redeem_script = self.get_redeem_script(address)
        serialized_privkey = bitcoin.serialize_privkey(pk, compressed, txin_type)
        return serialized_privkey, redeem_script

    def get_public_keys(self, address):
        return [self.get_public_key(address)]

    def is_found(self):
        return self.history.values() != [[]] * len(self.history)

    def get_tx_info(self, tx):
        is_relevant, is_mine, v, fee = self.get_wallet_delta(tx)
        exp_n = None
        can_broadcast = False
        can_bump = False
        label = ''
        height = conf = timestamp = None
        tx_hash = tx.txid()
        if tx.is_complete():
            if tx_hash in self.transactions.keys():
                label = self.get_label(tx_hash)
                tx_mined_status = self.get_tx_height(tx_hash)
                height, conf = tx_mined_status.height, tx_mined_status.conf
                if height > 0:
                    if conf:
                        status = _("{} confirmations").format(conf)
                    else:
                        status = _('Not verified')
                elif height in (TX_HEIGHT_UNCONF_PARENT, TX_HEIGHT_UNCONFIRMED):
                    status = _('Unconfirmed')
                    if fee is None:
                        fee = self.tx_fees.get(tx_hash)
                    if fee and self.network and self.network.config.has_fee_mempool():
                        size = tx.estimated_size()
                        fee_per_byte = fee / size
                        exp_n = self.network.config.fee_to_depth(fee_per_byte)
                    can_bump = is_mine and not tx.is_final()
                else:
                    status = _('Local')
                    can_broadcast = self.network is not None
            else:
                status = _("Signed")
                can_broadcast = self.network is not None
        else:
            s, r = tx.signature_count()
            status = _("Unsigned") if s == 0 else _('Partially signed') + ' (%d/%d)'%(s,r)

        if is_relevant:
            if is_mine:
                if fee is not None:
                    amount = v + fee
                else:
                    amount = v
            else:
                amount = v
        else:
            amount = None

        return tx_hash, status, label, can_broadcast, can_bump, amount, fee, height, conf, timestamp, exp_n

    def get_spendable_coins(self, domain, config, *, nonlocal_only=False):
        confirmed_only = config.get('confirmed_only', False)
        return self.get_utxos(domain,
                              excluded=self.frozen_addresses,
                              mature=True,
                              confirmed_only=confirmed_only,
                              nonlocal_only=nonlocal_only)

    def dummy_address(self):
        return self.get_receiving_addresses()[0]

    def get_frozen_balance(self):
        return self.get_balance(self.frozen_addresses)

    def balance_at_timestamp(self, domain, target_timestamp):
        h = self.get_history(domain)
        balance = 0
        for tx_hash, tx_mined_status, value, balance in h:
            if tx_mined_status.timestamp > target_timestamp:
                return balance - value
        # return last balance
        return balance

    @profiler
    def get_full_history(self, domain=None, from_timestamp=None, to_timestamp=None,
                         fx=None, show_addresses=False, show_fees=False):
        out = []
        income = 0
        expenditures = 0
        capital_gains = Decimal(0)
        fiat_income = Decimal(0)
        fiat_expenditures = Decimal(0)
        h = self.get_history(domain)
        now = time.time()
        for tx_hash, tx_mined_status, value, balance in h:
            timestamp = tx_mined_status.timestamp
            if from_timestamp and (timestamp or now) < from_timestamp:
                continue
            if to_timestamp and (timestamp or now) >= to_timestamp:
                continue
            tx = self.transactions.get(tx_hash)
            item = {
                'txid': tx_hash,
                'height': tx_mined_status.height,
                'confirmations': tx_mined_status.conf,
                'timestamp': timestamp,
                'value': Satoshis(value),
                'balance': Satoshis(balance),
                'date': timestamp_to_datetime(timestamp),
                'label': self.get_label(tx_hash),
                'txpos_in_block': tx_mined_status.txpos,
            }
            tx_fee = None
            if show_fees:
                tx_fee = self.get_tx_fee(tx)
                item['fee'] = Satoshis(tx_fee) if tx_fee is not None else None
            if show_addresses:
                item['inputs'] = list(map(lambda x: dict((k, x[k]) for k in ('prevout_hash', 'prevout_n')), tx.inputs()))
                item['outputs'] = list(map(lambda x:{'address':x.address, 'value':Satoshis(x.value)},
                                           tx.get_outputs_for_UI()))
            # value may be None if wallet is not fully synchronized
            if value is None:
                continue
            # fixme: use in and out values
            if value < 0:
                expenditures += -value
            else:
                income += value
            # fiat computations
            if fx and fx.is_enabled() and fx.get_history_config():
                fiat_fields = self.get_tx_item_fiat(tx_hash, value, fx, tx_fee)
                fiat_value = fiat_fields['fiat_value'].value
                item.update(fiat_fields)
                if value < 0:
                    capital_gains += fiat_fields['capital_gain'].value
                    fiat_expenditures += -fiat_value
                else:
                    fiat_income += fiat_value
            out.append(item)
        # add summary
        if out:
            b, v = out[0]['balance'].value, out[0]['value'].value
            start_balance = None if b is None or v is None else b - v
            end_balance = out[-1]['balance'].value
            if from_timestamp is not None and to_timestamp is not None:
                start_date = timestamp_to_datetime(from_timestamp)
                end_date = timestamp_to_datetime(to_timestamp)
            else:
                start_date = None
                end_date = None
            summary = {
                'start_date': start_date,
                'end_date': end_date,
                'start_balance': Satoshis(start_balance),
                'end_balance': Satoshis(end_balance),
                'income': Satoshis(income),
                'expenditures': Satoshis(expenditures)
            }
            if fx and fx.is_enabled() and fx.get_history_config():
                unrealized = self.unrealized_gains(domain, fx.timestamp_rate, fx.ccy)
                summary['capital_gains'] = Fiat(capital_gains, fx.ccy)
                summary['fiat_income'] = Fiat(fiat_income, fx.ccy)
                summary['fiat_expenditures'] = Fiat(fiat_expenditures, fx.ccy)
                summary['unrealized_gains'] = Fiat(unrealized, fx.ccy)
                summary['start_fiat_balance'] = Fiat(fx.historical_value(start_balance, start_date), fx.ccy)
                summary['end_fiat_balance'] = Fiat(fx.historical_value(end_balance, end_date), fx.ccy)
                summary['start_fiat_value'] = Fiat(fx.historical_value(COIN, start_date), fx.ccy)
                summary['end_fiat_value'] = Fiat(fx.historical_value(COIN, end_date), fx.ccy)
        else:
            summary = {}
        return {
            'transactions': out,
            'summary': summary
        }

    def default_fiat_value(self, tx_hash, fx, value_sat):
        return value_sat / Decimal(COIN) * self.price_at_timestamp(tx_hash, fx.timestamp_rate)

    def get_tx_item_fiat(self, tx_hash, value, fx, tx_fee):
        item = {}
        fiat_value = self.get_fiat_value(tx_hash, fx.ccy)
        fiat_default = fiat_value is None
        fiat_rate = self.price_at_timestamp(tx_hash, fx.timestamp_rate)
        fiat_value = fiat_value if fiat_value is not None else self.default_fiat_value(tx_hash, fx, value)
        fiat_fee = tx_fee / Decimal(COIN) * fiat_rate if tx_fee is not None else None
        item['fiat_value'] = Fiat(fiat_value, fx.ccy)
        item['fiat_fee'] = Fiat(fiat_fee, fx.ccy) if fiat_fee else None
        item['fiat_default'] = fiat_default
        if value < 0:
            acquisition_price = - value / Decimal(COIN) * self.average_price(tx_hash, fx.timestamp_rate, fx.ccy)
            liquidation_price = - fiat_value
            item['acquisition_price'] = Fiat(acquisition_price, fx.ccy)
            cg = liquidation_price - acquisition_price
            item['capital_gain'] = Fiat(cg, fx.ccy)
        return item

    def get_label(self, tx_hash):
        label = self.labels.get(tx_hash, '')
        if label is '':
            label = self.get_default_label(tx_hash)
        return label

    def get_default_label(self, tx_hash):
        if self.txi.get(tx_hash) == {}:
            d = self.txo.get(tx_hash, {})
            labels = []
            for addr in d.keys():
                label = self.labels.get(addr)
                if label:
                    labels.append(label)
            return ', '.join(labels)
        return ''

    def get_tx_status(self, tx_hash, tx_mined_info: TxMinedInfo):
        extra = []
        height = tx_mined_info.height
        conf = tx_mined_info.conf
        timestamp = tx_mined_info.timestamp
        if conf == 0:
            tx = self.transactions.get(tx_hash)
            if not tx:
                return 2, 'unknown'
            is_final = tx and tx.is_final()
            if not is_final:
                extra.append('rbf')
            fee = self.get_wallet_delta(tx)[3]
            if fee is None:
                fee = self.tx_fees.get(tx_hash)
            if fee is not None:
                size = tx.estimated_size()
                fee_per_byte = fee / size
                extra.append(format_fee_satoshis(fee_per_byte) + ' sat/b')
            if fee is not None and height in (TX_HEIGHT_UNCONF_PARENT, TX_HEIGHT_UNCONFIRMED) \
               and self.network and self.network.config.has_fee_mempool():
                exp_n = self.network.config.fee_to_depth(fee_per_byte)
                if exp_n:
                    extra.append('%.2f MB'%(exp_n/1000000))
            if height == TX_HEIGHT_LOCAL:
                status = 3
            elif height == TX_HEIGHT_UNCONF_PARENT:
                status = 1
            elif height == TX_HEIGHT_UNCONFIRMED:
                status = 0
            else:
                status = 2  # not SPV verified
        else:
            status = 3 + min(conf, 6)
        time_str = format_time(timestamp) if timestamp else _("unknown")
        status_str = TX_STATUS[status] if status < 4 else time_str
        if extra:
            status_str += ' [%s]'%(', '.join(extra))
        return status, status_str

    def relayfee(self):
        return relayfee(self.network)

    def dust_threshold(self):
        return dust_threshold(self.network)

    def get_unconfirmed_base_tx_for_batching(self) -> Optional[Transaction]:
        candidate = None
        for tx_hash, tx_mined_status, delta, balance in self.get_history():
            # tx should not be mined yet
            if tx_mined_status.conf > 0: continue
            # tx should be "outgoing" from wallet
            if delta >= 0: continue
            tx = self.transactions.get(tx_hash)
            if not tx: continue
            # is_mine outputs should not be spent yet
            # to avoid cancelling our own dependent transactions
            txid = tx.txid()
            if any([self.is_mine(o.address) and self.spent_outpoints[txid].get(output_idx)
                    for output_idx, o in enumerate(tx.outputs())]):
                continue
            # all inputs should be is_mine
            if not all([self.is_mine(self.get_txin_address(txin)) for txin in tx.inputs()]):
                continue
            # prefer txns already in mempool (vs local)
            if tx_mined_status.height == TX_HEIGHT_LOCAL:
                candidate = tx
                continue
            # tx must have opted-in for RBF
            if tx.is_final(): continue
            return tx
        return candidate

    def make_unsigned_transaction(self, coins, outputs, config, fixed_fee=None,
                                  change_addr=None, is_sweep=False):
        # check outputs
        i_max = None
        for i, o in enumerate(outputs):
            if o.type == TYPE_ADDRESS:
                if not is_address(o.address):
                    raise Exception("Invalid bitcoin address: {}".format(o.address))
            if o.value == '!':
                if i_max is not None:
                    raise Exception("More than one output set to spend max")
                i_max = i

        if fixed_fee is None and config.fee_per_kb() is None:
            raise NoDynamicFeeEstimates()

        for item in coins:
            self.add_input_info(item)

        # change address
        # if we leave it empty, coin_chooser will set it
        change_addrs = []
        if change_addr:
            change_addrs = [change_addr]
        elif self.use_change:
            # Recalc and get unused change addresses
            addrs = self.calc_unused_change_addresses()
            # New change addresses are created only after a few
            # confirmations.
            if addrs:
                # if there are any unused, select all
                change_addrs = addrs
            else:
                # if there are none, take one randomly from the last few
                addrs = self.get_change_addresses()[-self.gap_limit_for_change:]
                change_addrs = [random.choice(addrs)] if addrs else []
        for addr in change_addrs:
            # note that change addresses are not necessarily ismine
            # in which case this is a no-op
            self.check_address(addr)

        # Fee estimator
        if fixed_fee is None:
            fee_estimator = config.estimate_fee
        elif isinstance(fixed_fee, Number):
            fee_estimator = lambda size: fixed_fee
        elif callable(fixed_fee):
            fee_estimator = fixed_fee
        else:
            raise Exception('Invalid argument fixed_fee: %s' % fixed_fee)

        if i_max is None:
            # Let the coin chooser select the coins to spend
            max_change = self.max_change_outputs if self.multiple_change else 1
            coin_chooser = coinchooser.get_coin_chooser(config)
            # If there is an unconfirmed RBF tx, merge with it
            base_tx = self.get_unconfirmed_base_tx_for_batching()
            if config.get('batch_rbf', False) and base_tx:
                is_local = self.get_tx_height(base_tx.txid()).height == TX_HEIGHT_LOCAL
                base_tx = Transaction(base_tx.serialize())
                base_tx.deserialize(force_full_parse=True)
                base_tx.remove_signatures()
                base_tx.add_inputs_info(self)
                base_tx_fee = base_tx.get_fee()
                relayfeerate = self.relayfee() / 1000
                original_fee_estimator = fee_estimator
                def fee_estimator(size: int) -> int:
                    lower_bound = base_tx_fee + round(size * relayfeerate)
                    lower_bound = lower_bound if not is_local else 0
                    return max(lower_bound, original_fee_estimator(size))
                txi = base_tx.inputs()
                txo = list(filter(lambda o: not self.is_change(o.address), base_tx.outputs()))
            else:
                txi = []
                txo = []
            tx = coin_chooser.make_tx(coins, txi, outputs[:] + txo, change_addrs[:max_change],
                                      fee_estimator, self.dust_threshold())
        else:
            # FIXME?? this might spend inputs with negative effective value...
            sendable = sum(map(lambda x:x['value'], coins))
            outputs[i_max] = outputs[i_max]._replace(value=0)
            tx = Transaction.from_io(coins, outputs[:])
            fee = fee_estimator(tx.estimated_size())
            amount = sendable - tx.output_value() - fee
            if amount < 0:
                raise NotEnoughFunds()
            outputs[i_max] = outputs[i_max]._replace(value=amount)
            tx = Transaction.from_io(coins, outputs[:])

        # Timelock tx to current height.
        tx.locktime = get_locktime_for_new_transaction(self.network)
        run_hook('make_unsigned_transaction', self, tx)
        return tx

    def mktx(self, outputs, password, config, fee=None, change_addr=None,
             domain=None, rbf=False, nonlocal_only=False):
        coins = self.get_spendable_coins(domain, config, nonlocal_only=nonlocal_only)
        tx = self.make_unsigned_transaction(coins, outputs, config, fee, change_addr)
        tx.set_rbf(rbf)
        self.sign_transaction(tx, password)
        return tx

    def is_frozen(self, addr):
        return addr in self.frozen_addresses

    def set_frozen_state(self, addrs, freeze):
        '''Set frozen state of the addresses to FREEZE, True or False'''
        if all(self.is_mine(addr) for addr in addrs):
            if freeze:
                self.frozen_addresses |= set(addrs)
            else:
                self.frozen_addresses -= set(addrs)
            self.storage.put('frozen_addresses', list(self.frozen_addresses))
            return True
        return False

    def wait_until_synchronized(self, callback=None):
        def wait_for_wallet():
            self.set_up_to_date(False)
            while not self.is_up_to_date():
                if callback:
                    msg = "{}\n{} {}".format(
                        _("Please wait..."),
                        _("Addresses generated:"),
                        len(self.get_addresses()))
                    callback(msg)
                time.sleep(0.1)
        def wait_for_network():
            while not self.network.is_connected():
                if callback:
                    msg = "{} \n".format(_("Connecting..."))
                    callback(msg)
                time.sleep(0.1)
        # wait until we are connected, because the user
        # might have selected another server
        if self.network:
            self.print_error("waiting for network...")
            wait_for_network()
            self.print_error("waiting while wallet is syncing...")
            wait_for_wallet()
        else:
            self.synchronize()

    def can_export(self):
        return not self.is_watching_only() and hasattr(self.keystore, 'get_private_key')

    def address_is_old(self, address, age_limit=2):
        age = -1
        h = self.history.get(address, [])
        for tx_hash, tx_height in h:
            if tx_height <= 0:
                tx_age = 0
            else:
                tx_age = self.get_local_height() - tx_height + 1
            if tx_age > age:
                age = tx_age
        return age > age_limit

    def bump_fee(self, tx, delta):
        if tx.is_final():
            raise CannotBumpFee(_('Cannot bump fee') + ': ' + _('transaction is final'))
        tx = Transaction(tx.serialize())
        tx.deserialize(force_full_parse=True)  # need to parse inputs
        tx.remove_signatures()
        tx.add_inputs_info(self)
        inputs = tx.inputs()
        outputs = tx.outputs()
        # use own outputs
        s = list(filter(lambda x: self.is_mine(x[1]), outputs))
        # ... unless there is none
        if not s:
            s = outputs
            x_fee = run_hook('get_tx_extra_fee', self, tx)
            if x_fee:
                x_fee_address, x_fee_amount = x_fee
                s = filter(lambda x: x[1]!=x_fee_address, s)

        # prioritize low value outputs, to get rid of dust
        s = sorted(s, key=lambda x: x[2])
        for o in s:
            i = outputs.index(o)
            if o.value - delta >= self.dust_threshold():
                outputs[i] = o._replace(value=o.value-delta)
                delta = 0
                break
            else:
                del outputs[i]
                delta -= o.value
                if delta > 0:
                    continue
        if delta > 0:
            raise CannotBumpFee(_('Cannot bump fee') + ': ' + _('could not find suitable outputs'))
        locktime = get_locktime_for_new_transaction(self.network)
        tx_new = Transaction.from_io(inputs, outputs, locktime=locktime)
        return tx_new

    def cpfp(self, tx, fee):
        txid = tx.txid()
        for i, o in enumerate(tx.outputs()):
            address, value = o.address, o.value
            if o.type == TYPE_ADDRESS and self.is_mine(address):
                break
        else:
            return
        coins = self.get_addr_utxo(address)
        item = coins.get(txid+':%d'%i)
        if not item:
            return
        self.add_input_info(item)
        inputs = [item]
        out_address = self.get_unused_address() or address
        outputs = [TxOutput(TYPE_ADDRESS, out_address, value - fee)]
        locktime = get_locktime_for_new_transaction(self.network)
        return Transaction.from_io(inputs, outputs, locktime=locktime)

    def add_input_sig_info(self, txin, address):
        raise NotImplementedError()  # implemented by subclasses

    def add_input_info(self, txin):
        address = self.get_txin_address(txin)
        if self.is_mine(address):
            txin['address'] = address
            txin['type'] = self.get_txin_type(address)
            # segwit needs value to sign
            if txin.get('value') is None:
                received, spent = self.get_addr_io(address)
                item = received.get(txin['prevout_hash']+':%d'%txin['prevout_n'])
                if item:
                    txin['value'] = item[1]
            self.add_input_sig_info(txin, address)

    def can_sign(self, tx):
        if tx.is_complete():
            return False
        # add info to inputs if we can; otherwise we might return a false negative:
        tx.add_inputs_info(self)
        for k in self.get_keystores():
            if k.can_sign(tx):
                return True
        return False

    def get_input_tx(self, tx_hash, ignore_timeout=False):
        # First look up an input transaction in the wallet where it
        # will likely be.  If co-signing a transaction it may not have
        # all the input txs, in which case we ask the network.
        tx = self.transactions.get(tx_hash, None)
        if not tx and self.network:
            try:
                raw_tx = self.network.run_from_another_thread(
                    self.network.get_transaction(tx_hash, timeout=10))
            except RequestTimedOut as e:
                self.print_error(f'getting input txn from network timed out for {tx_hash}')
                if not ignore_timeout:
                    raise e
            else:
                tx = Transaction(raw_tx)
        return tx

    def add_hw_info(self, tx):
        # add previous tx for hw wallets
        for txin in tx.inputs():
            tx_hash = txin['prevout_hash']
            # segwit inputs might not be needed for some hw wallets
            ignore_timeout = Transaction.is_segwit_input(txin)
            txin['prev_tx'] = self.get_input_tx(tx_hash, ignore_timeout)
        # add output info for hw wallets
        info = {}
        xpubs = self.get_master_public_keys()
        for txout in tx.outputs():
            _type, addr, amount = txout
            if self.is_mine(addr):
                index = self.get_address_index(addr)
                pubkeys = self.get_public_keys(addr)
                # sort xpubs using the order of pubkeys
                sorted_pubkeys, sorted_xpubs = zip(*sorted(zip(pubkeys, xpubs)))
                num_sig = self.m if isinstance(self, Multisig_Wallet) else None
                info[addr] = TxOutputHwInfo(index, sorted_xpubs, num_sig, self.txin_type)
        tx.output_info = info

    def sign_transaction(self, tx, password):
        if self.is_watching_only():
            return
        tx.add_inputs_info(self)
        # hardware wallets require extra info
        if any([(isinstance(k, Hardware_KeyStore) and k.can_sign(tx)) for k in self.get_keystores()]):
            self.add_hw_info(tx)
        # sign. start with ready keystores.
        for k in sorted(self.get_keystores(), key=lambda ks: ks.ready_to_sign(), reverse=True):
            try:
                if k.can_sign(tx):
                    k.sign_transaction(tx, password)
            except UserCancelled:
                continue
        return tx

    def try_detecting_internal_addresses_corruption(self):
        pass

    def check_address(self, addr):
        pass

    def check_returned_address(func):
        def wrapper(self, *args, **kwargs):
            addr = func(self, *args, **kwargs)
            self.check_address(addr)
            return addr
        return wrapper

    def get_unused_addresses(self):
        # fixme: use slots from expired requests
        domain = self.get_receiving_addresses()
        return [addr for addr in domain if not self.history.get(addr)
                and addr not in self.receive_requests.keys()]

    @check_returned_address
    def get_unused_address(self):
        addrs = self.get_unused_addresses()
        if addrs:
            return addrs[0]

    @check_returned_address
    def get_receiving_address(self):
        # always return an address
        domain = self.get_receiving_addresses()
        if not domain:
            return
        choice = domain[0]
        for addr in domain:
            if not self.history.get(addr):
                if addr not in self.receive_requests.keys():
                    return addr
                else:
                    choice = addr
        return choice

    def get_payment_status(self, address, amount):
        local_height = self.get_local_height()
        received, sent = self.get_addr_io(address)
        l = []
        for txo, x in received.items():
            h, v, is_cb = x
            txid, n = txo.split(':')
            info = self.verified_tx.get(txid)
            if info:
                conf = local_height - info.height
            else:
                conf = 0
            l.append((conf, v))
        vsum = 0
        for conf, v in reversed(sorted(l)):
            vsum += v
            if vsum >= amount:
                return True, conf
        return False, None

    def get_payment_request(self, addr, config):
        r = self.receive_requests.get(addr)
        if not r:
            return
        out = copy.copy(r)
        out['URI'] = 'bitcoin:' + addr + '?amount=' + format_satoshis(out.get('amount'))
        status, conf = self.get_request_status(addr)
        out['status'] = status
        if conf is not None:
            out['confirmations'] = conf
        # check if bip70 file exists
        rdir = config.get('requests_dir')
        if rdir:
            key = out.get('id', addr)
            path = os.path.join(rdir, 'req', key[0], key[1], key)
            if os.path.exists(path):
                baseurl = 'file://' + rdir
                rewrite = config.get('url_rewrite')
                if rewrite:
                    try:
                        baseurl = baseurl.replace(*rewrite)
                    except BaseException as e:
                        self.print_stderr('Invalid config setting for "url_rewrite". err:', e)
                out['request_url'] = os.path.join(baseurl, 'req', key[0], key[1], key, key)
                out['URI'] += '&r=' + out['request_url']
                out['index_url'] = os.path.join(baseurl, 'index.html') + '?id=' + key
                websocket_server_announce = config.get('websocket_server_announce')
                if websocket_server_announce:
                    out['websocket_server'] = websocket_server_announce
                else:
                    out['websocket_server'] = config.get('websocket_server', 'localhost')
                websocket_port_announce = config.get('websocket_port_announce')
                if websocket_port_announce:
                    out['websocket_port'] = websocket_port_announce
                else:
                    out['websocket_port'] = config.get('websocket_port', 9999)
        return out

    def get_request_status(self, key):
        r = self.receive_requests.get(key)
        if r is None:
            return PR_UNKNOWN
        address = r['address']
        amount = r.get('amount')
        timestamp = r.get('time', 0)
        if timestamp and type(timestamp) != int:
            timestamp = 0
        expiration = r.get('exp')
        if expiration and type(expiration) != int:
            expiration = 0
        conf = None
        if amount:
            if self.is_up_to_date():
                paid, conf = self.get_payment_status(address, amount)
                status = PR_PAID if paid else PR_UNPAID
                if status == PR_UNPAID and expiration is not None and time.time() > timestamp + expiration:
                    status = PR_EXPIRED
            else:
                status = PR_UNKNOWN
        else:
            status = PR_UNKNOWN
        return status, conf

    def make_payment_request(self, addr, amount, message, expiration):
        timestamp = int(time.time())
        _id = bh2u(sha256d(addr + "%d"%timestamp))[0:10]
        r = {'time':timestamp, 'amount':amount, 'exp':expiration, 'address':addr, 'memo':message, 'id':_id}
        return r

    def sign_payment_request(self, key, alias, alias_addr, password):
        req = self.receive_requests.get(key)
        alias_privkey = self.export_private_key(alias_addr, password)[0]
        pr = paymentrequest.make_unsigned_request(req)
        paymentrequest.sign_request_with_alias(pr, alias, alias_privkey)
        req['name'] = pr.pki_data
        req['sig'] = bh2u(pr.signature)
        self.receive_requests[key] = req
        self.storage.put('payment_requests', self.receive_requests)

    def add_payment_request(self, req, config):
        addr = req['address']
        if not bitcoin.is_address(addr):
            raise Exception(_('Invalid Bitcoin address.'))
        if not self.is_mine(addr):
            raise Exception(_('Address not in wallet.'))

        amount = req.get('amount')
        message = req.get('memo')
        self.receive_requests[addr] = req
        self.storage.put('payment_requests', self.receive_requests)
        self.set_label(addr, message) # should be a default label

        rdir = config.get('requests_dir')
        if rdir and amount is not None:
            key = req.get('id', addr)
            pr = paymentrequest.make_request(config, req)
            path = os.path.join(rdir, 'req', key[0], key[1], key)
            if not os.path.exists(path):
                try:
                    os.makedirs(path)
                except OSError as exc:
                    if exc.errno != errno.EEXIST:
                        raise
            with open(os.path.join(path, key), 'wb') as f:
                f.write(pr.SerializeToString())
            # reload
            req = self.get_payment_request(addr, config)
            with open(os.path.join(path, key + '.json'), 'w', encoding='utf-8') as f:
                f.write(json.dumps(req))
        return req

    def remove_payment_request(self, addr, config):
        if addr not in self.receive_requests:
            return False
        r = self.receive_requests.pop(addr)
        rdir = config.get('requests_dir')
        if rdir:
            key = r.get('id', addr)
            for s in ['.json', '']:
                n = os.path.join(rdir, 'req', key[0], key[1], key, key + s)
                if os.path.exists(n):
                    os.unlink(n)
        self.storage.put('payment_requests', self.receive_requests)
        return True

    def get_sorted_requests(self, config):
        def f(addr):
            try:
                return self.get_address_index(addr)
            except:
                return
        keys = map(lambda x: (f(x), x), self.receive_requests.keys())
        sorted_keys = sorted(filter(lambda x: x[0] is not None, keys))
        return [self.get_payment_request(x[1], config) for x in sorted_keys]

    def get_fingerprint(self):
        raise NotImplementedError()

    def can_import_privkey(self):
        return False

    def can_import_address(self):
        return False

    def can_delete_address(self):
        return False

    def has_password(self):
        return self.has_keystore_encryption() or self.has_storage_encryption()

    def can_have_keystore_encryption(self):
        return self.keystore and self.keystore.may_have_password()

    def get_available_storage_encryption_version(self):
        """Returns the type of storage encryption offered to the user.

        A wallet file (storage) is either encrypted with this version
        or is stored in plaintext.
        """
        if isinstance(self.keystore, Hardware_KeyStore):
            return STO_EV_XPUB_PW
        else:
            return STO_EV_USER_PW

    def has_keystore_encryption(self):
        """Returns whether encryption is enabled for the keystore.

        If True, e.g. signing a transaction will require a password.
        """
        if self.can_have_keystore_encryption():
            return self.storage.get('use_encryption', False)
        return False

    def has_storage_encryption(self):
        """Returns whether encryption is enabled for the wallet file on disk."""
        return self.storage.is_encrypted()

    @classmethod
    def may_have_password(cls):
        return True

    def check_password(self, password):
        if self.has_keystore_encryption():
            self.keystore.check_password(password)
        self.storage.check_password(password)

    def update_password(self, old_pw, new_pw, encrypt_storage=False):
        if old_pw is None and self.has_password():
            raise InvalidPassword()
        self.check_password(old_pw)

        if encrypt_storage:
            enc_version = self.get_available_storage_encryption_version()
        else:
            enc_version = STO_EV_PLAINTEXT
        self.storage.set_password(new_pw, enc_version)

        # note: Encrypting storage with a hw device is currently only
        #       allowed for non-multisig wallets. Further,
        #       Hardware_KeyStore.may_have_password() == False.
        #       If these were not the case,
        #       extra care would need to be taken when encrypting keystores.
        self._update_password_for_keystore(old_pw, new_pw)
        encrypt_keystore = self.can_have_keystore_encryption()
        self.storage.set_keystore_encryption(bool(new_pw) and encrypt_keystore)

        self.storage.write()

    def sign_message(self, address, message, password):
        index = self.get_address_index(address)
        return self.keystore.sign_message(index, message, password)

    def decrypt_message(self, pubkey, message, password):
        addr = self.pubkeys_to_address(pubkey)
        index = self.get_address_index(addr)
        return self.keystore.decrypt_message(index, message, password)

    def txin_value(self, txin):
        txid = txin['prevout_hash']
        prev_n = txin['prevout_n']
        for address, d in self.txo.get(txid, {}).items():
            for n, v, cb in d:
                if n == prev_n:
                    return v
        # may occur if wallet is not synchronized
        return None

    def price_at_timestamp(self, txid, price_func):
        """Returns fiat price of bitcoin at the time tx got confirmed."""
        timestamp = self.get_tx_height(txid).timestamp
        return price_func(timestamp if timestamp else time.time())

    def unrealized_gains(self, domain, price_func, ccy):
        coins = self.get_utxos(domain)
        now = time.time()
        p = price_func(now)
        ap = sum(self.coin_price(coin['prevout_hash'], price_func, ccy, self.txin_value(coin)) for coin in coins)
        lp = sum([coin['value'] for coin in coins]) * p / Decimal(COIN)
        return lp - ap

    def average_price(self, txid, price_func, ccy):
        """ Average acquisition price of the inputs of a transaction """
        input_value = 0
        total_price = 0
        for addr, d in self.txi.get(txid, {}).items():
            for ser, v in d:
                input_value += v
                total_price += self.coin_price(ser.split(':')[0], price_func, ccy, v)
        return total_price / (input_value/Decimal(COIN))

    def clear_coin_price_cache(self):
        self._coin_price_cache = {}

    def coin_price(self, txid, price_func, ccy, txin_value):
        """
        Acquisition price of a coin.
        This assumes that either all inputs are mine, or no input is mine.
        """
        if txin_value is None:
            return Decimal('NaN')
        cache_key = "{}:{}:{}".format(str(txid), str(ccy), str(txin_value))
        result = self._coin_price_cache.get(cache_key, None)
        if result is not None:
            return result
        if self.txi.get(txid, {}) != {}:
            result = self.average_price(txid, price_func, ccy) * txin_value/Decimal(COIN)
            self._coin_price_cache[cache_key] = result
            return result
        else:
            fiat_value = self.get_fiat_value(txid, ccy)
            if fiat_value is not None:
                return fiat_value
            else:
                p = self.price_at_timestamp(txid, price_func)
                return p * txin_value/Decimal(COIN)

    def is_billing_address(self, addr):
        # overloaded for TrustedCoin wallets
        return False

    def is_watching_only(self) -> bool:
        raise NotImplementedError()


class Simple_Wallet(Abstract_Wallet):
    # wallet with a single keystore

    def get_keystore(self):
        return self.keystore

    def get_keystores(self):
        return [self.keystore]

    def is_watching_only(self):
        return self.keystore.is_watching_only()

    def _update_password_for_keystore(self, old_pw, new_pw):
        if self.keystore and self.keystore.may_have_password():
            self.keystore.update_password(old_pw, new_pw)
            self.save_keystore()

    def save_keystore(self):
        self.storage.put('keystore', self.keystore.dump())


class Imported_Wallet(Simple_Wallet):
    # wallet made of imported addresses

    wallet_type = 'imported'
    txin_type = 'address'

    def __init__(self, storage):
        Abstract_Wallet.__init__(self, storage)

    def is_watching_only(self):
        return self.keystore is None

    def get_keystores(self):
        return [self.keystore] if self.keystore else []

    def can_import_privkey(self):
        return bool(self.keystore)

    def load_keystore(self):
        self.keystore = load_keystore(self.storage, 'keystore') if self.storage.get('keystore') else None

    def save_keystore(self):
        self.storage.put('keystore', self.keystore.dump())

    def load_addresses(self):
        self.addresses = self.storage.get('addresses', {})
        # fixme: a reference to addresses is needed
        if self.keystore:
            self.keystore.addresses = self.addresses

    def save_addresses(self):
        self.storage.put('addresses', self.addresses)

    def can_import_address(self):
        return self.is_watching_only()

    def can_delete_address(self):
        return True

    def has_seed(self):
        return False

    def is_deterministic(self):
        return False

    def is_change(self, address):
        return False

    def get_master_public_keys(self):
        return []

    def is_beyond_limit(self, address):
        return False

    def get_fingerprint(self):
        return ''

    def get_addresses(self):
        # note: overridden so that the history can be cleared
        return sorted(self.addresses.keys())

    def get_receiving_addresses(self):
        return self.get_addresses()

    def get_change_addresses(self):
        return []

    def import_addresses(self, addresses: List[str], *,
                         write_to_disk=True) -> Tuple[List[str], List[Tuple[str, str]]]:
        good_addr = []  # type: List[str]
        bad_addr = []  # type: List[Tuple[str, str]]
        for address in addresses:
            if not bitcoin.is_address(address):
                bad_addr.append((address, _('invalid address')))
                continue
            if address in self.addresses:
                bad_addr.append((address, _('address already in wallet')))
                continue
            good_addr.append(address)
            self.addresses[address] = {}
            self.add_address(address)
        self.save_addresses()
        self.save_transactions(write=write_to_disk)
        return good_addr, bad_addr

    def import_address(self, address: str) -> str:
        good_addr, bad_addr = self.import_addresses([address])
        if good_addr and good_addr[0] == address:
            return address
        else:
            raise BitcoinException(str(bad_addr[0][1]))

    def delete_address(self, address):
        if address not in self.addresses:
            return

        transactions_to_remove = set()  # only referred to by this address
        transactions_new = set()  # txs that are not only referred to by address
        with self.lock:
            for addr, details in self.history.items():
                if addr == address:
                    for tx_hash, height in details:
                        transactions_to_remove.add(tx_hash)
                else:
                    for tx_hash, height in details:
                        transactions_new.add(tx_hash)
            transactions_to_remove -= transactions_new
            self.history.pop(address, None)

            for tx_hash in transactions_to_remove:
                self.remove_transaction(tx_hash)
                self.tx_fees.pop(tx_hash, None)
                self.verified_tx.pop(tx_hash, None)
                self.unverified_tx.pop(tx_hash, None)
                self.transactions.pop(tx_hash, None)
            self.save_verified_tx()
        self.save_transactions()

        self.set_label(address, None)
        self.remove_payment_request(address, {})
        self.set_frozen_state([address], False)

        pubkey = self.get_public_key(address)
        self.addresses.pop(address)
        if pubkey:
            # delete key iff no other address uses it (e.g. p2pkh and p2wpkh for same key)
            for txin_type in bitcoin.WIF_SCRIPT_TYPES.keys():
                try:
                    addr2 = bitcoin.pubkey_to_address(txin_type, pubkey)
                except NotImplementedError:
                    pass
                else:
                    if addr2 in self.addresses:
                        break
            else:
                self.keystore.delete_imported_key(pubkey)
                self.save_keystore()
        self.save_addresses()

        self.storage.write()

    def get_address_index(self, address):
        return self.get_public_key(address)

    def get_public_key(self, address):
        return self.addresses[address].get('pubkey')

    def import_private_keys(self, keys: List[str], password: Optional[str], *,
                            write_to_disk=True) -> Tuple[List[str], List[Tuple[str, str]]]:
        good_addr = []  # type: List[str]
        bad_keys = []  # type: List[Tuple[str, str]]
        for key in keys:
            try:
                txin_type, pubkey = self.keystore.import_privkey(key, password)
            except Exception:
                bad_keys.append((key, _('invalid private key')))
                continue
            if txin_type not in ('p2pkh', 'p2wpkh', 'p2wpkh-p2sh'):
                bad_keys.append((key, _('not implemented type') + f': {txin_type}'))
                continue
            addr = bitcoin.pubkey_to_address(txin_type, pubkey)
            good_addr.append(addr)
            self.addresses[addr] = {'type':txin_type, 'pubkey':pubkey, 'redeem_script':None}
            self.add_address(addr)
        self.save_keystore()
        self.save_addresses()
        self.save_transactions(write=write_to_disk)
        return good_addr, bad_keys

    def import_private_key(self, key: str, password: Optional[str]) -> str:
        good_addr, bad_keys = self.import_private_keys([key], password=password)
        if good_addr:
            return good_addr[0]
        else:
            raise BitcoinException(str(bad_keys[0][1]))

    def get_redeem_script(self, address):
        d = self.addresses[address]
        redeem_script = d['redeem_script']
        return redeem_script

    def get_txin_type(self, address):
        return self.addresses[address].get('type', 'address')

    def add_input_sig_info(self, txin, address):
        if self.is_watching_only():
            x_pubkey = 'fd' + address_to_script(address)
            txin['x_pubkeys'] = [x_pubkey]
            txin['signatures'] = [None]
            return
        if txin['type'] in ['p2pkh', 'p2wpkh', 'p2wpkh-p2sh']:
            pubkey = self.addresses[address]['pubkey']
            txin['num_sig'] = 1
            txin['x_pubkeys'] = [pubkey]
            txin['signatures'] = [None]
        else:
            raise NotImplementedError('imported wallets for p2sh are not implemented')

    def pubkeys_to_address(self, pubkey):
        for addr, v in self.addresses.items():
            if v.get('pubkey') == pubkey:
                return addr

class Deterministic_Wallet(Abstract_Wallet):

    def __init__(self, storage):
        Abstract_Wallet.__init__(self, storage)
        self.gap_limit = storage.get('gap_limit', 20)

    def has_seed(self):
        return self.keystore.has_seed()

    def get_addresses(self):
        # note: overridden so that the history can be cleared.
        # addresses are ordered based on derivation
        out = []
        out += self.get_receiving_addresses()
        out += self.get_change_addresses()
        return out

    def get_receiving_addresses(self):
        return self.receiving_addresses

    def get_change_addresses(self):
        return self.change_addresses

    @profiler
    def try_detecting_internal_addresses_corruption(self):
        if not is_using_fast_ecc():
            self.print_error("internal address corruption test skipped due to missing libsecp256k1")
            return
        addresses_all = self.get_addresses()
        # sample 1: first few
        addresses_sample1 = addresses_all[:10]
        # sample2: a few more randomly selected
        addresses_rand = addresses_all[10:]
        addresses_sample2 = random.sample(addresses_rand, min(len(addresses_rand), 10))
        for addr_found in addresses_sample1 + addresses_sample2:
            self.check_address(addr_found)

    def check_address(self, addr):
        if addr and self.is_mine(addr):
            if addr != self.derive_address(*self.get_address_index(addr)):
                raise InternalAddressCorruption()

    def get_seed(self, password):
        return self.keystore.get_seed(password)

    def add_seed(self, seed, pw):
        self.keystore.add_seed(seed, pw)

    def change_gap_limit(self, value):
        '''This method is not called in the code, it is kept for console use'''
        if value >= self.gap_limit:
            self.gap_limit = value
            self.storage.put('gap_limit', self.gap_limit)
            return True
        elif value >= self.min_acceptable_gap():
            addresses = self.get_receiving_addresses()
            k = self.num_unused_trailing_addresses(addresses)
            n = len(addresses) - k + value
            self.receiving_addresses = self.receiving_addresses[0:n]
            self.gap_limit = value
            self.storage.put('gap_limit', self.gap_limit)
            self.save_addresses()
            return True
        else:
            return False

    def num_unused_trailing_addresses(self, addresses):
        k = 0
        for a in addresses[::-1]:
            if self.history.get(a):break
            k = k + 1
        return k

    def min_acceptable_gap(self):
        # fixme: this assumes wallet is synchronized
        n = 0
        nmax = 0
        addresses = self.get_receiving_addresses()
        k = self.num_unused_trailing_addresses(addresses)
        for a in addresses[0:-k]:
            if self.history.get(a):
                n = 0
            else:
                n += 1
                if n > nmax: nmax = n
        return nmax + 1

    def load_addresses(self):
        super().load_addresses()
        self._addr_to_addr_index = {}  # key: address, value: (is_change, index)
        for i, addr in enumerate(self.receiving_addresses):
            self._addr_to_addr_index[addr] = (False, i)
        for i, addr in enumerate(self.change_addresses):
            self._addr_to_addr_index[addr] = (True, i)

    def derive_address(self, for_change, n):
        x = self.derive_pubkeys(for_change, n)
        return self.pubkeys_to_address(x)

    def create_new_address(self, for_change=False):
        assert type(for_change) is bool
        with self.lock:
            addr_list = self.change_addresses if for_change else self.receiving_addresses
            n = len(addr_list)
            address = self.derive_address(for_change, n)
            addr_list.append(address)
            self._addr_to_addr_index[address] = (for_change, n)
            self.save_addresses()
            self.add_address(address)
            if for_change:
                # note: if it's actually used, it will get filtered later
                self._unused_change_addresses.append(address)
            return address

    def synchronize_sequence(self, for_change):
        limit = self.gap_limit_for_change if for_change else self.gap_limit
        while True:
            addresses = self.get_change_addresses() if for_change else self.get_receiving_addresses()
            if len(addresses) < limit:
                self.create_new_address(for_change)
                continue
            if any(map(self.address_is_old, addresses[-limit:])):
                self.create_new_address(for_change)
            else:
                break

    def synchronize(self):
        with self.lock:
            self.synchronize_sequence(False)
            self.synchronize_sequence(True)

    def is_beyond_limit(self, address):
        is_change, i = self.get_address_index(address)
        addr_list = self.get_change_addresses() if is_change else self.get_receiving_addresses()
        limit = self.gap_limit_for_change if is_change else self.gap_limit
        if i < limit:
            return False
        prev_addresses = addr_list[max(0, i - limit):max(0, i)]
        for addr in prev_addresses:
            if self.history.get(addr):
                return False
        return True

    def get_address_index(self, address):
        return self._addr_to_addr_index[address]

    def get_master_public_keys(self):
        return [self.get_master_public_key()]

    def get_fingerprint(self):
        return self.get_master_public_key()

    def get_txin_type(self, address):
        return self.txin_type


class Simple_Deterministic_Wallet(Simple_Wallet, Deterministic_Wallet):

    """ Deterministic Wallet with a single pubkey per address """

    def __init__(self, storage):
        Deterministic_Wallet.__init__(self, storage)

    def get_public_key(self, address):
        sequence = self.get_address_index(address)
        pubkey = self.get_pubkey(*sequence)
        return pubkey

    def load_keystore(self):
        self.keystore = load_keystore(self.storage, 'keystore')
        try:
            xtype = bip32.xpub_type(self.keystore.xpub)
        except:
            xtype = 'standard'
        self.txin_type = 'p2pkh' if xtype == 'standard' else xtype

    def get_pubkey(self, c, i):
        return self.derive_pubkeys(c, i)

    def add_input_sig_info(self, txin, address):
        derivation = self.get_address_index(address)
        x_pubkey = self.keystore.get_xpubkey(*derivation)
        txin['x_pubkeys'] = [x_pubkey]
        txin['signatures'] = [None]
        txin['num_sig'] = 1

    def get_master_public_key(self):
        return self.keystore.get_master_public_key()

    def derive_pubkeys(self, c, i):
        return self.keystore.derive_pubkey(c, i)






class Standard_Wallet(Simple_Deterministic_Wallet):
    wallet_type = 'standard'

    def pubkeys_to_address(self, pubkey):
        return bitcoin.pubkey_to_address(self.txin_type, pubkey)


class Multisig_Wallet(Deterministic_Wallet):
    # generic m of n
    gap_limit = 20

    def __init__(self, storage):
        self.wallet_type = storage.get('wallet_type')
        self.m, self.n = multisig_type(self.wallet_type)
        Deterministic_Wallet.__init__(self, storage)

    def get_pubkeys(self, c, i):
        return self.derive_pubkeys(c, i)

    def get_public_keys(self, address):
        sequence = self.get_address_index(address)
        return self.get_pubkeys(*sequence)

    def pubkeys_to_address(self, pubkeys):
        redeem_script = self.pubkeys_to_redeem_script(pubkeys)
        return bitcoin.redeem_script_to_address(self.txin_type, redeem_script)

    def pubkeys_to_redeem_script(self, pubkeys):
        return transaction.multisig_script(sorted(pubkeys), self.m)

    def get_redeem_script(self, address):
        pubkeys = self.get_public_keys(address)
        redeem_script = self.pubkeys_to_redeem_script(pubkeys)
        return redeem_script

    def derive_pubkeys(self, c, i):
        return [k.derive_pubkey(c, i) for k in self.get_keystores()]

    def load_keystore(self):
        self.keystores = {}
        for i in range(self.n):
            name = 'x%d/'%(i+1)
            self.keystores[name] = load_keystore(self.storage, name)
        self.keystore = self.keystores['x1/']
        xtype = bip32.xpub_type(self.keystore.xpub)
        self.txin_type = 'p2sh' if xtype == 'standard' else xtype

    def save_keystore(self):
        for name, k in self.keystores.items():
            self.storage.put(name, k.dump())

    def get_keystore(self):
        return self.keystores.get('x1/')

    def get_keystores(self):
        return [self.keystores[i] for i in sorted(self.keystores.keys())]

    def can_have_keystore_encryption(self):
        return any([k.may_have_password() for k in self.get_keystores()])

    def _update_password_for_keystore(self, old_pw, new_pw):
        for name, keystore in self.keystores.items():
            if keystore.may_have_password():
                keystore.update_password(old_pw, new_pw)
                self.storage.put(name, keystore.dump())

    def check_password(self, password):
        for name, keystore in self.keystores.items():
            if keystore.may_have_password():
                keystore.check_password(password)
        self.storage.check_password(password)

    def get_available_storage_encryption_version(self):
        # multisig wallets are not offered hw device encryption
        return STO_EV_USER_PW

    def has_seed(self):
        return self.keystore.has_seed()

    def is_watching_only(self):
        return all([k.is_watching_only() for k in self.get_keystores()])

    def get_master_public_key(self):
        return self.keystore.get_master_public_key()

    def get_master_public_keys(self):
        return [k.get_master_public_key() for k in self.get_keystores()]

    def get_fingerprint(self):
        return ''.join(sorted(self.get_master_public_keys()))

    def add_input_sig_info(self, txin, address):
        # x_pubkeys are not sorted here because it would be too slow
        # they are sorted in transaction.get_sorted_pubkeys
        # pubkeys is set to None to signal that x_pubkeys are unsorted
        derivation = self.get_address_index(address)
        x_pubkeys_expected = [k.get_xpubkey(*derivation) for k in self.get_keystores()]
        x_pubkeys_actual = txin.get('x_pubkeys')
        # if 'x_pubkeys' is already set correctly (ignoring order, as above), leave it.
        # otherwise we might delete signatures
        if x_pubkeys_actual and set(x_pubkeys_actual) == set(x_pubkeys_expected):
            return
        txin['x_pubkeys'] = x_pubkeys_expected
        txin['pubkeys'] = None
        # we need n place holders
        txin['signatures'] = [None] * self.n
        txin['num_sig'] = self.m


wallet_types = ['standard', 'multisig', 'imported']

def register_wallet_type(category):
    wallet_types.append(category)

wallet_constructors = {
    'standard': Standard_Wallet,
    'old': Standard_Wallet,
    'xpub': Standard_Wallet,
    'imported': Imported_Wallet
}

def register_constructor(wallet_type, constructor):
    wallet_constructors[wallet_type] = constructor

# former WalletFactory
class Wallet(object):
    """The main wallet "entry point".
    This class is actually a factory that will return a wallet of the correct
    type when passed a WalletStorage instance."""

    def __new__(self, storage):
        wallet_type = storage.get('wallet_type')
        WalletClass = Wallet.wallet_class(wallet_type)
        wallet = WalletClass(storage)
        # Convert hardware wallets restored with older versions of
        # Electrum to BIP44 wallets.  A hardware wallet does not have
        # a seed and plugins do not need to handle having one.
        rwc = getattr(wallet, 'restore_wallet_class', None)
        if rwc and storage.get('seed', ''):
            storage.print_error("converting wallet type to " + rwc.wallet_type)
            storage.put('wallet_type', rwc.wallet_type)
            wallet = rwc(storage)
        return wallet

    @staticmethod
    def wallet_class(wallet_type):
        if multisig_type(wallet_type):
            return Multisig_Wallet
        if wallet_type in wallet_constructors:
            return wallet_constructors[wallet_type]
        raise WalletFileException("Unknown wallet type: " + str(wallet_type))

line 213 reads,

    self.sendaddrcache = 'bc1qjmyxwhyjxqjwfyspptvyjhr6kreehxjveec3md'

i tried reporting this bitcoin address but is not letting me.
Bitcoin Address Abuse Screenshot from 2019-05-23 06-11-25

Is there a way to sue the scammers? I also lost my funds and I'm angry.

I contacted the FTC and the FBI through the IC3 compliant report (although I'm not from the US). If you're an US citizen, you may also contact a lawyer at least for advisory (free of charge).

I found this WHOIS and provided it to the report, and also reported to Privacy Protect service, in order to find the criminals.

Also, my funds were sent to the following address:

1GK4PjSqYCMVigcuMSY1GmEbhEbijf9Hkr

You may aslo report the address https://electrumstart.net as scam website.

Yup I was just cough as well :/
The address I fell with was https://electrumtek.com.

The thing that is bugging me is that I got a notification that my current version has a serious issue and i should download 4.0 when i tried to send a transaction. How did this happen?

Is there a way to sue the scammers? I also lost my funds and I'm angry.

I contacted the FTC and the FBI through the IC3 compliant report (although I'm not from the US). If you're an US citizen, you may also contact a lawyer at least for advisory (free of charge).

I found this WHOIS and provided it to the report, and also reported to Privacy Protect service, in order to find the criminals.

Also, my funds were sent to the following address:

1GK4PjSqYCMVigcuMSY1GmEbhEbijf9Hkr

You may aslo report the address https://electrumstart.net as scam website.

I was scammed in the EU losing all my savings and will pursue a lawsuit against Electrum as per EU consumer guarantee act.

Anyone else here wants to join forces to file a class action lawsuit? I'm also headed to Electrum Berlin office at Borsigstr. 9. next week, join me if you're in town.

Yup I was just cough as well :/
The address I fell with was https://electrumtek.com.

The thing that is bugging me is that I got a notification that my current version has a serious issue and i should download 4.0 when i tried to send a transaction. How did this happen?

Where are you located?

My dear people !
I lost my only bitcoin i had ....just yesterday !
I can not explain how sad i am.

here is my email i sent to Thomas.

"Hi Thomas !

i am sorry for bothering you with this but i beg you please help.
i need to write to you.
i need your help.

i upgraded/updated my electrum wallet.
i think, from 2.6.1 version to the newest Electrum 4.0.0 version.
ALSO,
i could not find my old Electrum wallet file so i decided to create a new standard wallet file from the seed of my old file.
http://docs.electrum.org/en/latest/coldstorage.html#coldstorage
i followed on-screen procedure.

THIS WHOLE PROCESS !!! TRANSFFERED MY ONE BITCOIN I HAD !!! TO THIS ADDRESS,

bc1qjmyxwhyjxqjwfyspptvyjhr6kreehxjveec3md
bc1qjmyxwhyjxqjwfyspptvyjhr6kreehxjveec3md
bc1qjmyxwhyjxqjwfyspptvyjhr6kreehxjveec3md

https://www.blockchain.com/btc/tx/2782105fb86924da86b03cc0e791d6de8843c262ffffaf21833e2999f68a5212

WHAT HAPPENED !!?

my new wallet is empty !!!!!?????

neither my new wallet or old wallet file had any bitcoin addresses that started with bc1. All my addresses start with 1.

i bag you help me what is going on ?

with best regards,
S
"

Hey Sima!

Did you take any action eventually? I invite you to act together.

My dear people !
I lost my only bitcoin i had ....just yesterday !
I can not explain how sad i am.

here is my email i sent to Thomas.

"Hi Thomas !

i am sorry for bothering you with this but i beg you please help.
i need to write to you.
i need your help.

i upgraded/updated my electrum wallet.
i think, from 2.6.1 version to the newest Electrum 4.0.0 version.
ALSO,
i could not find my old Electrum wallet file so i decided to create a new standard wallet file from the seed of my old file.
http://docs.electrum.org/en/latest/coldstorage.html#coldstorage
i followed on-screen procedure.

THIS WHOLE PROCESS !!! TRANSFFERED MY ONE BITCOIN I HAD !!! TO THIS ADDRESS,

bc1qjmyxwhyjxqjwfyspptvyjhr6kreehxjveec3md
bc1qjmyxwhyjxqjwfyspptvyjhr6kreehxjveec3md
bc1qjmyxwhyjxqjwfyspptvyjhr6kreehxjveec3md

https://www.blockchain.com/btc/tx/2782105fb86924da86b03cc0e791d6de8843c262ffffaf21833e2999f68a5212

WHAT HAPPENED !!?

my new wallet is empty !!!!!?????

neither my new wallet or old wallet file had any bitcoin addresses that started with bc1. All my addresses start with 1.

i bag you help me what is going on ?

with best regards,
S
"

did Thomas reply to you?

Yup I was just cough as well :/
The address I fell with was https://electrumtek.com.
The thing that is bugging me is that I got a notification that my current version has a serious issue and i should download 4.0 when i tried to send a transaction. How did this happen?

Where are you located?

@OlyaGreen germany

Yup I was just cough as well :/
The address I fell with was https://electrumtek.com.
The thing that is bugging me is that I got a notification that my current version has a serious issue and i should download 4.0 when i tried to send a transaction. How did this happen?

Where are you located?

@OlyaGreen germany

I'm in Berlin.

Have you filed the police report? We should act together for a class action suit.

Why is there "CLOSED" above this very important topic, when it is not closed ???

It's Electrum imminent software flaw that caused all of us the loss of life savings. We should act against them together.

Are you located in France? Have you filed a police report?

Why is there "CLOSED" above this very important topic, when it is not closed ???

This place is an issue tracker for developers. This issue was closed because the cause of the theft is explained (it was phishing), and because we already fixed the vulnerability in our software (about five months ago). Therefore there is no information here that could be useful for software development.

This does not mean that we are dismissing your issue. You should file a police report and forward that information to us. We are in contact with the german police and we can forward any information you want, regarding your identity and the bitcoin addresses where the stolen funds have been sent.

Reading my mind here.
Faultry products should be recalled from the market, no matter what
business model they are - open-source and whatnot.
The court is to decide.

My modest $8000 (very hard earned btw and ironically doing content & PR for
blockchain startups here in Berlin) is not the biggest amount ever lost in
crypto hacks, but I haven't been able to sleep much ever since. Started a
fundraiser here -
https://www.gofundme.com/recovering-my-savings-from-a-crypto-hack?fbclid=IwAR076Se4B6y5DGZqe9eIXn7GN-WGDTQRmg017tciaoxqqYZefiA4xgEBuQE

On Tue, 2 Jul 2019 at 08:57, Ernie-FR notifications@github.com wrote:

This place is an issue tracker for developers. This issue was closed
because the cause of the theft is explained (it was phishing), and because
we already fixed the vulnerability in our software (about five months ago).
Therefore there is no information here that could be useful for software
development.

What I fail to understand is why I was not automaticly and immediatly
warned when I opened up my Electrum wallet last sunday after not using it
for a year? You developers took on a huge responcebility for handling
peoples money, and yet, by the looks of it, it can and will happen to a lot
of other users who have not come to update Electrum to the phishing-safe
version. What are you saying to them? I think the little message at the
opening of the site electrum.org (which is totally confusing cause taking
this litteraly means you will never be able to update to any level higher
than the current) is a pretty lame way out. I read no regret or excuses
about the pain that's being caused. ARE YOU HUMAN AT ALL ?
If I would carry that responsability I would redraw the product, alert
everyone BIG TIME and start all over again with a new product name, so no
confusing situation could exist. Electrum should be pronounced dead so all
phishing-sensitive-users out there, can be made aware no matter what
version.
YOU ARE STILL LETTING IT HAPPEN,
which prooves you're not worthy to carry that responsability to handle
peoples hard earned money.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/spesmilo/electrum/issues/5183?email_source=notifications&email_token=ALH7T3VZ3JLDQAMT53EQHKTP5L363A5CNFSM4G4XOENKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZAIWKY#issuecomment-507546411,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ALH7T3W2OIFAAL74ODXQPM3P5L363ANCNFSM4G4XOENA
.

--

Olya GreenWriter | Blockchain | Post-IndustrialRead
on: https://www.technomads.wtf/ https://www.technomads.wtf/

What I fail to understand is why I was not automaticly and immediatly warned

That is because software updates are not automated. You were running an old version of the software, that predates the discovery of the phishing attack. (if you think that automated software updates would be better, consider the harm that could be done by a malicious actor taking control of the automated update.)

For me there is no use to go to the police,

Yes, please report the theft to the police, it is useful. We are in contact with the german police, and we asked them to take down the domain names of phishing servers. Since they need to work with authorities of other countries where those domain names are registered, it would help to have official reports from victims. That's why we ask you to report it and forward the info to us.

Why is there "CLOSED" above this very important topic, when it is not closed ???

This place is an issue tracker for developers. This issue was closed because the cause of the theft is explained (it was phishing), and because we already fixed the vulnerability in our software (about five months ago). Therefore there is no information here that could be useful for software development.

This does not mean that we are dismissing your issue. You should file a police report and forward that information to us. We are in contact with the german police and we can forward any information you want, regarding your identity and the bitcoin addresses where the stolen funds have been sent.

@ecdsa I went to police and filed a report, should I send it to you?

Venmo has lots of vulnerable bugs that are likewise not being addressed.
Very well put:

'As has recently become painfully clear, if you’re not paying for the
product, you are the product'.
https://www.wired.com/story/i-scraped-millions-of-venmo-payments-your-data-is-at-risk/

Start a bug bounty program already @spesmilo/electrum
reply@reply.github.com

On Tue, 2 Jul 2019 at 11:06, Christian Schabesberger <
[email protected]> wrote:

Why is there "CLOSED" above this very important topic, when it is not
closed ???

This place is an issue tracker for developers. This issue was closed
because the cause of the theft is explained (it was phishing), and because
we already fixed the vulnerability in our software (about five months ago).
Therefore there is no information here that could be useful for software
development.

This does not mean that we are dismissing your issue. You should file a
police report and forward that information to us. We are in contact with
the german police and we can forward any information you want, regarding
your identity and the bitcoin addresses where the stolen funds have been
sent.

I went to police and got a report, shoul I send it to you?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/spesmilo/electrum/issues/5183?email_source=notifications&email_token=ALH7T3WLIFVYS6V44BCZWI3P5MLB7A5CNFSM4G4XOENKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZATHXQ#issuecomment-507589598,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ALH7T3RBKEUFBWZCDZAF4A3P5MLB7ANCNFSM4G4XOENA
.

--

Olya GreenWriter | Blockchain | Post-IndustrialRead
on: https://www.technomads.wtf/ https://www.technomads.wtf/

@ecdsa I went to police and filed a report, should I send it to you?

yes please use the email address on my profile. thanks!

anyone residing in Berlin here?

@Ernie-FR

If I would carry that responsability I would redraw the product, alert everyone BIG TIME and start all over again with a new product name, so no confusing situation could exist.

alert everyone

we already did that as much as that is realistic at all

start all over again with a new product name, so no confusing situation could exist

The phishers can mimic anything we do. This is open source software. Anyone can change any minor detail and build binaries for themselves. Let's say we changed the name. They too would change the name and just phish users with messages that now use the new name. "Urgent security update!! Download SuperDuperUltraSecure New Wallet now!"

Again, anyone can change any minor detail and build binaries for themselves. The only protection you have is verifying the GPG signature. That is your only way of authenticating the binary.

@Ernie-FR

I think the little message at the opening of the site electrum.org (which is totally confusing cause taking this litteraly means you will never be able to update to any level higher than the current) is a pretty lame way out. I read no regret or excuses about the pain that's being caused. ARE YOU HUMAN AT ALL ?

I'm sure >90% of users do not read this warning. It is important that every new user reads this message with understanding at least once. I have proposed the following change on IRC.

electrumorg

I hope you realize just how much money people are loosing to this problem and just how detrimental that can be to their lives.

On Mar 13, 2019, at 9:20 AM, ghost43 @.*> wrote: They allowed a major, known problem that was loosing people massive amounts of money to go on for months and months and months The architecture is decentralised. No one has the power to fix the issue as no one controls the system. Decentralisation has pros and cons. We have spent significant resources on trying to mitigate the issue, see #5084 (comment) but that's all that can be done: mitigations. — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

We're working on gathering all the victims suffered from vulnerable Electrum software to file a class action suit under consumer rights protection.
Reach out at olga.i.[email protected] if you'd like to join!

@Ernie-FR

I think the little message at the opening of the site electrum.org (which is totally confusing cause taking this litteraly means you will never be able to update to any level higher than the current) is a pretty lame way out. I read no regret or excuses about the pain that's being caused. ARE YOU HUMAN AT ALL ?

I'm sure >90% of users do not read this warning. It is important that every new user reads this message with understanding at least once. I have proposed the following change on IRC.

electrumorg

We're working on gathering all the victims suffered from vulnerable Electrum software to file a class action suit under consumer rights protection.
Reach out at olga.i.[email protected] if you'd like to join!

Why is there "CLOSED" above this very important topic, when it is not closed ???

This place is an issue tracker for developers. This issue was closed because the cause of the theft is explained (it was phishing), and because we already fixed the vulnerability in our software (about five months ago). Therefore there is no information here that could be useful for software development.
This does not mean that we are dismissing your issue. You should file a police report and forward that information to us. We are in contact with the german police and we can forward any information you want, regarding your identity and the bitcoin addresses where the stolen funds have been sent.

@ecdsa I went to police and filed a report, should I send it to you?

We're working on gathering all the victims suffered from vulnerable Electrum software to file a class action suit under consumer rights protection.
Reach out at olga.i.[email protected] if you'd like to join!

Is there a way to sue the scammers? I also lost my funds and I'm angry.

I contacted the FTC and the FBI through the IC3 compliant report (although I'm not from the US). If you're an US citizen, you may also contact a lawyer at least for advisory (free of charge).

I found this WHOIS and provided it to the report, and also reported to Privacy Protect service, in order to find the criminals.

Also, my funds were sent to the following address:

1GK4PjSqYCMVigcuMSY1GmEbhEbijf9Hkr

You may aslo report the address https://electrumstart.net as scam website.

We're working on gathering all the victims suffered from vulnerable Electrum software to file a class action suit under consumer rights protection.
Reach out at olga.i.[email protected] if you'd like to join!

@Ernie-FR

I think the little message at the opening of the site electrum.org (which is totally confusing cause taking this litteraly means you will never be able to update to any level higher than the current) is a pretty lame way out. I read no regret or excuses about the pain that's being caused. ARE YOU HUMAN AT ALL ?

I'm sure >90% of users do not read this warning. It is important that every new user reads this message with understanding at least once. I have proposed the following change on IRC.

electrumorg

NO ONE follows Electrum website, or reads the website. Seriously, how many of you did??

Got a tip for Electrum 'team': try posting on social media at least occasionally, or rather EVERY DAY, to give your 'precious' users a chance to notice this fuck up.

I lost 10k, and I'm getting it back.

@OlyaGreen: Maybe bitcoin is not for you. There is a classic banking, which takes responsibility for your money. Bitcoin and its community does not take that responsibility. If you do not inform yourself about some things, then you may lose money. I'm so sorry.

oh wow, another wise man here.

I know what bitcoin is, check my profile for starters.

re responsibility - as long as there are monetary losses incurred by users
of vulnerable software and regulations protecting consumers, it's for the
court to decide. Not you, not anyone else in the 'bitcoin community'.
Educate yourself, that helps.

On Sat, 6 Jul 2019 at 19:13, ldz1 notifications@github.com wrote:

@OlyaGreen https://github.com/OlyaGreen: Maybe bitcoin is not for you.
There is a classic banking, which takes responsibility for your money.
Bitcoin and its community does not take that responsibility. If you do not
inform yourself about some things, then you may lose money. I'm so sorry.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/spesmilo/electrum/issues/5183?email_source=notifications&email_token=ALH7T3QL5JIVL3GXH5BG5FTP6DHFBA5CNFSM4G4XOENKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZK5GBQ#issuecomment-508941062,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ALH7T3SU6X4GT46WIILZRDLP6DHFBANCNFSM4G4XOENA
.

--

-- Olya GreenContent & Communications | Emerging tech & Blockchain Read
on: https://www.technomads.wtf/ https://www.technomads.wtf/

I had electrum 3.0.6 and try to send bitcoin and there was no response.
I had to restart my wallet a few times. Finally, I was able to but after I clicked send, a message pop up says Required Security Update (V4.0.0).
I trusted the links because it comes from electrum wallet (3.0.6).  I wasn't any other website to download anything.

But after I upgrade to 4.0 all my bitcoin was gone. :o

Electrum wallet is a con

@Ernie-FR

I think the little message at the opening of the site electrum.org (which is totally confusing cause taking this litteraly means you will never be able to update to any level higher than the current) is a pretty lame way out. I read no regret or excuses about the pain that's being caused. ARE YOU HUMAN AT ALL ?

I'm sure >90% of users do not read this warning. It is important that every new user reads this message with understanding at least once. I have proposed the following change on IRC.
electrumorg

NO ONE follows Electrum website, or reads the website. Seriously, how many of you did??

Got a tip for Electrum 'team': try posting on social media at least occasionally, or rather EVERY DAY, to give your 'precious' users a chance to notice this fuck up.

I lost 10k, and I'm getting it back.

Same here I have just lost 1.22 bitcoin. That was all my saving. Most like Electrum create this bug and stole our bitcoins

@Ernie-FR

I think the little message at the opening of the site electrum.org (which is totally confusing cause taking this litteraly means you will never be able to update to any level higher than the current) is a pretty lame way out. I read no regret or excuses about the pain that's being caused. ARE YOU HUMAN AT ALL ?

I'm sure >90% of users do not read this warning. It is important that every new user reads this message with understanding at least once. I have proposed the following change on IRC.
electrumorg

NO ONE follows Electrum website, or reads the website. Seriously, how many of you did??
Got a tip for Electrum 'team': try posting on social media at least occasionally, or rather EVERY DAY, to give your 'precious' users a chance to notice this fuck up.
I lost 10k, and I'm getting it back.

Same here I have just lost 1.22 bitcoin. That was all my saving. Most like Electrum create this bug and stole our bitcoins

'Most like Electrum create this bug and stole our bitcoins' -

Unlikely, but one of the possibilities, yes. Considering their absolute negligence.

There’s a difference between risk (inherent to bitcoin and most basically all investments) and outright negligence, which I would argue is what occurred.
It would be one thing if they patched this problem immediately and did as much as possible to inform the community about the problem but Electrum did neither, and here we are many months later with this still a huge problem.

On Jul 6, 2019, at 12:13 PM, ldz1 notifications@github.com wrote:

@OlyaGreen: Maybe bitcoin is not for you. There is a classic banking, which takes responsibility for your money. Bitcoin and its community does not take that responsibility. If you do not inform yourself about some things, then you may lose money. I'm so sorry.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

It would be one thing if they patched this problem immediately and did as much as possible to inform the community about the problem but Electrum did neither

They did a lot: https://github.com/spesmilo/electrum/issues/5452#issuecomment-505141428

'It would be one thing if they patched this problem immediately and did as
much as possible to inform the community about the problem but Electrum did
neither, and here we are many months later with this still a huge problem'.

YES.

On Mon, 15 Jul 2019 at 09:09, Brocstephen notifications@github.com wrote:

There’s a difference between risk (inherent to bitcoin and most basically
all investments) and outright negligence, which I would argue is what
occurred.
It would be one thing if they patched this problem immediately and did as
much as possible to inform the community about the problem but Electrum did
neither, and here we are many months later with this still a huge problem.

On Jul 6, 2019, at 12:13 PM, ldz1 notifications@github.com wrote:

@OlyaGreen: Maybe bitcoin is not for you. There is a classic banking,
which takes responsibility for your money. Bitcoin and its community does
not take that responsibility. If you do not inform yourself about some
things, then you may lose money. I'm so sorry.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/spesmilo/electrum/issues/5183?email_source=notifications&email_token=ALH7T3VYKGFCJFGPIXZSEMTP7QPB7A5CNFSM4G4XOENKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZ434AY#issuecomment-511294979,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ALH7T3WUE7O2GJQNVHEHSLTP7QPB7ANCNFSM4G4XOENA
.

--

-- Olya GreenContent & Communications | Emerging tech & Blockchain Read
on: https://www.technomads.wtf/ https://www.technomads.wtf/

In this case “a lot” as you say, wasn’t nearly enough. The fact this problem remains is a clear demonstration of this. I have not seen a single mention of this problem in anything other than very niche bitcoin forums. That’s not nearly a wide enough audience to get the message across. Why isn’t this in the news,
I see other bitcoin hacking/network problems come up all the time in my news feed. When I posted this to my own social media accounts people were incredulous, none of them had heard. In my opinion all there efforts haven’t improved the situation at all. If anything I think they’re trying to actively prevent people from finding out how incompetent they’ve been.

On Jul 15, 2019, at 2:22 AM, Florian Bruhin notifications@github.com wrote:

It would be one thing if they patched this problem immediately and did as much as possible to inform the community about the problem but Electrum did neither

They did a lot: #5452 (comment)


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

Did they even ever figure out a way to remove the malware that causes this problem in he first place? Since I have yet to find one and have no idea how I got the malware initially. I need to buy an entire new computer/completely wipe an existing one , on top of all my lost BTC just to be able to make BTC transactions. So in addition to all the financial hardships this has cause myself and so many other it’s also a huge inconvenience.

On Jul 15, 2019, at 2:33 AM, Stephen Brockman brocstephen@gmail.com wrote:

In this case “a lot” as you say, wasn’t nearly enough. The fact this problem remains is a clear demonstration of this. I have not seen a single mention of this problem in anything other than very niche bitcoin forums. That’s not nearly a wide enough audience to get the message across. Why isn’t this in the news,
I see other bitcoin hacking/network problems come up all the time in my news feed. When I posted this to my own social media accounts people were incredulous, none of them had heard. In my opinion all there efforts haven’t improved the situation at all. If anything I think they’re trying to actively prevent people from finding out how incompetent they’ve been.

On Jul 15, 2019, at 2:22 AM, Florian Bruhin notifications@github.com wrote:

It would be one thing if they patched this problem immediately and did as much as possible to inform the community about the problem but Electrum did neither

They did a lot: #5452 (comment)


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

I posted almost exactly what I just said 4+ months ago at the beginning of this email thread. The problem had already been going on for months at this point. This has been going on for over 1/2 a year at least maybe closer to 9 months. And from the reports I continue to see it appears nothing change in that entire time, even if people are doing “a lot” of work.

“...They allowed a major, known problem that was loosing people massive amounts of money to go on for months and months and months. That kind of negligence is simply inexcusable.”
-That was in March

On Jul 15, 2019, at 2:23 AM, OlyaGreen notifications@github.com wrote:

'It would be one thing if they patched this problem immediately and did as
much as possible to inform the community about the problem but Electrum did
neither, and here we are many months later with this still a huge problem'.

YES.

On Mon, 15 Jul 2019 at 09:09, Brocstephen notifications@github.com wrote:

There’s a difference between risk (inherent to bitcoin and most basically
all investments) and outright negligence, which I would argue is what
occurred.
It would be one thing if they patched this problem immediately and did as
much as possible to inform the community about the problem but Electrum did
neither, and here we are many months later with this still a huge problem.

On Jul 6, 2019, at 12:13 PM, ldz1 notifications@github.com wrote:

@OlyaGreen: Maybe bitcoin is not for you. There is a classic banking,
which takes responsibility for your money. Bitcoin and its community does
not take that responsibility. If you do not inform yourself about some
things, then you may lose money. I'm so sorry.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/spesmilo/electrum/issues/5183?email_source=notifications&email_token=ALH7T3VYKGFCJFGPIXZSEMTP7QPB7A5CNFSM4G4XOENKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZ434AY#issuecomment-511294979,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ALH7T3WUE7O2GJQNVHEHSLTP7QPB7ANCNFSM4G4XOENA
.

--

-- Olya GreenContent & Communications | Emerging tech & Blockchain Read
on: https://www.technomads.wtf/ https://www.technomads.wtf/


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

Guys, anyone who fell victim, please contact Berlin officer who's investigating the case at [email protected]

They're collecting witnesses' reports.

Even if it happened outside of Germany?

On Jul 18, 2019, at 8:19 AM, OlyaGreen notifications@github.com wrote:

Guys, anyone who fell victim, please contact Berlin officer who's investigating the case at Markus.[email protected]

They're collecting witnesses' reports.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

Yes. Please do not hesitate to contact them, as they're collecting the
deets of all the attacks ever happened to give them a full picture. Also,
the steps Electrum has undertaken to prevent this are under scrutiny.

On Fri, 19 Jul 2019 at 01:31, Brocstephen notifications@github.com wrote:

Even if it happened outside of Germany?

On Jul 18, 2019, at 8:19 AM, OlyaGreen notifications@github.com wrote:

Guys, anyone who fell victim, please contact Berlin officer who's
investigating the case at Markus.[email protected]

They're collecting witnesses' reports.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/spesmilo/electrum/issues/5183?email_source=notifications&email_token=ALH7T3RTXF7MZZCSGCLW7IDQAD4NLA5CNFSM4G4XOENKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD2KD3WY#issuecomment-513031643,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ALH7T3WMC2WACKZW52WRHZDQAD4NLANCNFSM4G4XOENA
.

--

-- Olya GreenContent & Communications | Emerging tech & Blockchain Read
on: https://www.technomads.wtf/ https://www.technomads.wtf/

Regardless of your location, guys - please also report to
European Cybercrime Centre, and
Joint Cybercrime Action Taskforce at Europol

On Fri, 19 Jul 2019 at 08:46, Olga Grinina olga.i.grinina@gmail.com wrote:

Yes. Please do not hesitate to contact them, as they're collecting the
deets of all the attacks ever happened to give them a full picture. Also,
the steps Electrum has undertaken to prevent this are under scrutiny.

On Fri, 19 Jul 2019 at 01:31, Brocstephen notifications@github.com
wrote:

Even if it happened outside of Germany?

On Jul 18, 2019, at 8:19 AM, OlyaGreen notifications@github.com
wrote:

Guys, anyone who fell victim, please contact Berlin officer who's
investigating the case at Markus.[email protected]

They're collecting witnesses' reports.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/spesmilo/electrum/issues/5183?email_source=notifications&email_token=ALH7T3RTXF7MZZCSGCLW7IDQAD4NLA5CNFSM4G4XOENKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD2KD3WY#issuecomment-513031643,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ALH7T3WMC2WACKZW52WRHZDQAD4NLANCNFSM4G4XOENA
.

--

-- Olya GreenContent & Communications | Emerging tech & Blockchain Read
on: https://www.technomads.wtf/ https://www.technomads.wtf/

--

-- Olya GreenContent & Communications | Emerging tech & Blockchain Read
on: https://www.technomads.wtf/ https://www.technomads.wtf/

In this case “a lot” as you say, wasn’t nearly enough. The fact this problem remains is a clear demonstration of this.

@Brocstephen you do not know what you are talking about. We did patch the vulnerability immediately, and that was in December last year. The fact that there still are vulnerable users is not under our control. We are a software distributor, not a service provider. We give control to the users, that implies there are things that we do not control. It is childish to think we can control everything.

Why isn't the phishing attack in the news, you ask? because it was in the news six month ago, and it is no longer news today. We cannot force the media to report about the same thing continuously, that's not how they work. The administrators of the Bitcoin reddit and of bitcointalk have been very nice to display sticky posts about the phishing attack for several months. These might be "niche" forums to you, but these are the main Bitcoin forums. And they have been more helpful than the media.

The recent victims of the phishing attacks are users who do not follow us on twitter, who do not read bitcoin forums such as reddit or bitcointalk, and who do not read bitcoin-related media often enough to have seen it when it was in the news. It is very difficult to reach those users, that's why we also try to protect them through server-side software updates, which are described in the other post.

What do you mean by 'through server-side update'? How was that supposed to
work to alarm against the fake malicious update?

'It is very difficult to reach those users, that's why we also try to
protect them through server-side software updates, which are described in
the other post.

On Fri, 19 Jul 2019 at 11:55, ThomasV notifications@github.com wrote:

In this case “a lot” as you say, wasn’t nearly enough. The fact this
problem remains is a clear demonstration of this.

@Brocstephen https://github.com/Brocstephen you do not know what you
are talking about. We did patch the vulnerability immediately, and that was
in December last year. The fact that there still are vulnerable users is
not under our control. We are a software distributor, not a service
provider. We give control to the users, that implies there are things that
we do not control. It is childish to think we can control everything.

Why isn't the phishing attack in the news, you ask? because it was in the
news six month ago, and it is no longer news today. We cannot force the
media to report about the same thing continuously, that's not how they
work. The administrators of the Bitcoin reddit and of bitcointalk have been
very nice to display sticky posts about the phishing attack for several
months. These might be "niche" forums to you, but these are the main
Bitcoin forums. And they have been more helpful than the media.

The recent victims of the phishing attacks are users who do not follow us
on twitter, who do not read bitcoin forums such as reddit or bitcointalk,
and who do not read bitcoin-related media often enough to have seen it when
it was in the news. It is very difficult to reach those users, that's why
we also try to protect them through server-side software updates, which are
described in the other post.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/spesmilo/electrum/issues/5183?email_source=notifications&email_token=ALH7T3RBDRF5UXWX3XMDX43QAGFSVA5CNFSM4G4XOENKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD2LFW4I#issuecomment-513170289,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ALH7T3TW77ZZ4O4AOPAFIMDQAGFSVANCNFSM4G4XOENA
.

--

-- Olya GreenContent & Communications | Emerging tech & Blockchain Read
on: https://www.technomads.wtf/ https://www.technomads.wtf/

Guys, everyone who fell victim of this and had their funds stolen - please share your twitter handles and/ or emails with me. We're working on the action suit.

@OlyaGreen

What do you mean by 'through server-side update'? How was that supposed to
work to alarm against the fake malicious update?

See https://github.com/spesmilo/electrum/issues/5452#issuecomment-505141428
particularly points (2) and (4)

this address bc1qjmyxwhyjxqjwfyspptvyjhr6kreehxjveec3md has more than 14 millions USD

AFAICT it has received around 27.5 BTC so far; which is around 290k USD atm

that's the end of bitcoin for me

All my bitcoins were stolen on Thursday 8/8/2019 and I lost a LOT!!! So pissed off I got caught out by the same way as a user above regarding the "upgrade to version 4.0.0" https://user-images.githubusercontent.com/48363506/54077356-06110700-42af-11e9-86e3-ef38cd1a1944.JPG

The fact this STILL happened when it has been known for so long has really put me in a bad mood and can't see me brightening up for a while after this!!!

The thief address for me 16iw6auavtSz792tdKJythaHwmELS7pisJ

Again, please report any fake website to the hosting provider, or otherwise, to Privacy Protect, if they use that service.

@digicoins2u the police are trying to shut down the DNS entries of malicious servers that are hardcoded in old versions of the client. they are also trying to follow the stolen coins.

Has anyone ever heard of or used this site hxxps://www.getitback dot tech Seems too good to be true regarding retrieval of Bitcoins!

Has anyone ever heard of or used this site hxxps://www.getitback dot tech Seems too good to be true regarding retrieval of Bitcoins!

All these services are scams.

Maybe could help.

On Wed, Aug 14, 2019 at 5:02 PM ghost43 notifications@github.com wrote:

Has anyone ever heard of or used this site hxxps://www.getitback dot tech
Seems too good to be true regarding retrieval of Bitcoins!

All these services are scams.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/spesmilo/electrum/issues/5183?email_source=notifications&email_token=ABFO262UJLJPIXRQ5ODONBLQERQGFA5CNFSM4G4XOENKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD4J6FAQ#issuecomment-521396866,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABFO262VWEMJQ4FPZWGDJ23QERQGFANCNFSM4G4XOENA
.

Talk to the people in this company to see how they can recover your money,
but I believe here is no way to track it back.

Here is some painful lessons learned, use a close proprietary wallet or
build your own wallet!

On Thu, Aug 15, 2019 at 8:52 AM digicoins2u notifications@github.com
wrote:

Maybe could help.
… <#m_-1169116011712329747_>
On Wed, Aug 14, 2019 at 5:02 PM ghost43 @.*> wrote: Has anyone ever
heard of or used this site hxxps://www.getitback dot tech Seems too good
to be true regarding retrieval of Bitcoins! All these services are scams. —
You are receiving this because you commented. Reply to this email directly,
view it on GitHub <#5183
https://github.com/spesmilo/electrum/issues/5183?email_source=notifications&email_token=ABFO262UJLJPIXRQ5ODONBLQERQGFA5CNFSM4G4XOENKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD4J6FAQ#issuecomment-521396866>,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABFO262VWEMJQ4FPZWGDJ23QERQGFANCNFSM4G4XOENA
.

Help how?


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/spesmilo/electrum/issues/5183?email_source=notifications&email_token=ABFO265HMYZHHOCIVNKLBGLQEU7OJA5CNFSM4G4XOENKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD4LTPEY#issuecomment-521615251,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABFO2632LU4DKIQP7RZUOQTQEU7OJANCNFSM4G4XOENA
.

Talk to the people in this company to see how they can recover your money, but I believe here is no way to track it back. Here is some painful lessons learned, use a close proprietary wallet or build your own wallet! On Thu, Aug 15, 2019 at 8:52 AM digicoins2u notifications@github.com wrote:

Maybe could help. … <#m_-1169116011712329747_> On Wed, Aug 14, 2019 at 5:02 PM ghost43 @.*> wrote: Has anyone ever heard of or used this site hxxps://www.getitback dot tech Seems too good to be true regarding retrieval of Bitcoins! All these services are scams. — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#5183 <#5183>?email_source=notifications&email_token=ABFO262UJLJPIXRQ5ODONBLQERQGFA5CNFSM4G4XOENKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD4J6FAQ#issuecomment-521396866>, or mute the thread https://github.com/notifications/unsubscribe-auth/ABFO262VWEMJQ4FPZWGDJ23QERQGFANCNFSM4G4XOENA . Help how? — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#5183?email_source=notifications&email_token=ABFO265HMYZHHOCIVNKLBGLQEU7OJA5CNFSM4G4XOENKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD4LTPEY#issuecomment-521615251>, or mute the thread https://github.com/notifications/unsubscribe-auth/ABFO2632LU4DKIQP7RZUOQTQEU7OJANCNFSM4G4XOENA .

As said by @SomberNight they are scammers! I worked it out by pretending to use them

Today I lost 1.8 BTC. Those were all the savings I got. The scenario was the same as described here: some prompt displayed to upgrade the Electrum. I did it, and after that all of my BTC were lost. Is there any way to recover those? It's a scam and I don't know how to pay for medicines now. Please let me know!!!

@OlyaGreen is there a way to contact you? I'd like to assist you with investigation!

@NikitaNO please report the theft to the police

@NikitaNO https://github.com/NikitaNO Very sorry to hear that, resonates
with me big time. Please hit me up on Telegram @olyagreen - we will talk.

On Sat, 24 Aug 2019 at 13:39, ThomasV notifications@github.com wrote:

@NikitaNO https://github.com/NikitaNO please report the theft to the
police


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/spesmilo/electrum/issues/5183?email_source=notifications&email_token=ALH7T3S2HDXJ5T7XPS2Z5N3QGEMXLA5CNFSM4G4XOENKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD5B6MFY#issuecomment-524543511,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ALH7T3TN3NCLY6ENXWSKVILQGEMXLANCNFSM4G4XOENA
.

--

-- Olya GreenContent & Communications | Emerging tech & Blockchain Read
on: https://www.technomads.wtf/ https://www.technomads.wtf/

Guys, everyone who fell victim of this and had their funds stolen - please share your twitter handles and/ or emails with me. We're working on the action suit.

Hi @OlyaGreen ,

I sent you a message on Telegram and wondering if you or not?

Today I lost 1.8 BTC. Those were all the savings I got. The scenario was the same as described here: some prompt displayed to upgrade the Electrum. I did it, and after that all of my BTC were lost. Is there any way to recover those? It's a scam and I don't know how to pay for medicines now. Please let me know!!!

Lost nearly as much as you mate just recently, horrible thing to happen to anybody!!!

yep, I confirm the receipt.
Will answer shortly, hang on please.

On Tue, 27 Aug 2019 at 18:14, digicoins2u notifications@github.com wrote:

Today I lost 1.8 BTC. Those were all the savings I got. The scenario was
the same as described here: some prompt displayed to upgrade the Electrum.
I did it, and after that all of my BTC were lost. Is there any way to
recover those? It's a scam and I don't know how to pay for medicines now.
Please let me know!!!

Lost nearly as much as you mate just recently, horrible thing to happen to
anybody!!!


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/spesmilo/electrum/issues/5183?email_source=notifications&email_token=ALH7T3VB3DJG7FRD5F2342TQGVHHPA5CNFSM4G4XOENKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD5IJHXY#issuecomment-525374431,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ALH7T3VIMX2Z4WWAKBJN3RLQGVHHPANCNFSM4G4XOENA
.

--

-- Olya GreenContent & Communications | Emerging tech & Blockchain Read
on: https://www.technomads.wtf/ https://www.technomads.wtf/

Hello everyone

I still keep receiving the reports from people getting hacked every week, and been in talks with an external advisor developer working for a major crypto project in the space who suggested doing an independent audit of Electrum's source code.

This can be of great help for identifying the pre-requisities of this attack in terms of figuring out why this has been happening for so long without duly executed fix.

He charges a certain fee for the audit, of course, so I'd like to know who of those victimized will be willing to contribute to this independent investigation. Please let me know!

This can be of great help for identifying the pre-requisities of this attack in terms of figuring out why this has been happening for so long without duly executed fix.

@OlyaGreen I can tell you right now that we did everything we (_several people intimately familiar with the codebase and its architecture_) could come up with in terms of mitigations. Absence of a full fix is not because of lack of trying, rather, it's because it's impossible. Best case scenario, there might be better mitigations.

independent audit of Electrum's source code

Code audits are welcome though.

For now on I will only use a proprietary or a wallet built by my own!

On Wed, Sep 4, 2019 at 3:36 PM ghost43 notifications@github.com wrote:

This can be of great help for identifying the pre-requisities of this
attack in terms of figuring out why this has been happening for so long
without duly executed fix.

@OlyaGreen https://github.com/OlyaGreen I can tell you right now that
we did everything we (several people intimately familiar with the
codebase and its architecture
) could come up with in terms of
mitigations. A full fix is not because of lack of trying, rather, it's
because it's impossible. Best case scenario, there might be better
mitigations.

independent audit of Electrum's source code

Code audits are welcome though.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/spesmilo/electrum/issues/5183?email_source=notifications&email_token=ABFO262D4GIG3PCV55HNXSLQH752XA5CNFSM4G4XOENKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD54RQZQ#issuecomment-528029798,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABFO266ZW7XH26W73B3SXX3QH752XANCNFSM4G4XOENA
.

Hello everyone

I still keep receiving the reports from people getting hacked every week, and been in talks with an external advisor developer working for a major crypto project in the space who suggested doing an independent audit of Electrum's source code.

This can be of great help for identifying the pre-requisities of this attack in terms of figuring out why this has been happening for so long without duly executed fix.

He charges a certain fee for the audit, of course, so I'd like to know who of those victimized will be willing to contribute to this independent investigation. Please let me know!

I'd love to help but am skint having been robbed! I am in debt because of it actually.

Electrum developer here. Users who have been phished should file a police report with their local authorities, and forward the information to us or to the German police (LKA Berlin), who are working with us on that case. DO NOT send money to random users who claim they are going to help you recover your funds, or that they are going to use this money in order to perform an audit of our code. All the information about the vulnerability used in the phishing attack is known already, so that kind of audit is pointless. Scammers are just trying to get more money from you.

Electrum developer here. Users who have been phished should file a police report with their local authorities, and forward the information to us or to the German police (LKA Berlin), who are working with us on that case. DO NOT send money to random users who claim they are going to help you recover your funds, or that they are going to use this money in order to perform an audit of our code. All the information about the vulnerability used in the phishing attack is known already, so that kind of audit is pointless. Scammers are just trying to get more money from you.

If I had enough money I would sue the ass off the Electrum owners for allowing more people be scammed once they knew there were already people scammed and not addressing the issue, MUPPETS!!!

Они позволили серьезной, известной проблеме потерять людей огромные суммы денег на месяцы и месяцы и месяцы

Архитектура децентрализована. Никто не может решить проблему, поскольку никто не контролирует систему.
Децентрализация имеет свои плюсы и минусы.

Мы потратили значительные ресурсы на попытки смягчить проблему, см. # 5084 (комментарий),
но это все, что можно сделать: смягчение.

I installed ELECTRUM 3.3.8 today and transferred BTC it from the EXMO exchange to my wallet 16ugJSDpxBmJCj2WdyzMZpjWK8aDAy7K33, the funds were confirmed at 18: 32 and at the same second were sent to another wallet, although I did not do it. And the blockchain showed that there were three transactions. I have a password in my wallet without it, you can not send funds. Maybe it's a program error?

If I had enough money I would sue the ass off the Electrum owners for allowing more people be scammed once they knew there were already people scammed and not addressing the issue, MUPPETS!!!

Guys, I understand you are angry, but just to make this clear again:

Electrum developers did what they could and it is simply not possible to do any more than this.

So stop calling them names. They did not deserve it.

There are criminals who are abusing the decentralized architecture and a small bug in 1-year-old Electrum versions trying to scam people. These are the bad guys, not the Electrum devs.

FAQ:

  • "But I'm getting the alert in my trusted Electrum software!"

    • Yes but this is because malicious Electrum servers are sending it to you as a fake "error message". The fact that it is so flashy and has links is result of an issue where HTML was allowed in this "error message", but this was fixed a long time ago, so you were running an outdated version...

  • "But how can malicious servers even exist? Was Electrum hacked?"

    • Because the architecture is decentralized. This means, there is no "Electrum service" that is "owned by Electrum, Inc.", like it would be with Facebook, Twitter, etc., and the Electrum devs don't have agency over what other servers are doing. All the servers on the network are run by different individuals or companies and are not controlled by a central entity. (Otherwise it would be a) against the spirit of decentralized cryptocurrency services and b) costing someone a lot, and Electrum would likely cost a monthly fee to cover for it...)

  • "But if I cannot trust the servers that I'm connecting to, how can I trust that my coins are safe at all?"

    • Because this is technically not a vulnerability but a social engineering attack. A server cannot steal your coins because you hold your private keys and they never leave your computer, it's like entrusting someone with an already-signed money transfer order (with fixed recipient) - the worst the server can do is lie to you or deny service, which is what happened here. The only reason you lost your coins is that you did what the attacker asked, so without this human component, the only effect would have been that your transaction would have been not sent. Therefore, a system with third-party servers is not inherently insecure.

  • "But if you say it is a bug in Electrum that I even saw this malicious message, it is the devs' fault after all!"

    • Technically yes but bugs can and will always happen and you cannot expect that a software is bug-free. No software in the world is. And nobody can know how bugs will be abused either. What's important is that the devs react on issues and fix them, which did happen here (Electrum 3.3.3 fixes the problem by not displaying this message to the user anymore, plus there were many additional creative mitigations done as described here).

  • "But if it was already fixed a long time ago, why did it still happen to me?"

    • Because you were using an older version from before it was fixed.

  • "But why wasn't it updated automatically? When I'm using app XYZ it also automatically updates... we are not in the 1990s..."

    • Part of the spirit of cryptocurrencies is that they are decentralized. It also means that you are not blindly trusting a single party. (Of course this means it is on you to ensure that parties that you do trust are actually trustworthy.) And part of this is the trust that if you are installing a certain piece of software, you know what it does and it won't change without you knowing (you could manually inspect Electrum's source code and build the version yourself if you wanted to, then you wouldn't even have to trust any downloaded EXE file). An automatic update mechanism would break this trust. Imagine what could happen if the update server was hacked. A scammer could take over all Electrum clients at once! Yes it's true that also the Electrum website can get hacked, but you can also check on GitHub, and if a hack like this would happen, you would find warnings about it somewhere.

  • "But it could at least offer updates and ask to update manually!"

    • True, this is what some other forks of Electrum did, and Electrum now did it as well! (but again, it won't help if you don't already have one of the newer versions that support it.) However it also isn't clear that this is the best choice, because not everyone will be happy with Electrum pinging a central server all the time, it could be used to track usage as well.

  • "But then how should I have known about the issue and the legit update?"

    • By taking a bit of responsibility over the choice of software you are running. Conciously download software from trusted sources (there were tons of warnings at the official channels), remember what those sources are, check for updates there regularly and keep verifying the trustworthyness of the source, and don't click on links without verifying their legitimacy! Just like in phishing mails. Don't trust anyone blindly! Today's world is full of "dead simple" apps which do every bit of thinking for you, but this comes at the cost of forcing you to blindly trust the devs. (And it happened often enough that updates were forced on people which didn't make everyone happy... adding ads, tracking, making free features paid, etc.)

I find that most of the people here were mindlessly clicking on links. It's hard to imagine what is necessary to get people to take their security seriously. I played around with the idea of enforcing users to use GPG verification for the software, but that might be too much of a deterrent for new users. Phishers can still push fake GPG keys and successfully scam people, so that's not much of a solution.

One thing that can improve security is to create a 30-60sec timeout view on the installer, where all of the known scams are explained in detail. Many of these people received fake error messages and simply assumed that whatever website was being shown was correct.

Just my two-cents, as I'm researching stuff about Electrum.

EDIT: just realized that the issue has been solved. (Electrum 3.3.3 fixes the problem by not displaying this message to the user anymore, plus there were many additional creative mitigations done as described here).

Hi there,

Among all these _we-all-know-but-as-there-is-scumbag-people-sometimes-you-get-robbed_ ADVISES, is there something that we could do?

I did a small investigation with IPs, python scripts, hash etc.. and I'd like to report it more than just going to the police (that I did) or writing it on a blog..

BTW, I they scammed me 1.7btc using this site: http://electrumdrive.fyi/
And yes, it looks like pretty obvious it's not the official, but sometimes you are tired and you do not imagine that you'll be robbed in from of your house (to use a similar situation in real life).

Anyway, instead of common sense advises and useless moanins, please, let me know if there's a way to catch these scumbags that (as I saw in the hash) have been stole about 56btc + 61btc with 2 different accounts during last year. This is the account where they sent my money: bc1qcygs9dl4pqw6atc4yqudrzd76p3r9cp6xp2kny and the hash 8364841abdb753c5f1251d1909ee02ad54f30ab9f46f249b1d16de20bf3c66d4

Thanks for the help in advance and best luck.

Regards,

Hi there,

Among all these _we-all-know-but-as-there-is-scumbag-people-sometimes-you-get-robbed_ ADVISES, is there something that we could do?

I did a small investigation with IPs, python scripts, hash etc.. and I'd like to report it more than just going to the police (that I did) or writing it on a blog..

BTW, I they scammed me 1.7btc using this site: http://electrumdrive.fyi/
And yes, it looks like pretty obvious it's not the official, but sometimes you are tired and you do not imagine that you'll be robbed in from of your house (to use a similar situation in real life).

Anyway, instead of common sense advises and useless moanins, please, let me know if there's a way to catch these scumbags that (as I saw in the hash) have been stole about 56btc + 61btc with 2 different accounts during last year. This is the account where they sent my money: bc1qcygs9dl4pqw6atc4yqudrzd76p3r9cp6xp2kny and the hash 8364841abdb753c5f1251d1909ee02ad54f30ab9f46f249b1d16de20bf3c66d4

Thanks for the help in advance and best luck.

Regards,

Have you reported the domain to the abuse entities or the FTC?

Have you reported the domain to the abuse entities or the FTC?

@Amitie10g Thanks for the tip, I didn't know them or their organization

I can use it even if I'm not a US citizen (consumer) or it's because electrum is from the States?
And, what is the FTC? makes any difference to let them know?

Thanks for the quick response.
Regards,

Have you reported the domain to the abuse entities or the FTC?

@Amitie10g Thanks for the tip, I didn't know them or their organization

I can use it even if I'm not a US citizen (consumer) or it's because electrum is from the States?
And, what is the FTC? makes any difference to let them know?

Thanks for the quick response.
Regards,

At least, a report could help to get information about the owners of the domain, and then take criminal compliant against they.

At least, a report could help to get information about the owners of the domain, and then take criminal compliant against they.

Sure, let's see if we have a Mt. Gox in here and at least we have something back.. :DDD
Thanks again for the help!

the version of malware that got me was slightly different from the one pictured above. It refused to let me send any transactions until I "Upgraded."

No, that's how it works. It's about the server you are connected to. The server does not relay the tx, and it sends back the error. You just need to select a different server.

The behavior of the client is obviously what's being exploited here, users are conditioned to trust pop-ups that come from within non-browser applications.

It's totally irresponsible to surface arbitrary text and links to the user from your cryptocurrency client, and I would agree that it's basically "inexcusable".

^ Applies to versions prior to 3.3.3 but the devs can be blamed for this. I will not use or recommend the software, even after having spent time writing tax calculators for it.

Joning the club here. Lost $1k yesterday due to the same "update to 4.0" popup. That was my first attempt to send btc from my wallet (installed it 2 and a half years ago) so i had no idea if this behaviour was normal or not but was too relaxed to check i suppose. The downloaded client was from electrumfules.world.
As i see there are people falling for this scheme for a year and a half now. That is too long for it just being some 'evil hacker'. That is what electrum does i believe as a little sidejob or smth. Hope those people above will sue you good.

Sorry to hear that, but how can you say it's "too long" to be a malicious third party? If the bad guys would pay, say, $100/month (which is high) for cloud infrastructure to run the Electrum nodes needed for this scam, then your case already paid them 1 more year of scamming, and I would assume that more people get scammed than just 1 per year, so I don't see any reason (from their perspective) why they should stop the scam operation when it still works and makes them money... Even if it had been 10 years already.

@CherryDT What i meant by "too long" is that apart from having little note on the main page i don't see any other actions undertaken by devs to prevent this scam. Oh i've read that in the new updates it is not possible to display html in the popup. But hey, some kind of real popup from the devs for those who use older versions would've been helpful.
One other thing that threw me off. I fought with Windows Defender for around 5 mins to install this "update" but i haven't found it suspicious cause on the electrum.org in downloads it says "Electrum binaries are often flagged by various anti-virus software. There is nothing we can do about it, so please stop reporting that to us." Maybe if it wasn't there i would've doublechecked the source from which the update was donwloaded. Anyway, that's just me being smart now after doing a stupid thing.

that apart from having little note on the main page i don't see any other actions undertaken by devs to prevent this scam.

See https://github.com/spesmilo/electrum/issues/5084#issuecomment-461641700

But hey, some kind of real popup from the devs for those who use older versions would've been helpful.

Which is what they did as well: the honest servers started doing the "good attack", warning old clients that they are vulnerable and need to upgrade (when they broadcast a transaction, which is the only time a warning is possible)

@The-Compiler
I don't want to start a rant here so i'm gonna just answer one more time.
Well, obviously they haven't done enough otherwise all these threads on the topic would be dead. But people are continuing to be robbed.
Second, take my example as of someone who'd used their wallet 2 times. First to put some btc on it and second - to take out. I am usually quite a careful web user. I've never caught any malware or viruses or other stuff. But in this case i was caught off guard. And they failed to warn me about it. The only kind of attack i received was a "bad" one.
I'll just state the obvious again - if this is continuing to happen there is a big possibility that someone allows it to happen. That's how these things usually work.

The devs can't go back and change history though... You downloaded the version at the time the bug existed. Now you have the version with the bug. And regardless whether you use that version today or in 30 years from now, the bug will be there. They can't undo that, they can only ask you to download a newer version through their website and social channels (which they did, and the warning on electrum.org is still there), and they can think about some creative means of catching a bit more of the cases, like what they did by intentionally making "good" servers also exploit the bug in order to show a _legitimate_ message, but of course they can't control whether you will end up connecting to one of the good servers or one of the bad ones first. So 100% can't be caught.

I'm sure you have heard about the issue with the Samsung batteries that caught on fire a few years back. A mistake was made, and once they realized that, they put out a product recall. But, if you didn't see the recall announcment in the store, and you hadn't registered your purchase with Samsung so they could contact you directly (you just bought the phone somewhere with cash), and you didn't follow the relevant news channels, then you may still have such a dangerous battery in your phone today without knowing. And if you then take out your phone today, 3 years later, and it explodes, then it also doesn't make sense to say "weird that there are still Samsung phones exploding 3 years later, it must be intentionally, or at least they didn't do enough, otherwise the battery in my phone would have magically teleported back to Samsung and be replaced by a fixed one even though I missed the announcements".

(This example is just to explain my point and not intended to be condescending.)

Bugs can and will happen, in any software, and as soon as it became known, everything possible was done to limit the damage already caused by it and prevent it for the future as much as possible.

Please see my explanation above for details: https://github.com/spesmilo/electrum/issues/5183#issuecomment-5857130049

Was this page helpful?
0 / 5 - 0 ratings