electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 0ecb665b95917459d17ef3f9e47bde4864a2e318
parent 23c02692521d0b6c6bbe05e1bb574957ddd6e98b
Author: ThomasV <thomasv@electrum.org>
Date:   Fri, 10 Nov 2017 09:15:40 +0100

Merge pull request #3257 from SomberNight/bitcoin_network_constants

bitcoin.NetworkConstants: easier changing between testnet and mainnet
Diffstat:
Melectrum | 2+-
Mgui/kivy/main_window.py | 4++--
Mgui/qt/network_dialog.py | 6+++---
Mlib/bitcoin.py | 76+++++++++++++++++++++++++++++++++++++---------------------------------------
Mlib/blockchain.py | 6+++---
Mlib/keystore.py | 2+-
Mlib/network.py | 12++++++------
Mlib/util.py | 2+-
Mplugins/trezor/plugin.py | 4++--
9 files changed, 56 insertions(+), 58 deletions(-)

diff --git a/electrum b/electrum @@ -357,7 +357,7 @@ if __name__ == '__main__': cmdname = config.get('cmd') if config.get('testnet'): - bitcoin.set_testnet() + bitcoin.NetworkConstants.set_testnet() # run non-RPC commands separately if cmdname in ['create', 'restore']: diff --git a/gui/kivy/main_window.py b/gui/kivy/main_window.py @@ -95,8 +95,8 @@ class ElectrumWindow(App): from .uix.dialogs.choice_dialog import ChoiceDialog protocol = 's' def cb2(host): - from electrum.network import DEFAULT_PORTS - pp = servers.get(host, DEFAULT_PORTS) + from electrum.bitcoin import NetworkConstants + pp = servers.get(host, NetworkConstants.DEFAULT_PORTS) port = pp.get(protocol, '') popup.ids.host.text = host popup.ids.port.text = port diff --git a/gui/qt/network_dialog.py b/gui/qt/network_dialog.py @@ -30,7 +30,7 @@ from PyQt5.QtCore import * import PyQt5.QtCore as QtCore from electrum.i18n import _ -from electrum.network import DEFAULT_PORTS +from electrum.bitcoin import NetworkConstants from electrum.network import serialize_server, deserialize_server from electrum.util import print_error @@ -397,7 +397,7 @@ class NetworkChoiceLayout(object): def change_protocol(self, use_ssl): p = 's' if use_ssl else 't' host = self.server_host.text() - pp = self.servers.get(host, DEFAULT_PORTS) + pp = self.servers.get(host, NetworkConstants.DEFAULT_PORTS) if p not in pp.keys(): p = list(pp.keys())[0] port = pp[p] @@ -422,7 +422,7 @@ class NetworkChoiceLayout(object): self.change_server(str(x.text(0)), self.protocol) def change_server(self, host, protocol): - pp = self.servers.get(host, DEFAULT_PORTS) + pp = self.servers.get(host, NetworkConstants.DEFAULT_PORTS) if protocol and protocol not in protocol_letters: protocol = None if protocol: diff --git a/lib/bitcoin.py b/lib/bitcoin.py @@ -69,36 +69,34 @@ XPUB_HEADERS = { } -# Bitcoin network constants -TESTNET = False -WIF_PREFIX = 0x80 -ADDRTYPE_P2PKH = 0 -ADDRTYPE_P2SH = 5 -SEGWIT_HRP = "bc" -HEADERS_URL = "https://headers.electrum.org/blockchain_headers" -GENESIS = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f" -SERVERLIST = 'servers.json' -DEFAULT_PORTS = {'t':'50001', 's':'50002'} -DEFAULT_SERVERS = read_json_dict('servers.json') - -def set_testnet(): - global ADDRTYPE_P2PKH, ADDRTYPE_P2SH - global TESTNET, HEADERS_URL - global GENESIS - global SEGWIT_HRP - global DEFAULT_PORTS, SERVERLIST, DEFAULT_SERVERS - global WIF_PREFIX - TESTNET = True - WIF_PREFIX = 0xef - ADDRTYPE_P2PKH = 111 - ADDRTYPE_P2SH = 196 - SEGWIT_HRP = "tb" - HEADERS_URL = "https://headers.electrum.org/testnet_headers" - GENESIS = "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943" - SERVERLIST = 'servers_testnet.json' - DEFAULT_PORTS = {'t':'51001', 's':'51002'} - DEFAULT_SERVERS = read_json_dict('servers_testnet.json') +class NetworkConstants: + @classmethod + def set_mainnet(cls): + cls.TESTNET = False + cls.WIF_PREFIX = 0x80 + cls.ADDRTYPE_P2PKH = 0 + cls.ADDRTYPE_P2SH = 5 + cls.SEGWIT_HRP = "bc" + cls.HEADERS_URL = "https://headers.electrum.org/blockchain_headers" + cls.GENESIS = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f" + cls.DEFAULT_PORTS = {'t': '50001', 's': '50002'} + cls.DEFAULT_SERVERS = read_json_dict('servers.json') + + @classmethod + def set_testnet(cls): + cls.TESTNET = True + cls.WIF_PREFIX = 0xef + cls.ADDRTYPE_P2PKH = 111 + cls.ADDRTYPE_P2SH = 196 + cls.SEGWIT_HRP = "tb" + cls.HEADERS_URL = "https://headers.electrum.org/testnet_headers" + cls.GENESIS = "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943" + cls.DEFAULT_PORTS = {'t':'51001', 's':'51002'} + cls.DEFAULT_SERVERS = read_json_dict('servers_testnet.json') + + +NetworkConstants.set_mainnet() ################################## transactions @@ -339,16 +337,16 @@ def b58_address_to_hash160(addr): def hash160_to_p2pkh(h160): - return hash160_to_b58_address(h160, ADDRTYPE_P2PKH) + return hash160_to_b58_address(h160, NetworkConstants.ADDRTYPE_P2PKH) def hash160_to_p2sh(h160): - return hash160_to_b58_address(h160, ADDRTYPE_P2SH) + return hash160_to_b58_address(h160, NetworkConstants.ADDRTYPE_P2SH) def public_key_to_p2pkh(public_key): return hash160_to_p2pkh(hash_160(public_key)) def hash_to_segwit_addr(h): - return segwit_addr.encode(SEGWIT_HRP, 0, h) + return segwit_addr.encode(NetworkConstants.SEGWIT_HRP, 0, h) def public_key_to_p2wpkh(public_key): return hash_to_segwit_addr(hash_160(public_key)) @@ -394,7 +392,7 @@ def script_to_address(script): return addr def address_to_script(addr): - witver, witprog = segwit_addr.decode(SEGWIT_HRP, addr) + witver, witprog = segwit_addr.decode(NetworkConstants.SEGWIT_HRP, addr) if witprog is not None: assert (0 <= witver <= 16) OP_n = witver + 0x50 if witver > 0 else 0 @@ -402,11 +400,11 @@ def address_to_script(addr): script += push_script(bh2u(bytes(witprog))) return script addrtype, hash_160 = b58_address_to_hash160(addr) - if addrtype == ADDRTYPE_P2PKH: + if addrtype == NetworkConstants.ADDRTYPE_P2PKH: script = '76a9' # op_dup, op_hash_160 script += push_script(bh2u(hash_160)) script += '88ac' # op_equalverify, op_checksig - elif addrtype == ADDRTYPE_P2SH: + elif addrtype == NetworkConstants.ADDRTYPE_P2SH: script = 'a9' # op_hash_160 script += push_script(bh2u(hash_160)) script += '87' # op_equal @@ -524,7 +522,7 @@ SCRIPT_TYPES = { def serialize_privkey(secret, compressed, txin_type): - prefix = bytes([(SCRIPT_TYPES[txin_type]+WIF_PREFIX)&255]) + prefix = bytes([(SCRIPT_TYPES[txin_type]+NetworkConstants.WIF_PREFIX)&255]) suffix = b'\01' if compressed else b'' vchIn = prefix + secret + suffix return EncodeBase58Check(vchIn) @@ -536,7 +534,7 @@ def deserialize_privkey(key): if is_minikey(key): return 'p2pkh', minikey_to_private_key(key), True elif vch: - txin_type = inv_dict(SCRIPT_TYPES)[vch[0] - WIF_PREFIX] + txin_type = inv_dict(SCRIPT_TYPES)[vch[0] - NetworkConstants.WIF_PREFIX] assert len(vch) in [33, 34] compressed = len(vch) == 34 return txin_type, vch[1:33], compressed @@ -571,7 +569,7 @@ def address_from_private_key(sec): return pubkey_to_address(txin_type, public_key) def is_segwit_address(addr): - witver, witprog = segwit_addr.decode(SEGWIT_HRP, addr) + witver, witprog = segwit_addr.decode(NetworkConstants.SEGWIT_HRP, addr) return witprog is not None def is_b58_address(addr): @@ -579,7 +577,7 @@ def is_b58_address(addr): addrtype, h = b58_address_to_hash160(addr) except Exception as e: return False - if addrtype not in [ADDRTYPE_P2PKH, ADDRTYPE_P2SH]: + if addrtype not in [NetworkConstants.ADDRTYPE_P2PKH, NetworkConstants.ADDRTYPE_P2SH]: return False return addr == hash160_to_b58_address(h, addrtype) diff --git a/lib/blockchain.py b/lib/blockchain.py @@ -148,7 +148,7 @@ class Blockchain(util.PrintError): _hash = hash_header(header) if prev_hash != header.get('prev_block_hash'): raise BaseException("prev hash mismatch: %s vs %s" % (prev_hash, header.get('prev_block_hash'))) - if bitcoin.TESTNET: + if bitcoin.NetworkConstants.TESTNET: return if bits != header.get('bits'): raise BaseException("bits mismatch: %s vs %s" % (bits, header.get('bits'))) @@ -265,7 +265,7 @@ class Blockchain(util.PrintError): return sum([self.BIP9(h-i, 2) for i in range(N)])*10000/N/100. def get_target(self, index): - if bitcoin.TESTNET: + if bitcoin.NetworkConstants.TESTNET: return 0, 0 if index == 0: return 0x1d00ffff, MAX_TARGET @@ -302,7 +302,7 @@ class Blockchain(util.PrintError): if check_height and self.height() != height - 1: return False if height == 0: - return hash_header(header) == bitcoin.GENESIS + return hash_header(header) == bitcoin.NetworkConstants.GENESIS previous_header = self.read_header(height -1) if not previous_header: return False diff --git a/lib/keystore.py b/lib/keystore.py @@ -678,7 +678,7 @@ is_bip32_key = lambda x: is_xprv(x) or is_xpub(x) def bip44_derivation(account_id, segwit=False): bip = 49 if segwit else 44 - coin = 1 if bitcoin.TESTNET else 0 + coin = 1 if bitcoin.NetworkConstants.TESTNET else 0 return "m/%d'/%d'/%d'" % (bip, coin, int(account_id)) def from_seed(seed, passphrase, is_p2sh): diff --git a/lib/network.py b/lib/network.py @@ -66,7 +66,7 @@ def parse_servers(result): for v in item[2]: if re.match("[st]\d*", v): protocol, port = v[0], v[1:] - if port == '': port = bitcoin.DEFAULT_PORTS[protocol] + if port == '': port = bitcoin.NetworkConstants.DEFAULT_PORTS[protocol] out[protocol] = port elif re.match("v(.?)+", v): version = v[1:] @@ -100,7 +100,7 @@ def filter_protocol(hostmap, protocol = 's'): def pick_random_server(hostmap = None, protocol = 's', exclude_set = set()): if hostmap is None: - hostmap = bitcoin.DEFAULT_SERVERS + hostmap = bitcoin.NetworkConstants.DEFAULT_SERVERS eligible = list(set(filter_protocol(hostmap, protocol)) - exclude_set) return random.choice(eligible) if eligible else None @@ -363,7 +363,7 @@ class Network(util.DaemonThread): return list(self.interfaces.keys()) def get_servers(self): - out = bitcoin.DEFAULT_SERVERS + out = bitcoin.NetworkConstants.DEFAULT_SERVERS if self.irc_servers: out.update(filter_version(self.irc_servers.copy())) else: @@ -947,7 +947,7 @@ class Network(util.DaemonThread): def init_headers_file(self): b = self.blockchains[0] - if b.get_hash(0) == bitcoin.GENESIS: + if b.get_hash(0) == bitcoin.NetworkConstants.GENESIS: self.downloading_headers = False return filename = b.path() @@ -955,8 +955,8 @@ class Network(util.DaemonThread): try: import urllib.request, socket socket.setdefaulttimeout(30) - self.print_error("downloading ", bitcoin.HEADERS_URL) - urllib.request.urlretrieve(bitcoin.HEADERS_URL, filename + '.tmp') + self.print_error("downloading ", bitcoin.NetworkConstants.HEADERS_URL) + urllib.request.urlretrieve(bitcoin.NetworkConstants.HEADERS_URL, filename + '.tmp') os.rename(filename + '.tmp', filename) self.print_error("done.") except Exception: diff --git a/lib/util.py b/lib/util.py @@ -476,7 +476,7 @@ testnet_block_explorers = { def block_explorer_info(): from . import bitcoin - return testnet_block_explorers if bitcoin.TESTNET else mainnet_block_explorers + return testnet_block_explorers if bitcoin.NetworkConstants.TESTNET else mainnet_block_explorers def block_explorer(config): return config.get('block_explorer', 'Blocktrail.com') diff --git a/plugins/trezor/plugin.py b/plugins/trezor/plugin.py @@ -9,7 +9,7 @@ from electrum.util import bfh, bh2u from electrum.bitcoin import (is_segwit_address, b58_address_to_hash160, xpub_from_pubkey, public_key_to_p2pkh, EncodeBase58Check, TYPE_ADDRESS, TYPE_SCRIPT, - TESTNET, ADDRTYPE_P2PKH, ADDRTYPE_P2SH) + NetworkConstants) from electrum.i18n import _ from electrum.plugins import BasePlugin, hook from electrum.transaction import deserialize, Transaction @@ -142,7 +142,7 @@ class TrezorCompatiblePlugin(HW_PluginBase): return client def get_coin_name(self): - return "Testnet" if TESTNET else "Bitcoin" + return "Testnet" if NetworkConstants.TESTNET else "Bitcoin" def initialize_device(self, device_id, wizard, handler): # Initialization method