tMerge pull request #4008 from SomberNight/network_constants_refactor - electrum - Electrum Bitcoin wallet (HTM) git clone https://git.parazyd.org/electrum (DIR) Log (DIR) Files (DIR) Refs (DIR) Submodules --- (DIR) commit c3ff6040d25eb58a874aac2ff4355292843daec3 (DIR) parent 1c0e23c8b90a99f7a2fe1b8e2dbbd128fa1c7d5f (HTM) Author: ThomasV <thomasv@electrum.org> Date: Sun, 4 Mar 2018 23:13:50 +0100 Merge pull request #4008 from SomberNight/network_constants_refactor refactor network constants Diffstat: M electrum | 3 ++- M gui/kivy/main_window.py | 4 ++-- M gui/qt/exception_window.py | 4 ++-- M gui/qt/main_window.py | 5 +++-- M gui/qt/network_dialog.py | 6 +++--- M lib/bitcoin.py | 131 +++++++++---------------------- M lib/blockchain.py | 11 ++++++----- A lib/constants.py | 107 +++++++++++++++++++++++++++++++ M lib/keystore.py | 4 ++-- M lib/network.py | 11 ++++++----- M lib/tests/test_bitcoin.py | 7 ++++--- M lib/util.py | 4 ++-- M plugins/digitalbitbox/digitalbitbo… | 7 ++++--- M plugins/keepkey/plugin.py | 9 +++++---- M plugins/trezor/trezor.py | 5 +++-- M plugins/trustedcoin/trustedcoin.py | 5 +++-- 16 files changed, 191 insertions(+), 132 deletions(-) --- (DIR) diff --git a/electrum b/electrum t@@ -89,6 +89,7 @@ if is_local or is_android: from electrum import bitcoin, util +from electrum import constants from electrum import SimpleConfig, Network from electrum.wallet import Wallet, Imported_Wallet from electrum.storage import WalletStorage, get_derivation_used_for_hw_device_encryption t@@ -411,7 +412,7 @@ if __name__ == '__main__': cmdname = config.get('cmd') if config.get('testnet'): - bitcoin.NetworkConstants.set_testnet() + constants.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@@ -99,8 +99,8 @@ class ElectrumWindow(App): from .uix.dialogs.choice_dialog import ChoiceDialog protocol = 's' def cb2(host): - from electrum.bitcoin import NetworkConstants - pp = servers.get(host, NetworkConstants.DEFAULT_PORTS) + from electrum import constants + pp = servers.get(host, constants.net.DEFAULT_PORTS) port = pp.get(protocol, '') popup.ids.host.text = host popup.ids.port.text = port (DIR) diff --git a/gui/qt/exception_window.py b/gui/qt/exception_window.py t@@ -36,7 +36,7 @@ from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import * from electrum.i18n import _ -from electrum import ELECTRUM_VERSION, bitcoin +from electrum import ELECTRUM_VERSION, bitcoin, constants issue_template = """<h2>Traceback</h2> <pre> t@@ -107,7 +107,7 @@ class Exception_Window(QWidget): self.show() def send_report(self): - if bitcoin.NetworkConstants.GENESIS[-4:] not in ["4943", "e26f"] and ".electrum.org" in report_server: + if constants.net.GENESIS[-4:] not in ["4943", "e26f"] and ".electrum.org" in report_server: # Gah! Some kind of altcoin wants to send us crash reports. self.main_window.show_critical(_("Please report this issue manually.")) return (DIR) diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py t@@ -40,7 +40,8 @@ from .exception_window import Exception_Hook from PyQt5.QtWidgets import * from electrum import keystore, simple_config -from electrum.bitcoin import COIN, is_address, TYPE_ADDRESS, NetworkConstants +from electrum.bitcoin import COIN, is_address, TYPE_ADDRESS +from electrum import constants from electrum.plugins import run_hook from electrum.i18n import _ from electrum.util import (format_time, format_satoshis, PrintError, t@@ -371,7 +372,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): self.setGeometry(100, 100, 840, 400) def watching_only_changed(self): - name = "Electrum Testnet" if NetworkConstants.TESTNET else "Electrum" + name = "Electrum Testnet" if constants.net.TESTNET else "Electrum" title = '%s %s - %s' % (name, self.wallet.electrum_version, self.wallet.basename()) extra = [self.wallet.storage.get('wallet_type', '?')] (DIR) diff --git a/gui/qt/network_dialog.py b/gui/qt/network_dialog.py t@@ -31,7 +31,7 @@ from PyQt5.QtWidgets import * import PyQt5.QtCore as QtCore from electrum.i18n import _ -from electrum.bitcoin import NetworkConstants +from electrum import constants from electrum.util import print_error from electrum.network import serialize_server, deserialize_server t@@ -393,7 +393,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, NetworkConstants.DEFAULT_PORTS) + pp = self.servers.get(host, constants.net.DEFAULT_PORTS) if p not in pp.keys(): p = list(pp.keys())[0] port = pp[p] t@@ -418,7 +418,7 @@ class NetworkChoiceLayout(object): self.change_server(str(x.text(0)), self.protocol) def change_server(self, host, protocol): - pp = self.servers.get(host, NetworkConstants.DEFAULT_PORTS) + pp = self.servers.get(host, constants.net.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@@ -36,75 +36,8 @@ from .util import bfh, bh2u, to_string from . import version from .util import print_error, InvalidPassword, assert_bytes, to_bytes, inv_dict from . import segwit_addr +from . import constants -def read_json(filename, default): - path = os.path.join(os.path.dirname(__file__), filename) - try: - with open(path, 'r') as f: - r = json.loads(f.read()) - except: - r = default - return r - - -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.GENESIS = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f" - cls.DEFAULT_PORTS = {'t': '50001', 's': '50002'} - cls.DEFAULT_SERVERS = read_json('servers.json', {}) - cls.CHECKPOINTS = read_json('checkpoints.json', []) - - cls.XPRV_HEADERS = { - 'standard': 0x0488ade4, # xprv - 'p2wpkh-p2sh': 0x049d7878, # yprv - 'p2wsh-p2sh': 0x0295b005, # Yprv - 'p2wpkh': 0x04b2430c, # zprv - 'p2wsh': 0x02aa7a99, # Zprv - } - cls.XPUB_HEADERS = { - 'standard': 0x0488b21e, # xpub - 'p2wpkh-p2sh': 0x049d7cb2, # ypub - 'p2wsh-p2sh': 0x0295b43f, # Ypub - 'p2wpkh': 0x04b24746, # zpub - 'p2wsh': 0x02aa7ed3, # Zpub - } - - @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.GENESIS = "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943" - cls.DEFAULT_PORTS = {'t':'51001', 's':'51002'} - cls.DEFAULT_SERVERS = read_json('servers_testnet.json', {}) - cls.CHECKPOINTS = read_json('checkpoints_testnet.json', []) - - cls.XPRV_HEADERS = { - 'standard': 0x04358394, # tprv - 'p2wpkh-p2sh': 0x044a4e28, # uprv - 'p2wsh-p2sh': 0x024285b5, # Uprv - 'p2wpkh': 0x045f18bc, # vprv - 'p2wsh': 0x02575048, # Vprv - } - cls.XPUB_HEADERS = { - 'standard': 0x043587cf, # tpub - 'p2wpkh-p2sh': 0x044a5262, # upub - 'p2wsh-p2sh': 0x024285ef, # Upub - 'p2wpkh': 0x045f1cf6, # vpub - 'p2wsh': 0x02575483, # Vpub - } - - -NetworkConstants.set_mainnet() ################################## transactions t@@ -341,16 +274,16 @@ def b58_address_to_hash160(addr): def hash160_to_p2pkh(h160): - return hash160_to_b58_address(h160, NetworkConstants.ADDRTYPE_P2PKH) + return hash160_to_b58_address(h160, constants.net.ADDRTYPE_P2PKH) def hash160_to_p2sh(h160): - return hash160_to_b58_address(h160, NetworkConstants.ADDRTYPE_P2SH) + return hash160_to_b58_address(h160, constants.net.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(NetworkConstants.SEGWIT_HRP, 0, h) + return segwit_addr.encode(constants.net.SEGWIT_HRP, 0, h) def public_key_to_p2wpkh(public_key): return hash_to_segwit_addr(hash_160(public_key)) t@@ -396,7 +329,7 @@ def script_to_address(script): return addr def address_to_script(addr): - witver, witprog = segwit_addr.decode(NetworkConstants.SEGWIT_HRP, addr) + witver, witprog = segwit_addr.decode(constants.net.SEGWIT_HRP, addr) if witprog is not None: assert (0 <= witver <= 16) OP_n = witver + 0x50 if witver > 0 else 0 t@@ -404,11 +337,11 @@ def address_to_script(addr): script += push_script(bh2u(bytes(witprog))) return script addrtype, hash_160 = b58_address_to_hash160(addr) - if addrtype == NetworkConstants.ADDRTYPE_P2PKH: + if addrtype == constants.net.ADDRTYPE_P2PKH: script = '76a9' # op_dup, op_hash_160 script += push_script(bh2u(hash_160)) script += '88ac' # op_equalverify, op_checksig - elif addrtype == NetworkConstants.ADDRTYPE_P2SH: + elif addrtype == constants.net.ADDRTYPE_P2SH: script = 'a9' # op_hash_160 script += push_script(bh2u(hash_160)) script += '87' # op_equal t@@ -526,9 +459,9 @@ SCRIPT_TYPES = { def serialize_privkey(secret, compressed, txin_type, internal_use=False): if internal_use: - prefix = bytes([(SCRIPT_TYPES[txin_type] + NetworkConstants.WIF_PREFIX) & 255]) + prefix = bytes([(SCRIPT_TYPES[txin_type] + constants.net.WIF_PREFIX) & 255]) else: - prefix = bytes([NetworkConstants.WIF_PREFIX]) + prefix = bytes([constants.net.WIF_PREFIX]) suffix = b'\01' if compressed else b'' vchIn = prefix + secret + suffix base58_wif = EncodeBase58Check(vchIn) t@@ -552,9 +485,9 @@ def deserialize_privkey(key): if txin_type is None: # keys exported in version 3.0.x encoded script type in first byte - txin_type = inv_dict(SCRIPT_TYPES)[vch[0] - NetworkConstants.WIF_PREFIX] + txin_type = inv_dict(SCRIPT_TYPES)[vch[0] - constants.net.WIF_PREFIX] else: - assert vch[0] == NetworkConstants.WIF_PREFIX + assert vch[0] == constants.net.WIF_PREFIX assert len(vch) in [33, 34] compressed = len(vch) == 34 t@@ -590,7 +523,7 @@ def address_from_private_key(sec): def is_segwit_address(addr): try: - witver, witprog = segwit_addr.decode(NetworkConstants.SEGWIT_HRP, addr) + witver, witprog = segwit_addr.decode(constants.net.SEGWIT_HRP, addr) except Exception as e: return False return witprog is not None t@@ -600,7 +533,7 @@ def is_b58_address(addr): addrtype, h = b58_address_to_hash160(addr) except Exception as e: return False - if addrtype not in [NetworkConstants.ADDRTYPE_P2PKH, NetworkConstants.ADDRTYPE_P2SH]: + if addrtype not in [constants.net.ADDRTYPE_P2PKH, constants.net.ADDRTYPE_P2SH]: return False return addr == hash160_to_b58_address(h, addrtype) t@@ -912,25 +845,35 @@ def _CKD_pub(cK, c, s): return cK_n, c_n -def xprv_header(xtype): - return bfh("%08x" % NetworkConstants.XPRV_HEADERS[xtype]) +def xprv_header(xtype, *, net=None): + if net is None: + net = constants.net + return bfh("%08x" % net.XPRV_HEADERS[xtype]) -def xpub_header(xtype): - return bfh("%08x" % NetworkConstants.XPUB_HEADERS[xtype]) +def xpub_header(xtype, *, net=None): + if net is None: + net = constants.net + return bfh("%08x" % net.XPUB_HEADERS[xtype]) -def serialize_xprv(xtype, c, k, depth=0, fingerprint=b'\x00'*4, child_number=b'\x00'*4): - xprv = xprv_header(xtype) + bytes([depth]) + fingerprint + child_number + c + bytes([0]) + k +def serialize_xprv(xtype, c, k, depth=0, fingerprint=b'\x00'*4, + child_number=b'\x00'*4, *, net=None): + xprv = xprv_header(xtype, net=net) \ + + bytes([depth]) + fingerprint + child_number + c + bytes([0]) + k return EncodeBase58Check(xprv) -def serialize_xpub(xtype, c, cK, depth=0, fingerprint=b'\x00'*4, child_number=b'\x00'*4): - xpub = xpub_header(xtype) + bytes([depth]) + fingerprint + child_number + c + cK +def serialize_xpub(xtype, c, cK, depth=0, fingerprint=b'\x00'*4, + child_number=b'\x00'*4, *, net=None): + xpub = xpub_header(xtype, net=net) \ + + bytes([depth]) + fingerprint + child_number + c + cK return EncodeBase58Check(xpub) -def deserialize_xkey(xkey, prv): +def deserialize_xkey(xkey, prv, *, net=None): + if net is None: + net = constants.net xkey = DecodeBase58Check(xkey) if len(xkey) != 78: raise BaseException('Invalid length') t@@ -939,7 +882,7 @@ def deserialize_xkey(xkey, prv): child_number = xkey[9:13] c = xkey[13:13+32] header = int('0x' + bh2u(xkey[0:4]), 16) - headers = NetworkConstants.XPRV_HEADERS if prv else NetworkConstants.XPUB_HEADERS + headers = net.XPRV_HEADERS if prv else net.XPUB_HEADERS if header not in headers.values(): raise BaseException('Invalid xpub format', hex(header)) xtype = list(headers.keys())[list(headers.values()).index(header)] t@@ -948,11 +891,11 @@ def deserialize_xkey(xkey, prv): return xtype, depth, fingerprint, child_number, c, K_or_k -def deserialize_xpub(xkey): - return deserialize_xkey(xkey, False) +def deserialize_xpub(xkey, *, net=None): + return deserialize_xkey(xkey, False, net=net) -def deserialize_xprv(xkey): - return deserialize_xkey(xkey, True) +def deserialize_xprv(xkey, *, net=None): + return deserialize_xkey(xkey, True, net=net) def xpub_type(x): return deserialize_xpub(x)[0] (DIR) diff --git a/lib/blockchain.py b/lib/blockchain.py t@@ -25,6 +25,7 @@ import threading from . import util from . import bitcoin +from . import constants from .bitcoin import * MAX_TARGET = 0x00000000FFFF0000000000000000000000000000000000000000000000000000 t@@ -102,7 +103,7 @@ class Blockchain(util.PrintError): self.config = config self.catch_up = None # interface catching up self.checkpoint = checkpoint - self.checkpoints = bitcoin.NetworkConstants.CHECKPOINTS + self.checkpoints = constants.net.CHECKPOINTS self.parent_id = parent_id self.lock = threading.Lock() with self.lock: t@@ -152,7 +153,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.NetworkConstants.TESTNET: + if constants.net.TESTNET: return bits = self.target_to_bits(target) if bits != header.get('bits'): t@@ -262,7 +263,7 @@ class Blockchain(util.PrintError): if height == -1: return '0000000000000000000000000000000000000000000000000000000000000000' elif height == 0: - return bitcoin.NetworkConstants.GENESIS + return constants.net.GENESIS elif height < len(self.checkpoints) * 2016: assert (height+1) % 2016 == 0, height index = height // 2016 t@@ -273,7 +274,7 @@ class Blockchain(util.PrintError): def get_target(self, index): # compute target from chunk x, used in chunk x+1 - if bitcoin.NetworkConstants.TESTNET: + if constants.net.TESTNET: return 0 if index == -1: return MAX_TARGET t@@ -317,7 +318,7 @@ class Blockchain(util.PrintError): #self.print_error("cannot connect at height", height) return False if height == 0: - return hash_header(header) == bitcoin.NetworkConstants.GENESIS + return hash_header(header) == constants.net.GENESIS try: prev_hash = self.get_hash(height - 1) except: (DIR) diff --git a/lib/constants.py b/lib/constants.py t@@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2018 The Electrum developers +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import os +import json + + +def read_json(filename, default): + path = os.path.join(os.path.dirname(__file__), filename) + try: + with open(path, 'r') as f: + r = json.loads(f.read()) + except: + r = default + return r + + +class BitcoinMainnet: + + TESTNET = False + WIF_PREFIX = 0x80 + ADDRTYPE_P2PKH = 0 + ADDRTYPE_P2SH = 5 + SEGWIT_HRP = "bc" + GENESIS = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f" + DEFAULT_PORTS = {'t': '50001', 's': '50002'} + DEFAULT_SERVERS = read_json('servers.json', {}) + CHECKPOINTS = read_json('checkpoints.json', []) + + XPRV_HEADERS = { + 'standard': 0x0488ade4, # xprv + 'p2wpkh-p2sh': 0x049d7878, # yprv + 'p2wsh-p2sh': 0x0295b005, # Yprv + 'p2wpkh': 0x04b2430c, # zprv + 'p2wsh': 0x02aa7a99, # Zprv + } + XPUB_HEADERS = { + 'standard': 0x0488b21e, # xpub + 'p2wpkh-p2sh': 0x049d7cb2, # ypub + 'p2wsh-p2sh': 0x0295b43f, # Ypub + 'p2wpkh': 0x04b24746, # zpub + 'p2wsh': 0x02aa7ed3, # Zpub + } + + +class BitcoinTestnet: + + TESTNET = True + WIF_PREFIX = 0xef + ADDRTYPE_P2PKH = 111 + ADDRTYPE_P2SH = 196 + SEGWIT_HRP = "tb" + GENESIS = "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943" + DEFAULT_PORTS = {'t': '51001', 's': '51002'} + DEFAULT_SERVERS = read_json('servers_testnet.json', {}) + CHECKPOINTS = read_json('checkpoints_testnet.json', []) + + XPRV_HEADERS = { + 'standard': 0x04358394, # tprv + 'p2wpkh-p2sh': 0x044a4e28, # uprv + 'p2wsh-p2sh': 0x024285b5, # Uprv + 'p2wpkh': 0x045f18bc, # vprv + 'p2wsh': 0x02575048, # Vprv + } + XPUB_HEADERS = { + 'standard': 0x043587cf, # tpub + 'p2wpkh-p2sh': 0x044a5262, # upub + 'p2wsh-p2sh': 0x024285ef, # Upub + 'p2wpkh': 0x045f1cf6, # vpub + 'p2wsh': 0x02575483, # Vpub + } + + +# don't import net directly, import the module instead (so that net is singleton) +net = BitcoinMainnet + + +def set_mainnet(): + global net + net = BitcoinMainnet + + +def set_testnet(): + global net + net = BitcoinTestnet (DIR) diff --git a/lib/keystore.py b/lib/keystore.py t@@ -28,7 +28,7 @@ from unicodedata import normalize from . import bitcoin from .bitcoin import * - +from . import constants from .util import PrintError, InvalidPassword, hfu from .mnemonic import Mnemonic, load_wordlist from .plugins import run_hook t@@ -688,7 +688,7 @@ is_bip32_key = lambda x: is_xprv(x) or is_xpub(x) def bip44_derivation(account_id, bip43_purpose=44): - coin = 1 if bitcoin.NetworkConstants.TESTNET else 0 + coin = 1 if constants.net.TESTNET else 0 return "m/%d'/%d'/%d'" % (bip43_purpose, coin, int(account_id)) def from_seed(seed, passphrase, is_p2sh): (DIR) diff --git a/lib/network.py b/lib/network.py t@@ -37,6 +37,7 @@ import socks from . import util from . import bitcoin from .bitcoin import * +from . import constants from .interface import Connection, Interface from . import blockchain from .version import ELECTRUM_VERSION, PROTOCOL_VERSION t@@ -60,7 +61,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.NetworkConstants.DEFAULT_PORTS[protocol] + if port == '': port = constants.net.DEFAULT_PORTS[protocol] out[protocol] = port elif re.match("v(.?)+", v): version = v[1:] t@@ -94,7 +95,7 @@ def filter_protocol(hostmap, protocol = 's'): def pick_random_server(hostmap = None, protocol = 's', exclude_set = set()): if hostmap is None: - hostmap = bitcoin.NetworkConstants.DEFAULT_SERVERS + hostmap = constants.net.DEFAULT_SERVERS eligible = list(set(filter_protocol(hostmap, protocol)) - exclude_set) return random.choice(eligible) if eligible else None t@@ -364,7 +365,7 @@ class Network(util.DaemonThread): return list(self.interfaces.keys()) def get_servers(self): - out = bitcoin.NetworkConstants.DEFAULT_SERVERS + out = constants.net.DEFAULT_SERVERS if self.irc_servers: out.update(filter_version(self.irc_servers.copy())) else: t@@ -967,7 +968,7 @@ class Network(util.DaemonThread): def init_headers_file(self): b = self.blockchains[0] filename = b.path() - length = 80 * len(bitcoin.NetworkConstants.CHECKPOINTS) * 2016 + length = 80 * len(constants.net.CHECKPOINTS) * 2016 if not os.path.exists(filename) or os.path.getsize(filename) < length: with open(filename, 'wb') as f: if length>0: t@@ -1092,4 +1093,4 @@ class Network(util.DaemonThread): f.write(json.dumps(cp, indent=4)) def max_checkpoint(self): - return max(0, len(bitcoin.NetworkConstants.CHECKPOINTS) * 2016 - 1) + return max(0, len(constants.net.CHECKPOINTS) * 2016 - 1) (DIR) diff --git a/lib/tests/test_bitcoin.py b/lib/tests/test_bitcoin.py t@@ -11,8 +11,9 @@ from lib.bitcoin import ( var_int, op_push, address_to_script, regenerate_key, verify_message, deserialize_privkey, serialize_privkey, is_segwit_address, is_b58_address, address_to_scripthash, is_minikey, is_compressed, is_xpub, - xpub_type, is_xprv, is_bip32_derivation, seed_type, NetworkConstants) + xpub_type, is_xprv, is_bip32_derivation, seed_type) from lib.util import bfh +from lib import constants try: import ecdsa t@@ -168,12 +169,12 @@ class Test_bitcoin_testnet(unittest.TestCase): @classmethod def setUpClass(cls): super().setUpClass() - NetworkConstants.set_testnet() + constants.set_testnet() @classmethod def tearDownClass(cls): super().tearDownClass() - NetworkConstants.set_mainnet() + constants.set_mainnet() def test_address_to_script(self): # bech32 native segwit (DIR) diff --git a/lib/util.py b/lib/util.py t@@ -530,8 +530,8 @@ testnet_block_explorers = { } def block_explorer_info(): - from . import bitcoin - return testnet_block_explorers if bitcoin.NetworkConstants.TESTNET else mainnet_block_explorers + from . import constants + return testnet_block_explorers if constants.net.TESTNET else mainnet_block_explorers def block_explorer(config): return config.get('block_explorer', 'Blocktrail.com') (DIR) diff --git a/plugins/digitalbitbox/digitalbitbox.py b/plugins/digitalbitbox/digitalbitbox.py t@@ -7,6 +7,7 @@ try: import electrum from electrum.bitcoin import TYPE_ADDRESS, push_script, var_int, msg_magic, Hash, verify_message, pubkey_from_signature, point_to_ser, public_key_to_p2pkh, EncodeAES, DecodeAES, MyVerifyingKey from electrum.bitcoin import serialize_xpub, deserialize_xpub + from electrum import constants from electrum.transaction import Transaction from electrum.i18n import _ from electrum.keystore import Hardware_KeyStore t@@ -92,10 +93,10 @@ class DigitalBitbox_Client(): if reply: xpub = reply['xpub'] # Change type of xpub to the requested type. The firmware - # only ever returns the standard type, but it is agnostic + # only ever returns the mainnet standard type, but it is agnostic # to the type when signing. - if xtype != 'standard': - _, depth, fingerprint, child_number, c, cK = deserialize_xpub(xpub) + if xtype != 'standard' or constants.net.TESTNET: + _, depth, fingerprint, child_number, c, cK = deserialize_xpub(xpub, net=constants.BitcoinMainnet) xpub = serialize_xpub(xtype, c, cK, depth, fingerprint, child_number) return xpub else: (DIR) diff --git a/plugins/keepkey/plugin.py b/plugins/keepkey/plugin.py t@@ -4,8 +4,9 @@ from binascii import hexlify, unhexlify from electrum.util import bfh, bh2u from electrum.bitcoin import (b58_address_to_hash160, xpub_from_pubkey, - TYPE_ADDRESS, TYPE_SCRIPT, NetworkConstants, + TYPE_ADDRESS, TYPE_SCRIPT, is_segwit_address) +from electrum import constants from electrum.i18n import _ from electrum.plugins import BasePlugin from electrum.transaction import deserialize t@@ -139,7 +140,7 @@ class KeepKeyCompatiblePlugin(HW_PluginBase): return client def get_coin_name(self): - return "Testnet" if NetworkConstants.TESTNET else "Bitcoin" + return "Testnet" if constants.net.TESTNET else "Bitcoin" def initialize_device(self, device_id, wizard, handler): # Initialization method t@@ -344,9 +345,9 @@ class KeepKeyCompatiblePlugin(HW_PluginBase): txoutputtype.script_type = self.types.PAYTOWITNESS else: addrtype, hash_160 = b58_address_to_hash160(address) - if addrtype == NetworkConstants.ADDRTYPE_P2PKH: + if addrtype == constants.net.ADDRTYPE_P2PKH: txoutputtype.script_type = self.types.PAYTOADDRESS - elif addrtype == NetworkConstants.ADDRTYPE_P2SH: + elif addrtype == constants.net.ADDRTYPE_P2SH: txoutputtype.script_type = self.types.PAYTOSCRIPTHASH else: raise BaseException('addrtype: ' + str(addrtype)) (DIR) diff --git a/plugins/trezor/trezor.py b/plugins/trezor/trezor.py t@@ -4,7 +4,8 @@ from binascii import hexlify, unhexlify from electrum.util import bfh, bh2u, versiontuple from electrum.bitcoin import (b58_address_to_hash160, xpub_from_pubkey, - TYPE_ADDRESS, TYPE_SCRIPT, NetworkConstants) + TYPE_ADDRESS, TYPE_SCRIPT) +from electrum import constants from electrum.i18n import _ from electrum.plugins import BasePlugin, Device from electrum.transaction import deserialize t@@ -173,7 +174,7 @@ class TrezorPlugin(HW_PluginBase): return client def get_coin_name(self): - return "Testnet" if NetworkConstants.TESTNET else "Bitcoin" + return "Testnet" if constants.net.TESTNET else "Bitcoin" def initialize_device(self, device_id, wizard, handler): # Initialization method (DIR) diff --git a/plugins/trustedcoin/trustedcoin.py b/plugins/trustedcoin/trustedcoin.py t@@ -32,6 +32,7 @@ from urllib.parse import quote import electrum from electrum import bitcoin +from electrum import constants from electrum import keystore from electrum.bitcoin import * from electrum.mnemonic import Mnemonic t@@ -44,13 +45,13 @@ from electrum.storage import STO_EV_USER_PW # signing_xpub is hardcoded so that the wallet can be restored from seed, without TrustedCoin's server def get_signing_xpub(): - if NetworkConstants.TESTNET: + if constants.net.TESTNET: return "tpubD6NzVbkrYhZ4XdmyJQcCPjQfg6RXVUzGFhPjZ7uvRC8JLcS7Hw1i7UTpyhp9grHpak4TyK2hzBJrujDVLXQ6qB5tNpVx9rC6ixijUXadnmY" else: return "xpub661MyMwAqRbcGnMkaTx2594P9EDuiEqMq25PM2aeG6UmwzaohgA6uDmNsvSUV8ubqwA3Wpste1hg69XHgjUuCD5HLcEp2QPzyV1HMrPppsL" def get_billing_xpub(): - if NetworkConstants.TESTNET: + if constants.net.TESTNET: return "tpubD6NzVbkrYhZ4X11EJFTJujsYbUmVASAYY7gXsEt4sL97AMBdypiH1E9ZVTpdXXEy3Kj9Eqd1UkxdGtvDt5z23DKsh6211CfNJo8bLLyem5r" else: return "xpub6DTBdtBB8qUmH5c77v8qVGVoYk7WjJNpGvutqjLasNG1mbux6KsojaLrYf2sRhXAVU4NaFuHhbD9SvVPRt1MB1MaMooRuhHcAZH1yhQ1qDU"