URI: 
       tMerge pull request #3257 from SomberNight/bitcoin_network_constants - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 0ecb665b95917459d17ef3f9e47bde4864a2e318
   DIR parent 23c02692521d0b6c6bbe05e1bb574957ddd6e98b
  HTML 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:
         M electrum                            |       2 +-
         M gui/kivy/main_window.py             |       4 ++--
         M gui/qt/network_dialog.py            |       6 +++---
         M lib/bitcoin.py                      |      76 +++++++++++++++----------------
         M lib/blockchain.py                   |       6 +++---
         M lib/keystore.py                     |       2 +-
         M lib/network.py                      |      12 ++++++------
         M lib/util.py                         |       2 +-
         M plugins/trezor/plugin.py            |       4 ++--
       
       9 files changed, 56 insertions(+), 58 deletions(-)
       ---
   DIR diff --git a/electrum b/electrum
       t@@ -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']:
   DIR diff --git a/gui/kivy/main_window.py b/gui/kivy/main_window.py
       t@@ -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
   DIR diff --git a/gui/qt/network_dialog.py b/gui/qt/network_dialog.py
       t@@ -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
        
       t@@ -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]
       t@@ -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:
   DIR diff --git a/lib/bitcoin.py b/lib/bitcoin.py
       t@@ -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
        
       t@@ -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))
       t@@ -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
       t@@ -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
       t@@ -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)
       t@@ -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
       t@@ -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):
       t@@ -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)
        
   DIR diff --git a/lib/blockchain.py b/lib/blockchain.py
       t@@ -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')))
       t@@ -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
       t@@ -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
   DIR diff --git a/lib/keystore.py b/lib/keystore.py
       t@@ -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):
   DIR diff --git a/lib/network.py b/lib/network.py
       t@@ -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:]
       t@@ -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
        
       t@@ -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:
       t@@ -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()
       t@@ -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:
   DIR diff --git a/lib/util.py b/lib/util.py
       t@@ -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')
   DIR diff --git a/plugins/trezor/plugin.py b/plugins/trezor/plugin.py
       t@@ -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
       t@@ -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