refactor network constants

This commit is contained in:
SomberNight 2018-03-04 22:10:59 +01:00
parent 10057b18de
commit 81b6d65764
16 changed files with 191 additions and 132 deletions

View File

@ -89,6 +89,7 @@ if is_local or is_android:
from electrum import bitcoin, util from electrum import bitcoin, util
from electrum import constants
from electrum import SimpleConfig, Network from electrum import SimpleConfig, Network
from electrum.wallet import Wallet, Imported_Wallet from electrum.wallet import Wallet, Imported_Wallet
from electrum.storage import WalletStorage, get_derivation_used_for_hw_device_encryption from electrum.storage import WalletStorage, get_derivation_used_for_hw_device_encryption
@ -411,7 +412,7 @@ if __name__ == '__main__':
cmdname = config.get('cmd') cmdname = config.get('cmd')
if config.get('testnet'): if config.get('testnet'):
bitcoin.NetworkConstants.set_testnet() constants.set_testnet()
# run non-RPC commands separately # run non-RPC commands separately
if cmdname in ['create', 'restore']: if cmdname in ['create', 'restore']:

View File

@ -99,8 +99,8 @@ class ElectrumWindow(App):
from .uix.dialogs.choice_dialog import ChoiceDialog from .uix.dialogs.choice_dialog import ChoiceDialog
protocol = 's' protocol = 's'
def cb2(host): def cb2(host):
from electrum.bitcoin import NetworkConstants from electrum import constants
pp = servers.get(host, NetworkConstants.DEFAULT_PORTS) pp = servers.get(host, constants.net.DEFAULT_PORTS)
port = pp.get(protocol, '') port = pp.get(protocol, '')
popup.ids.host.text = host popup.ids.host.text = host
popup.ids.port.text = port popup.ids.port.text = port

View File

@ -36,7 +36,7 @@ from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import * from PyQt5.QtWidgets import *
from electrum.i18n import _ from electrum.i18n import _
from electrum import ELECTRUM_VERSION, bitcoin from electrum import ELECTRUM_VERSION, bitcoin, constants
issue_template = """<h2>Traceback</h2> issue_template = """<h2>Traceback</h2>
<pre> <pre>
@ -107,7 +107,7 @@ class Exception_Window(QWidget):
self.show() self.show()
def send_report(self): 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. # Gah! Some kind of altcoin wants to send us crash reports.
self.main_window.show_critical(_("Please report this issue manually.")) self.main_window.show_critical(_("Please report this issue manually."))
return return

View File

@ -40,7 +40,8 @@ from .exception_window import Exception_Hook
from PyQt5.QtWidgets import * from PyQt5.QtWidgets import *
from electrum import keystore, simple_config 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.plugins import run_hook
from electrum.i18n import _ from electrum.i18n import _
from electrum.util import (format_time, format_satoshis, PrintError, from electrum.util import (format_time, format_satoshis, PrintError,
@ -371,7 +372,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
self.setGeometry(100, 100, 840, 400) self.setGeometry(100, 100, 840, 400)
def watching_only_changed(self): 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, title = '%s %s - %s' % (name, self.wallet.electrum_version,
self.wallet.basename()) self.wallet.basename())
extra = [self.wallet.storage.get('wallet_type', '?')] extra = [self.wallet.storage.get('wallet_type', '?')]

View File

@ -31,7 +31,7 @@ from PyQt5.QtWidgets import *
import PyQt5.QtCore as QtCore import PyQt5.QtCore as QtCore
from electrum.i18n import _ from electrum.i18n import _
from electrum.bitcoin import NetworkConstants from electrum import constants
from electrum.util import print_error from electrum.util import print_error
from electrum.network import serialize_server, deserialize_server from electrum.network import serialize_server, deserialize_server
@ -393,7 +393,7 @@ class NetworkChoiceLayout(object):
def change_protocol(self, use_ssl): def change_protocol(self, use_ssl):
p = 's' if use_ssl else 't' p = 's' if use_ssl else 't'
host = self.server_host.text() 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(): if p not in pp.keys():
p = list(pp.keys())[0] p = list(pp.keys())[0]
port = pp[p] port = pp[p]
@ -418,7 +418,7 @@ class NetworkChoiceLayout(object):
self.change_server(str(x.text(0)), self.protocol) self.change_server(str(x.text(0)), self.protocol)
def change_server(self, host, 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: if protocol and protocol not in protocol_letters:
protocol = None protocol = None
if protocol: if protocol:

View File

@ -36,75 +36,8 @@ from .util import bfh, bh2u, to_string
from . import version from . import version
from .util import print_error, InvalidPassword, assert_bytes, to_bytes, inv_dict from .util import print_error, InvalidPassword, assert_bytes, to_bytes, inv_dict
from . import segwit_addr 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 ################################## transactions
@ -341,16 +274,16 @@ def b58_address_to_hash160(addr):
def hash160_to_p2pkh(h160): 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): 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): def public_key_to_p2pkh(public_key):
return hash160_to_p2pkh(hash_160(public_key)) return hash160_to_p2pkh(hash_160(public_key))
def hash_to_segwit_addr(h): 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): def public_key_to_p2wpkh(public_key):
return hash_to_segwit_addr(hash_160(public_key)) return hash_to_segwit_addr(hash_160(public_key))
@ -396,7 +329,7 @@ def script_to_address(script):
return addr return addr
def address_to_script(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: if witprog is not None:
assert (0 <= witver <= 16) assert (0 <= witver <= 16)
OP_n = witver + 0x50 if witver > 0 else 0 OP_n = witver + 0x50 if witver > 0 else 0
@ -404,11 +337,11 @@ def address_to_script(addr):
script += push_script(bh2u(bytes(witprog))) script += push_script(bh2u(bytes(witprog)))
return script return script
addrtype, hash_160 = b58_address_to_hash160(addr) 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 = '76a9' # op_dup, op_hash_160
script += push_script(bh2u(hash_160)) script += push_script(bh2u(hash_160))
script += '88ac' # op_equalverify, op_checksig script += '88ac' # op_equalverify, op_checksig
elif addrtype == NetworkConstants.ADDRTYPE_P2SH: elif addrtype == constants.net.ADDRTYPE_P2SH:
script = 'a9' # op_hash_160 script = 'a9' # op_hash_160
script += push_script(bh2u(hash_160)) script += push_script(bh2u(hash_160))
script += '87' # op_equal script += '87' # op_equal
@ -526,9 +459,9 @@ SCRIPT_TYPES = {
def serialize_privkey(secret, compressed, txin_type, internal_use=False): def serialize_privkey(secret, compressed, txin_type, internal_use=False):
if internal_use: 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: else:
prefix = bytes([NetworkConstants.WIF_PREFIX]) prefix = bytes([constants.net.WIF_PREFIX])
suffix = b'\01' if compressed else b'' suffix = b'\01' if compressed else b''
vchIn = prefix + secret + suffix vchIn = prefix + secret + suffix
base58_wif = EncodeBase58Check(vchIn) base58_wif = EncodeBase58Check(vchIn)
@ -552,9 +485,9 @@ def deserialize_privkey(key):
if txin_type is None: if txin_type is None:
# keys exported in version 3.0.x encoded script type in first byte # 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: else:
assert vch[0] == NetworkConstants.WIF_PREFIX assert vch[0] == constants.net.WIF_PREFIX
assert len(vch) in [33, 34] assert len(vch) in [33, 34]
compressed = len(vch) == 34 compressed = len(vch) == 34
@ -590,7 +523,7 @@ def address_from_private_key(sec):
def is_segwit_address(addr): def is_segwit_address(addr):
try: try:
witver, witprog = segwit_addr.decode(NetworkConstants.SEGWIT_HRP, addr) witver, witprog = segwit_addr.decode(constants.net.SEGWIT_HRP, addr)
except Exception as e: except Exception as e:
return False return False
return witprog is not None return witprog is not None
@ -600,7 +533,7 @@ def is_b58_address(addr):
addrtype, h = b58_address_to_hash160(addr) addrtype, h = b58_address_to_hash160(addr)
except Exception as e: except Exception as e:
return False 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 False
return addr == hash160_to_b58_address(h, addrtype) return addr == hash160_to_b58_address(h, addrtype)
@ -912,25 +845,35 @@ def _CKD_pub(cK, c, s):
return cK_n, c_n return cK_n, c_n
def xprv_header(xtype): def xprv_header(xtype, *, net=None):
return bfh("%08x" % NetworkConstants.XPRV_HEADERS[xtype]) if net is None:
net = constants.net
return bfh("%08x" % net.XPRV_HEADERS[xtype])
def xpub_header(xtype): def xpub_header(xtype, *, net=None):
return bfh("%08x" % NetworkConstants.XPUB_HEADERS[xtype]) 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): def serialize_xprv(xtype, c, k, depth=0, fingerprint=b'\x00'*4,
xprv = xprv_header(xtype) + bytes([depth]) + fingerprint + child_number + c + bytes([0]) + k 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) return EncodeBase58Check(xprv)
def serialize_xpub(xtype, c, cK, depth=0, fingerprint=b'\x00'*4, child_number=b'\x00'*4): def serialize_xpub(xtype, c, cK, depth=0, fingerprint=b'\x00'*4,
xpub = xpub_header(xtype) + bytes([depth]) + fingerprint + child_number + c + cK child_number=b'\x00'*4, *, net=None):
xpub = xpub_header(xtype, net=net) \
+ bytes([depth]) + fingerprint + child_number + c + cK
return EncodeBase58Check(xpub) 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) xkey = DecodeBase58Check(xkey)
if len(xkey) != 78: if len(xkey) != 78:
raise BaseException('Invalid length') raise BaseException('Invalid length')
@ -939,7 +882,7 @@ def deserialize_xkey(xkey, prv):
child_number = xkey[9:13] child_number = xkey[9:13]
c = xkey[13:13+32] c = xkey[13:13+32]
header = int('0x' + bh2u(xkey[0:4]), 16) 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(): if header not in headers.values():
raise BaseException('Invalid xpub format', hex(header)) raise BaseException('Invalid xpub format', hex(header))
xtype = list(headers.keys())[list(headers.values()).index(header)] xtype = list(headers.keys())[list(headers.values()).index(header)]
@ -948,11 +891,11 @@ def deserialize_xkey(xkey, prv):
return xtype, depth, fingerprint, child_number, c, K_or_k return xtype, depth, fingerprint, child_number, c, K_or_k
def deserialize_xpub(xkey): def deserialize_xpub(xkey, *, net=None):
return deserialize_xkey(xkey, False) return deserialize_xkey(xkey, False, net=net)
def deserialize_xprv(xkey): def deserialize_xprv(xkey, *, net=None):
return deserialize_xkey(xkey, True) return deserialize_xkey(xkey, True, net=net)
def xpub_type(x): def xpub_type(x):
return deserialize_xpub(x)[0] return deserialize_xpub(x)[0]

View File

@ -25,6 +25,7 @@ import threading
from . import util from . import util
from . import bitcoin from . import bitcoin
from . import constants
from .bitcoin import * from .bitcoin import *
MAX_TARGET = 0x00000000FFFF0000000000000000000000000000000000000000000000000000 MAX_TARGET = 0x00000000FFFF0000000000000000000000000000000000000000000000000000
@ -102,7 +103,7 @@ class Blockchain(util.PrintError):
self.config = config self.config = config
self.catch_up = None # interface catching up self.catch_up = None # interface catching up
self.checkpoint = checkpoint self.checkpoint = checkpoint
self.checkpoints = bitcoin.NetworkConstants.CHECKPOINTS self.checkpoints = constants.net.CHECKPOINTS
self.parent_id = parent_id self.parent_id = parent_id
self.lock = threading.Lock() self.lock = threading.Lock()
with self.lock: with self.lock:
@ -152,7 +153,7 @@ class Blockchain(util.PrintError):
_hash = hash_header(header) _hash = hash_header(header)
if prev_hash != header.get('prev_block_hash'): if prev_hash != header.get('prev_block_hash'):
raise BaseException("prev hash mismatch: %s vs %s" % (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 return
bits = self.target_to_bits(target) bits = self.target_to_bits(target)
if bits != header.get('bits'): if bits != header.get('bits'):
@ -262,7 +263,7 @@ class Blockchain(util.PrintError):
if height == -1: if height == -1:
return '0000000000000000000000000000000000000000000000000000000000000000' return '0000000000000000000000000000000000000000000000000000000000000000'
elif height == 0: elif height == 0:
return bitcoin.NetworkConstants.GENESIS return constants.net.GENESIS
elif height < len(self.checkpoints) * 2016: elif height < len(self.checkpoints) * 2016:
assert (height+1) % 2016 == 0, height assert (height+1) % 2016 == 0, height
index = height // 2016 index = height // 2016
@ -273,7 +274,7 @@ class Blockchain(util.PrintError):
def get_target(self, index): def get_target(self, index):
# compute target from chunk x, used in chunk x+1 # compute target from chunk x, used in chunk x+1
if bitcoin.NetworkConstants.TESTNET: if constants.net.TESTNET:
return 0 return 0
if index == -1: if index == -1:
return MAX_TARGET return MAX_TARGET
@ -317,7 +318,7 @@ class Blockchain(util.PrintError):
#self.print_error("cannot connect at height", height) #self.print_error("cannot connect at height", height)
return False return False
if height == 0: if height == 0:
return hash_header(header) == bitcoin.NetworkConstants.GENESIS return hash_header(header) == constants.net.GENESIS
try: try:
prev_hash = self.get_hash(height - 1) prev_hash = self.get_hash(height - 1)
except: except:

107
lib/constants.py Normal file
View File

@ -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

View File

@ -28,7 +28,7 @@ from unicodedata import normalize
from . import bitcoin from . import bitcoin
from .bitcoin import * from .bitcoin import *
from . import constants
from .util import PrintError, InvalidPassword, hfu from .util import PrintError, InvalidPassword, hfu
from .mnemonic import Mnemonic, load_wordlist from .mnemonic import Mnemonic, load_wordlist
from .plugins import run_hook from .plugins import run_hook
@ -688,7 +688,7 @@ is_bip32_key = lambda x: is_xprv(x) or is_xpub(x)
def bip44_derivation(account_id, bip43_purpose=44): 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)) return "m/%d'/%d'/%d'" % (bip43_purpose, coin, int(account_id))
def from_seed(seed, passphrase, is_p2sh): def from_seed(seed, passphrase, is_p2sh):

View File

@ -37,6 +37,7 @@ import socks
from . import util from . import util
from . import bitcoin from . import bitcoin
from .bitcoin import * from .bitcoin import *
from . import constants
from .interface import Connection, Interface from .interface import Connection, Interface
from . import blockchain from . import blockchain
from .version import ELECTRUM_VERSION, PROTOCOL_VERSION from .version import ELECTRUM_VERSION, PROTOCOL_VERSION
@ -60,7 +61,7 @@ def parse_servers(result):
for v in item[2]: for v in item[2]:
if re.match("[st]\d*", v): if re.match("[st]\d*", v):
protocol, port = v[0], v[1:] 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 out[protocol] = port
elif re.match("v(.?)+", v): elif re.match("v(.?)+", v):
version = v[1:] version = v[1:]
@ -94,7 +95,7 @@ def filter_protocol(hostmap, protocol = 's'):
def pick_random_server(hostmap = None, protocol = 's', exclude_set = set()): def pick_random_server(hostmap = None, protocol = 's', exclude_set = set()):
if hostmap is None: if hostmap is None:
hostmap = bitcoin.NetworkConstants.DEFAULT_SERVERS hostmap = constants.net.DEFAULT_SERVERS
eligible = list(set(filter_protocol(hostmap, protocol)) - exclude_set) eligible = list(set(filter_protocol(hostmap, protocol)) - exclude_set)
return random.choice(eligible) if eligible else None return random.choice(eligible) if eligible else None
@ -364,7 +365,7 @@ class Network(util.DaemonThread):
return list(self.interfaces.keys()) return list(self.interfaces.keys())
def get_servers(self): def get_servers(self):
out = bitcoin.NetworkConstants.DEFAULT_SERVERS out = constants.net.DEFAULT_SERVERS
if self.irc_servers: if self.irc_servers:
out.update(filter_version(self.irc_servers.copy())) out.update(filter_version(self.irc_servers.copy()))
else: else:
@ -967,7 +968,7 @@ class Network(util.DaemonThread):
def init_headers_file(self): def init_headers_file(self):
b = self.blockchains[0] b = self.blockchains[0]
filename = b.path() 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: if not os.path.exists(filename) or os.path.getsize(filename) < length:
with open(filename, 'wb') as f: with open(filename, 'wb') as f:
if length>0: if length>0:
@ -1092,4 +1093,4 @@ class Network(util.DaemonThread):
f.write(json.dumps(cp, indent=4)) f.write(json.dumps(cp, indent=4))
def max_checkpoint(self): def max_checkpoint(self):
return max(0, len(bitcoin.NetworkConstants.CHECKPOINTS) * 2016 - 1) return max(0, len(constants.net.CHECKPOINTS) * 2016 - 1)

View File

@ -11,8 +11,9 @@ from lib.bitcoin import (
var_int, op_push, address_to_script, regenerate_key, var_int, op_push, address_to_script, regenerate_key,
verify_message, deserialize_privkey, serialize_privkey, is_segwit_address, verify_message, deserialize_privkey, serialize_privkey, is_segwit_address,
is_b58_address, address_to_scripthash, is_minikey, is_compressed, is_xpub, 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.util import bfh
from lib import constants
try: try:
import ecdsa import ecdsa
@ -168,12 +169,12 @@ class Test_bitcoin_testnet(unittest.TestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
super().setUpClass() super().setUpClass()
NetworkConstants.set_testnet() constants.set_testnet()
@classmethod @classmethod
def tearDownClass(cls): def tearDownClass(cls):
super().tearDownClass() super().tearDownClass()
NetworkConstants.set_mainnet() constants.set_mainnet()
def test_address_to_script(self): def test_address_to_script(self):
# bech32 native segwit # bech32 native segwit

View File

@ -530,8 +530,8 @@ testnet_block_explorers = {
} }
def block_explorer_info(): def block_explorer_info():
from . import bitcoin from . import constants
return testnet_block_explorers if bitcoin.NetworkConstants.TESTNET else mainnet_block_explorers return testnet_block_explorers if constants.net.TESTNET else mainnet_block_explorers
def block_explorer(config): def block_explorer(config):
return config.get('block_explorer', 'Blocktrail.com') return config.get('block_explorer', 'Blocktrail.com')

View File

@ -7,6 +7,7 @@ try:
import electrum 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 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.bitcoin import serialize_xpub, deserialize_xpub
from electrum import constants
from electrum.transaction import Transaction from electrum.transaction import Transaction
from electrum.i18n import _ from electrum.i18n import _
from electrum.keystore import Hardware_KeyStore from electrum.keystore import Hardware_KeyStore
@ -92,10 +93,10 @@ class DigitalBitbox_Client():
if reply: if reply:
xpub = reply['xpub'] xpub = reply['xpub']
# Change type of xpub to the requested type. The firmware # 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. # to the type when signing.
if xtype != 'standard': if xtype != 'standard' or constants.net.TESTNET:
_, depth, fingerprint, child_number, c, cK = deserialize_xpub(xpub) _, depth, fingerprint, child_number, c, cK = deserialize_xpub(xpub, net=constants.BitcoinMainnet)
xpub = serialize_xpub(xtype, c, cK, depth, fingerprint, child_number) xpub = serialize_xpub(xtype, c, cK, depth, fingerprint, child_number)
return xpub return xpub
else: else:

View File

@ -4,8 +4,9 @@ from binascii import hexlify, unhexlify
from electrum.util import bfh, bh2u from electrum.util import bfh, bh2u
from electrum.bitcoin import (b58_address_to_hash160, xpub_from_pubkey, from electrum.bitcoin import (b58_address_to_hash160, xpub_from_pubkey,
TYPE_ADDRESS, TYPE_SCRIPT, NetworkConstants, TYPE_ADDRESS, TYPE_SCRIPT,
is_segwit_address) is_segwit_address)
from electrum import constants
from electrum.i18n import _ from electrum.i18n import _
from electrum.plugins import BasePlugin from electrum.plugins import BasePlugin
from electrum.transaction import deserialize from electrum.transaction import deserialize
@ -139,7 +140,7 @@ class KeepKeyCompatiblePlugin(HW_PluginBase):
return client return client
def get_coin_name(self): 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): def initialize_device(self, device_id, wizard, handler):
# Initialization method # Initialization method
@ -344,9 +345,9 @@ class KeepKeyCompatiblePlugin(HW_PluginBase):
txoutputtype.script_type = self.types.PAYTOWITNESS txoutputtype.script_type = self.types.PAYTOWITNESS
else: else:
addrtype, hash_160 = b58_address_to_hash160(address) 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 txoutputtype.script_type = self.types.PAYTOADDRESS
elif addrtype == NetworkConstants.ADDRTYPE_P2SH: elif addrtype == constants.net.ADDRTYPE_P2SH:
txoutputtype.script_type = self.types.PAYTOSCRIPTHASH txoutputtype.script_type = self.types.PAYTOSCRIPTHASH
else: else:
raise BaseException('addrtype: ' + str(addrtype)) raise BaseException('addrtype: ' + str(addrtype))

View File

@ -4,7 +4,8 @@ from binascii import hexlify, unhexlify
from electrum.util import bfh, bh2u, versiontuple from electrum.util import bfh, bh2u, versiontuple
from electrum.bitcoin import (b58_address_to_hash160, xpub_from_pubkey, 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.i18n import _
from electrum.plugins import BasePlugin, Device from electrum.plugins import BasePlugin, Device
from electrum.transaction import deserialize from electrum.transaction import deserialize
@ -173,7 +174,7 @@ class TrezorPlugin(HW_PluginBase):
return client return client
def get_coin_name(self): 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): def initialize_device(self, device_id, wizard, handler):
# Initialization method # Initialization method

View File

@ -32,6 +32,7 @@ from urllib.parse import quote
import electrum import electrum
from electrum import bitcoin from electrum import bitcoin
from electrum import constants
from electrum import keystore from electrum import keystore
from electrum.bitcoin import * from electrum.bitcoin import *
from electrum.mnemonic import Mnemonic from electrum.mnemonic import Mnemonic
@ -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 # signing_xpub is hardcoded so that the wallet can be restored from seed, without TrustedCoin's server
def get_signing_xpub(): def get_signing_xpub():
if NetworkConstants.TESTNET: if constants.net.TESTNET:
return "tpubD6NzVbkrYhZ4XdmyJQcCPjQfg6RXVUzGFhPjZ7uvRC8JLcS7Hw1i7UTpyhp9grHpak4TyK2hzBJrujDVLXQ6qB5tNpVx9rC6ixijUXadnmY" return "tpubD6NzVbkrYhZ4XdmyJQcCPjQfg6RXVUzGFhPjZ7uvRC8JLcS7Hw1i7UTpyhp9grHpak4TyK2hzBJrujDVLXQ6qB5tNpVx9rC6ixijUXadnmY"
else: else:
return "xpub661MyMwAqRbcGnMkaTx2594P9EDuiEqMq25PM2aeG6UmwzaohgA6uDmNsvSUV8ubqwA3Wpste1hg69XHgjUuCD5HLcEp2QPzyV1HMrPppsL" return "xpub661MyMwAqRbcGnMkaTx2594P9EDuiEqMq25PM2aeG6UmwzaohgA6uDmNsvSUV8ubqwA3Wpste1hg69XHgjUuCD5HLcEp2QPzyV1HMrPppsL"
def get_billing_xpub(): def get_billing_xpub():
if NetworkConstants.TESTNET: if constants.net.TESTNET:
return "tpubD6NzVbkrYhZ4X11EJFTJujsYbUmVASAYY7gXsEt4sL97AMBdypiH1E9ZVTpdXXEy3Kj9Eqd1UkxdGtvDt5z23DKsh6211CfNJo8bLLyem5r" return "tpubD6NzVbkrYhZ4X11EJFTJujsYbUmVASAYY7gXsEt4sL97AMBdypiH1E9ZVTpdXXEy3Kj9Eqd1UkxdGtvDt5z23DKsh6211CfNJo8bLLyem5r"
else: else:
return "xpub6DTBdtBB8qUmH5c77v8qVGVoYk7WjJNpGvutqjLasNG1mbux6KsojaLrYf2sRhXAVU4NaFuHhbD9SvVPRt1MB1MaMooRuhHcAZH1yhQ1qDU" return "xpub6DTBdtBB8qUmH5c77v8qVGVoYk7WjJNpGvutqjLasNG1mbux6KsojaLrYf2sRhXAVU4NaFuHhbD9SvVPRt1MB1MaMooRuhHcAZH1yhQ1qDU"