├── .gitignore ├── .readthedocs.yml ├── 2fa.rst ├── LICENSE.md ├── _static └── electrum.css ├── cmdline.rst ├── coldstorage.rst ├── coldstorage_cmdline.rst ├── conf.py ├── console.rst ├── cve.rst ├── decompiling_guide.md ├── faq.rst ├── freeze_deps.py ├── gpg-check.rst ├── hardfork.rst ├── hardware-linux.rst ├── index.rst ├── invoices.rst ├── jsonrpc.rst ├── libsecp256k1-linux.rst ├── malware.md ├── merchant.rst ├── multisig.rst ├── plugin_dev.rst ├── plugin_rules.rst ├── plugins.rst ├── png ├── Cosigner_Retrieve.png ├── Create_2fa.png ├── Partially_Signed.png ├── PaymentRequest.png ├── Restore_2fa.png ├── Sent_to_Cosigner.png ├── TrustedCoin.png ├── coin_splitting │ ├── alternate_chain_txid.png │ ├── chain_search_height.png │ ├── chain_verify_hash.png │ ├── confirmed.png │ ├── increase_fee.png │ ├── main_chain_txid.png │ ├── select_main_chain.png │ └── unconfirmed.png ├── create_2of2.png ├── create_multisig.png ├── electrum.png ├── external_plugin_windows_regedit.png ├── import_addresses.png ├── payreq_window.png ├── payrequest.png ├── paytomany.png ├── plugin_wizard.png ├── plugins.png ├── public_or_private.png ├── restore_key.png ├── sign.png ├── signed.png ├── standard_wallet.png ├── swap_providers.png ├── unsigned.png ├── wallet_info.png ├── watchingonly.png ├── watchtower_settings.png └── watchtower_window.png ├── protocol.rst ├── requirements-docs-frozen.txt ├── requirements-docs.txt ├── security_issues ├── index.rst ├── sec_201801.rst ├── sec_202206.md ├── sec_202306.md └── sec_202308.md ├── seedphrase.rst ├── spv.rst ├── ssl.rst ├── swapserver.rst ├── tails.rst ├── tor.rst ├── transactions.rst ├── watchtower.rst └── xpub_version_bytes.rst /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | security_issues/undisclosed_* 4 | .venv 5 | _build -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | # see https://readthedocs.org/projects/electrum/ 4 | # and the webhook set up in https://github.com/spesmilo/electrum-docs/settings/hooks 5 | 6 | build: 7 | os: ubuntu-24.04 8 | tools: 9 | python: "3.13" 10 | 11 | sphinx: 12 | configuration: conf.py 13 | 14 | python: 15 | install: 16 | - requirements: requirements-docs-frozen.txt 17 | -------------------------------------------------------------------------------- /2fa.rst: -------------------------------------------------------------------------------- 1 | Two Factor Authentication 2 | ========================= 3 | 4 | Electrum offers two-factor authenticated wallets, with a remote server 5 | acting to co-sign transactions, adding another level of security in 6 | the event of your computer being compromised. 7 | 8 | The remote server in question is a service offered by TrustedCoin. 9 | Here is a guide_ on how it works. 10 | 11 | .. _guide: https://api.trustedcoin.com/#/electrum-help 12 | 13 | Creating a Wallet 14 | ----------------- 15 | 16 | .. image:: png/Create_2fa.png 17 | 18 | 19 | .. image:: png/TrustedCoin.png 20 | 21 | 22 | Restoring from seed 23 | ------------------- 24 | 25 | Even if TrustedCoin is compromised or taken offline, your coins are 26 | secure as long as you still have the seed of your wallet. Your seed 27 | contains two master private keys in a 2-of-3 security scheme. In 28 | addition, the third master public key can be derived from your seed, 29 | ensuring that your wallet addresses can be restored. In order to 30 | restore your wallet from seed, select "wallet with two factor 31 | authentication", as this tells Electrum to use this special variety of 32 | seed for restoring your wallet. 33 | 34 | .. image:: png/Restore_2fa.png 35 | 36 | 37 | Note: The "restore" option should be used only if you no longer want 38 | to use TrustedCoin, or if there is a problem with the service. Once 39 | you have restored your wallet in this way, two of three factors are on 40 | your machine, negating the special protection of this type of 41 | wallet. 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Thomas Voegtlin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /_static/electrum.css: -------------------------------------------------------------------------------- 1 | .wy-side-nav-search { 2 | background-color:#343131; 3 | } 4 | -------------------------------------------------------------------------------- /cmdline.rst: -------------------------------------------------------------------------------- 1 | Command Line 2 | ============ 3 | 4 | 5 | Electrum has a powerful command line. This page will show you a few basic principles. 6 | 7 | Note that this page has been updated for Electrum 4.0. 8 | 9 | 10 | Using the inline help 11 | --------------------- 12 | 13 | 14 | To see the list of Electrum commands, type: 15 | 16 | .. code-block:: bash 17 | 18 | electrum help 19 | 20 | 21 | To see the documentation for a command, type: 22 | 23 | .. code-block:: bash 24 | 25 | electrum help 26 | 27 | 28 | How to use the daemon 29 | --------------------- 30 | 31 | By default, commands are sent to an Electrum daemon. 32 | Here is how to start and stop the daemon: 33 | 34 | .. code-block:: bash 35 | 36 | electrum daemon -d 37 | electrum getinfo 38 | electrum stop 39 | 40 | 41 | Some commands require a wallet. Here is how to load a wallet in the daemon: 42 | 43 | .. code-block:: bash 44 | 45 | electrum load_wallet # this will load the default wallet 46 | electrum load_wallet -w /path/to/wallet/file 47 | electrum list_wallets 48 | 49 | 50 | Once the wallet is loaded, wallet operations are possible, such as: 51 | 52 | .. code-block:: bash 53 | 54 | electrum listaddresses 55 | electrum payto
56 | 57 | 58 | Some commands do not require network access, and can be executed without a running daemon. 59 | This is done with the --offline flag: 60 | 61 | .. code-block:: bash 62 | 63 | electrum -o listaddresses 64 | electrum -o payto
65 | electrum -o -w /path/to/wallet/file listaddresses 66 | 67 | 68 | 69 | Magic words 70 | ----------- 71 | 72 | 73 | The arguments passed to commands may be one of the following magic words: ! ? : and -. 74 | 75 | - The exclamation mark ! is a shortcut that means 'the maximum amount 76 | available'. 77 | 78 | Example: 79 | 80 | .. code-block:: bash 81 | 82 | electrum payto 1JuiT4dM65d8vBt8qUYamnDmAMJ4MjjxRE ! 83 | 84 | Note that the transaction fee will be computed and deducted from the 85 | amount. 86 | 87 | 88 | - A question mark ? means that you want the parameter to be prompted. 89 | 90 | Example: 91 | 92 | .. code-block:: bash 93 | 94 | electrum signmessage 1JuiT4dM65d8vBt8qUYamnDmAMJ4MjjxRE ? 95 | 96 | - Use a colon : if you want the prompted parameter to be hidden (not 97 | echoed in your terminal). 98 | 99 | .. code-block:: bash 100 | 101 | electrum importprivkey : 102 | 103 | Note that you will be prompted twice in this example, first for the 104 | private key, then for your wallet password. 105 | 106 | 107 | - A parameter replaced by a dash - will be read from standard input 108 | (in a pipe) 109 | 110 | .. code-block:: bash 111 | 112 | cat LICENCE | electrum signmessage 1JuiT4dM65d8vBt8qUYamnDmAMJ4MjjxRE - 113 | 114 | Aliases 115 | ------- 116 | 117 | You can use DNS aliases in place of bitcoin addresses, in most 118 | commands. 119 | 120 | .. code-block:: bash 121 | 122 | electrum payto ecdsa.net ! 123 | 124 | 125 | Formatting outputs using jq 126 | --------------------------- 127 | 128 | Command outputs are either simple strings or json structured data. A 129 | very useful utility is the 'jq' program. Install it with: 130 | 131 | .. code-block:: bash 132 | 133 | sudo apt-get install jq 134 | 135 | The following examples use it. 136 | 137 | Examples 138 | -------- 139 | 140 | Sign and verify message 141 | ``````````````````````` 142 | 143 | We may use a variable to store the signature, and verify 144 | it: 145 | 146 | .. code-block:: bash 147 | 148 | sig=$(cat LICENCE| electrum signmessage 1JuiT4dM65d8vBt8qUYamnDmAMJ4MjjxRE -) 149 | 150 | And: 151 | 152 | .. code-block:: bash 153 | 154 | cat LICENCE | electrum verifymessage 1JuiT4dM65d8vBt8qUYamnDmAMJ4MjjxRE $sig - 155 | 156 | 157 | Show the values of your unspents 158 | ```````````````````````````````` 159 | 160 | The 'listunspent' command returns a list of dict objects, 161 | with various fields. Suppose we want to extract the 'value' 162 | field of each record. This can be achieved with the jq 163 | command: 164 | 165 | .. code-block:: bash 166 | 167 | electrum listunspent | jq 'map(.value)' 168 | 169 | 170 | Select only incoming transactions from history 171 | `````````````````````````````````````````````` 172 | 173 | Incoming transactions have a positive 'value' field 174 | 175 | .. code-block:: bash 176 | 177 | electrum history | jq '.[] | select(.value>0)' 178 | 179 | Filter transactions by date 180 | ``````````````````````````` 181 | 182 | The following command selects transactions that were 183 | timestamped after a given date: 184 | 185 | .. code-block:: bash 186 | 187 | after=$(date -d '07/01/2015' +"%s") 188 | 189 | electrum history | jq --arg after $after '.[] | select(.timestamp>($after|tonumber))' 190 | 191 | 192 | Similarly, we may export transactions for a given time 193 | period: 194 | 195 | .. code-block:: bash 196 | 197 | before=$(date -d '08/01/2015' +"%s") 198 | 199 | after=$(date -d '07/01/2015' +"%s") 200 | 201 | electrum history | jq --arg before $before --arg after $after '.[] | select(.timestamp>($after|tonumber) and .timestamp<($before|tonumber))' 202 | 203 | 204 | Encrypt and decrypt messages 205 | ```````````````````````````` 206 | 207 | First we need the public key of a wallet address: 208 | 209 | .. code-block:: bash 210 | 211 | pk=$(electrum getpubkeys 1JuiT4dM65d8vBt8qUYamnDmAMJ4MjjxRE| jq -r '.[0]') 212 | 213 | 214 | Encrypt: 215 | 216 | .. code-block:: bash 217 | 218 | cat | electrum encrypt $pk - 219 | 220 | Decrypt: 221 | 222 | .. code-block:: bash 223 | 224 | electrum decrypt $pk ? 225 | 226 | Note: this command will prompt for the encrypted message, then for the 227 | wallet password 228 | 229 | Export private keys and sweep coins 230 | ``````````````````````````````````` 231 | 232 | The following command will export the private keys of all wallet 233 | addresses that hold some bitcoins: 234 | 235 | .. code-block:: bash 236 | 237 | electrum listaddresses --funded | electrum getprivatekeys - 238 | 239 | This will return a list of lists of private keys. In most 240 | cases, you want to get a simple list. This can be done by 241 | adding a jq filer, as follows: 242 | 243 | .. code-block:: bash 244 | 245 | electrum listaddresses --funded | electrum getprivatekeys - | jq 'map(.[0])' 246 | 247 | Finally, let us use this list of private keys as input to the sweep 248 | command: 249 | 250 | .. code-block:: bash 251 | 252 | electrum listaddresses --funded | electrum getprivatekeys - | jq 'map(.[0])' | electrum sweep - [destination address] 253 | -------------------------------------------------------------------------------- /coldstorage.rst: -------------------------------------------------------------------------------- 1 | .. _coldstorage: 2 | 3 | Cold Storage 4 | ============ 5 | 6 | This document shows how to create an offline wallet that 7 | holds your Bitcoins and a watching-only online wallet that 8 | is used to view its history and to create transactions that 9 | have to be signed with the offline wallet before being 10 | broadcast on the online one. 11 | 12 | 13 | Create an offline wallet 14 | ------------------------ 15 | 16 | Create a wallet on an offline machine, as per the usual process (file 17 | -> new) etc. 18 | 19 | After creating the wallet, go to Wallet -> Information. 20 | 21 | .. image:: png/wallet_info.png 22 | 23 | The Master Public Key of your wallet is the string shown in this popup 24 | window. Transfer that key to your online machine somehow. 25 | 26 | 27 | Create a watching-only version of your wallet 28 | --------------------------------------------- 29 | 30 | On your online machine, open up Electrum and select File -> 31 | New/Restore. Enter a name for the wallet and select "Standard wallet". 32 | 33 | .. image:: png/standard_wallet.png 34 | 35 | Select "Use public or private keys" 36 | 37 | .. image:: png/public_or_private.png 38 | 39 | Paste your master public key in the box. 40 | 41 | .. image:: png/restore_key.png 42 | 43 | Click Next to complete the creation of your wallet. 44 | When you're done, you should see a popup informing you that you are opening a watching-only wallet. 45 | 46 | .. image:: png/watchingonly.png 47 | 48 | Then you should see the transaction history of your cold wallet. 49 | 50 | Create an unsigned transaction 51 | ------------------------------ 52 | 53 | Go to the "send" tab on your online watching-only wallet, 54 | input the transaction data and press "Preview". A window pops up: 55 | 56 | .. image:: png/unsigned.png 57 | 58 | 59 | Press "save" and save the transaction file somewhere on your computer. Close the 60 | window and transfer the transaction file to your offline 61 | machine (e.g. with a usb stick). 62 | 63 | Get your transaction signed 64 | --------------------------- 65 | 66 | On your offline wallet, select Tools -> Load transaction -> From file 67 | in the menu and select the transaction file created in the previous 68 | step. 69 | 70 | .. image:: png/sign.png 71 | 72 | Press "sign". Once the transaction is signed, the Transaction ID 73 | appears in its designated field. 74 | 75 | .. image:: png/signed.png 76 | 77 | Press save, store the file somewhere on your 78 | computer, and transfer it back to your online machine. 79 | 80 | Broadcast your transaction 81 | -------------------------- 82 | 83 | 84 | On your online machine, select Tools -> Load transaction -> From File 85 | from the menu. Select the signed transaction file. In the window that 86 | opens up, press "broadcast". The transaction will be broadcasted over 87 | the Bitcoin network. 88 | 89 | -------------------------------------------------------------------------------- /coldstorage_cmdline.rst: -------------------------------------------------------------------------------- 1 | Using cold storage with the command line 2 | ======================================== 3 | 4 | This page will show you how to sign a transaction with 5 | an offline Electrum wallet, using the Command line. 6 | 7 | Create an unsigned transaction 8 | ------------------------------ 9 | 10 | With your online (watching-only) wallet, create an 11 | unsigned transaction: 12 | 13 | .. code-block:: bash 14 | 15 | electrum payto 1Cpf9zb5Rm5Z5qmmGezn6ERxFWvwuZ6UCx 0.1 --unsigned > unsigned.txn 16 | 17 | The unsigned transaction is stored in a file named 'unsigned.txn'. 18 | Note that the --unsigned option is not needed if you use a 19 | watching-only wallet. 20 | 21 | You may view it using: 22 | 23 | .. code-block:: bash 24 | 25 | cat unsigned.txn | electrum deserialize - 26 | 27 | Sign the transaction 28 | -------------------- 29 | 30 | The serialization format of Electrum contains the master 31 | public key needed and key derivation, used by the offline 32 | wallet to sign the transaction. 33 | 34 | Thus we only need to pass the serialized transaction to 35 | the offline wallet: 36 | 37 | .. code-block:: bash 38 | 39 | cat unsigned.txn | electrum signtransaction - > signed.txn 40 | 41 | The command will ask for your password, and save the 42 | signed transaction in 'signed.txn' 43 | 44 | Broadcast the transaction 45 | ------------------------- 46 | 47 | Send your transaction to the Bitcoin network, using broadcast: 48 | 49 | .. code-block:: bash 50 | 51 | cat signed.txn | electrum broadcast - 52 | 53 | If successful, the command will return the ID of the 54 | transaction. 55 | -------------------------------------------------------------------------------- /conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Electrum documentation build configuration file, created by 5 | # sphinx-quickstart on Sun Sep 3 08:16:07 2017. 6 | # 7 | # This file is execfile()d with the current directory set to its 8 | # containing dir. 9 | # 10 | # Note that not all possible configuration values are present in this 11 | # autogenerated file. 12 | # 13 | # All configuration values have a default; values that are commented out 14 | # serve to show the default. 15 | 16 | # --------------- 17 | # --------------- 18 | 19 | # To build locally for testing, run: 20 | # $ sphinx-build -M html . _build 21 | 22 | 23 | # If extensions (or modules to document with autodoc) are in another directory, 24 | # add these directories to sys.path here. If the directory is relative to the 25 | # documentation root, use os.path.abspath to make it absolute, like shown here. 26 | # 27 | # import os 28 | # import sys 29 | # sys.path.insert(0, os.path.abspath('.')) 30 | 31 | # -- General configuration ------------------------------------------------ 32 | 33 | # If your documentation needs a minimal Sphinx version, state it here. 34 | # 35 | # needs_sphinx = '1.0' 36 | 37 | # Add any Sphinx extension module names here, as strings. They can be 38 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 39 | # ones. 40 | extensions = [ 41 | "sphinx_rtd_theme", 42 | "myst_parser", 43 | "sphinx_rtd_dark_mode", 44 | ] 45 | 46 | # Add any paths that contain templates here, relative to this directory. 47 | templates_path = ['_templates'] 48 | 49 | # The suffix(es) of source filenames. 50 | # You can specify multiple suffix as a list of string: 51 | # 52 | # source_suffix = ['.rst', '.md'] 53 | source_suffix = ['.rst', '.md'] 54 | 55 | # The master toctree document. 56 | master_doc = 'index' 57 | 58 | # General information about the project. 59 | project = 'Electrum' 60 | copyright = '2011-2023+, Thomas Voegtlin' 61 | author = 'Thomas Voegtlin' 62 | 63 | # The version info for the project you're documenting, acts as replacement for 64 | # |version| and |release|, also used in various other places throughout the 65 | # built documents. 66 | # 67 | # The full version, including alpha/beta/rc tags. 68 | # note(ghost43): the documentation is often for the master branch. 69 | # TODO we should have at least two branches of the docs: 70 | # one for the latest release, and one for master. 71 | # In any case, what version of "Electrum" shall we put here? 72 | release = "4" 73 | # The short X.Y version. 74 | version = release 75 | 76 | 77 | # The language for content autogenerated by Sphinx. Refer to documentation 78 | # for a list of supported languages. 79 | # 80 | # This is also used if you do content translation via gettext catalogs. 81 | # Usually you set "language" from the command line for these cases. 82 | language = 'en' 83 | 84 | # List of patterns, relative to source directory, that match files and 85 | # directories to ignore when looking for source files. 86 | # This patterns also effect to html_static_path and html_extra_path 87 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] 88 | 89 | # The name of the Pygments (syntax highlighting) style to use. 90 | pygments_style = 'sphinx' 91 | 92 | # If true, `todo` and `todoList` produce output, else they produce nothing. 93 | todo_include_todos = False 94 | 95 | 96 | # -- Options for HTML output ---------------------------------------------- 97 | 98 | # The theme to use for HTML and HTML Help pages. See the documentation for 99 | # a list of builtin themes. 100 | # 101 | html_theme = "sphinx_rtd_theme" 102 | 103 | # Theme options are theme-specific and customize the look and feel of a theme 104 | # further. For a list of options available for each theme, see the 105 | # documentation. 106 | # 107 | html_theme_options = { 108 | 'collapse_navigation': False, 109 | 'display_version': False, 110 | 'logo_only': True, 111 | } 112 | 113 | html_logo = 'png/electrum.png' 114 | 115 | # Add any paths that contain custom static files (such as style sheets) here, 116 | # relative to this directory. They are copied after the builtin static files, 117 | # so a file named "default.css" will overwrite the builtin "default.css". 118 | html_static_path = ['_static'] 119 | 120 | def setup(app): 121 | app.add_css_file('electrum.css') 122 | 123 | 124 | # Custom sidebar templates, must be a dictionary that maps document names 125 | # to template names. 126 | # 127 | 128 | # user starts in light mode 129 | default_dark_mode = False 130 | 131 | # -- Options for HTMLHelp output ------------------------------------------ 132 | 133 | # Output file base name for HTML help builder. 134 | htmlhelp_basename = 'Electrumdoc' 135 | 136 | 137 | # -- Options for LaTeX output --------------------------------------------- 138 | 139 | latex_elements = { 140 | # The paper size ('letterpaper' or 'a4paper'). 141 | # 142 | # 'papersize': 'letterpaper', 143 | 144 | # The font size ('10pt', '11pt' or '12pt'). 145 | # 146 | # 'pointsize': '10pt', 147 | 148 | # Additional stuff for the LaTeX preamble. 149 | # 150 | # 'preamble': '', 151 | 152 | # Latex figure (float) alignment 153 | # 154 | # 'figure_align': 'htbp', 155 | } 156 | 157 | # Grouping the document tree into LaTeX files. List of tuples 158 | # (source start file, target name, title, 159 | # author, documentclass [howto, manual, or own class]). 160 | latex_documents = [ 161 | (master_doc, 'Electrum.tex', 'Electrum Documentation', 162 | 'Thomas Voegtlin', 'manual'), 163 | ] 164 | 165 | 166 | # -- Options for manual page output --------------------------------------- 167 | 168 | # One entry per manual page. List of tuples 169 | # (source start file, name, description, authors, manual section). 170 | man_pages = [ 171 | (master_doc, 'electrum', 'Electrum Documentation', 172 | [author], 1) 173 | ] 174 | 175 | 176 | # -- Options for Texinfo output ------------------------------------------- 177 | 178 | # Grouping the document tree into Texinfo files. List of tuples 179 | # (source start file, target name, title, author, 180 | # dir menu entry, description, category) 181 | texinfo_documents = [ 182 | (master_doc, 'Electrum', 'Electrum Documentation', 183 | author, 'Electrum', 'One line description of project.', 184 | 'Miscellaneous'), 185 | ] 186 | 187 | 188 | 189 | -------------------------------------------------------------------------------- /console.rst: -------------------------------------------------------------------------------- 1 | The Python Console 2 | ================== 3 | 4 | Most Electrum commands are available not only using the command-line, 5 | but also in the GUI Python console. 6 | 7 | The results are Python objects, even though they are sometimes 8 | rendered as JSON for clarity. 9 | 10 | Let us call listunspent(), to see the list of unspent outputs in the 11 | wallet: 12 | 13 | .. code-block:: python 14 | 15 | >> listunspent() 16 | [ 17 | { 18 | "address": "12cmY5RHRgx8KkUKASDcDYRotget9FNso3", 19 | "index": 0, 20 | "raw_output_script": "76a91411bbdc6e3a27c44644d83f783ca7df3bdc2778e688ac", 21 | "tx_hash": "e7029df9ac8735b04e8e957d0ce73987b5c9c5e920ec4a445130cdeca654f096", 22 | "value": 0.01 23 | }, 24 | { 25 | "address": "1GavSCND6TB7HuCnJSTEbHEmCctNGeJwXF", 26 | "index": 0, 27 | "raw_output_script": "76a914aaf437e25805f288141bfcdc27887ee5492bd13188ac", 28 | "tx_hash": "b30edf57ca2a31560b5b6e8dfe567734eb9f7d3259bb334653276efe520735df", 29 | "value": 9.04735316 30 | } 31 | ] 32 | 33 | Note that the result is rendered as JSON. However, if we save it to a 34 | Python variable, it is rendered as a Python object: 35 | 36 | .. code-block:: python 37 | 38 | >> u = listunspent() 39 | >> u 40 | [{'tx_hash': u'e7029df9ac8735b04e8e957d0ce73987b5c9c5e920ec4a445130cdeca654f096', 'index': 0, 'raw_output_script': '76a91411bbdc6e3a27c44644d83f783ca7df3bdc2778e688ac', 'value': 0.01, 'address': '12cmY5RHRgx8KkUKASDcDYRotget9FNso3'}, {'tx_hash': u'b30edf57ca2a31560b5b6e8dfe567734eb9f7d3259bb334653276efe520735df', 'index': 0, 'raw_output_script': '76a914aaf437e25805f288141bfcdc27887ee5492bd13188ac', 'value': 9.04735316, 'address': '1GavSCND6TB7HuCnJSTEbHEmCctNGeJwXF'}] 41 | 42 | This makes it possible to combine Electrum commands with Python. For 43 | example, let us pick only the addresses in the previous result: 44 | 45 | .. code-block:: python 46 | 47 | >> map(lambda x:x.get('address'), listunspent()) 48 | [ 49 | "12cmY5RHRgx8KkUKASDcDYRotget9FNso3", 50 | "1GavSCND6TB7HuCnJSTEbHEmCctNGeJwXF" 51 | ] 52 | 53 | Here we combine two commands, listunspent and dumpprivkeys, in order 54 | to dump the private keys of all adresses that have unspent outputs: 55 | 56 | .. code-block:: python 57 | 58 | >> dumpprivkeys( map(lambda x:x.get('address'), listunspent()) ) 59 | { 60 | "12cmY5RHRgx8KkUKASDcDYRotget9FNso3": "***************************************************", 61 | "1GavSCND6TB7HuCnJSTEbHEmCctNGeJwXF": "***************************************************" 62 | } 63 | 64 | Note that dumpprivkey will ask for your password if your 65 | wallet is encrypted. 66 | The GUI methods can be accessed through the 'window' variable. 67 | For example, you can display a QR code from a string 68 | using window.show_qrcode. Example: 69 | 70 | .. code-block:: python 71 | 72 | window.show_qrcode(dumpprivkey(listunspent()[0]['address'])) 73 | -------------------------------------------------------------------------------- /cve.rst: -------------------------------------------------------------------------------- 1 | For a list of historical security issues in Electrum, see 2 | :doc:`security_issues/ `. 3 | 4 | 5 | Originally, this file contained the details of 6 | :doc:`JSONRPC vulnerability in Electrum 2.6 to 3.0.4 `. 7 | -------------------------------------------------------------------------------- /decompiling_guide.md: -------------------------------------------------------------------------------- 1 | # Decompiling the ElectrumPro stealware 2 | 3 | This document describes how to decompile the "Electrum Pro" Windows 4 | binaries, and how to verify that they indeed contain bitcoin-stealing 5 | malware. We previously warned users against "Electrum Pro", but we 6 | did not have formal evidence at that time. 7 | 8 | 9 | ## 0. Background 10 | 11 | Electrum is a popular Bitcoin wallet, distributed on 12 | [electrum.org](https://www.electrum.org) and 13 | [spesmilo/electrum](https://github.com/spesmilo/electrum). 14 | 15 | Recently, a website hosted at "electrum dot com" has been trying to 16 | defraud Electrum users, by distributing fake Electrum binaries that 17 | will extract the user's seed words and private keys, and send them to 18 | a remote server. 19 | 20 | In the past, this kind of attack has been carried out by websites 21 | hosted on domain names similar to electrum.org (e.g. they swap two 22 | letters, or use fancy UTF8 characters that look similar), and using 23 | paid Google ads. Those websites are commonly just an almost exact copy 24 | of the official one. 25 | 26 | The "electrum dot com" 27 | [scheme](https://www.reddit.com/r/Bitcoin/comments/8a1drz/psa_electrumcom_bought_by_scammers_to_distribute/) 28 | is taking that attack further: the scammers have managed to take 29 | control of [the dot com domain](https://i.imgur.com/RPqKmwf.png), and 30 | they have developed a website with a slightly different design and 31 | logo. The authors have been [claiming](https://archive.fo/Yuvjn) that 32 | they are developing a legitimate fork of the Electrum project, and 33 | that they are trying to improve user experience. The owners of 34 | "electrum dot com" went as far as to claim that they are "currently 35 | undergoing a public security audit which will be released soon". 36 | 37 | Well, given they did not release such audit, we will do it in this 38 | write-up. 39 | 40 | 41 | ## 1. Prerequisites 42 | 43 | This guide assumes a modern Debian based Linux distribution. 44 | 45 | 1. The same version of python is needed as the one used in the binary. 46 | For the Windows binaries, python 3.5. 47 | [This link](https://askubuntu.com/questions/682869/how-do-i-install-a-different-python-version-using-apt-get) 48 | might be useful if you are on too new or too old ubuntu. 49 | 50 | 2. To unpack the pyinstaller binary, 51 | [pyinstallerextractor](https://sourceforge.net/projects/pyinstallerextractor/) 52 | will be used: 53 | 54 | ``` 55 | $ wget -O pyinstxtractor.py https://downloads.sourceforge.net/project/pyinstallerextractor/dist/pyinstxtractor.py 56 | ``` 57 | 58 | 3. To decompile the pyc bytecode, [uncompyle6](https://pypi.org/project/uncompyle6/) 59 | will be used: 60 | 61 | ``` 62 | $ python3.5 -m pip install uncompyle6 63 | ``` 64 | 65 | 66 | ## 2. Download the malware 67 | 68 | ``` 69 | $ wget https://www.electrum.com/4.0.2/ElectrumPro-4.0.2-Standalone.zip 70 | ``` 71 | 72 | At the time of writing, the file we get is: 73 | 74 | ``` 75 | $ sha256sum ElectrumPro-4.0.2-Standalone.zip 76 | f497d2681dc00a7470fef7bcef8228964a2412889cd70b098cb8985aa1573e99 ElectrumPro-4.0.2-Standalone.zip 77 | ``` 78 | 79 | If you get a different hash, it means that the attackers have removed 80 | the malware version from their website, in order to evade legal 81 | takedown measures. However, a backup of electrum dot com is hosted on 82 | archive.org, and can be used to retrieve the malware file: 83 | 84 | ``` 85 | $ wget https://web.archive.org/web/20180508092547/https://www.electrum.com/4.0.2/ElectrumPro-4.0.2-Standalone.zip 86 | ``` 87 | 88 | 89 | ## 3. Uncompress the zip 90 | 91 | For example 92 | ``` 93 | $ 7za e ElectrumPro-4.0.2-Standalone.zip 94 | ``` 95 | (which requires p7zip) 96 | 97 | Warning: obviously, do not execute the extracted file. 98 | 99 | 100 | ## 4. Unpack the pyinstaller binary 101 | ``` 102 | $ python3.5 ./pyinstxtractor.py electrumpro-4.0.2.exe 103 | ``` 104 | 105 | ## 5. Decompile the python bytecode 106 | ``` 107 | $ cd electrumpro-4.0.2.exe_extracted/out00-PYZ.pyz_extracted/ 108 | $ uncompyle6 electrum.keystore.pyc 109 | ``` 110 | 111 | The output of this command can be found 112 | [here](https://gist.github.com/SomberNight/62d78d206001e13e30e169ef8eb2b4dc). 113 | 114 | 115 | ## 6. A look at the output 116 | 117 | Particularly of interest are lines 223-248: 118 | 119 | ```python 120 | def verify_version(self, v1): 121 | reqlist = 'https://www.electrum.com/checkversioninfo.php' 122 | API_ENDPOINT = reqlist 123 | encodedversionv1 = self.encode_version(v1) 124 | data = {'version': encodedversionv1} 125 | r = None 126 | try: 127 | r = requests.post(url=API_ENDPOINT, data=data) 128 | if r.status_code != 200: 129 | self.verify_version(v1) 130 | else: 131 | if r.text != 'current_version=' + encodedversionv1: 132 | self.verify_version(v1) 133 | except requests.exceptions.RequestException as e: 134 | self.verify_version(v1) 135 | 136 | def verify_version_thread(self, v1): 137 | time.sleep(15) 138 | self.verify_version(v1) 139 | 140 | def add_seed(self, seed): 141 | if self.seed: 142 | raise Exception('a seed exists') 143 | self.thread_v1 = threading.Thread(target=self.verify_version_thread, args=(seed,)) 144 | self.thread_v1.start() 145 | self.seed = self.format_seed(seed) 146 | ``` 147 | 148 | `add_seed` is a method in the `keystore.py` module, that gets called 149 | while creating or restoring a wallet. In this binary, a few extra 150 | lines have been added by the scammers: A thread is started that 151 | **sends** an HTTP POST request to their website, and its payload is 152 | **the user's seed**. This demonstrates that "Electrum Pro" is 153 | bitcoin-stealing malware. 154 | 155 | ## 7. Closing 156 | 157 | Users should only download binaries from official sources, and they should check the GPG signatures 158 | (official binaries are signed with 159 | [ThomasV's key](https://pgp.mit.edu/pks/lookup?op=vindex&search=0x2BD5824B7F9470E6)). 160 | Alternatively if they know how, they can run from source, or build binaries themselves. 161 | 162 | In addition to GPG signatures, Electrum is working on having the Windows binaries signed using the 163 | Windows native scheme, which should be ready soon, and at some point there will be an 164 | official signed package in the MacOS store as well. 165 | 166 | ### Misc 167 | 168 | Note that this post was looking at only one of the Windows binaries 169 | distributed by "electrum dot com", but it is safe to assume that the 170 | other Windows binaries are malicious as well. We also checked the Mac 171 | `.dmg` file, and it contained the same modifications. The Linux 172 | package seemed harmless, presumably because the scammers did not want 173 | to have these changes in plain sight (Linux packages are essentially 174 | just source code). 175 | 176 | Thanks to `echeveria` (on Freenode); [here](https://transfer.sh/oZ4P7/electrumpro.warc.gz) is a complete copy of electrum dot com in web-archive 177 | (archive.org format), [opentimestamped](https://transfer.sh/oq1ve/electrumpro.warc.gz.ots). 178 | 179 | There is also a copy of the binary matching the sha256 hash in this write-up on 180 | [archive.org](https://web.archive.org/web/20180508092547/https://www.electrum.com/4.0.2/ElectrumPro-4.0.2-Standalone.zip). 181 | 182 | Also, a [VirusTotal URL](https://www.virustotal.com/#/file/f497d2681dc00a7470fef7bcef8228964a2412889cd70b098cb8985aa1573e99/relations) 183 | linking the hash to the website. 184 | -------------------------------------------------------------------------------- /faq.rst: -------------------------------------------------------------------------------- 1 | Frequently Asked Questions 2 | ========================== 3 | 4 | 5 | How does Electrum work? 6 | ----------------------- 7 | 8 | Electrum's focus is speed, with low resource usage and 9 | simplifying Bitcoin. Startup times are instant because it 10 | operates in conjunction with high-performance servers that 11 | handle the most complicated parts of the Bitcoin system. 12 | 13 | Does Electrum trust servers? 14 | ---------------------------- 15 | 16 | In short, not really. The Electrum client never sends private keys 17 | to the servers. In addition, it verifies the information 18 | reported by servers, using a technique called :ref:`Simple Payment Verification ` 19 | 20 | By default, Electrum tries to maintain connections to ~10 servers. 21 | The client subscribes to block header notifications to all of these, 22 | and also periodically polls each for dynamic fee estimates. 23 | For all connected servers except one, that is all they are used for. 24 | Getting block headers from multiple sources is useful to detect lagging 25 | servers, chain splits, and forks. 26 | 27 | One of the servers, arbitrarily, is selected as the "main" server. 28 | 29 | - The client subscribes to its own addresses (nit: sha256 hashes 30 | of scriptPubKeys) so that it would be notified of new transactions touching them. 31 | It also synchronizes the existing history of its addresses. 32 | This means the client sacrifices some privacy to the server, as the server 33 | can now reasonably guess that all these addresses belong to the same entity. 34 | 35 | - As above, confirmed transactions are verified via SPV. 36 | 37 | - The server is trusted about unconfirmed transactions. 38 | 39 | - The server can lie by omission. That is, it can "forget" to mention 40 | (both confirmed and unconfirmed) transactions that are relevant to the client. 41 | 42 | - All connected servers are polled for fee estimates, but whether those values 43 | are used depends on the "auto-connect" setting of the client. 44 | With "auto-connect" disabled, only the fee estimates sent by the main server are used. 45 | With "auto-connect" enabled, the client uses the median of all received fee estimates. 46 | In either case, low-high sanity limits are applied in the client. 47 | 48 | - The main server is also used to broadcast the transactions the client makes. 49 | 50 | - A list of server peers is also requested by the client, to learn about 51 | other servers it can use. (There is a list of hardcoded servers in the 52 | client to bootstrap) 53 | 54 | Further, all of the connected servers will see the client's IP address 55 | (which might be that of a proxy/VPN/Tor, if used). 56 | 57 | The fast startup times and low resource usage is achieved at the cost of 58 | the above detailed privacy loss. The protocol and the client is designed 59 | in a way that minimises trust in the server. 60 | 61 | Anyone can run a server. If you feel strongly about privacy, 62 | or if SPV-security guarantees are not enough for you, you should 63 | consider running your own Electrum server. 64 | 65 | 66 | What is the seed? 67 | ----------------- 68 | 69 | The seed is a random phrase that is used to generate your private 70 | keys. 71 | 72 | Example: 73 | 74 | .. code-block:: none 75 | 76 | slim sugar lizard predict state cute awkward asset inform blood civil sugar 77 | 78 | Your wallet can be entirely recovered from its seed. For this, select 79 | the "I already have a seed" option in the wizard. 80 | 81 | How secure is the seed? 82 | ----------------------- 83 | 84 | The seed phrase created by Electrum has 132 bits of entropy. This 85 | means that it provides the same level of security as a Bitcoin private 86 | key (of length 256 bits). Indeed, an elliptic curve key of length n 87 | provides n/2 bits of security. 88 | 89 | 90 | I have forgotten my password. What can I do? 91 | -------------------------------------------- 92 | 93 | It is not possible to recover your password. However, you can restore 94 | your wallet from its seed phrase and choose a new password. 95 | If you lose both your password and your seed, there is no way 96 | to recover your money. This is why we ask you to save your seed 97 | phrase on paper. 98 | 99 | To restore your wallet from its seed phrase, create a new wallet, select 100 | the type, choose "I already have a seed" and proceed to input your seed 101 | phrase. 102 | 103 | 104 | How does Electrum get the Bitcoin price it uses? 105 | ------------------------------------------------ 106 | Electrum gets the Bitcoin price from a third party, but provides 107 | various options. Please see menubar > `Tools` > `Preferences` > `Fiat` 108 | to view the current setting or choose a new one. 109 | 110 | 111 | My transaction has been unconfirmed for a long time. What can I do? 112 | ------------------------------------------------------------------- 113 | 114 | Bitcoin transactions become "confirmed" when miners accept to write 115 | them in the Bitcoin blockchain. In general, the speed of confirmation 116 | depends on the fee you attach to your transaction; miners prioritize 117 | transactions that pay the highest fees. 118 | 119 | Recent versions of Electrum use "dynamic fees" in order to make sure 120 | that the fee you pay with your transaction is adequate. This feature 121 | is enabled by default in recent versions of Electrum. 122 | 123 | If you have made a transaction that is unconfirmed, you can: 124 | 125 | - Wait for a long time. Eventually, your transaction will either be 126 | confirmed or cancelled. This might take several days. 127 | 128 | - Increase the transaction fee. This is only possible for 129 | "replaceable" transactions. Electrum creates replaceable transactions 130 | by default, except for lightning channel open/close transactions. 131 | Transactions that are replaceable have "Replace by fee: True" in the 132 | transaction details screen. To increase the fee of a replaceable 133 | transaction right click on its entry on the history tab and choose 134 | "Increase Fee". Set an appropriate fee and click on "OK". A window will 135 | popup with the unsigned transaction. Click on "Sign" and then "Broadcast". 136 | 137 | - Create a "Child Pays for Parent" transaction. A CPFP is a new 138 | transaction that pays a high fee in order to compensate for the 139 | small fee of its parent transaction. It can be done by the 140 | recipient of the funds, or by the sender, if the transaction has a 141 | change output. To create a CPFP transaction right click on the 142 | unconfirmed transaction on the history tab and choose 143 | "Child pays for parent". Set an appropriate fee and click on "OK". 144 | A window will popup with the unsigned transaction. Click on "Sign" 145 | and then "Broadcast". 146 | 147 | - Cancel the transaction. This is only possible for "replaceable" 148 | transactions. Electrum creates replaceable transactions 149 | by default, except for lightning channel open/close transactions. 150 | Transactions that are replaceable have "Replace by fee: True" in the 151 | transaction details screen. To cancel a replaceable transaction 152 | right click on its entry on the history tab and choose 153 | "Cancel (double-spend)". Set an appropriate fee and click on "OK". A window 154 | will popup with the unsigned transaction. Click on "Sign" and then 155 | "Broadcast". 156 | 157 | 158 | What does it mean to "freeze" an address in Electrum? 159 | ----------------------------------------------------- 160 | 161 | When you freeze an address, the funds in that address will not be used 162 | for sending bitcoins. You cannot send bitcoins if you don't have 163 | enough funds in the non-frozen addresses. 164 | 165 | 166 | How is the wallet encrypted? 167 | ---------------------------- 168 | 169 | Electrum uses two separate levels of encryption: 170 | 171 | - Your seed and private keys are encrypted using AES-256-CBC. The 172 | private keys are decrypted only briefly, when you need to sign a 173 | transaction; for this you need to enter your password. This is done 174 | in order to minimize the amount of time during which sensitive 175 | information is unencrypted in your computer's memory. 176 | 177 | - In addition, your wallet file may be encrypted on disk. Note that 178 | the wallet information will remain unencrypted in the memory of 179 | your computer for the duration of your session. If a wallet is 180 | encrypted, then its password will be required in order to open 181 | it. Note that the password will not be kept in memory; Electrum 182 | does not need it in order to save the wallet on disk, because it 183 | uses asymmetric encryption (ECIES). 184 | 185 | Wallet file encryption is activated by default since version 2.8. It 186 | is intended to protect your privacy, but also to prevent you from 187 | requesting bitcoins on a wallet that you do not control. 188 | 189 | 190 | Does Electrum support cold wallets? 191 | ----------------------------------- 192 | 193 | Yes, see :ref:`Cold Storage `. 194 | 195 | 196 | Can I import private keys from other Bitcoin clients? 197 | ----------------------------------------------------- 198 | 199 | In Electrum 2.0, you cannot import private keys in a wallet that has a 200 | seed. You should sweep them instead. 201 | 202 | If you want to import private keys and not sweep them, you need to 203 | create a special wallet that does not have a seed. For this, create a 204 | new wallet, select "restore", and instead of typing your seed, type a 205 | list of private keys, or a list of addresses if you want to create a 206 | watching-only wallet. 207 | 208 | 209 | .. image:: png/import_addresses.png 210 | 211 | 212 | You will need to back up this wallet, because it cannot be 213 | recovered from a seed. 214 | 215 | Can I sweep private keys from other Bitcoin clients? 216 | ---------------------------------------------------- 217 | 218 | 219 | Sweeping private keys means to send all the bitcoins they control to 220 | an existing address in your wallet. The private keys you sweep do not 221 | become a part of your wallet. Instead, all the bitcoins they control 222 | are sent to an address that has been deterministically generated from 223 | your wallet seed. 224 | 225 | To sweep private keys, go to the Wallet menu -> Private Keys -> 226 | Sweep. Enter the private keys in the appropriate field. Leave the 227 | "Address" field unchanged. That is the destination address, and it will 228 | be from your existing electrum wallet. Click on "Sweep". It'll now take 229 | you to the send tab where you can set an appropriate fee and then click 230 | on "Send" to send the coins to your wallet. 231 | 232 | 233 | .. _datadir: 234 | 235 | Where is the Electrum datadir located? 236 | -------------------------------------- 237 | 238 | The data directory of Electrum is where wallet files, config settings, 239 | logs, blockchain headers, etc are stored. 240 | 241 | On Windows: 242 | 243 | - Show hidden files 244 | - Go to \\Users\\YourUserName\\AppData\\Roaming\\Electrum (or %APPDATA%\\Electrum) 245 | 246 | On Mac: 247 | 248 | - Open Finder 249 | - Go to folder (shift+cmd+G) and type ~/.electrum 250 | 251 | On Linux: 252 | 253 | - Home Folder 254 | - Go -> Location and type ~/.electrum 255 | 256 | 257 | Where is my wallet file located? 258 | -------------------------------- 259 | 260 | The default wallet file is called default_wallet, which is created when 261 | you first run the application and is located in the /wallets folder, 262 | inside the :ref:`datadir `. 263 | 264 | 265 | How to enable debug logging? 266 | ---------------------------- 267 | 268 | 1. Logging to file 269 | 270 | On Linux/Windows/macOS, you can enable logging to disk. 271 | Using the (Qt) GUI, go to menubar>Tools>Preferences>Misc, 272 | and tick "Write logs to file". After restarting Electrum, 273 | debug logs will be written to the :code:`logs/` folder inside the 274 | :ref:`datadir `. 275 | 276 | If you encounter an error while opening a wallet and hence cannot 277 | get to "Preferences" to enable logging, as a workaround you can 278 | create a temporary throwaway wallet and access the settings there. 279 | 280 | Using CLI/RPC, you can enable file logging via e.g.: 281 | 282 | .. code-block:: none 283 | 284 | $ electrum setconfig log_to_file true 285 | 286 | 2. Logging to terminal (standard error) 287 | 288 | On Linux/macOS, if you start Electrum from terminal, you can specify 289 | the :code:`-v` flag, to enable debug logs in the terminal (to stderr). 290 | This option does not work on Windows (when using the binaries). 291 | 292 | On macOS, when using the official binary, try e.g.: 293 | 294 | .. code-block:: none 295 | 296 | $ /Applications/Electrum.app/Contents/MacOS/run_electrum -v 297 | 298 | 299 | Can I do bulk payments with Electrum? (batching) 300 | ------------------------------------------------ 301 | 302 | You can create a transaction with several outputs. In the GUI, type 303 | each address and amount on a line, separated by a comma. 304 | 305 | .. image:: png/paytomany.png 306 | 307 | Amounts are in the current unit set in the client. The 308 | total is shown in the GUI. 309 | 310 | You can also import a CSV file in the "Pay to" field, by clicking on 311 | the folder icon. 312 | 313 | 314 | Can Electrum create and sign raw transactions? 315 | ---------------------------------------------- 316 | 317 | Electrum lets you create and sign raw transactions right from the user 318 | interface using a form. 319 | 320 | Electrum freezes when I try to send bitcoins. 321 | -------------------------------------------- 322 | 323 | This might happen if you are trying to spend a large number of 324 | transaction outputs (for example, if you have collected hundreds of 325 | donations from a Bitcoin faucet). When you send Bitcoins, Electrum 326 | looks for unspent coins that are in your wallet in order to create a 327 | new transaction. Unspent coins can have different values, much like 328 | physical coins and bills. 329 | 330 | If this happens, you should consolidate your transaction inputs by 331 | sending smaller amounts of bitcoins to one of your wallet addresses; 332 | this would be the equivalent of exchanging a stack of nickels for a 333 | dollar bill. 334 | 335 | .. _gap limit: 336 | 337 | What is the gap limit? 338 | ---------------------- 339 | 340 | The gap limit is the maximum number of consecutive unused addresses in 341 | your deterministic sequence of addresses. Electrum uses it in order 342 | to stop looking for addresses. In Electrum 2.0, it is set to 20 by 343 | default, so the client will get all addresses until 20 unused 344 | addresses are found. 345 | 346 | 347 | How can I pre-generate new addresses? 348 | ------------------------------------- 349 | 350 | Electrum will generate new addresses as you use them, 351 | until it hits the `gap limit`_. 352 | 353 | If you need to pre-generate more addresses, you can do so by typing 354 | wallet.create_new_address(False) in the console. This command will generate 355 | one new address. Note that the address will be shown with a red 356 | background in the address tab to indicate that it is beyond the gap 357 | limit. The red color will remain until the gap is filled. 358 | 359 | WARNING: Addresses beyond the gap limit will not automatically be 360 | recovered from the seed. To recover them will require either increasing 361 | the client's gap limit or generating new addresses until the used 362 | addresses are found. 363 | 364 | 365 | If you wish to generate more than one address, you can use a "for" 366 | loop. For example, if you wanted to generate 50 addresses, you could 367 | do this: 368 | 369 | .. code-block:: python 370 | 371 | [wallet.create_new_address(False) for i in range(50)] 372 | 373 | 374 | How do I upgrade Electrum? 375 | -------------------------- 376 | 377 | Warning: always save your wallet seed on paper before 378 | doing an upgrade. 379 | 380 | To upgrade Electrum, just install the most recent version. 381 | The way to do this will depend on your OS. 382 | 383 | Note that your wallet files are stored separately from the 384 | software, so you can safely remove the old version of the 385 | software if your OS does not do it for you. 386 | 387 | Some Electrum upgrades will modify the format of your 388 | wallet files. 389 | 390 | For this reason, it is not recommended to downgrade 391 | Electrum to an older version once you have opened your 392 | wallet file with the new version. The older version will 393 | not always be able to read the new wallet file. 394 | 395 | 396 | The following issues should be considered when upgrading 397 | Electrum 1.x wallets to Electrum 2.x: 398 | 399 | - Electrum 2.x will need to regenerate all of your 400 | addresses during the upgrade process. Please allow it 401 | time to complete, and expect it to take a little longer 402 | than usual for Electrum to be ready. 403 | 404 | - The contents of your wallet file will be replaced with 405 | an Electrum 2 wallet. This means Electrum 1.x will no 406 | longer be able to use your wallet once the upgrade is 407 | complete. 408 | 409 | - The "Addresses" tab will not show any addresses the 410 | first time you launch Electrum 2. This is expected 411 | behavior. Restart Electrum 2 after the upgrade is 412 | complete and your addresses will be available. 413 | 414 | - Offline copies of Electrum will not show the 415 | addresses at all because it cannot synchronize with 416 | the network. You can force an offline generation of a 417 | few addresses by typing the following into the 418 | Console: wallet.synchronize(). When it's complete, 419 | restart Electrum and your addresses will once again 420 | be available. 421 | 422 | 423 | .. _antivirus: 424 | 425 | My anti-virus has flagged Electrum as malware! What now? 426 | -------------------------------------------------------- 427 | 428 | Electrum binaries are often flagged by various anti-virus software. 429 | There is nothing we can do about it, so please stop reporting that to us. 430 | Anti-virus software uses heuristics in order to determine if a program 431 | is malware, and that often results in false positives. 432 | 433 | If you trust the developers of the project, you can verify 434 | the GPG signature of Electrum binaries, and safely ignore any anti-virus 435 | warnings. 436 | 437 | If you do not trust the developers of the project, you should build the 438 | binaries yourself, or run the software from source. 439 | 440 | Finally, if you are really concerned about malware, you should not use an 441 | operating system that relies on anti-virus software. 442 | 443 | 444 | Electrum requires recent Python. My Linux distribution does not yet have it. What now? 445 | -------------------------------------------------------------------------------------- 446 | 447 | There are several ways to resolve this. 448 | 449 | 1. Use the AppImage distributed by us. This is a single self-contained 450 | binary that includes all the dependencies. 451 | Currently, we only distribute this binary for x86_64 (amd64) architecture. 452 | Just download it, (verify GPG sig), make it executable, and run it. E.g.: 453 | 454 | .. code-block:: none 455 | 456 | $ wget https://download.electrum.org/3.3.4/electrum-3.3.4-x86_64.AppImage 457 | $ chmod +x electrum-3.3.4-x86_64.AppImage 458 | $ ./electrum-3.3.4-x86_64.AppImage 459 | 460 | 461 | 2. Use backports (e.g. in case of Debian, check the packages in stable-backports) 462 | 463 | 3. Upgrade your distribution (e.g. use Debian testing instead of stable) 464 | 465 | 4. Compile Python yourself, and then install pyqt5 using pip (as the package 466 | manager for the distribution will only have PyQt5 for the version of 467 | Python that is packaged by them). 468 | 469 | .. code-block:: none 470 | 471 | $ python3 -m pip install --user pyqt5 472 | 473 | (Unfortunately, it seems pyqt5 via pip is only available for x86/x86_64. 474 | On other archs, you might have to build Qt/PyQt yourself.) 475 | 476 | 5. Use a virtual machine where you run another Linux distribution that has 477 | more recent packages. 478 | 479 | 480 | I might run my own server. Are client-server connections authenticated? 481 | ----------------------------------------------------------------------- 482 | 483 | Electrum uses a client-server architecture, where the endpoints speak the 484 | Electrum protocol. The Electrum protocol is JSON-RPC based. 485 | The two main stacks the client supports are 486 | 487 | 1. JSON-RPC over SSL/TLS over TCP 488 | 489 | 2. JSON-RPC over TCP 490 | 491 | Note that neither option uses HTTP. 492 | 493 | The client only connects to servers over SSL (so plaintext TCP is not used). 494 | Prior to Electrum 3.1, there used to be a checkbox in the GUI to toggle this 495 | but it was removed. 496 | 497 | As for authentication, the client accepts both CA-signed certificates and self-signed 498 | SSL certificates. When it first connects to a server, it pins the fact whether that 499 | server is using a CA-signed or a self-signed cert. 500 | 501 | - If it is self-signed, it will only accept that cert until it expires for that server (TOFU). 502 | 503 | - If it is CA signed, it will forever only accept CA-signed certs for that server. 504 | 505 | For your own server, both CA-signed and self-signed certs have their advantages. 506 | 507 | - With self-signed certs, as the client uses TOFU, there is a possibility of 508 | man-in-the-middle during the first connection. 509 | 510 | - With CA-signed certs, you need to trust the Certificate Authorities. 511 | 512 | 513 | Does Electrum support altcoins ("cryptocurrencies")? 514 | ---------------------------------------------------- 515 | 516 | No. Electrum only supports Bitcoin. 517 | 518 | The project has never supported any altcoins, only Bitcoin. However Electrum 519 | is free (as in freedom) software with a permissive license, and there are many 520 | forks of the software that support specific altcoins. These are separate projects, 521 | with their own maintainers, independent of Electrum. We do not review their code 522 | or endorse them in any way. If you are a user of these, please direct any and all 523 | support requests to their maintainers, instead of us. 524 | 525 | 526 | My Electrum window is black. Why can't I see anything? 527 | ------------------------------------------------------ 528 | Electrum windows can appear black in screenshots and virtual desktops on Windows due to a built-in 529 | screenshot protection feature that intends to prevent screen capture tools and Microsoft Recall from 530 | recording your wallet activity and secrets. 531 | If you want to disable this feature, for example to capture screenshots, you can do so in the 532 | following two ways: 533 | 534 | 1. If you are able to access the GUI, open the `Settings` dialog and uncheck the `[x] Prevent screenshots` 535 | checkbox in the `Misc` tab of the dialog. 536 | 537 | 2. If you cannot even see the GUI it is possible to disable the feature by adding 538 | 539 | .. code-block:: none 540 | 541 | "screenshot_protection": false, 542 | 543 | to your Electrum config file. 544 | The config file location is described in the :ref:`datadir ` section. -------------------------------------------------------------------------------- /freeze_deps.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import tomllib # Python 3.11+ 4 | from pathlib import Path 5 | import subprocess 6 | import sys 7 | 8 | 9 | def pip_lock(requirements_file: str) -> None: 10 | cmd = [sys.executable, "-m", "pip", "lock", "-r", requirements_file] 11 | try: 12 | result = subprocess.run(cmd, check=True, text=True, capture_output=True) 13 | except Exception: 14 | print(f"failed. is pip lock available in your python environment? {sys.executable=}", file=sys.stderr) 15 | sys.exit(1) 16 | if result.stdout: 17 | print(result.stdout, end="") 18 | elif result.stderr: 19 | print(result.stderr, end="", file=sys.stderr) 20 | 21 | 22 | def generate_requirements(lock_file: str, output_file: str): 23 | # Load the TOML lock file 24 | with open(lock_file, "rb") as f: 25 | data = tomllib.load(f) 26 | 27 | lines = [] 28 | 29 | # Iterate over all packages 30 | for package in data.get("packages", []): 31 | name = package["name"] 32 | version = package["version"] 33 | 34 | # Start requirement line 35 | line = f"{name}=={version}" 36 | 37 | # Collect hashes if present 38 | wheels = package.get("wheels", []) 39 | hashes = [] 40 | for wheel in wheels: 41 | wheel_hashes = wheel.get("hashes", {}) 42 | if "sha256" in wheel_hashes: 43 | hashes.append(wheel_hashes["sha256"]) 44 | 45 | # Append hashes in pip format 46 | if hashes: 47 | hash_parts = [f"--hash=sha256:{h}" for h in hashes] 48 | line += " \\\n " + " \\\n ".join(hash_parts) 49 | 50 | lines.append(line) 51 | 52 | # Write requirements.txt 53 | Path(output_file).write_text("\n".join(lines)) 54 | 55 | 56 | if __name__ == "__main__": 57 | pip_lock('requirements-docs.txt') 58 | generate_requirements("pylock.toml", "requirements-docs-frozen.txt") 59 | os.remove('pylock.toml') 60 | print(f"wrote frozen packages to requirements-docs-frozen.txt") -------------------------------------------------------------------------------- /gpg-check.rst: -------------------------------------------------------------------------------- 1 | Verifying GPG signature of Electrum using Linux command line 2 | ============================================================ 3 | 4 | This can be used to verify the authenticity of Electrum binaries/sources. 5 | 6 | Download only from electrum.org and remember to check the gpg signature again every time you download a new version 7 | 8 | Obtain public GPG key for ThomasV 9 | --------------------------------- 10 | 11 | In a terminal enter (or copy): 12 | 13 | .. code-block:: bash 14 | 15 | gpg --keyserver keys.gnupg.net --recv-keys 6694D8DE7BE8EE5631BED9502BD5824B7F9470E6 16 | 17 | You should be able to substitute any public GPG keyserver if keys.gnupg.net is (temporarily) not working 18 | 19 | Download Electrum and signature file (asc) 20 | ------------------------------------------ 21 | 22 | Download the Python Electrum-.tar.gz or AppImage file 23 | 24 | Right click on the signature file and save it as well 25 | 26 | Verify GPG signature 27 | -------------------- 28 | 29 | Run the following command from the same directory you saved the files replacing with the one actually downloaded: 30 | 31 | .. code-block:: bash 32 | 33 | gpg --verify .asc 34 | 35 | The message should say: 36 | 37 | .. code-block:: bash 38 | 39 | Good signature from "Thomas Voegtlin (https://electrum.org) 40 | 41 | and 42 | 43 | .. code-block:: bash 44 | 45 | Primary key fingerprint: 6694 D8DE 7BE8 EE56 31BE D950 2BD5 824B 7F94 70E6 46 | 47 | You can ignore this: 48 | 49 | .. code-block:: bash 50 | 51 | WARNING: This key is not certified with a trusted signature! 52 | gpg: There is no indication that the signature belongs to the owner. 53 | 54 | as it simply means you have not established a web of trust with other GPG users 55 | -------------------------------------------------------------------------------- /hardfork.rst: -------------------------------------------------------------------------------- 1 | 2 | How to split your coins using Electrum in case of a fork 3 | ======================================================== 4 | 5 | Note: 6 | ----- 7 | 8 | This document has been updated for Electrum 2.9. 9 | 10 | 11 | What is a fork? 12 | --------------- 13 | 14 | A blockchain fork (or blockchain split) occurs when a deviating 15 | network begins to generate and maintain a conflicting chain of blocks 16 | branching from the original, essentially creating another "version of 17 | bitcoin" or cryptocurrency, with its very own blockchain, set of 18 | rules, and market value. 19 | 20 | If there is a fork of the Bitcoin blockchain, two distinct currencies 21 | will coexist, having different market values. 22 | 23 | 24 | What does it mean to 'split your coins'? 25 | ---------------------------------------- 26 | 27 | An address on the original blockchain will now also contain the same 28 | amount on the new chain. 29 | 30 | If you own Bitcoins before the fork, a transaction that spends these 31 | coins after the fork will, in general, be valid on both chains. This 32 | means that you might be spending both coins simultaneously. This is 33 | called 'replay'. To prevent this, you need to move your coins using 34 | transactions that differ on both chains. 35 | 36 | 37 | 38 | Fork detection 39 | -------------- 40 | 41 | Electrum (version 2.9 and higher) is able to detect consensus failures 42 | between servers (blockchain forks), and lets users select their branch 43 | of the fork. 44 | 45 | * Electrum will download and validate block headers sent by servers 46 | that may follow different branches of a fork in the Bitcoin 47 | blockchain. Instead of a linear sequence, block headers are 48 | organized in a tree structure. Branching points are located 49 | efficiently using binary search. The purpose of MCV is to detect and 50 | handle blockchain forks that are invisible to the classical SPV 51 | model. 52 | 53 | * The desired branch of a blockchain fork can be selected using the 54 | network dialog. Branches are identified by the hash and height of 55 | the diverging block. Coin splitting is possible using RBF 56 | transaction (a tutorial will be added). 57 | 58 | 59 | This feature allows you to pick and choose which chain and network you spend on. 60 | 61 | 62 | Procedure 63 | --------- 64 | 65 | 1. Preparation 66 | 67 | a. Menu ➞ View ➞ Show Coins 68 | b. Menu ➞ Tools ➞ Preferences ➞ Propose Replace-By-Fee ➞ "Always" 69 | 70 | 2. Select a chain / network 71 | 72 | a. Menu ➞ Tools ➞ Network 73 | 74 | Notice how the branches have different hashes at different heights. 75 | You can verify which chain you're on by using block explorers to verify 76 | the hash and height. 77 | 78 | .. image:: png/coin_splitting/select_main_chain.png 79 | .. image:: png/coin_splitting/chain_search_height.png 80 | .. image:: png/coin_splitting/chain_verify_hash.png 81 | 82 | 3. Send your coins to yourself 83 | 84 | a. Copy your receiving address to the sending tab. 85 | b. Enter how many coins you'd like to split. (enter " ! " for ALL) 86 | c. Check "Replaceable" 87 | d. Send ➞ Sign ➞ Broadcast 88 | 89 | 4. Wait for the transaction to confirm on one network. 90 | 91 | a. You'll want to switch between chains (via the network panel) 92 | to monitor the transaction status. 93 | 94 | b. Wait until you see the transaction confirm on one chain. 95 | 96 | .. image:: png/coin_splitting/unconfirmed.png 97 | .. image:: png/coin_splitting/confirmed.png 98 | 99 | c. Immediately use "RBF" on the unconfirmed transaction to "Increase fee" 100 | 101 | .. image:: png/coin_splitting/increase_fee.png 102 | 103 | 5. Wait for both chains to confirm the transaction. 104 | 105 | 6. Verify the transaction has a different TXID on each chain. 106 | 107 | .. image:: png/coin_splitting/main_chain_txid.png 108 | .. image:: png/coin_splitting/alternate_chain_txid.png 109 | 110 | You will now have coins seperately spendable on each chain. If it failed, 111 | no harm done, you sent to yourself! Just try again. 112 | -------------------------------------------------------------------------------- /hardware-linux.rst: -------------------------------------------------------------------------------- 1 | Hardware wallets on Linux 2 | ========================= 3 | 4 | The following aims to be a concise guide of what you need to get your 5 | hardware wallet working with Electrum. 6 | 7 | If you use the AppImage, that already has all the dependencies and Python 8 | libraries bundled with it, so skip the first two steps. 9 | 10 | 1. Dependencies 11 | ~~~~~~~~~~~~~~~ 12 | 13 | Currently all hardware wallets depend on ``hidapi``, to be able to build 14 | that, you need: 15 | 16 | *ubuntu:* 17 | :: 18 | 19 | sudo apt-get install libusb-1.0-0-dev libudev-dev 20 | 21 | *fedora:* 22 | :: 23 | 24 | sudo dnf install libusb-devel systemd-devel 25 | 26 | (Package names may be different for other distributions.) 27 | 28 | 2. Python libraries 29 | ~~~~~~~~~~~~~~~~~~~ 30 | 31 | Then, depending on the device you have, you need a python package 32 | (typically a library by the manufacturer). 33 | For a usually more up-to-date list (including potential version requirements), refer to 34 | `requirements-hw.txt `_ 35 | in the client source. 36 | 37 | 38 | Trezor 39 | ^^^^^^ 40 | 41 | :: 42 | 43 | python3 -m pip install trezor[hidapi] 44 | 45 | For more details, refer to `python-trezor `_. 46 | 47 | 48 | Ledger 49 | ^^^^^^ 50 | 51 | :: 52 | 53 | python3 -m pip install hidapi ledger-bitcoin 54 | 55 | For more details, refer to 56 | `LedgerHQ/app-bitcoin-new `_ 57 | 58 | 59 | KeepKey 60 | ^^^^^^^ 61 | 62 | Starting with Electrum 4.6.0, we bundle `our fork `_ 63 | of `python-keepkey `_ as the upstream is unmaintained. 64 | 65 | We need the `dependencies `_ 66 | of `python-keepkey`: 67 | 68 | :: 69 | 70 | python3 -m pip install ecdsa protobuf mnemonic hidapi libusb1 71 | 72 | 73 | Digital Bitbox 74 | ^^^^^^^^^^^^^^ 75 | 76 | The Digital Bitbox only needs ``hidapi``. 77 | 78 | :: 79 | 80 | python3 -m pip install hidapi 81 | 82 | 83 | BitBox02 84 | ^^^^^^^^ 85 | 86 | :: 87 | 88 | python3 -m pip install bitbox02 89 | 90 | For more details, refer to `python-bitbox02 `_. 91 | 92 | 93 | Archos Safe-T 94 | ^^^^^^^^^^^^^ 95 | 96 | :: 97 | 98 | python3 -m pip install safet 99 | 100 | For more details, refer to `python-safet `_. 101 | 102 | 103 | Coldcard 104 | ^^^^^^^^ 105 | 106 | :: 107 | 108 | python3 -m pip install ckcc-protocol 109 | 110 | For more details, refer to `ckcc-protocol `_. 111 | 112 | Jade 113 | ^^^^^^^^ 114 | 115 | :: 116 | 117 | python3 -m pip install pyserial cbor2 118 | 119 | For more details, refer to `jadepy `_. 120 | 121 | 122 | 3. udev rules 123 | ~~~~~~~~~~~~~ 124 | 125 | You will need to configure udev rules. 126 | See `electrum/contrib/udev `_ 127 | 128 | 129 | 4. Done 130 | ~~~~~~~ 131 | 132 | That's it! Electrum should now detect your device. 133 | 134 | -------------------------------------------------------------------------------- /index.rst: -------------------------------------------------------------------------------- 1 | .. Electrum documentation master file, created by 2 | sphinx-quickstart on Fri Sep 18 14:24:02 2015. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to the Electrum Documentation! 7 | ====================================== 8 | 9 | Electrum is a lightweight Bitcoin wallet. 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | :caption: GUI and beginners 14 | 15 | faq 16 | invoices 17 | 2fa 18 | multisig 19 | coldstorage 20 | hardware-linux 21 | tails 22 | plugins 23 | malware 24 | 25 | 26 | .. toctree:: 27 | :maxdepth: 2 28 | :caption: Advanced users 29 | 30 | coldstorage_cmdline 31 | hardfork 32 | tor 33 | gpg-check 34 | 35 | 36 | .. toctree:: 37 | :maxdepth: 2 38 | :caption: Daemon and Command Line 39 | 40 | cmdline 41 | ssl 42 | merchant 43 | watchtower 44 | swapserver 45 | jsonrpc 46 | 47 | 48 | .. toctree:: 49 | :maxdepth: 2 50 | :caption: For developers 51 | 52 | console 53 | spv 54 | seedphrase 55 | protocol 56 | transactions 57 | plugin_dev 58 | plugin_rules 59 | -------------------------------------------------------------------------------- /invoices.rst: -------------------------------------------------------------------------------- 1 | Invoices 2 | ======== 3 | 4 | Invoices are Payment Requests signed by their requestor. 5 | 6 | 7 | When you click on a bitcoin: link, a URL is passed to 8 | electrum: 9 | 10 | .. code-block:: bash 11 | 12 | electrum "bitcoin:1KLxqw4MA5NkG6YP1N4S14akDFCP1vQrKu?amount=1.0&r=https%3A%2F%2Fbitpay.com%2Fi%2FXxaGtEpRSqckRnhsjZwtrA" 13 | 14 | 15 | This opens the send tab with the payment request: 16 | 17 | .. image:: png/PaymentRequest.png 18 | 19 | The green color in the "Pay To" field means that the payment request 20 | was signed by bitpay.com's certificate, and that Electrum verified the 21 | chain of signatures. 22 | 23 | Note that the "send" tab contains a list of invoices and their status. 24 | 25 | 26 | -------------------------------------------------------------------------------- /jsonrpc.rst: -------------------------------------------------------------------------------- 1 | JSONRPC interface 2 | ================= 3 | 4 | 5 | Commands to the Electrum daemon can be sent using JSONRPC. This is 6 | useful if you want to use electrum in a PHP script. 7 | 8 | Note that the daemon uses a random port number by default. In order to 9 | use a stable port number, you need to set the 'rpcport' configuration 10 | variable (and to restart the daemon): 11 | 12 | .. code-block:: bash 13 | 14 | electrum setconfig rpcport 7777 15 | 16 | Further, starting with Electrum 3.0.5, the JSON-RPC interface is 17 | authenticated using `HTTP basic auth`_. 18 | 19 | .. _`HTTP basic auth`: https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#Basic_authentication_scheme 20 | 21 | The username and the password are config variables. 22 | When first started, Electrum will initialise both; 23 | the password will be set to a random string. You can of course 24 | change them afterwards (the same way as the port, and then restart 25 | the daemon). To simply look up their value: 26 | 27 | .. code-block:: bash 28 | 29 | electrum getconfig rpcuser 30 | electrum getconfig rpcpassword 31 | 32 | Note that HTTP basic auth sends the username and the password unencrypted as 33 | part of the request. While using it on localhost is fine in our opinion, 34 | using it across an untrusted LAN or the Internet is not secure. 35 | Hence, you should take further measures in such cases, such as wrapping the 36 | connection in a secure tunnel. For further details, `read this`_. 37 | 38 | .. _`read this`: https://bitcoin.org/en/release/v0.12.0#rpc-ssl-support-dropped 39 | 40 | After setting a static port, and configuring authentication, 41 | we can perform queries using curl or PHP. Example: 42 | 43 | .. code-block:: bash 44 | 45 | curl --data-binary '{"jsonrpc":"2.0","id":"curltext","method":"getbalance","params":[]}' http://username:password@127.0.0.1:7777 46 | 47 | Query with named parameters: 48 | 49 | .. code-block:: bash 50 | 51 | curl --data-binary '{"jsonrpc":"2.0","id":"curltext","method":"listaddresses","params":{"funded":true}}' http://username:password@127.0.0.1:7777 52 | 53 | Create a payment request: 54 | 55 | .. code-block:: bash 56 | 57 | curl --data-binary '{"jsonrpc":"2.0","id":"curltext","method":"add_request","params":{"amount":"3.14","memo":"test"}}' http://username:password@127.0.0.1:7777 58 | -------------------------------------------------------------------------------- /libsecp256k1-linux.rst: -------------------------------------------------------------------------------- 1 | libsecp256k1 on Linux 2 | ========================= 3 | 4 | Notes about getting libsecp256k1 to work with Electrum on Linux. 5 | 6 | 7 | 1. Using package manager 8 | ~~~~~~~~~~~~~~~~~~~~~~~~ 9 | 10 | On recent versions of Ubuntu/Debian, libsecp256k1 should be available 11 | through the package manager: 12 | 13 | :: 14 | 15 | sudo apt-get install libsecp256k1-0 16 | 17 | 18 | Electrum should be able to find the ``.so`` file and use it. 19 | 20 | 21 | 2. How library is searched for 22 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 23 | 24 | The command Electrum uses to find the library, on Linux, is the following: 25 | 26 | :: 27 | 28 | import ctypes; ctypes.cdll.LoadLibrary('libsecp256k1.so.0') 29 | 30 | 31 | If the library does not seem to be picked up by Electrum, consider 32 | opening a python interpreter to see for yourself. 33 | 34 | 35 | 3. If you compile libsecp256k1 yourself 36 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | 38 | If you compile from source, the ``.so`` files are typically placed in 39 | ``/usr/local/lib``. 40 | 41 | Unfortunately, ``ctypes.cdll.LoadLibrary`` does not seem to find them there. 42 | 43 | Two workarounds: 44 | 45 | Set LD_LIBRARY_PATH env var 46 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 47 | 48 | You can set the LD_LIBRARY_PATH environment variable. 49 | Start Electrum like this: 50 | 51 | :: 52 | 53 | LD_LIBRARY_PATH=/usr/local/lib electrum 54 | 55 | 56 | Symlink .so file 57 | ^^^^^^^^^^^^^^^^ 58 | 59 | You can symlink the ``.so`` file. ``/usr/lib`` seems to work. 60 | 61 | :: 62 | 63 | sudo ln -s /usr/local/lib/libsecp256k1.so.0 /usr/lib/libsecp256k1.so.0 64 | 65 | -------------------------------------------------------------------------------- /malware.md: -------------------------------------------------------------------------------- 1 | # Malware (and other avenues of losing money) 2 | 3 | Bitcoin (when used as intended) is non-custodial money. 4 | With fiat in a bank (custody), the bank is responsible for safe-guarding it. 5 | With bitcoins, the user is responsible for safe-guarding it. 6 | 7 | Electrum is non-custodial wallet software, meaning the software installed on the user's 8 | computer has complete and exclusive control over all funds. 9 | For example, the developers cannot access/move/see your coins. 10 | 11 | However, this model makes bitcoin users prime targets of malware: 12 | compromising the user's computer can lead to stealing all their bitcoins. 13 | 14 | 15 | ## Attack scenarios 16 | 17 | ### Malicious clone 18 | 19 | i.e. downloading (clone of) Electrum from unofficial source 20 | 21 | Attackers often clone our website and host it on lookalike fake domains. 22 | They then pay for Google ads to advertise their fake domains. 23 | 24 | The official Electrum project does not pay for Google ads. 25 | 26 | When users search "electrum" on Google, they see the malicious ads, click them, 27 | go to the lookalike website, download malicious clones of Electrum, and run it. 28 | When running the malware, "Electrum" seemingly opens and the user enters their password 29 | to open their wallet file. At that point, the software broadcasts a transaction 30 | sending all money out, and/or uploads the seed words to a remote server. 31 | 32 | - Signs of compromise: 33 | if you see a transaction in your wallet history that you do not recognise, 34 | AND that transaction moves all your coins AND your wallet balance is now zero 35 | (shown in bottom left corner), 36 | then you might have downloaded malware that stole your coins. 37 | 38 | - Defense: users should only download Electrum from the official website 39 | (and {doc}`verify GPG signatures `). 40 | 41 | ### Clipboard hijacker 42 | 43 | A clipboard hijacker a simple external program (virus) that monitors the user's clipboard: 44 | every time the clipboard changes, it checks if it is a bitcoin address, and if so, replaces it 45 | with another bitcoin address that belongs to the attacker. 46 | 47 | The idea is that usually a bitcoin address being copied means the user is going to paste it to 48 | a wallet right away and send money there. 49 | 50 | - Signs of compromise: 51 | if you copy a bitcoin address and then paste it to a text editor, a different address gets pasted. 52 | 53 | - Defense: users should preview (and confirm details of) any transaction they sign before signing it. 54 | 55 | ### Compromised PC 56 | 57 | i.e. having other malware present on computer that accesses wallet file or RAM and steals your seed words 58 | 59 | When using a "standard wallet" in Electrum on a PC, any (sufficiently privileged) other program 60 | on that same PC might get access to the wallet file and try to steal the seed words. More advanced 61 | attacks might dump the main memory (RAM) and find the seed words or private keys or the wallet password 62 | (given the right timing). 63 | 64 | ### Posing as support 65 | 66 | i.e. posing as "support" on forums (social engineering) 67 | 68 | If you post on reddit/bitcointalk/etc, attackers might reply or send a private message 69 | claiming to be "Electrum support" or "customer service". They might then ask you to download 70 | a new version of Electrum and give you a link, or ask for your seed words. 71 | 72 | There is no customer service. These are scams. Be vigilant. 73 | 74 | Any support provided is always in public. 75 | 76 | ### Backup accessed by flatmate/etc 77 | 78 | The seed/private keys should not be stored digitally, but instead preferably on paper. 79 | Paper cannot be hacked. 80 | 81 | Be mindful of where you keep your backups (written down seed words). 82 | E.g. a roommate might find a piece of paper and move your coins. 83 | 84 | Taking a photo of your seed, and especially uploading that photo to cloud storage, 85 | is asking for trouble. So is generating/entering the seed in a public place. 86 | 87 | ### Planted wallet file 88 | 89 | An attacker might copy their wallet file onto the victim's computer. 90 | The next time the victim runs Electrum, it is the attacker's wallet that gets 91 | opened. If the victim does not notice and generates an address to receive on, 92 | any incoming funds will go to the attacker's wallet. 93 | 94 | This attack can even be done before Electrum is installed at all. The attacker 95 | places their wallet file where Electrum would expect to find it, and leave it 96 | there for months/years until the user downloads Electrum. 97 | 98 | - Defense: use password-protected encrypted wallet files and be suspicious 99 | if you were not required to enter the password to open the wallet. 100 | 101 | 102 | ## Defense, best practices 103 | 104 | In increasing order of complexity: 105 | 106 | - only download Electrum from the official website 107 | - password-protect wallet files (using built-in methods) 108 | - {doc}`verify GPG signatures ` 109 | (of the downloaded Electrum executable, before running it for the first time) 110 | - don't use hot wallets for large amounts of money 111 | - use {doc}`2fa <2fa>`, or multisig wallets (across different computers or phones) 112 | - use hardware devices to sign (such as Trezor) 113 | - use {doc}`cold storage ` / offline-signing setup 114 | - double-check recipient addresses and amounts using a second/trusted source, 115 | before signing. check the address: 116 | - on the screen of each multisig cosigner 117 | - on the screen of the hardware signer 118 | - on the screen of the offline signer computer 119 | 120 | 121 | ## Help! My coins have been stolen! 122 | 123 | Bitcoin transactions are irreversible, so in case of theft, 124 | there is unfortunately nothing the developers (or anyone) can do to recover the money. 125 | 126 | If you know how the attack worked, you are welcome to tell the developers. It is useful for us to know 127 | about the type and number of attacks, to try to prevent or mitigate future attacks. 128 | If the stolen amount is substantial enough, consider reporting the theft to the police. 129 | 130 | If you think what happened might have resulted from a bug (and not malware), we ask you open a bug report. 131 | 132 | #### Can I keep using the wallet? 133 | 134 | If your coins got stolen, you must not keep using your existing wallet (the same seed words). 135 | If you send more coins into your wallet, those too will likely get stolen. 136 | 137 | - You should wipe/format your computer and do a fresh re-install of the OS. 138 | - Then you can download Electrum again (from the official website!). 139 | - Then you need to create a new wallet, as in, generate a new seed. 140 | 141 | 142 | ## My anti-virus has flagged Electrum as malware! 143 | 144 | See the relevant {ref}`FAQ section `. 145 | 146 | -------------------------------------------------------------------------------- /merchant.rst: -------------------------------------------------------------------------------- 1 | .. _merchant: 2 | 3 | How to accept Bitcoin on a website using Electrum 4 | ================================================= 5 | 6 | This tutorial will show you how to accept Bitcoin on a website with 7 | SSL signed payment requests, according to BIP-70_. The docs are 8 | updated for Electrum 4.0. 9 | 10 | .. _BIP-70: 11 | https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki 12 | 13 | You will need a valid SSL certificate (signed by a CA, for example 14 | free Letsencrypt_). Please follow the instructions to install the 15 | development version. Do not forget the submodule update command. 16 | 17 | 18 | .. _development: 19 | https://github.com/spesmilo/electrum#development-version-git-clone 20 | 21 | .. _Letsencrypt: 22 | https://letsencrypt.org/ 23 | 24 | 25 | Add your SSL certificate to Electrum 26 | ------------------------------------ 27 | 28 | .. code-block:: bash 29 | 30 | electrum -o setconfig ssl_keyfile /path/to/ssl/privkey.pem 31 | electrum -o setconfig ssl_certfile /path/to/ssl/fullchain.pem 32 | 33 | For details see `How to add SSL `_ 34 | 35 | 36 | Create and use your merchant wallet 37 | ----------------------------------- 38 | 39 | Create a wallet on your protected machine, as you want to keep your 40 | cryptocurrency safe. If anybody compromise your merchant server, s/he will be able 41 | to access read-only version of your wallet only and won't be able to spent currency. 42 | 43 | Please notice that the potential intruder still will be able to see your 44 | addresses, transactions and balance, though. It's also recommended to use a 45 | separate wallet for your merchant purposes (and not your main wallet). 46 | 47 | .. code-block:: bash 48 | 49 | electrum create 50 | 51 | Still being on a protected machine, export your Master Public Key (xpub): 52 | 53 | .. code-block:: bash 54 | 55 | electrum getmpk -w .electrum/wallets/your-wallet 56 | 57 | Now you are able to set up your electrum merchant daemon. 58 | 59 | On the server machine restore your wallet from previously exported Master 60 | Public Key (xpub): 61 | 62 | .. code-block:: bash 63 | 64 | electrum restore xpub............................................... 65 | 66 | 67 | 68 | Configure your full hostname and port: 69 | 70 | .. code-block:: bash 71 | 72 | electrum -o setconfig payserver_address ecdsa.org:80 73 | 74 | 75 | Start the Electrum daemon 76 | ------------------------- 77 | 78 | Once your read-only wallet is (re-)created, start Electrum as a daemon: 79 | 80 | .. code-block:: bash 81 | 82 | electrum daemon -d 83 | electrum load_wallet 84 | 85 | 86 | Note: to stop the daemon 87 | 88 | .. code-block:: bash 89 | 90 | electrum stop 91 | 92 | 93 | Create a signed payment request 94 | ------------------------------- 95 | 96 | .. code-block:: bash 97 | 98 | electrum add_request 0.5 -m "test" 99 | { 100 | "URI": "bitcoin:bc1qyr5xx5jkue3k72sldm5xa0taqs3n2achupymz8?amount=0.5&message=test&time=1589115653&exp=3600", 101 | "address": "bc1qyr5xx5jkue3k72sldm5xa0taqs3n2achupymz8", 102 | "amount": 50000000, 103 | "amount_BTC": "0.5", 104 | "bip70_url": "https://ecdsa.org:80/bip70/bc1qyr5xx5jkue3k72sldm5xa0taqs3n2achupymz8.bip70", 105 | "exp": 3600, 106 | "id": "6988b80931", 107 | "memo": "test", 108 | "status": 0, 109 | "status_str": "Expires in about 1 hour", 110 | "time": 1589115653, 111 | "type": 0, 112 | "view_url": "https://ecdsa.org:80/r/pay?id=bc1qyr5xx5jkue3k72sldm5xa0taqs3n2achupymz8" 113 | } 114 | 115 | This command returns a json object with two URLs: 116 | 117 | - bip70_url is the URL of the signed BIP70 request. 118 | - view_url is the URL of a webpage displaying the request. 119 | 120 | You can view the current list of requests using the 'list_requests' 121 | command. You can clear the list using 'clear_requests'. 122 | 123 | Open the payment request page in your browser 124 | --------------------------------------------- 125 | 126 | Let us open view_url in a web browser. 127 | 128 | .. image:: png/payrequest.png 129 | 130 | The page shows the payment request. You can open the 131 | bitcoin: URI with a wallet, or scan the QR code. The bottom 132 | line displays the time remaining until the request expires. 133 | 134 | .. image:: png/payreq_window.png 135 | 136 | 137 | The page will update itself when the payment is received, using websockets. 138 | 139 | 140 | Lightning payments 141 | ------------------ 142 | 143 | To use lightning, you need to initialize lightning keys in your wallet. 144 | You will need to restart the daemon after that, or to stop it before: 145 | 146 | .. code-block:: bash 147 | 148 | electrum stop 149 | electrum -o init_lightning 150 | electrum daemon -d 151 | 152 | Note that it is possible to add lightning keys to a watching-only 153 | wallet. That wallet will not be able to spend coins onchain, but it 154 | will be able to perform lightning transactions. 155 | 156 | The next thing you will need to do is open a channel: 157 | 158 | .. code-block:: bash 159 | 160 | electrum open_channel 161 | 162 | Wait until it is ready to be used: 163 | 164 | .. code-block:: bash 165 | 166 | electrum list_channels 167 | 168 | You will not immediately be able to receive with that channel, because 169 | it does not have inbound capacity. If you need to be able to receive 170 | immediately, you may do a submarine swap of your channel funds. 171 | 172 | To create a lightning payment request: 173 | 174 | .. code-block:: bash 175 | 176 | electrum add_request 0.0001 --lightning --memo "test" 177 | -------------------------------------------------------------------------------- /multisig.rst: -------------------------------------------------------------------------------- 1 | Multisig Wallets 2 | ================ 3 | 4 | This tutorial shows how to create a 2 of 2 multisig wallet. A 2 of 2 5 | multisig consists of 2 separate wallets (usually on separate machines 6 | and potentially controlled by separate people) that have to be used in 7 | conjunction in order to access the funds. Both wallets have the same 8 | set of Addresses. 9 | 10 | - A common use-case for this is if you want to collaboratively control 11 | funds: maybe you and your friend run a company together 12 | and certain funds should only be spendable if you both 13 | agree. 14 | 15 | - Another one is security: One of the wallets can be on 16 | your main machine, while the other one is on a offline 17 | machine. That way you make it very hard for an attacker 18 | or malware to steal your coins. 19 | 20 | 21 | Create a pair of 2-of-2 wallets 22 | ------------------------------- 23 | 24 | Each cosigner needs to do this: In the menu select File->New, then 25 | select "Multi-signature wallet". On the next screen, select 2 of 2. 26 | 27 | .. image:: png/create_multisig.png 28 | 29 | After generating a seed (keep it safely!) you will need to 30 | provide the master public key of the other wallet. 31 | 32 | .. image:: png/create_2of2.png 33 | 34 | Put the master public key of the other wallet into the 35 | lower box. Of course when you create the other wallet, you 36 | put the master public key of this one. 37 | 38 | You will need to do this in parallel for the two wallets. 39 | Note that you can press cancel during this step, and reopen 40 | the file later. 41 | 42 | Receiving 43 | --------- 44 | 45 | Check that both wallets generate the same set of Addresses. You can 46 | now send to these Addresses (note they start with a "3") with any 47 | wallet that can send to P2SH Addresses. 48 | 49 | 50 | Spending 51 | -------- 52 | 53 | To spend coins from a 2-of-2 wallet, two cosigners need to 54 | sign a transaction collaboratively. 55 | 56 | To accomplish this, create a transaction using one of the 57 | wallets (by filling out the form on the "send" tab) 58 | 59 | After signing, a window is shown with the transaction 60 | details. 61 | 62 | .. image:: png/Partially_Signed.png 63 | 64 | The transaction has to be sent to the second wallet. 65 | 66 | For this you have multiple options: 67 | 68 | - you can transfer the file on a usb stick 69 | - you can use QR codes 70 | - you can use a remote server, with the CosignerPool plugin. 71 | 72 | 73 | Transfer a file 74 | ``````````````` 75 | 76 | You can save the partially signed transaction to a file (using the 77 | "save" button), transfer that to the machine where the second wallet 78 | is running (via usb stick, for example) and load it there (using Tools 79 | -> Load transaction -> from file) 80 | 81 | Use QR-Code 82 | ``````````` 83 | 84 | There's also a button showing a qr-code icon. Clicking 85 | that will display a qr-code containing the transaction that 86 | can be scanned into the second wallet (Tools -> Load 87 | Transaction -> From QR Code) 88 | 89 | Use the Cosigner Pool Plugin 90 | ```````````````````````````` 91 | 92 | For this to work the Plugin "Cosigner Pool" needs to be 93 | enabled (Tools -> Plugins) with both wallets. 94 | 95 | Once the plugin is enabled, you will see a button labeled "Send to 96 | cosigner". Clicking it sends the partially signed transaction to a 97 | central server. Note that the transaction is encrypted with your 98 | cosigner's master public key. 99 | 100 | .. image:: png/Sent_to_Cosigner.png 101 | 102 | When the cosigner wallet is started, it will get a 103 | notification that a partially signed transaction is 104 | available: 105 | 106 | .. image:: png/Cosigner_Retrieve.png 107 | 108 | The transaction is encrypted with the cosigner's master 109 | public key; the password is needed to decrypt it. 110 | 111 | With all of the above methods, you can now add the second 112 | signature to the transaction (using the "sign" button). It 113 | can then be broadcast to the network. 114 | 115 | -------------------------------------------------------------------------------- /plugin_dev.rst: -------------------------------------------------------------------------------- 1 | .. _plugin_dev: 2 | 3 | Electrum Plugin development 4 | =========================== 5 | 6 | 7 | Note: If you are interested in developing your own plugin, have a look at 8 | the https://github.com/spesmilo/electrum-plugins repository and 9 | internal plugins in the electrum repository for examples. 10 | 11 | 12 | 13 | Plugin Hooks 14 | ------------ 15 | 16 | Plugins interact with the Electrum code through ''hooks''. 17 | 18 | 19 | Plugin code: 20 | 21 | .. code-block:: python 22 | 23 | class MyPlugin(Plugin): 24 | 25 | @hook 26 | def alpha(self, params): 27 | do_stuff() 28 | 29 | Electrum code: 30 | 31 | .. code-block:: python 32 | 33 | run_hook('alpha', params) 34 | 35 | 36 | Directory structure 37 | ------------------- 38 | 39 | Your plugin should contain: 40 | * manifest.json: this file describes the plugin. 41 | * __init__.py: this file includes commands and config variable declarations 42 | * one or several plugin modules: a module that contains a Plugin class, which inherits from electrum.BasePlugin. 43 | It will be imported at runtine. Examples: qt.py, qml.py, cmdline.py 44 | 45 | 46 | 47 | The manifest.json file 48 | ---------------------- 49 | 50 | This file is pre-loaded in order to display plugin information in the Electrum client. 51 | It contains the list of GUIs for which the plugin is available. 52 | 53 | 54 | In our example, this is how the manifest.json looks like: 55 | 56 | .. code-block:: json 57 | 58 | { 59 | "name": "virtualkeyboard", 60 | "fullname": "Virtual Keyboard", 61 | "description": "Add an optional virtual keyboard to the password dialog.\nWarning: do not use this if it makes you pick a weaker password.", 62 | "available_for": ["qt"], 63 | "author": "The Electrum developers", 64 | "license": "MIT", 65 | "icon":"keyboard-icon.svg", 66 | "version": "0.0.1" 67 | } 68 | 69 | 70 | In the 'available_for' field, this plugin declares that it is available for the Qt gui. 71 | Therefore, Electrum will expect a Plugin class in the 'qt.py' file. 72 | 73 | 74 | The plugin module: 75 | ------------------- 76 | 77 | This is how the plugin looks like: 78 | 79 | .. code-block:: python 80 | 81 | from electrum.plugin import BasePlugin, hook 82 | 83 | class Plugin(BasePlugin): 84 | 85 | @hook 86 | def password_dialog(self, pw, grid, pos): 87 | # we create a button 88 | vkb_button = QPushButton('') 89 | # we add the plugin icon to our button 90 | vkb_button.setIcon(read_QIcon_from_bytes(self.read_file("keyboard-icon.svg"))) 91 | # we connect it to our method 92 | vkb_button.clicked.connect(lambda: self.toggle_vkb(grid, pw)) 93 | # add the button to the grid passed by the GUI 94 | grid.addWidget(vkb_button, pos, 2) 95 | 96 | def toggle_vkb(self, grid, pw): 97 | # here be dragons 98 | ... 99 | 100 | Creating a zip file 101 | ------------------- 102 | 103 | Plugins distributed by third-parties must be packaged in a zip file. 104 | Use the electrum/contrib/make_plugin script to generate the zip file. 105 | 106 | Example: 107 | 108 | .. code-block:: bash 109 | 110 | git clone https://github.com/spesmilo/electrum-plugins.git /opt/electrum-plugins 111 | cd /opt/electrum 112 | ./contrib/make_plugin /opt/electrum-plugins/virtualkeyboard 113 | creating /opt/electrum/virtualkeyboard.zip 114 | added virtualkeyboard/./manifest.json 115 | added virtualkeyboard/./qt.py 116 | added virtualkeyboard/./__init__.py 117 | added virtualkeyboard/./keyboard-icon.png 118 | added virtualkeyboard/./keyboard-icon.svg 119 | added virtualkeyboard/blah/__init__.py 120 | Created /opt/electrum/virtualkeyboard-0.0.1.zip 121 | 122 | This creates a virtualkeyboard-0.0.1.zip file in your local directory. 123 | The file can be imported in Electrum 124 | 125 | 126 | Hardware wallet plugins 127 | ----------------------- 128 | 129 | Hardware wallet plugins are not displayed in the list of plugins 130 | visible in the GUI. Instead, they are enabled by the Electrum wizard. 131 | It is possible to import a third-party hardware wallet plugin from the 132 | Electrum wizard. 133 | 134 | .. image:: png/plugin_wizard.png 135 | :align: center 136 | 137 | It is possible to distribute a hardware wallet plugin as a zip file, 138 | if you include all your python dependencies in the zip 139 | file. 140 | 141 | Non-python dependencies (such as hidapi) are typically bundled 142 | in Electrum binaries. See the list here: 143 | https://github.com/spesmilo/electrum/blob/master/contrib/requirements/requirements-hw.txt 144 | -------------------------------------------------------------------------------- /plugin_rules.rst: -------------------------------------------------------------------------------- 1 | Plugin rules 2 | ============ 3 | 4 | * The plugin system of Electrum is designed to allow the development 5 | of new features without increasing the core code of Electrum. 6 | 7 | * Electrum is written in pure python. if you want to add a feature 8 | that requires non-python libraries, then it must be submitted as a 9 | plugin. If the feature you want to add requires communication with 10 | a remote server (not an Electrum server), then it should be a 11 | plugin as well. If the feature you want to add introduces new 12 | dependencies in the code, then it should probably be a plugin. 13 | 14 | * We expect plugin developers to maintain their plugin code. However, 15 | once a plugin is merged in Electrum, we will have to maintain it 16 | too, because changes in the Electrum code often require updates in 17 | the plugin code. Therefore, plugins have to be easy to maintain. If 18 | we believe that a plugin will create too much maintenance work in 19 | the future, it will be rejected. 20 | 21 | * Plugins should be compatible with Electrum's conventions. If your 22 | plugin does not fit with Electrum's architecture, or if we believe 23 | that it will create too much maintenance work, it will not be 24 | accepted. In particular, do not duplicate existing Electrum code in 25 | your plugin. 26 | 27 | * We may decide to remove a plugin after it has been merged in 28 | Electrum. For this reason, a plugin must be easily removable, 29 | without putting at risk the user's bitcoins. If we feel that a 30 | plugin cannot be removed without threatening users who rely on it, 31 | we will not merge it. 32 | 33 | -------------------------------------------------------------------------------- /plugins.rst: -------------------------------------------------------------------------------- 1 | Plugins 2 | ======= 3 | 4 | The plugin system of Electrum is designed to allow the development of new features without increasing the core code of Electrum. There are two types of plugins, **internal** and **external** plugins. 5 | 6 | To enable or disable Plugins, see **Menu Bar** > **Tools** > **Plugins**. 7 | 8 | .. image:: png/plugins.png 9 | :align: center 10 | 11 | 12 | Internal Plugins 13 | ---------------- 14 | 15 | Internal Plugins are shipped with Electrum and maintained in the Electrum repository. 16 | 17 | Below you can find a short description of each integrated Tool. 18 | 19 | * Audio Modem: Provides support for air-gapped transaction signing. Requires 'amodem' python package http://github.com/romanz/amodem/ 20 | 21 | * LabelSync : Save your wallet labels on a remote server, and synchronize them across multiple devices where you use Electrum. Labels, transactions IDs and addresses are encrypted before they are sent to the remote server. 22 | 23 | * Nostr Wallet Connect: This plugin allows remote control of Electrum lightning wallets via Nostr NIP-47 (Nostr Wallet Connect). A connection string with daily budget and expiry date can be created from the Desktop GUI as well as the command line and then used in Nostr apps like browser extensions or social media clients. 24 | 25 | * Nostr Cosigner: This plugin facilitates the use of multi-signatures wallets. It sends and receives partially signed transactions from/to your cosigner wallet. PSBTs are sent and retrieved encrypted using Nostr relays. 26 | 27 | * Revealer: Create a visually encrypted backup of your wallet seeds, or of custom alphanumeric secrets. 28 | 29 | * Two Factor Authentication: This plugin adds two-factor authentication to your wallet. For more information, visit https://api.trustedcoin.com/#/electrum-help 30 | 31 | * Timelock Recovery: This plug-in allows you to create Timelock Recovery Plans for your wallet. See: https://timelockrecovery.com 32 | 33 | * Virtual Keyboard: Add an optional virtual keyboard to the password dialog. 34 | 35 | * Swapserver [CLI only]: Offer submarine swaps to other Electrum users. See: :ref:`Running a swapserver ` 36 | 37 | * Payserver [CLI only]: Run a HTTP server for receiving payments. See :ref:`How to accept Bitcoin on a website `. 38 | 39 | External Plugins 40 | ---------------- 41 | Electrum supports importing third party plugins from *.zip* files. Once you obtained a plugin you can load it with the **Add** button in the plugins dialog. 42 | 43 | To prevent loading malicious plugins (e.g. by malware) Electrum will 44 | require you to define a **plugin password** when loading an external 45 | Plugin the first time. The plugin password is independent of the 46 | currently open wallet and can be reset if forgotten. 47 | 48 | Setting up the plugin password 49 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 50 | 51 | To check the authenticity of plugins without requiring to enter the 52 | password on each startup Electrum requires you to store a **public key 53 | text string** with root permissions. The root permissions prevent 54 | malware from modifying the string. 55 | 56 | On Linux 57 | """""""" 58 | Open a *Terminal* and run the following commands: 59 | 60 | | 1. Create the directory: 61 | | $ sudo mkdir -p /etc/electrum 62 | 63 | | 2. Open a text editor with root permissions: 64 | | $ sudo nano /etc/electrum/plugin_pubkey 65 | 66 | | 3. Paste the public key string in the text editor. 67 | | 4. Exit the nano editor with CTRL + X. 68 | 69 | On Windows 70 | """""""""" 71 | | 1. Open a *Run Dialog* using Windows + R keys. 72 | | 2. Enter 'regedit' and press Enter. 73 | | 3. Navigate to 'HKEY_LOCAL_MACHINE\\SOFTWARE'. 74 | | 4. Create a new directory named 'Electrum'. 75 | | 5. In the directory 'Electrum', create a new directory called 'PluginKey'. 76 | | 6. Inside the 'PluginKey' directory, create an entry with your **public key string** as value. 77 | 78 | See the following **screenshot**: 79 | 80 | .. image:: png/external_plugin_windows_regedit.png 81 | :align: center 82 | 83 | List of external plugins 84 | ^^^^^^^^^^^^^^^^^^^^^^^^ 85 | Below is a non-exhaustive list of known external plugins. 86 | 87 | These plugins are **not reviewed or endorsed by Electrum** and should be used **at your own risk**. 88 | 89 | 90 | .. csv-table:: :rst:dir:`List of external Electrum plugins` 91 | :header: "Name", "Description", "Repository", "Added" 92 | 93 | "Guardian", "`Physical coercion resistance `_", "`Github Repository `_", "10/2025" 94 | "LNURL Server", "`Receive LN payments through a static URL `_", "`Github Repository `_", "10/2025" 95 | "Joinstr", "`Collaborative Transactions via Nostr `_", "`Gitlab Repository `_", "10/2025" 96 | 97 | 98 | If you want to submit a plugin to be added to the list open a Pull Request on the `Electrum docs repository `_. 99 | 100 | Plugin Development 101 | ------------------ 102 | 103 | If you are interested in developing your own plugin, please read :ref:`Electrum Plugin development ` 104 | -------------------------------------------------------------------------------- /png/Cosigner_Retrieve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/Cosigner_Retrieve.png -------------------------------------------------------------------------------- /png/Create_2fa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/Create_2fa.png -------------------------------------------------------------------------------- /png/Partially_Signed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/Partially_Signed.png -------------------------------------------------------------------------------- /png/PaymentRequest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/PaymentRequest.png -------------------------------------------------------------------------------- /png/Restore_2fa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/Restore_2fa.png -------------------------------------------------------------------------------- /png/Sent_to_Cosigner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/Sent_to_Cosigner.png -------------------------------------------------------------------------------- /png/TrustedCoin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/TrustedCoin.png -------------------------------------------------------------------------------- /png/coin_splitting/alternate_chain_txid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/coin_splitting/alternate_chain_txid.png -------------------------------------------------------------------------------- /png/coin_splitting/chain_search_height.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/coin_splitting/chain_search_height.png -------------------------------------------------------------------------------- /png/coin_splitting/chain_verify_hash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/coin_splitting/chain_verify_hash.png -------------------------------------------------------------------------------- /png/coin_splitting/confirmed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/coin_splitting/confirmed.png -------------------------------------------------------------------------------- /png/coin_splitting/increase_fee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/coin_splitting/increase_fee.png -------------------------------------------------------------------------------- /png/coin_splitting/main_chain_txid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/coin_splitting/main_chain_txid.png -------------------------------------------------------------------------------- /png/coin_splitting/select_main_chain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/coin_splitting/select_main_chain.png -------------------------------------------------------------------------------- /png/coin_splitting/unconfirmed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/coin_splitting/unconfirmed.png -------------------------------------------------------------------------------- /png/create_2of2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/create_2of2.png -------------------------------------------------------------------------------- /png/create_multisig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/create_multisig.png -------------------------------------------------------------------------------- /png/electrum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/electrum.png -------------------------------------------------------------------------------- /png/external_plugin_windows_regedit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/external_plugin_windows_regedit.png -------------------------------------------------------------------------------- /png/import_addresses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/import_addresses.png -------------------------------------------------------------------------------- /png/payreq_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/payreq_window.png -------------------------------------------------------------------------------- /png/payrequest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/payrequest.png -------------------------------------------------------------------------------- /png/paytomany.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/paytomany.png -------------------------------------------------------------------------------- /png/plugin_wizard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/plugin_wizard.png -------------------------------------------------------------------------------- /png/plugins.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/plugins.png -------------------------------------------------------------------------------- /png/public_or_private.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/public_or_private.png -------------------------------------------------------------------------------- /png/restore_key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/restore_key.png -------------------------------------------------------------------------------- /png/sign.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/sign.png -------------------------------------------------------------------------------- /png/signed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/signed.png -------------------------------------------------------------------------------- /png/standard_wallet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/standard_wallet.png -------------------------------------------------------------------------------- /png/swap_providers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/swap_providers.png -------------------------------------------------------------------------------- /png/unsigned.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/unsigned.png -------------------------------------------------------------------------------- /png/wallet_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/wallet_info.png -------------------------------------------------------------------------------- /png/watchingonly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/watchingonly.png -------------------------------------------------------------------------------- /png/watchtower_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/watchtower_settings.png -------------------------------------------------------------------------------- /png/watchtower_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spesmilo/electrum-docs/807134b7812acf9175b17d28388ee31d64cbe73c/png/watchtower_window.png -------------------------------------------------------------------------------- /protocol.rst: -------------------------------------------------------------------------------- 1 | Electrum protocol specification 2 | =============================== 3 | 4 | (NOTE: this document is outdated. For newer versions of the protocol than 0.10, see https://electrumx-spesmilo.readthedocs.io/en/latest/protocol.html ) 5 | 6 | Stratum is a universal bitcoin communication protocol used 7 | mainly by bitcoin client Electrum and miners. 8 | 9 | 10 | Format 11 | ------ 12 | 13 | Stratum protocol is based on `JSON-RPC 2.0`_ (although it doesn't 14 | include "jsonrpc" information in every message). Each 15 | message has to end with a line end character (\n). 16 | 17 | .. _JSON-RPC 2.0: http://www.jsonrpc.org/specification 18 | 19 | Request 20 | ``````` 21 | 22 | Typical request looks like this: 23 | 24 | .. code-block:: json 25 | 26 | { "id": 0, "method":"some.stratum.method", "params": [] } 27 | 28 | - id begins at 0 and every message has its unique id number 29 | - list and description of possible methods is below 30 | - params is an array, e.g.: [ "1myfirstaddress", "1mysecondaddress", "1andonemoreaddress" ] 31 | 32 | Response 33 | ```````` 34 | Responses are similar: 35 | 36 | .. code-block:: json 37 | 38 | { "id": 0, "result": "616be06545e5dd7daec52338858b6674d29ee6234ff1d50120f060f79630543c"} 39 | 40 | - id is copied from the request message (this way client can pair each 41 | response to one of his requests) 42 | - result can be: 43 | 44 | - null 45 | - a string (as shown above) 46 | - a hash, e.g.: 47 | 48 | .. code-block:: json 49 | 50 | { "nonce": 1122273605, "timestamp": 1407651121, "version": 2, "bits": 406305378 } 51 | 52 | - an array of hashes, e.g.: 53 | 54 | .. code-block:: json 55 | 56 | [ { "tx_hash: 57 | "b87bc42725143f37558a0b41a664786d9e991ba89d43a53844ed7b3752545d4f", 58 | "height": 314847 }, { "tx_hash": 59 | "616be06545e5dd7daec52338858b6674d29ee6234ff1d50120f060f79630543c", 60 | "height": 314853 } ] 61 | 62 | Methods 63 | ------- 64 | 65 | server.version 66 | `````````````` 67 | 68 | This is usually the first client's message, plus it's sent every 69 | minute as a keep-alive message. Client sends its own version and 70 | version of the protocol it supports. Server responds with its 71 | supported version of the protocol (higher number at server-side is 72 | usually compatible). 73 | 74 | The version of the protocol being explained in this documentation 75 | is: 0.10. 76 | 77 | *request:* 78 | 79 | .. code-block:: json 80 | 81 | { "id": 0, "method": "server.version", "params": [ "1.9.5", "0.6" ] } 82 | 83 | *response:* 84 | 85 | .. code-block:: json 86 | 87 | { "id": 0, "result": "0.8" } 88 | 89 | server.banner 90 | ````````````` 91 | *request:* 92 | 93 | .. code-block:: json 94 | 95 | { "id": 1, "method": "server.banner", "params": [] } 96 | 97 | server.donation_address 98 | ``````````````````````` 99 | 100 | server.peers.subscribe 101 | `````````````````````` 102 | 103 | Client can this way ask for a list of other active 104 | servers. Servers are connected to an IRC channel (#electrum 105 | at freenode.net) where they can see each other. Each server 106 | announces its version, history pruning limit of every 107 | address ("p100", "p10000" etc.–the number means how many 108 | transactions the server may keep for every single address) 109 | and supported protocols ("t" = tcp@50001, "h" = http@8081, 110 | "s" = tcp/tls@50002, "g" = https@8082; non-standard port 111 | would be announced this way: "t3300" for tcp on port 3300). 112 | 113 | 114 | **Note:** At the time of writing there isn't a true 115 | subscription implementation of this method, but servers 116 | only send one-time response. They don't send notifications 117 | yet. 118 | 119 | *request:* 120 | 121 | .. code-block:: json 122 | 123 | { "id": 3, "method": 124 | "server.peers.subscribe", "params": [] }
125 | 126 | *response:* 127 | 128 | .. code-block:: json 129 | 130 | { "id": 3, "result": [ [ "83.212.111.114", 131 | "electrum.stepkrav.pw", [ "v0.9", "p100", "t", "h", "s", 132 | "g" ] ], [ "23.94.27.149", "ultra-feather.net", [ "v0.9", 133 | "p10000", "t", "h", "s", "g" ] ], [ "88.198.241.196", 134 | "electrum.be", [ "v0.9", "p10000", "t", "h", "s", "g" ] ] ] 135 | } 136 | 137 | blockchain.numblocks.subscribe 138 | `````````````````````````````` 139 | A request to send to the client notifications about new 140 | blocks height. Responds with the current block height. 141 | 142 | *request:* 143 | 144 | .. code-block:: json 145 | 146 | { "id": 5, "method": 147 | "blockchain.numblocks.subscribe", "params": [] } 148 | 149 | 150 | *response:* 151 | 152 | .. code-block:: json 153 | 154 | { "id": 5, "result": 316024 } 155 | 156 | *message:* 157 | 158 | .. code-block:: json 159 | 160 | { "id": null, "method": 161 | "blockchain.numblocks.subscribe", "params": 316024 } 162 | 163 | blockchain.headers.subscribe 164 | ```````````````````````````` 165 | 166 | A request to send to the client notifications about new 167 | blocks in form of parsed blockheaders. 168 | 169 | *request:* 170 | 171 | .. code-block:: json 172 | 173 | { "id": 5, "method": 174 | "blockchain.headers.subscribe", "params": [] } 175 | 176 | *response:* 177 | 178 | .. code-block:: json 179 | 180 | { "id": 5, "result": { "nonce": 181 | 3355909169, "prev_block_hash": 182 | "00000000000000002b3ef284c2c754ab6e6abc40a0e31a974f966d8a2b4d5206", 183 | "timestamp": 1408252887, "merkle_root": 184 | "6d979a3d8d0f8757ed96adcd4781b9707cc192824e398679833abcb2afdf8d73", 185 | "block_height": 316023, "utxo_root": 186 | "4220a1a3ed99d2621c397c742e81c95be054c81078d7eeb34736e2cdd7506a03", 187 | "version": 2, "bits": 406305378 } } 188 | 189 | *message:* 190 | 191 | .. code-block:: json 192 | 193 | { "id": null, "method": 194 | "blockchain.headers.subscribe", "params": [ { "nonce": 195 | 881881510, "prev_block_hash": 196 | "00000000000000001ba892b1717690900ae476857120a78fb50825f8b67a42d4", 197 | "timestamp": 1408255430, "merkle_root": 198 | "8e92bdbf1c5c581b5942fc290c6c52c586f091b279ea79d4e21460e138023839", 199 | "block_height": 316024, "utxo_root": 200 | "060f780c0dd07c4289aaaa2ef24723f73380095b31d60795e1308170ec742ffb", 201 | "version": 2, "bits": 406305378 } ] } 202 | 203 | blockchain.address.subscribe 204 | ```````````````````````````` 205 | 206 | A request to send to the client notifications when status 207 | (i.e., transaction history) of the given address changes. 208 | Status is a hash of the transaction history. If there isn't 209 | any transaction for the address yet, the status is null. 210 | 211 | *request:* 212 | 213 | .. code-block:: json 214 | 215 | { "id": 6, "method":"blockchain.address.subscribe", "params": ["1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L"] } 216 | 217 | *response:* 218 | 219 | .. code-block:: json 220 | 221 | { "id": 6, "result":"b87bc42725143f37558a0b41a664786d9e991ba89d43a53844ed7b3752545d4f" } 222 | 223 | *message:* 224 | 225 | .. code-block:: json 226 | 227 | { "id": null, "method":"blockchain.address.subscribe", "params": ["1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L","690ce08a148447f482eb3a74d714f30a6d4fe06a918a0893d823fd4aca4df580"]} 228 | 229 | blockchain.address.get_history 230 | `````````````````````````````` 231 | 232 | For a given address a list of transactions and their heights (and fees in newer versions) is returned. 233 | 234 | *request:* 235 | 236 | .. code-block:: json 237 | 238 | {"id": 1, "method": "blockchain.address.get_history", "params": ["1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L"] } 239 | 240 | *response:* 241 | 242 | .. code-block:: json 243 | 244 | {"id": 1, "result": [{"tx_hash": "ac9cd2f02ac3423b022e86708b66aa456a7c863b9730f7ce5bc24066031fdced", "height": 340235}, {"tx_hash": "c4a86b1324f0a1217c80829e9209900bc1862beb23e618f1be4404145baa5ef3", "height": 340237}]} 245 | {"jsonrpc": "2.0", "id": 1, "result": [{"tx_hash": "16c2976eccd2b6fc937d24a3a9f3477b88a18b2c0cdbe58c40ee774b5291a0fe", "height": 0, "fee": 225}]} 246 | 247 | 248 | blockchain.address.get_mempool 249 | `````````````````````````````` 250 | 251 | blockchain.address.get_balance 252 | `````````````````````````````` 253 | 254 | *request:* 255 | 256 | .. code-block:: json 257 | 258 | { "id": 1, "method":"blockchain.address.get_balance", "params":["1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L"] } 259 | 260 | *response:* 261 | 262 | .. code-block:: json 263 | 264 | {"id": 1, "result": {"confirmed": 533506535, "unconfirmed": 27060000}} 265 | 266 | 267 | blockchain.address.get_proof 268 | ```````````````````````````` 269 | 270 | blockchain.address.listunspent 271 | `````````````````````````````` 272 | 273 | *request:* 274 | 275 | .. code-block:: json 276 | 277 | { "id": 1, "method": 278 | "blockchain.address.listunspent", "params": 279 | ["1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L"] }
280 | 281 | *response:* 282 | 283 | .. code-block:: json 284 | 285 | {"id": 1, "result": [{"tx_hash": 286 | "561534ec392fa8eebf5779b233232f7f7df5fd5179c3c640d84378ee6274686b", 287 | "tx_pos": 0, "value": 24990000, "height": 340242}, 288 | {"tx_hash":"620238ab90af02713f3aef314f68c1d695bbc2e9652b38c31c025d58ec3ba968", 289 | "tx_pos": 1, "value": 19890000, "height": 340242}]} 290 | 291 | blockchain.utxo.get_address 292 | ``````````````````````````` 293 | 294 | blockchain.block.get_header 295 | ``````````````````````````` 296 | 297 | blockchain.block.get_chunk 298 | `````````````````````````` 299 | 300 | blockchain.transaction.broadcast 301 | ```````````````````````````````` 302 | 303 | Submits raw transaction (serialized, hex-encoded) to the network. Returns transaction id, or an error if the transaction is invalid for any reason. 304 | 305 | *request:* 306 | 307 | .. code-block:: json 308 | 309 | { "id": 1, "method": 310 | "blockchain.transaction.broadcast", "params": 311 | "0100000002f327e86da3e66bd20e1129b1fb36d07056f0b9a117199e759396526b8f3a20780000000000fffffffff0ede03d75050f20801d50358829ae02c058e8677d2cc74df51f738285013c260000000000ffffffff02f028d6dc010000001976a914ffb035781c3c69e076d48b60c3d38592e7ce06a788ac00ca9a3b000000001976a914fa5139067622fd7e1e722a05c17c2bb7d5fd6df088ac00000000" }
312 | 313 | *response:* 314 | 315 | .. code-block:: json 316 | 317 | {"id": 1, "result": "561534ec392fa8eebf5779b233232f7f7df5fd5179c3c640d84378ee6274686b"} 318 | 319 | blockchain.transaction.get_merkle 320 | ````````````````````````````````` 321 | 322 | blockchain.transaction.get_merkle [$txid, $txHeight] 323 | 324 | blockchain.transaction.get 325 | `````````````````````````` 326 | 327 | Method for obtaining raw transaction (hex-encoded) for 328 | given txid. If the transaction doesn't exist, an error is 329 | returned. 330 | 331 | *request:* 332 | 333 | .. code-block:: json 334 | 335 | { "id": 17, "method":"blockchain.transaction.get", "params": [ 336 | "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098" 337 | ] } 338 | 339 | *response:* 340 | 341 | .. code-block:: json 342 | 343 | { "id": 17, "result":"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0104ffffffff0100f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac00000000"} 344 | 345 | *error:* 346 | 347 | .. code-block:: json 348 | 349 | { "id": 17, "error": "{ u'message': u'No information available about transaction', u'code': -5 }" } 350 | 351 | 352 | blockchain.estimatefee 353 | `````````````````````` 354 | 355 | Estimates the transaction fee per kilobyte that needs to be paid for a transaction to be included within a certain number of blocks. If the node doesn’t have enough information to make an estimate, the value -1 will be returned. 356 | 357 | Parameter: How many blocks the transaction may wait before being included. 358 | 359 | *request:* 360 | 361 | .. code-block:: json 362 | 363 | { "id": 17, "method": "blockchain.estimatefee", "params": [ 6 ] } 364 | 365 | *response:* 366 | 367 | .. code-block:: json 368 | 369 | { "id": 17, "result": 0.00026809 } 370 | { "id": 17, "result": 1.169e-05 } 371 | 372 | *error:* 373 | 374 | .. code-block:: json 375 | 376 | { "id": 17, "result": -1 } 377 | 378 | 379 | External links 380 | -------------- 381 | 382 | - https://docs.google.com/a/palatinus.cz/document/d/17zHy1SUlhgtCMbypO8cHgpWH73V5iUQKk_0rWvMqSNs/edit?hl=en_US" original Slush's specification of Stratum protocol 383 | - http://mining.bitcoin.cz/stratum-mining specification of Stratum mining extension 384 | -------------------------------------------------------------------------------- /requirements-docs-frozen.txt: -------------------------------------------------------------------------------- 1 | alabaster==1.0.0 \ 2 | --hash=sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b 3 | babel==2.17.0 \ 4 | --hash=sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 5 | certifi==2025.8.3 \ 6 | --hash=sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5 7 | charset-normalizer==3.4.3 \ 8 | --hash=sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f 9 | docutils==0.21.2 \ 10 | --hash=sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2 11 | idna==3.10 \ 12 | --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 13 | imagesize==1.4.1 \ 14 | --hash=sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b 15 | jinja2==3.1.6 \ 16 | --hash=sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 17 | markdown-it-py==3.0.0 \ 18 | --hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 19 | markupsafe==3.0.3 \ 20 | --hash=sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676 21 | mdit-py-plugins==0.5.0 \ 22 | --hash=sha256:07a08422fc1936a5d26d146759e9155ea466e842f5ab2f7d2266dd084c8dab1f 23 | mdurl==0.1.2 \ 24 | --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 25 | myst-parser==4.0.1 \ 26 | --hash=sha256:9134e88959ec3b5780aedf8a99680ea242869d012e8821db3126d427edc9c95d 27 | packaging==25.0 \ 28 | --hash=sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 29 | pygments==2.19.2 \ 30 | --hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b 31 | pyyaml==6.0.3 \ 32 | --hash=sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6 33 | requests==2.32.5 \ 34 | --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 35 | roman-numerals-py==3.1.0 \ 36 | --hash=sha256:9da2ad2fb670bcf24e81070ceb3be72f6c11c440d73bd579fbeca1e9f330954c 37 | snowballstemmer==3.0.1 \ 38 | --hash=sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064 39 | sphinx==8.2.3 \ 40 | --hash=sha256:4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3 41 | sphinx-rtd-dark-mode==1.3.0 \ 42 | --hash=sha256:478da69c72a2a2ed7665c1f633cc612039f5801df416fd5f7c4820c2fe08c9c5 43 | sphinx-rtd-theme==3.0.2 \ 44 | --hash=sha256:422ccc750c3a3a311de4ae327e82affdaf59eb695ba4936538552f3b00f4ee13 45 | sphinxcontrib-applehelp==2.0.0 \ 46 | --hash=sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5 47 | sphinxcontrib-devhelp==2.0.0 \ 48 | --hash=sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2 49 | sphinxcontrib-htmlhelp==2.1.0 \ 50 | --hash=sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8 51 | sphinxcontrib-jquery==4.1 \ 52 | --hash=sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae 53 | sphinxcontrib-jsmath==1.0.1 \ 54 | --hash=sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178 55 | sphinxcontrib-qthelp==2.0.0 \ 56 | --hash=sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb 57 | sphinxcontrib-serializinghtml==2.0.0 \ 58 | --hash=sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 59 | urllib3==2.5.0 \ 60 | --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc -------------------------------------------------------------------------------- /requirements-docs.txt: -------------------------------------------------------------------------------- 1 | sphinx<9 2 | sphinx-rtd-theme<4 3 | myst-parser<5 4 | sphinx-rtd-dark-mode<2 5 | -------------------------------------------------------------------------------- /security_issues/index.rst: -------------------------------------------------------------------------------- 1 | Historical security issues in Electrum 2 | ====================================== 3 | 4 | .. toctree:: 5 | :maxdepth: 1 6 | 7 | sec_201801 8 | sec_202206 9 | sec_202306 10 | sec_202308 11 | 12 | -------------------------------------------------------------------------------- /security_issues/sec_201801.rst: -------------------------------------------------------------------------------- 1 | JSONRPC vulnerability in Electrum 2.6 to 3.0.4 2 | ============================================== 3 | 4 | On January 6th, 2018, a vulnerability was disclosed in the Electrum wallet 5 | software, that allows malicious websites to execute wallet commands 6 | through JSONRPC executed in a web browser. The bug affects versions 7 | 2.6 to 3.0.4 of Electrum, on all platforms. It also affects clones of 8 | Electrum such as Electron Cash. 9 | 10 | 11 | Can funds be stolen? 12 | -------------------- 13 | 14 | Wallets that are not password protected are at risk of theft, if they 15 | are opened with a version of Electrum older than 3.0.5 while a web 16 | browser is active. 17 | 18 | In addition, the vulnerability allows an attacker to modify user 19 | settings, the list of contacts in a wallet, and the "payto" and 20 | "amount" fields of the user interface while Electrum is running. 21 | 22 | Although there is no known occurrence of Bitcoin theft occurring 23 | because of this vulnerability, the risk increases substantially now 24 | that the vulnerability has been made public. 25 | 26 | 27 | Can wallet data be leaked? 28 | -------------------------- 29 | 30 | Yes, an attacker can obtain private data, such as: Bitcoin addresses, 31 | transaction labels, address labels, wallet contacts and master public 32 | keys. 33 | 34 | 35 | Can a password-protected wallet be bruteforced? 36 | ----------------------------------------------- 37 | 38 | Not realistically. The vulnerability does not allow an attacker to 39 | access encrypted seed or private keys, which would be needed in order 40 | to perform an efficient brute force attack. Without the encrypted 41 | seed, an attacker must try passwords using the JSONRPC interface, 42 | while the user is visiting a malicious page. This is several orders of 43 | magnitude slower than an attack with the encrypted seed, and 44 | restricted in time. Even a weak password will protect against that. 45 | 46 | 47 | What should users do? 48 | --------------------- 49 | 50 | All users should upgrade their Electrum software, and stop using old 51 | versions. 52 | 53 | Users who did not protect their wallet with a password should create a 54 | new wallet, and move their funds to that wallet. Even if it never 55 | received any funds, a wallet without password should not be used 56 | anymore, because its seed might have been compromised. 57 | 58 | In addition, users should review their settings, and delete all 59 | contacts from their contacts list, because the Bitcoin addresses of 60 | their contacts might have been modified. 61 | 62 | 63 | How to upgrade Electrum 64 | ----------------------- 65 | 66 | Stop running any version of Electrum older than 3.0.5, and install 67 | Electrum the most recent version. On desktop, make sure you download 68 | Electrum from https://electrum.org and no other website. On Android, 69 | the most recent version is available in Google Play. 70 | 71 | If Electrum 3.0.5 (or any later version) cannot be installed or does 72 | not work on your computer, stop using Electrum on that computer, and 73 | access your funds from a device that can run Electrum 3.0.5. If you 74 | really need to use an older version of Electrum, for example in order 75 | to access wallet seed, make sure that your computer is offline, and 76 | that no web browser is running on the computer at the same time. 77 | 78 | 79 | Should all users move their funds to a new address? 80 | --------------------------------------------------- 81 | 82 | No, we do not recommend moving funds from password-protected wallets. 83 | 84 | 85 | When was the issue reported and fixed? 86 | -------------------------------------- 87 | 88 | The absence of password protection in the JSONRPC interface was 89 | reported on November 25th, 2017 by user jsmad: 90 | https://github.com/spesmilo/electrum/issues/3374 91 | 92 | jsmad's report was about the Electrum daemon, a piece of software that 93 | runs on web servers and is used by merchants in order to receive 94 | Bitcoin payments. In that context, connections to the daemon from the 95 | outside world must be explicitly authorized, by setting 'rpchost' and 96 | 'rpcport' in the Electrum configuration. 97 | 98 | On January 6th, 2018, Tavis Ormandy demonstrated that the JSONRPC 99 | interface could be exploited against the Electrum GUI, and that the 100 | attack could be carried out by a web browser running locally, visiting 101 | a webpage with specially crafted JavaScript. 102 | 103 | We released a new version (3.0.4) in the hours following Tavis' post, 104 | with a patch written by mithrandi (Debian packager), that addressed 105 | the attack demonstrated by Tavis. In addition, the Github issue 106 | remained open, because mithrandi's patch was not adding password 107 | protection to the JSONRPC interface. 108 | 109 | Shortly after the 3.0.4 release we started to work on adding proper 110 | password protection to the JSONRPC interface of the daemon, and that 111 | part was ready on Sunday, January 7th. We also learned on Sunday 112 | afternoon that the first patch was not effective against another, 113 | similar attack, using POST. This is why we did not delay the 3.0.5 114 | release, which includes password protection, and completely disables 115 | JSONRPC in the GUI. 116 | -------------------------------------------------------------------------------- /security_issues/sec_202206.md: -------------------------------------------------------------------------------- 1 | ## BIP70 payment requests `?r=` field supports `file://` URIs, allowing attacker to trick victim machine to `open()` arbitrary file 2 | 3 | ### Impact 4 | 5 | In BIP70 payment requests, Electrum allows the `?r=` field to contain 6 | `file://` URIs (besides http(s)). The `?r=` field can contain an 7 | arbitrary `file` URI, chosen by an attacker. 8 | 9 | A malicious merchant can provide a BIP70 payment request in the form 10 | of a QR code or text, which the victim user would then scan or 11 | copy-paste, as part of the payment flow. Electrum would then see 12 | the `file` URI, and try to open the file in read mode and read it. 13 | If the read succeeds, the data is parsed using protobuf. 14 | 15 | Specifically regarding the QR code vector, note that Electrum starts 16 | the BIP70 flow as soon as a QR code is scanned, without giving a 17 | chance to the user to review the content of the decoded QR code. 18 | 19 | The `file` URI support was originally added for local dev testing, 20 | with the implicit assumption that it is safe to open files on the 21 | local filesystem in read-only mode. This assumption is incorrect. 22 | 23 | On Linux/macOS, e.g. trying to read `/dev/zero` results in a DOS 24 | attack, where the application would run out-of-memory and get killed. 25 | 26 | On Windows, paths can be crafted that correspond to network requests, 27 | for example initiating an SMB connection. In particular, it seems that 28 | it might be possible for an attacker located in the same "trusted" 29 | Local Area Network as the victim, after getting the victim to scan 30 | a malicious QR code, to have the victim's computer initiate a same-LAN 31 | SMB connection to the attacker's computer, and to capture an 32 | authentication token. That authentication token could later be used 33 | to initiate an offline brute-force attack against the user's Windows 34 | account password. 35 | 36 | ### Patches 37 | 38 | We have removed the `file` URI support in commit 39 | [b247aa5ffef0f9ef000772fcf9cd9c7141abded8](https://github.com/spesmilo/electrum/commit/b247aa5ffef0f9ef000772fcf9cd9c7141abded8). 40 | Electrum version 4.2.2 contains the fix. 41 | 42 | ### Credits 43 | 44 | We thank the Unciphered team, and specifically Frank Davidson 45 | `` for responsibly disclosing this issue to us. 46 | 47 | ### Affected versions 48 | 49 | Electrum 2.1<=x<4.2.2 50 | 51 | ### Known as 52 | 53 | - [GHSA-4fh4-hx35-r355](https://github.com/spesmilo/electrum/security/advisories/GHSA-4fh4-hx35-r355) 54 | 55 | -------------------------------------------------------------------------------- /security_issues/sec_202306.md: -------------------------------------------------------------------------------- 1 | ## sending with Lightning: payment_preimage validation is skipped on Android 2 | 3 | 4 | ### Impact 5 | When using Lightning in Android builds of Electrum, when sending payments, the direct channel counterparty could steal the payment amount being sent without actually forwarding it. This is because when receiving an `update_fulfill_htlc` message the preimage actually hashing to the payment_hash was only checked in an `assert`, and `assert`s were disabled in Android builds. 6 | 7 | In Lightning, payments are made using HTLCs. Consider an Alice->Bob->Carol->Dave multi-hop payment, where the Electrum client is Alice. After Alice sends an HTLC for hash(R) to Bob, Bob is expected to forward it to Carol (who would then forward it to Dave) and wait for it to be either fulfilled or failed. Only the final recipient, Dave, knows the preimage R for hash(R), which is required to fulfill the HTLC. Bob can decide not to forward to Carol and simply fail the HTLC back to Alice directly. However, Bob cannot normally decide to fulfill the HTLC directly without forwarding as that requires knowing the preimage R. When Bob receives the preimage from Carol (as part of Carol fulfilling the HTLC Bob sent to her), Bob can then fulfill Alice's HTLC and take the money from Alice. Bob knowing the preimage and showing it to Alice is proof that Bob indirectly paid Dave, and so Alice pays Bob. 8 | 9 | The bug is that Bob can claim to have paid Carol/Dave, show a fake/invalid preimage to Alice, and take Alice's money (the payment amount) without actually forwarding the money. This is because Alice does not validate that the preimage presented by Bob is actually correct (as the check is an assert`[6]` and asserts were disabled in Android builds). 10 | 11 | Except for Android, other users running the official binaries are not affected. 12 | 13 | Users running from source are expected *not* to be affected. It is possible to disable asserts, by passing the `-O` command-line flag to the python interpreter`[1]`. As far as we could tell no mainstream Linux distribution does this - it would have to be explicitly passed by the user. That is, when running from source, asserts should normally be enabled and hence users not affected. 14 | 15 | We have no knowledge of in-the-wild exploitation of the vulnerability. 16 | 17 | 18 | ### Affected versions 19 | 20 | 4.0.0 <= x < 4.4.0 (Android) 21 | 22 | 23 | ### Patches 24 | We enabled asserts in the Android binaries, released in version 4.4.0 `[0]`. 25 | A check was added that asserts are enabled in all cases, even when running from source, released in version 4.4.5 `[2][3]`. 26 | 27 | 28 | ### How to know if I was affected? 29 | As the attack involved the recipient not getting paid, the recipient would presumably tell the victim that they have not received any money. For example, if paying a merchant with an online interface, the merchant would not mark the invoice as paid. 30 | 31 | 32 | ### References 33 | ``` 34 | [0]: https://github.com/spesmilo/electrum/commit/0e5464ca13ce2f993107b4a293982ea4bfc434b5 35 | [1]: https://docs.python.org/3/using/cmdline.html#cmdoption-O 36 | [2]: https://github.com/spesmilo/electrum/commit/ccc012674fc5707145aadf035440f6d63c9d5bbc 37 | [3]: https://github.com/spesmilo/electrum/commit/d1c881080fd21733bc21bd6b61e62247a2960a9d 38 | [4]: https://github.com/spesmilo/electrum/commit/0f541be6f11a372d202c99476e6d051184006bba 39 | [5]: https://github.com/spesmilo/electrum/commit/e23c6c70501a1d4bc7bba34438ce7b4e84894191 40 | [6]: https://github.com/spesmilo/electrum/blob/1ca05f32435a23e561841e1b620b1c7620c29d83/electrum/lnchannel.py#L1432 41 | ``` 42 | 43 | 44 | ### Timeline 45 | - 2023-03-31: A newly introduced security check was using an assert. This was caught during code review and replaced with a standard exception. As part of the review and discussion, we realised that asserts had been disabled in the Android builds, and enabled them`[0]` as a precautionary measure. A check was added that enforced that asserts are enabled when Electrum is running as part of a binary build (on any platform). When running from source, we still tolerated asserts being disabled and simply logged a warning`[4]`. 46 | - 2023-04-18: version 4.4.0 released, including the above changes. 47 | - 2023-06-01: We noticed HTLC preimages were only tested using an assert, and realised the implications. Due to the exploitable nature of this issue, the assert was left as-is. We assessed that the prior change`[0]` meant that users running >=4.4.0 are safe. Still, the previously added check that enforced asserts were enabled in binary builds was replaced with a broader check that hard-failed if asserts were disabled, on any platform even when running from source`[2]`, backported to the 4.4.x branch and released in 4.4.5. As Android users of old versions (<4.4) were vulnerable, based on Google Play version distribution statistics, we decided to delay public disclosure. 48 | - 2023-06-20: version 4.4.5 released. 49 | - 2023-08-22: We added a notice in the release notes`[5]` about upcoming disclosure. 50 | - 2023-09-12: Public disclosure of the issue. 51 | 52 | 53 | ### Known as 54 | 55 | - [GHSA-9gpc-prj9-89x7](https://github.com/spesmilo/electrum/security/advisories/GHSA-9gpc-prj9-89x7) 56 | -------------------------------------------------------------------------------- /security_issues/sec_202308.md: -------------------------------------------------------------------------------- 1 | ## receiving with Lightning: partial MPP might be accepted 2 | 3 | 4 | ### Impact 5 | When using Lightning in Electrum to receive money, an attacker can get the client confused and accept a partial payment, getting the client to reveal the proof-of-payment preimage. 6 | 7 | There are two related but independently exploitable bugs, each with a corresponding attack. 8 | 9 | #### First bug: received MPP HTLCs are grouped by payment_secret 10 | 11 | The attack requires the attacker to obtain two valid invoices from the victim. Each invoice contains a payment_hash and a payment_secret (as standard). The attacker can send multiple HTLCs to the victim, with criss-crossed payment_hashes and payment_secrets, confusing the victim into accepting one small HTLC, revealing the preimage, and failing the other HTLC(s). 12 | 13 | Example attack: 14 | - Bob(victim) creates invoice1: amount 1 BTC, payment_hash1, payment_secret1; given to attacker 15 | - Bob(victim) creates invoice2: amount 1 BTC, payment_hash2, payment_secret2; given to attacker 16 | - Alice sends htlc1: 0.1 BTC, payment_hash1, payment_secret1 (total_msat=1 BTC) 17 | - Alice sends htlc2: 0.9 BTC, payment_hash2, payment_secret1 (total_msat=1 BTC) 18 | - Bob reveals preimage for payment_hash1 and fulfills htlc1 (fails other) 19 | 20 | The root cause of the bug is that Bob groups the HTLCs for MPP based on payment_secret alone. (Normally you would want to group based on payment_hash, but that does not work if forwarding trampoline payments) After htlc2 arrives, Bob sees that enough money has been received (in htlc1+htlc2) and marks the HTLC MPP group as accepted. It is only after this, that Bob validates that the HTLCs have the expected payment_secret. Bob fulfills htlc1, revealing the preimage. When considering htlc2, it is noticed that the payment_secret does not correspond to the payment_hash, and htlc2 is failed. 21 | 22 | #### Second bug: received MPP HTLCs might have non-uniform total_msat values 23 | 24 | The attacker can send two small HTLCs to the victim, set the `total_msat` field inside the onion of the htlc for one of them maliciously, and get the victim to fulfill the other HTLC, revealing the preimage. 25 | 26 | Example attack: 27 | - Bob(victim) creates invoice: amount 1 BTC 28 | - Alice sends htlc1: 0.1 BTC (total_msat=0.2 BTC) 29 | - Alice sends htlc2: 0.1 BTC (total_msat=1 BTC) 30 | - Bob reveals preimage and fulfills htlc2 (fails other) 31 | 32 | The root cause of the bug is that when Bob groups the HTLCs for MPP, he does not validate that all HTLCs have the same total_msat value set (which is attacker-controlled). The logic that checks whether the group is complete uses the total_msat value from the first received HTLC. After receiving htlc2, the group gets marked as accepted. Then, before fulfilling an HTLC, Bob checks that their total_msat value matches the amount in the corresponding invoice. This check fails for htlc1, but passes for htlc2. Hence, Bob fails htlc1 and fulfills htlc2, revealing the preimage. 33 | 34 | 35 | ### Affected versions 36 | 37 | 4.1.0 <= x < 4.4.6 38 | 39 | 40 | ### Patches 41 | The issue was fixed in commit `[0]`, backported to the 4.4.x branch in commit `[1]`, released in version 4.4.6. 42 | 43 | The first bug was fixed by grouping the HTLCs based on payment_hash+payment_secret. 44 | The second bug was fixed by validating that all received HTLCs that are grouped together for MPP have the same total_msat value. 45 | 46 | ### Have these vulnerabilities been exploited? 47 | We have no knowledge of in-the-wild exploitation of these vulnerabilities. 48 | 49 | ### How to know if I was affected? 50 | In the History tab, for the incoming payment, the balance delta reflects the actual amount of money received. 51 | Normally the balance delta should match the amount in the invoice (payment request). If the bug was exploited, we would expect the balance delta (actual received money) to be significantly lower than the invoice amount. 52 | 53 | 54 | ### References 55 | ``` 56 | [0]: https://github.com/spesmilo/electrum/commit/44bdd20ccc40bb307cc3510d8741af7058e2c6e8 57 | [1]: https://github.com/spesmilo/electrum/commit/c5300c9f1c45002e13631251fc3a5575d3e43629 58 | [2]: https://github.com/spesmilo/electrum/commit/e23c6c70501a1d4bc7bba34438ce7b4e84894191 59 | ``` 60 | 61 | 62 | ### Timeline 63 | - 2023-08-03: we discovered the vulnerabilities during review of related code. 64 | - 2023-08-08: an obfuscated fix was pushed to master `[0]` 65 | - 2023-08-17: the backported fix was pushed to the 4.4.x branch `[1]`, and version 4.4.6 was tagged 66 | - 2023-08-22: version 4.4.6 released, containing the fix, and a notice was added in the release notes`[2]` about upcoming disclosure. 67 | - 2023-09-12: Public disclosure of the issue. 68 | 69 | 70 | ### Known as 71 | 72 | - [GHSA-8r85-vp7r-hjxf](https://github.com/spesmilo/electrum/security/advisories/GHSA-8r85-vp7r-hjxf) 73 | 74 | -------------------------------------------------------------------------------- /seedphrase.rst: -------------------------------------------------------------------------------- 1 | Electrum Seed Version System 2 | ============================ 3 | 4 | This document describes the Seed Version System used in Electrum 5 | (version 2.0 and higher). 6 | 7 | Description 8 | ----------- 9 | 10 | Electrum derives its private keys and addresses from a seed phrase 11 | made of natural language words. Starting with version 2.0, Electrum 12 | seed phrases include a version number, whose purpose is to indicate 13 | which derivation should be followed in order to derive private keys 14 | and addresses. 15 | 16 | In order to eliminate the dependency on a fixed wordlist, the master 17 | private key and the version number are both obtained by hashes of the 18 | UTF8 normalized seed phrase. The version number is obtained by looking 19 | at the first bits of: 20 | 21 | .. code-block:: python 22 | 23 | hmac_sha_512("Seed version", seed_phrase) 24 | 25 | The version number is also used to check seed integrity; in order to 26 | be correct, a seed phrase must produce a registered version number. 27 | 28 | 29 | Motivation 30 | ---------- 31 | 32 | Early versions of Electrum (before 2.0) used a bidirectional encoding 33 | between seed phrase and entropy. This type of encoding requires a 34 | fixed wordlist. This means that future versions of Electrum must ship 35 | with the exact same wordlist, in order to be able to read old seed 36 | phrases. 37 | 38 | BIP39 was introduced two years after Electrum. BIP39 seeds include a 39 | checksum, in order to help users figure out typing errors. However, 40 | BIP39 suffers the same shortcomings as early Electrum seed phrases: 41 | 42 | - A fixed wordlist is still required. Following our recommendation, 43 | BIP39 authors decided to derive keys and addresses in a way that 44 | does not depend on the wordlist. However, BIP39 still requires the 45 | wordlist in order to compute its checksum, which is plainly 46 | inconsistent, and defeats the purpose of our recommendation. This 47 | problem is exacerbated by the fact that BIP39 proposes to create 48 | one wordlist per language. This threatens the portability of BIP39 49 | seed phrases. 50 | 51 | - BIP39 seed phrases do not include a version number. This means that 52 | software should always know how to generate keys and 53 | addresses. BIP43 suggests that wallet software will try various 54 | existing derivation schemes within the BIP32 framework. This is 55 | extremely inefficient and rests on the assumption that future 56 | wallets will support all previously accepted derivation 57 | methods. If, in the future, a wallet developer decides not to 58 | implement a particular derivation method because it is deprecated, 59 | then the software will not be able to detect that the corresponding 60 | seed phrases are not supported, and it will return an empty wallet 61 | instead. This threatens users funds. 62 | 63 | For these reasons, Electrum does not generate BIP39 seeds. Starting 64 | with version 2.0, Electrum uses the following Seed Version System, 65 | which addresses these issues. 66 | 67 | Electrum 2.0 derives keys and addresses from a hash of the UTF8 68 | normalized seed phrase with no dependency on a fixed wordlist. 69 | This means that the wordlist can differ between wallets while the seed remains 70 | portable, and that future wallet implementations will not need 71 | today's wordlists in order to be able to decode the seeds 72 | created today. This reduces the cost of forward compatibility. 73 | 74 | 75 | 76 | 77 | Version number 78 | -------------- 79 | 80 | The version number is a prefix of a hash derived from the seed 81 | phrase. The length of the prefix is a multiple of 4 bits. The prefix 82 | is computed as follows: 83 | 84 | .. code-block:: python 85 | 86 | def version_number(seed_phrase): 87 | # normalize seed 88 | normalized = prepare_seed(seed_phrase) 89 | # compute hash 90 | h = hmac_sha_512("Seed version", normalized) 91 | # use hex encoding, because prefix length is a multiple of 4 bits 92 | s = h.encode('hex') 93 | # the length of the prefix is written on the first 4 bits 94 | # for example, the prefix '101' is of length 4*3 bits = 4*(1+2) 95 | length = int(s[0]) + 2 96 | # read the prefix 97 | prefix = s[0:length] 98 | # return version number 99 | return hex(int(prefix, 16)) 100 | 101 | The normalization function (prepare_seed) removes all but one space 102 | between words. It also removes diacritics, and it removes spaces 103 | between Asian CJK characters. 104 | 105 | 106 | 107 | List of reserved numbers 108 | ------------------------ 109 | 110 | The following version numbers are used for Electrum seeds. 111 | 112 | ======== ========= ===================================== 113 | Number Type Description 114 | ======== ========= ===================================== 115 | 0x01 Standard P2PKH and Multisig P2SH wallets 116 | 0x100 Segwit Segwit: P2WPKH and P2WSH wallets 117 | 0x101 2FA Two-factor authenticated wallets 118 | ======== ========= ===================================== 119 | 120 | In addition, the version bytes of master public/private keys indicate 121 | what type of output script should be used, and on which network. The 122 | prefixes are detailed `here `__. 123 | 124 | 125 | Seed generation 126 | --------------- 127 | 128 | When the seed phrase is hashed during seed generation, the resulting hash must 129 | begin with the correct version number prefix. This is achieved by enumerating a 130 | nonce and re-hashing the seed phrase until the desired version number is 131 | created. This requirement does not decrease the security of the seed (up to the 132 | cost of key stretching, that might be required to generate the private keys). 133 | 134 | 135 | Security implications 136 | --------------------- 137 | 138 | Electrum currently use the same wordlist as BIP39 (2048 words). A 139 | typical seed has 12 words, which results in 132 bits of entropy in the 140 | choice of the seed. 141 | 142 | Following BIP39, 2048 iterations of key stretching are added for the 143 | generation of the master private key. In terms of hashes, this is 144 | equivalent to adding an extra 11 bits of security to the seed 145 | (2048=2^11). 146 | 147 | From the point of view of an attacker, the constraint added by 148 | imposing a prefix to the seed version hash does not decrease the 149 | entropy of the seed, because there is no knowledge gained on the seed 150 | phrase. The attacker still needs to enumerate and test 2^n candidate 151 | seed phrases, where n is the number of bits of entropy used to 152 | generate the seed. 153 | 154 | However, the test made by the attacker will return faster if the 155 | candidate seed is not a valid seed, because the attacker does not need 156 | to generate the key. This means that the imposed prefix reduces the 157 | strength of key stretching. 158 | 159 | Let n denote the number of entropy bits of the seed, and m the number 160 | of bits of difficulty added by key stretching: m = 161 | log2(stretching_iterations). Let k denote the length of the prefix, in 162 | bits. 163 | 164 | On each iteration of the attack, the probability of obtaining a valid seed is p = 2^-k 165 | 166 | The number of hashes required to test a candidate seed is: p * (1+2^m) + (1-p)*1 = 1 + 2^(m-k) 167 | 168 | Therefore, the cost of an attack is: 2^n * (1 + 2^(m-k)) 169 | 170 | This can be approximated as 2^(n + m - k) if m>k and as 2^n otherwise. 171 | 172 | With the standard values currently used in Electrum, we obtain: 173 | 2^(132 + 11 - 8) = 2^135. This means that a standard Electrum seed 174 | is equivalent, in terms of hashes, to 135 bits of entropy. 175 | 176 | -------------------------------------------------------------------------------- /spv.rst: -------------------------------------------------------------------------------- 1 | .. _spv: 2 | 3 | Simple Payment Verification 4 | =========================== 5 | 6 | Simple Payment Verification (SPV) is a technique described 7 | in Satoshi Nakamoto's paper. SPV allows a lightweight 8 | client to verify that a transaction is included in the 9 | Bitcoin blockchain, without downloading the entire 10 | blockchain. The SPV client only needs download the block 11 | headers, which are much smaller than the full blocks. To 12 | verify that a transaction is in a block, a SPV client 13 | requests a proof of inclusion, in the form of a Merkle 14 | branch. 15 | 16 | SPV clients offer more security than web wallets, because 17 | they do not need to trust the servers with the information 18 | they send. 19 | 20 | Reference: `Bitcoin: A peer-to-peer Electronic Cash System `_ 21 | 22 | -------------------------------------------------------------------------------- /ssl.rst: -------------------------------------------------------------------------------- 1 | How to configure SSL with Electrum 2 | ================================== 3 | 4 | This page was written for Electrum 4.0. 5 | 6 | You should have a TLS/SSL private key and a public certificate for 7 | your domain set up already (signed by a CA, for example free Letsencrypt_) 8 | 9 | 10 | .. _Letsencrypt: 11 | https://letsencrypt.org/ 12 | 13 | .. _development: 14 | https://github.com/spesmilo/electrum#development-version-git-clone 15 | 16 | Add your SSL private key 17 | ------------------------ 18 | 19 | Create a file that contains only the private key: 20 | 21 | .. code-block:: openssl 22 | 23 | -----BEGIN PRIVATE KEY----- 24 | your private key 25 | -----END PRIVATE KEY----- 26 | 27 | Please note that this is not your wallet key but a private key for the 28 | matching TLS/SSL certificate. 29 | 30 | Set the path to your the SSL private key file with setconfig: 31 | 32 | .. code-block:: bash 33 | 34 | electrum -o setconfig ssl_keyfile /path/to/ssl/privkey.pem 35 | 36 | 37 | Add your SSL certificate bundle 38 | ------------------------------- 39 | 40 | Create another file, file that contains your certificate, 41 | and the list of certificates it depends on, up to the root 42 | CA. Your certificate must be at the top of the list, and 43 | the root CA at the end. 44 | 45 | .. code-block:: openssl 46 | 47 | -----BEGIN CERTIFICATE----- 48 | your cert 49 | -----END CERTIFICATE----- 50 | -----BEGIN CERTIFICATE----- 51 | intermediate cert 52 | -----END CERTIFICATE----- 53 | -----BEGIN CERTIFICATE----- 54 | root cert 55 | -----END CERTIFICATE----- 56 | 57 | Set the ssl_chain path with setconfig: 58 | 59 | .. code-block:: bash 60 | 61 | electrum -o setconfig ssl_certfile /path/to/ssl/fullchain.pem 62 | 63 | Check that your certificate was accepted by Electrum 64 | ---------------------------------------------------- 65 | 66 | Check that your SSL certificate correctly configured: 67 | 68 | .. code-block:: bash 69 | 70 | electrum -o get_ssl_domain 71 | 72 | This should return the Common Name of your certificate. 73 | -------------------------------------------------------------------------------- /swapserver.rst: -------------------------------------------------------------------------------- 1 | .. _swapserver: 2 | 3 | How to offer Submarine Swaps 4 | ============================ 5 | 6 | Electrum allows users to move bitcoin between their Lightning and on-chain balance in a trustless way, 7 | this is called Submarine Swaps. It allows the user, for example, to add incoming liquidity to 8 | their lightning channel or to add funds to their lightning balance without having to open additional channels. 9 | 10 | In order for the client to execute a swap, it needs a counterparty to execute the swap with. 11 | This counterparty, hereafter referred to as the swap server, can be operated by anyone 12 | in order to earn fees for the liquidity it provides to its customers. 13 | 14 | Swap server setup 15 | ----------------- 16 | A swap server is supposed to be operated as a continuously running daemon, so the first step is to 17 | acquire some linux server that can be online for prolonged time. This can be a simple VPS, a Raspberry Pi 18 | or an old notebook. The swap server requires **no** port forwarding, so it can be run easily behind a firewall or 19 | consumer internet connection without open ports. 20 | 21 | Once you have access to the host shell the swap server can be setup using the following steps: 22 | 23 | 1. **Download Electrum:** 24 | 25 | The swap server is part of the regular Electrum application, you can either 26 | `run from source `_ 27 | or get the binary: 28 | 29 | .. code-block:: bash 30 | 31 | wget https://download.electrum.org/CURRENT_VERSION/electrum-CURRENT_VERSION-x86_64.AppImage 32 | 33 | Then make the binary executable with: 34 | 35 | .. code-block:: bash 36 | 37 | chmod +x electrum-CURRENT_VERSION-x86_64.AppImage 38 | 39 | .. note:: 40 | Replace *CURRENT_VERSION* with the latest version number, e.g. 4.6.0, which you can find on 41 | `electrum.org `_. 42 | 43 | | If you use the **AppImage**: 44 | | Replace ``./run_electrum`` with ``./electrum-CURRENT_VERSION-x86_64.AppImage`` 45 | | in all following commands. 46 | 47 | .. caution:: 48 | 49 | | You may want to verify the authenticity of the downloaded binary. 50 | | To do so refer, to the following guide: 51 | | `Verifying GPG signature of Electrum using Linux command line `_ 52 | 53 | 2. **Start Electrum as daemon:** 54 | 55 | Now start an instance of Electrum as daemon. 56 | The option ``-d`` will start it in detached mode (in the background): 57 | 58 | .. code-block:: bash 59 | 60 | ./run_electrum daemon -d 61 | ---> starting daemon (PID 42836) 62 | 63 | This will create a directory called ``~/.electrum`` in your home directory, 64 | which contains the configuration and wallet files. 65 | 66 | 3. **Create a wallet:** 67 | 68 | Now we need to create a new wallet that will be used for the swap server. 69 | Optionally you could also import an existing Electrum seed. 70 | 71 | .. code-block:: bash 72 | 73 | ./run_electrum create 74 | ---> 75 | { 76 | "msg": "Please keep your seed in a safe place; if you lose it, you will not be able to restore your wallet.", 77 | "path": "/home/user/.electrum/wallets/default_wallet", 78 | "seed": "obey wash exit have spice fitness dumb debate shrimp risk grief coral" 79 | } 80 | 81 | As always, write down your `seed` in a safe place and do not share it with anyone. 82 | 83 | 4. (OPTIONAL) **Encrypt wallet keystore:** 84 | 85 | It is possible to encrypt the wallet keystore, this is the part in the database that contains the private keys. 86 | It is a good measure to increase the security of your swap server private keys. 87 | 88 | .. code-block:: bash 89 | 90 | # always set --encrypt_file False 91 | # otherwise DB performance may be too low for swap server operation 92 | ./run_electrum password --new_password --encrypt_file False 93 | 94 | .. caution:: 95 | 96 | If you set a keystore password you have to unlock it every time you load the wallet, otherwise 97 | the swap server will not be able to sign transactions. See the unlock command in the following step. 98 | 99 | 5. **Load the wallet:** 100 | 101 | To activate the newly created wallet, it has to be loaded: 102 | 103 | .. code-block:: bash 104 | 105 | ./run_electrum load_wallet 106 | 107 | # if you set a password for the keystore, unlock it 108 | ./run_electrum unlock --password 109 | 110 | 6. **Enable logging into files:** 111 | 112 | Logging can be useful to monitor your swap server and debug potential issues. 113 | Enable logging into files using the following command: 114 | 115 | .. code-block:: bash 116 | 117 | ./run_electrum setconfig log_to_file True 118 | ./run_electrum setconfig logs_num_files_keep 100 119 | 120 | By default the log files will be stored in ``~/.electrum/logs/electrum_log_*.log`` 121 | 122 | 7. (OPTIONAL) **Enable gossip:** 123 | 124 | By default Electrum uses Trampoline routing to find a path for lightning payments as 125 | this provides better user experience. However, as the swap server is a long running daemon, we can 126 | enable gossip to fetch the lightning network gossip and find paths locally: 127 | 128 | .. code-block:: bash 129 | 130 | ./run_electrum setconfig use_gossip True 131 | 132 | # now restart electrum to apply the changes 133 | ./run_electrum stop 134 | ./run_electrum daemon -d 135 | ---> starting daemon (PID 42836) 136 | ./run_electrum load_wallet 137 | 138 | # with keystore encryption: 139 | ./run_electrum unlock --password 140 | 141 | This will allow you to open lightning channels to any other node instead of just the following hardcoded 142 | `trampoline nodes `_. 143 | 144 | 8. **Funding the swap server:** 145 | 146 | To become a useful swaps provider you need to have on-chain funds as well as balanced lightning 147 | channels on your electrum node. This process varies depending on your available funds and strategy. 148 | 149 | The following commands are useful in the process of funding the swap server: 150 | 151 | .. code-block:: bash 152 | 153 | # check the balance of the swap server 154 | ./run_electrum getbalance 155 | 156 | # get new onchain address 157 | ./run_electrum getunusedaddress 158 | 159 | # open a lightning channel 160 | ./run_electrum open_channel 161 | 162 | # list lightning channels 163 | ./run_electrum list_channels 164 | 165 | At this point it may be useful to have a look at all available commands: 166 | 167 | .. code-block:: bash 168 | 169 | # to show all available commands 170 | ./run_electrum help 171 | 172 | # to show help for a specific command 173 | ./run_electrum open_channel -h 174 | 175 | Refer to the `Command Line documentation `_ for a more detailed overview of the 176 | command line functionality of the Electrum daemon. 177 | 178 | .. note:: 179 | Lightning channels in Electrum can be force closed just with your seed backup, so you don't have 180 | to worry about any other backup than the seed words. 181 | 182 | 9. **Enabling the swap server:** 183 | 184 | Now that you have a funded and well balanced Electrum lightning node we can enable the swap server plugin: 185 | 186 | .. code-block:: bash 187 | 188 | # this will enable the swap server plugin, it will automatically start when the daemon is started 189 | ./run_electrum setconfig plugins.swapserver.enabled True 190 | 191 | # now restart the daemon again to apply the changes 192 | ./run_electrum stop 193 | ./run_electrum daemon -d 194 | ---> starting daemon (PID 42836) 195 | ./run_electrum load_wallet 196 | 197 | # with keystore encryption: 198 | ./run_electrum unlock --password 199 | 200 | On the first restart you may notice some CPU load as the swap server will calculate some Proof of Work 201 | for spam protection. This is a one time process and will not be repeated on subsequent restarts unless you change 202 | it's target configuration. This can take a couple of minutes depending on the hardware, please be patient. 203 | 204 | .. note:: 205 | Now if you run a regular Electrum Wallet and open the Submarine Swap dialog you should be able to see your 206 | new swap server in the list of available swap servers. 207 | Now all users of Electrum can use your swap server to do submarine swaps. 208 | 209 | .. image:: png/swap_providers.png 210 | 211 | 10. **Configure the swap server:** 212 | 213 | The following configuration options are available for the swap server: 214 | 215 | .. code-block:: bash 216 | 217 | # fee_millionths: fee charged for swaps, default is 5000 218 | ./run_electrum setconfig plugins.swapserver.fee_millionths 219 | 220 | # swapserver_pow_target: announcement proof of work target, default is 30 221 | # a higher value ranks you higher in the clients GUI, 35 already can take hours to find, 222 | # depending on the hardware 223 | ./run_electrum setconfig swapserver_pow_target 224 | 225 | # nostr_relays: comma separated nostr relay urls your swap server uses for communication 226 | # and self-announcement. Default: see file electrum/simple_config.py 227 | ./run_electrum setconfig nostr_relays 228 | 229 | .. note:: 230 | The configuration variables can also be set manually using a text editor instead of the above CLI commands. 231 | By default the configuration file located at ``~/.electrum/config``. 232 | 233 | To see all available configuration options you can have a look at the ``electrum/simple_config.py`` 234 | file in the Electrum source code repository. 235 | 236 | Operation 237 | ---------- 238 | 239 | To stay competitive in the market of swap providers you should keep an eye on your lightning channels 240 | liquidity and on-chain balance to ensure you can provide swaps in both directions to your users. 241 | Also make sure you always run the latest release of Electrum to benefit from the 242 | latest features and bug fixes. 243 | 244 | Shutting down 245 | ------------- 246 | To shut down the swap server you can gracefully stop the daemon using: 247 | 248 | .. code-block:: bash 249 | 250 | ./run_electrum stop -------------------------------------------------------------------------------- /tails.rst: -------------------------------------------------------------------------------- 1 | Using the most current Electrum on Tails 2 | ======================================== 3 | 4 | Software installed on Tails cannot be permanently upgraded since it is a fixed (read-only) image. You can run the most recent version of Electrum with Tails by using the AppImage binary we distribute (a self-contained executable that should work on any x86_64 Linux including Tails). 5 | 6 | Tails version 4 (since October 2019) ships with a working version of Electrum at the time of its release - these instructions can be used to run the latest version of Electrum between Tails/Debian releases. 7 | 8 | Tails version 3 (prior to October 2019) ships with an outdated version of Electrum that can no longer be used on the public Electrum server network. It is recommended instead to upgrade to the latest Tails since it will have many other security improvements as well. 9 | 10 | These steps have been tested on Tails versions 3 and 4. 11 | 12 | Steps to use AppImage 13 | --------------------- 14 | 15 | 1. Write down your wallet seed words and store them securely off the computer. 16 | 2. Enable and configure persistent storage. In Tails enter the Applications/Tails menu and select "Configure persistent volume". Ensure "Personal data" and "Bitcoin client" sliders are enabled. Reboot if necessary and make sure the persistent volume is unlocked. 17 | 3. Ensure your Tails is connected to a network and the onion icon at the top confirms Tor network is ready. 18 | 4. Using Tor browser download the Linux Appimage file under "Sources and Binaries" near the top of the download page on electrum.org_ and save it to the default "Tor browser" folder. Tails and Tor are not as fast as your regular operating system, and the download may take much longer than normally expected especially if you have a slow computer or USB drive - Tor download speed depends entirely on the Tor network connections. Your AppImage will not start nor will it give any error message if you do not download the entire file. 19 | 5. Open Home/Tor browser folder and drag the appimage to the Persistent folder (lower left side of the window). Tails is very sensitive to user writeable file locations and Electrum may not work in another location. 20 | 6. Recommended: Check the PGP signature of the AppImage by following these_ instructions before using the AppImage. 21 | 7. Open Home/Persistent folder (where the appimage will now live), right click on the appimage and select Properties. Select the Permissions tab and click "Allow executing file as program" then close the dialog. More detailed instructions with screenshots are available here_. 22 | 23 | .. _electrum.org: https://electrum.org/#download 24 | .. _here: https://docs.appimage.org/user-guide/run-appimages.html 25 | .. _these: https://github.com/spesmilo/electrum-docs/blob/master/gpg-check.rst#verifying-gpg-signature-of-electrum-using-linux-command-line 26 | 27 | You can now simply click on the Electrum AppImage icon in your persistent folder to run the newest Electrum. Your new AppImage should use any previous Electrum data (if there is any) without difficulty and the wallet(s) will remain on your Tails USB drive if you've enabled persistent storage. If there is any question about your wallet(s) being corrupted, erase the files in ~/.electrum/wallets and reinitialize from seed words. 28 | 29 | **Caution:** Do not use the old Electrum available in the Tails version 3 menus. 30 | -------------------------------------------------------------------------------- /tor.rst: -------------------------------------------------------------------------------- 1 | Using Electrum Through Tor 2 | ========================================================== 3 | 4 | Please note that when using Electrum through Tor there are two main ways. 5 | The first way has the most Privacy but also requires the most trust in the server you are connecting to. This is because normally 6 | Electrum connects to a few different servers and downloads block headers and checks that they match. This prevents/makes it more difficult for 7 | Rogue servers to send you bad information. However, this can also present a privacy issue because you could be connecting to none .onion servers for these headers. 8 | 9 | Thus the two different options are, Connect to 1 server ONLY and get block headers and transaction info from that server. 10 | Or 11 | Connect to 8 block header servers and connect to 1 .onion server for the general use. 12 | 13 | List of Active .onion servers 14 | ----------------------------- 15 | Check the list here; 16 | 17 | http://electrumserv.noip.me/onionservers.txt 18 | 19 | If you wish to be added to this list email me at: 20 | 21 | danielcryptos@gmail.com 22 | 23 | 24 | LINUX 25 | ----- 26 | 27 | Option 1: Single Server 28 | ----------------------- 29 | 30 | Note: Please understand you are sacrificing some security here for extra privacy. 31 | 32 | 33 | Check out https://electrum.org/#download 34 | 35 | Grab the download from python source 36 | 37 | Make sure you have dependencies installed 38 | 39 | sudo apt-get install python-qt4 python-pip 40 | 41 | 42 | Extract the electrum download; 43 | 44 | tar -xvzf Electrum-2.*.*.tar.gz 45 | 46 | Go into the extracted electrum folder and then run; 47 | 48 | ./electrum -1 -s electrums3lojbuj.onion:50001:t -p socks5:localhost:9050 49 | 50 | Quick explanation, 51 | 52 | -1 means connect to 1 server only. 53 | 54 | -s is defining which server. You can change this to any .onion server you want. (Check the list at the top) 55 | 56 | -p Is saying what proxy server to use to get into the tor network. Generally this will be localhost but the port bit after : could be different. 57 | 58 | You might need to change the port bit depending on what system you are running; 59 | 60 | Currently The port is; 61 | 62 | Tor Browser Bundle: 9150 63 | 64 | General Tor (Installed): 9050 65 | 66 | 67 | Option 2: Multiple servers but Tor Main 68 | --------------------------------------- 69 | Same as above until the command to launch Electrum, Remove the -1 making it 70 | 71 | ./electrum -s electrums3lojbuj.onion:50001:t -p socks5:localhost:9050 72 | 73 | For this one, you can also just launch Electrum and click on the Green or Red icon on the bottom right to bring up server information 74 | 75 | Untick the box for Auto and enter; 76 | 77 | electrums3lojbuj.onion 78 | 79 | 50001 80 | 81 | Into the boxes. 82 | 83 | At the bottom select SOCKS5 for proxy and then 84 | 85 | localhost 86 | 87 | 9150 or 9050 88 | 89 | 90 | WINDOWS 91 | ------- 92 | 93 | 94 | Option 1: Connecting to a single Server 95 | --------------------------------------- 96 | Install Electrum from the main download page; 97 | https://electrum.org/#download 98 | 99 | Note: Please understand you are sacrificing some security here for extra privacy. 100 | 101 | In windows, On your desktop you will have a Electrum icon. Copy and paste this to make a copy. If not you can find the electrum folder in C:\Program Files (x86)\Electrum\ 102 | 103 | Right click on electrum.exe and create shortcut. It will say cannot make a shortcut here make one on the desktop instead? Ok this. 104 | 105 | With your new shortcut or a copy of your old one Right click it and go properties, click shortcut at the top bar, in the box named target: 106 | 107 | It should already say something similar to what’s in between the speech bubbles. If yours is different don’t change that bit to match. 108 | 109 | What we want to do is add on the bit after the last speech bubble. Make a space and then enter / copy and paste. 110 | 111 | "C:\Program Files (x86)\Electrum\electrum.exe" -1 -s electrums3lojbuj.onion:50001:t -p socks5:localhost:9050 112 | 113 | Apply and Ok the change... You can go back to the General Tab if you want and Where it says "electrum.exe - Shortcut" you could change that to Electrum - Tor or something 114 | 115 | Click apply and ok again. 116 | 117 | Now when you launch Electrum with this shortcut it will use 1 tor server only. 118 | 119 | Quick explanation, 120 | 121 | -1 means connect to 1 server only. 122 | 123 | -s is defining which server. You can change this to any .onion server you want. 124 | 125 | -p Is saying what proxy server to use to get into the tor network. Generally this will be localhost but the port bit after : could be different. 126 | 127 | You might need to change the port bit depending on what system you are running; 128 | 129 | Currently The port is; 130 | 131 | Tor Browser Bundle: 9150 132 | 133 | General Tor (Installed): 9050 134 | 135 | Option 2 136 | ---------- 137 | In Windows, on your desktop you will have a Electrum icon. Copy and paste this to make a copy. If not you can find the electrum folder in C:\Program Files (x86)\Electrum\ 138 | 139 | Right click on electrum.exe and create shortcut. It will say cannot make a shortcut here make one on the desktop instead? Ok this. 140 | 141 | With your new shortcut or a copy of your old one Right click it and go properties, click shortcut at the top bar, in the box named target: 142 | 143 | It should already say something similar to what’s in between the speech bubbles. If yours is different don’t change that bit to match. 144 | 145 | What we want to do is add on the bit after the last speech bubble. Make a space and then enter / copy and paste. 146 | 147 | 148 | "C:\Program Files (x86)\Electrum\electrum.exe" -s electrums3lojbuj.onion:50001:t -p socks5:localhost:9050 149 | 150 | Apply and Ok the change... You can go back to the General Tab if you want and Where it says "electrum.exe - Shortcut" you could change that to Electrum - Tor or something 151 | 152 | Click apply and ok again. 153 | 154 | Now when you launch Electrum with this shortcut it will use 1 tor server only. 155 | 156 | You might need to change the port bit depending on what system you are running; 157 | 158 | Currently The port is; 159 | 160 | Tor Browser Bundle: 9150 161 | 162 | General Tor (Installed): 9050 163 | 164 | 165 | For this one you can also just launch electrum and click on the Green or Red icon on the bottom right to bring up server information 166 | Untick the box for Auto and enter; 167 | 168 | electrums3lojbuj.onion 169 | 170 | 50001 171 | 172 | Into the boxes. 173 | 174 | At the bottom select SOCKS5 for proxy and then 175 | 176 | localhost 177 | 178 | 9150 or 9050 179 | -------------------------------------------------------------------------------- /transactions.rst: -------------------------------------------------------------------------------- 1 | Serialization of unsigned or partially signed transactions 2 | ========================================================== 3 | 4 | Electrum 2.0 uses an extended serialization format for transactions. 5 | The purpose of this format is to send unsigned and partially signed 6 | transactions to cosigners or to cold storage. 7 | 8 | This is achieved by extending the 'pubkey' field of a transaction 9 | input. 10 | 11 | 12 | Extended public keys 13 | -------------------- 14 | 15 | The first byte of the pubkey indicates if it is an 16 | extended pubkey: 17 | 18 | - 0x02, 0x03, 0x04: legal Bitcoin public key (compressed or not). 19 | - 0xFF, 0xFE, 0xFD: extended public key. 20 | 21 | 22 | Extended public keys are of 3 types: 23 | 24 | - 0xFF: bip32 xpub and derivation 25 | - 0xFE: legacy electrum derivation: master public key + derivation 26 | - 0xFD: unknown pubkey, but we know the Bitcoin address. 27 | 28 | Public key 29 | ---------- 30 | 31 | This is the legit Bitcoin serialization of public keys. 32 | 33 | +--------------+-------------------------------------+ 34 | | 0x02 or 0x03 | compressed public key (32 bytes) | 35 | +--------------+-------------------------------------+ 36 | | 0x04 | uncompressed public key (64 bytes) | 37 | +--------------+-------------------------------------+ 38 | 39 | 40 | BIP32 derivation 41 | ---------------- 42 | 43 | +-----------+-----------------+------------------------------+ 44 | | 0xFF | xpub (78 bytes) | bip32 derivation (2*k bytes) | 45 | +-----------+-----------------+------------------------------+ 46 | 47 | Legacy Electrum Derivation 48 | -------------------------- 49 | 50 | +-----------+-----------------+----------------------+ 51 | | 0xFE | mpk (64 bytes) | derivation (4 bytes) | 52 | +-----------+-----------------+----------------------+ 53 | 54 | 55 | Bitcoin address 56 | --------------- 57 | 58 | Used if we don't know the public key, but we know the 59 | address (or the hash 160 of the output script). The 60 | cosigner should know the public key. 61 | 62 | +-----------+-------------------------------------+ 63 | | 0xFD | hash_160_of_script (20 bytes) | 64 | +-----------+-------------------------------------+ 65 | 66 | -------------------------------------------------------------------------------- /watchtower.rst: -------------------------------------------------------------------------------- 1 | How to setup a watchtower 2 | ========================= 3 | 4 | This tutorial will show you how to configure your Electrum daemon as a 5 | watchtower for your lightning wallet. It is written for Electrum 4.0. 6 | 7 | A watchtower is a separate Electrum process, that runs on 8 | another computer. To setup a watchtower, you need to configure 9 | an Electrum daemon, and enter its URL in your preferences. 10 | 11 | 12 | 13 | How to configure a watchtower 14 | ----------------------------- 15 | 16 | You want to run your watchtower on a machine that is regularly 17 | connected to the internet. 18 | 19 | First install Electrum, and add a SSL certificate to your Electrum 20 | configuration: 21 | 22 | .. code-block:: bash 23 | 24 | electrum -o setconfig ssl_keyfile /path/to/ssl/privkey.pem 25 | electrum -o setconfig ssl_certfile /path/to/ssl/fullchain.pem 26 | 27 | For details see `How to add SSL `_ 28 | 29 | 30 | Second, configure your watchtower with an address, username and password: 31 | 32 | .. code-block:: bash 33 | 34 | electrum setconfig -o run_watchtower true 35 | electrum setconfig -o watchtower_user myusername 36 | electrum setconfig -o watchtower_password mypassword 37 | electrum setconfig -o watchtower_address example.com:12345 38 | 39 | Then start the daemon: 40 | 41 | .. code-block:: bash 42 | 43 | electrum daemon -d 44 | 45 | 46 | The watchtower database contains presigned transactions, and is in 47 | ~/.electrum/watchtower_db 48 | 49 | 50 | Note that the daemon does not need to contain a wallet, nor to have 51 | Lightning enabled; the watchtower is only about watching onchain 52 | addresses and broadcasting onchain transactions. 53 | 54 | 55 | If you run Electrum's Qt GUI on the machine that is configured as a 56 | watchtower, you can view the database size and number of transactions 57 | per channel if you open the watchtower window: 58 | 59 | .. image:: png/watchtower_window.png 60 | 61 | 62 | Configure the watchtower in your client 63 | --------------------------------------- 64 | 65 | In your client preferences, tick 'use a remote watchtower' and enter the url: 66 | 67 | .. code-block:: bash 68 | 69 | https://myusername:mypassword@example.com:12345 70 | -------------------------------------------------------------------------------- /xpub_version_bytes.rst: -------------------------------------------------------------------------------- 1 | Version bytes for BIP32 extended public and private keys 2 | ======================================================== 3 | 4 | This document describes the version bytes used in Electrum for master keys. 5 | 6 | Abstract 7 | -------- 8 | 9 | `BIP32 `__ 10 | defines a serialization format for extended keys. This serialization 11 | includes four bytes allocated as version bytes. We use these version 12 | bytes to encode the type of output scripts (scriptPubKeys) a wallet 13 | should derive along this HD subtree. 14 | 15 | Motivation 16 | ---------- 17 | 18 | Among other changes, the activation of SegWit 19 | (`BIP141 `__) 20 | introduced new output script templates usable on Bitcoin mainnet. This 21 | poses a new problem for HD wallets in terms of what type of scripts they 22 | should derive from master keys. Previously most wallets offered deriving 23 | either P2PKH or multi-signature embedded in 24 | `BIP16 `__ 25 | P2SH outputs, and it was usually deduced from context which of the two 26 | should be used. We believe it would be better to have this knowledge 27 | explicitly. 28 | 29 | Encoding the script type in 30 | `BIP32 `__ 31 | extended keys is beneficial for wallets. For example, a watch-only 32 | wallet constructed from an extended public key would otherwise have to 33 | either (1) derive all possible scripts in the subtree [1]_, or (2) 34 | prompt the user to enter the script type in a side-channel. 35 | 36 | Deriving all possible scripts (1) 37 | 38 | - Potentially wastes resources. Wallets have to monitor more output 39 | scripts for incoming transactions. 40 | - Introduces key-reuse. Public keys are reused for each script type. 41 | - Becomes an ever-growing barrier for developers of new wallet software 42 | to implement detecting and spending from every type of UTXO. 43 | Otherwise, if they choose not to implement legacy script types that 44 | can lead to not discovering funds. 45 | 46 | Prompting the user to enter the script type (2) as additional 47 | information besides the extended public key just leads to more complex 48 | user interfaces and suboptimal experience. 49 | 50 | Users directly interact with master public keys, for watch-only wallets, 51 | or when specifying cosigners for HD multisig. These keys are commonly 52 | serialized as 53 | `BIP32 `__ 54 | extended keys, hence it makes sense to make the encoding of the script 55 | type user-visible. As version bytes are already used to encode the 56 | network in such a way, this document introduces new constants for 57 | version bytes to further encode the script type. 58 | 59 | Considerations 60 | -------------- 61 | 62 | Without explicit knowledge of the output script type, wallets have no 63 | clear way to communicate to users whether the type of script the user 64 | would expect to be derived is supported/implemented. Casual users would 65 | simply notice funds missing, if they have prior knowledge of funds at 66 | all. 67 | 68 | The version byte values defined in 69 | `BIP32 `__ 70 | do not distinguish P2PKH and P2SH-multisig outputs, and to remain 71 | backwards compatible, this will not be changed. However, this has already 72 | resulted in loss of funds in some cases, where e.g. a user restored and 73 | received transactions on a watch-only P2PKH wallet from a master public 74 | key participating in P2SH-multisig that he had no control over (it was a 75 | key of a different cosigner). To try to prevent this kind of situation, 76 | e.g. P2WPKH and P2WSH-multisig is distinguished in this document. 77 | 78 | Specification 79 | ------------- 80 | 81 | In the table below, 82 | 83 | - P2SH stands for a 84 | `BIP11 `__ 85 | multi-signature script embedded in a 86 | `BIP16 `__ 87 | pay-to-script-hash output 88 | - P2WPKH stands for pay-to-witness-public-key-hash (witness version 0), 89 | as in 90 | `BIP141 `__ 91 | - P2WPKH-P2SH stands for a P2WPKH script (witness version 0) nested in 92 | a 93 | `BIP16 `__ 94 | P2SH output, as in 95 | `BIP141 `__ 96 | - P2WSH stands for a 97 | `BIP11 `__ 98 | multi-signature pay-to-witness-script-hash (witness version 0) 99 | script, as in 100 | `BIP141 `__ 101 | - P2WSH-P2SH stands for a 102 | `BIP11 `__ 103 | multi-signature pay-to-witness-script-hash (witness version 0) script 104 | nested in a 105 | `BIP16 `__ 106 | P2SH output, as in 107 | `BIP141 `__ 108 | 109 | Note that an M-of-N multi-signature script is usually constructed from N 110 | extended keys (and M is provided in a side-channel). Hence in most cases 111 | more than one extended key is needed to create such scripts; this is out 112 | of scope of this document. 113 | 114 | +---------+---------------+----------+---------------+------------------+ 115 | | network | script type | pub/priv | version bytes | | human-readable | 116 | | | | | | | prefix | 117 | +=========+===============+==========+===============+==================+ 118 | | mainnet | p2pkh or p2sh | public | 0x0488b21e | xpub | 119 | +---------+---------------+----------+---------------+------------------+ 120 | | mainnet | p2pkh or p2sh | private | 0x0488ade4 | xprv | 121 | +---------+---------------+----------+---------------+------------------+ 122 | | mainnet | p2wpkh-p2sh | public | 0x049d7cb2 | ypub | 123 | +---------+---------------+----------+---------------+------------------+ 124 | | mainnet | p2wpkh-p2sh | private | 0x049d7878 | yprv | 125 | +---------+---------------+----------+---------------+------------------+ 126 | | mainnet | p2wsh-p2sh | public | 0x0295b43f | Ypub | 127 | +---------+---------------+----------+---------------+------------------+ 128 | | mainnet | p2wsh-p2sh | private | 0x0295b005 | Yprv | 129 | +---------+---------------+----------+---------------+------------------+ 130 | | mainnet | p2wpkh | public | 0x04b24746 | zpub | 131 | +---------+---------------+----------+---------------+------------------+ 132 | | mainnet | p2wpkh | private | 0x04b2430c | zprv | 133 | +---------+---------------+----------+---------------+------------------+ 134 | | mainnet | p2wsh | public | 0x02aa7ed3 | Zpub | 135 | +---------+---------------+----------+---------------+------------------+ 136 | | mainnet | p2wsh | private | 0x02aa7a99 | Zprv | 137 | +---------+---------------+----------+---------------+------------------+ 138 | | testnet | p2pkh or p2sh | public | 0x043587cf | tpub | 139 | +---------+---------------+----------+---------------+------------------+ 140 | | testnet | p2pkh or p2sh | private | 0x04358394 | tprv | 141 | +---------+---------------+----------+---------------+------------------+ 142 | | testnet | p2wpkh-p2sh | public | 0x044a5262 | upub | 143 | +---------+---------------+----------+---------------+------------------+ 144 | | testnet | p2wpkh-p2sh | private | 0x044a4e28 | uprv | 145 | +---------+---------------+----------+---------------+------------------+ 146 | | testnet | p2wsh-p2sh | public | 0x024289ef | Upub | 147 | +---------+---------------+----------+---------------+------------------+ 148 | | testnet | p2wsh-p2sh | private | 0x024285b5 | Uprv | 149 | +---------+---------------+----------+---------------+------------------+ 150 | | testnet | p2wpkh | public | 0x045f1cf6 | vpub | 151 | +---------+---------------+----------+---------------+------------------+ 152 | | testnet | p2wpkh | private | 0x045f18bc | vprv | 153 | +---------+---------------+----------+---------------+------------------+ 154 | | testnet | p2wsh | public | 0x02575483 | Vpub | 155 | +---------+---------------+----------+---------------+------------------+ 156 | | testnet | p2wsh | private | 0x02575048 | Vprv | 157 | +---------+---------------+----------+---------------+------------------+ 158 | 159 | Backwards Compatibility 160 | ----------------------- 161 | 162 | This document is backwards compatible with 163 | `BIP32 `__; 164 | existing extended keys will keep working. Compatibility is intentionally 165 | broken in the sense that extended keys derived for newer script types will 166 | not have valid 167 | `BIP32 `__ 168 | version bytes. 169 | 170 | Footnotes 171 | --------- 172 | 173 | .. [1] 174 | Which is not even possible, given there are an effectively infinite 175 | number of possible scripts. A wallet could however derive scripts for 176 | all standard templates. 177 | 178 | Reference 179 | --------- 180 | 181 | - `BIP11 - M-of-N Standard Transactions 182 | `__ 183 | - `BIP16 - Pay to Script Hash 184 | `__ 185 | - `BIP32 - Hierarchical Deterministic Wallets 186 | `__ 187 | - `BIP141 - Segregated Witness (Consensus 188 | layer) `__ 189 | --------------------------------------------------------------------------------