From b4f8cd8746e89f0ad714e5a40ba69d785400f64b Mon Sep 17 00:00:00 2001 From: zebra-lucky Date: Sun, 11 Mar 2018 01:40:56 +0200 Subject: [PATCH] remove segwit from plugins/gui/RELEASE-NOTES/main --- RELEASE-NOTES | 53 ------------------ electrum | 2 +- gui/qt/main_window.py | 4 +- plugins/digitalbitbox/digitalbitbox.py | 2 +- plugins/keepkey/plugin.py | 40 ++++++-------- plugins/ledger/ledger.py | 74 ++++---------------------- plugins/trezor/plugin.py | 22 ++++---- 7 files changed, 38 insertions(+), 159 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 2a06061e..4a9b99f6 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -22,10 +22,8 @@ issue #3374. Users should upgrade to 3.0.5. * Qt GUI: sweeping now uses the Send tab, allowing fees to be set * Windows: if using the installer binary, there is now a separate shortcut for "Electrum Testnet" - * Digital Bitbox: added suport for p2sh-segwit * OS notifications for incoming transactions * better transaction size estimation: - - fees for segwit txns were somewhat underestimated (#3347) - some multisig txns were underestimated - handle uncompressed pubkeys * fix #3321: testnet for Windows binaries @@ -39,7 +37,6 @@ issue #3374. Users should upgrade to 3.0.5. * sweeping minikeys: search for both compressed and uncompressed pubkeys * fix wizard crash when attempting to reset Google Authenticator - * fix #3248: fix Ledger+segwit signing * fix #3262: fix SSL payment request signing * other minor fixes. @@ -53,55 +50,6 @@ issue #3374. Users should upgrade to 3.0.5. run "python3 setup.py install" in order to install the new dependencies. - * Segwit support: - - - Native segwit scripts are supported using a new type of - seed. The version number for segwit seeds is 0x100. The install - wizard will not create segwit seeds by default; users must - opt-in with the segwit option. - - - Native segwit scripts are represented using bech32 addresses, - following BIP173. Please note that BIP173 is still in draft - status, and that other wallets/websites may not support - it. Thus, you should keep a non-segwit wallet in order to be - able to receive bitcoins during the transition period. If BIP173 - ends up being rejected or substantially modified, your wallet - may have to be restored from seed. This will not affect funds - sent to bech32 addresses, and it will not affect the capacity of - Electrum to spend these funds. - - - Segwit scripts embedded in p2sh are supported with hardware - wallets or bip39 seeds. To create a segwit-in-p2sh wallet, - trezor/ledger users will need to enter a BIP49 derivation path. - - - The BIP32 master keys of segwit wallets are serialized using new - version numbers. The new version numbers encode the script type, - and they result in the following prefixes: - - * xpub/xprv : p2pkh or p2sh - * ypub/yprv : p2wpkh-in-p2sh - * Ypub/Yprv : p2wsh-in-p2sh - * zpub/zprv : p2wpkh - * Zpub/Zprv : p2wsh - - These values are identical for mainnet and testnet; tpub/tprv - prefixes are no longer used in testnet wallets. - - - The Wallet Import Format (WIF) is similarly extended for segwit - scripts. After a base58-encoded key is decoded to binary, its - first byte encodes the script type: - - * 128 + 0: p2pkh - * 128 + 1: p2wpkh - * 128 + 2: p2wpkh-in-p2sh - * 128 + 5: p2sh - * 128 + 6: p2wsh - * 128 + 7: p2wsh-in-p2sh - - The distinction between p2sh and p2pkh in private key means that - it is not possible to import a p2sh private key and associate it - to a p2pkh address. - * A new version of the Electrum protocol is required by the client (version 1.1). Servers using older versions of the protocol will not be displayed in the GUI. @@ -184,7 +132,6 @@ issue #3374. Users should upgrade to 3.0.5. - Dynamic fees are enabled by default. - Child Pays For Parent (CPFP) dialog in the GUI. - RBF is automatically proposed for low fee transactions. - * Support for Segregated Witness (testnet only). * Support for Digital Bitbox hardware wallet. * The GUI shows a blue icon when connected using a proxy. diff --git a/electrum b/electrum index f47d2c68..94f0ec64 100755 --- a/electrum +++ b/electrum @@ -168,7 +168,7 @@ def run_non_RPC(config): elif cmdname == 'create': password = password_dialog() passphrase = config.get('passphrase', '') - seed_type = 'segwit' if config.get('segwit') else 'standard' + seed_type = 'standard' seed = Mnemonic('en').make_seed(seed_type) k = keystore.from_seed(seed, passphrase, False) storage.put('keystore', k.dump()) diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py index 8a6cb9ad..288c2c6b 100644 --- a/gui/qt/main_window.py +++ b/gui/qt/main_window.py @@ -1937,8 +1937,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): rds_e = ShowQRTextEdit(text=redeem_script) rds_e.addCopyButton(self.app) vbox.addWidget(rds_e) - if xtype in ['p2wpkh', 'p2wsh', 'p2wpkh-p2sh', 'p2wsh-p2sh']: - vbox.addWidget(WWLabel(_("Warning: the format of private keys associated to segwit addresses may not be compatible with other wallets"))) vbox.addLayout(Buttons(CloseButton(d))) d.setLayout(vbox) d.exec_() @@ -1956,7 +1954,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): self.show_message('Invalid Bitcoin address.') return txin_type = self.wallet.get_txin_type(address) - if txin_type not in ['p2pkh', 'p2wpkh', 'p2wpkh-p2sh']: + if txin_type not in ['p2pkh']: self.show_message('Cannot sign messages with this type of address.' + '\n\n' + self.msg_sign) return if not self.wallet.is_mine(address): diff --git a/plugins/digitalbitbox/digitalbitbox.py b/plugins/digitalbitbox/digitalbitbox.py index a96e18ef..f283750e 100644 --- a/plugins/digitalbitbox/digitalbitbox.py +++ b/plugins/digitalbitbox/digitalbitbox.py @@ -86,7 +86,7 @@ class DigitalBitbox_Client(): def get_xpub(self, bip32_path, xtype): - assert xtype in ('standard', 'p2wpkh-p2sh') + assert xtype in ('standard') reply = self._get_xpub(bip32_path) if reply: xpub = reply['xpub'] diff --git a/plugins/keepkey/plugin.py b/plugins/keepkey/plugin.py index d61594a5..f0d747fd 100644 --- a/plugins/keepkey/plugin.py +++ b/plugins/keepkey/plugin.py @@ -4,8 +4,7 @@ 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, - is_segwit_address) + TYPE_ADDRESS, TYPE_SCRIPT, NetworkConstants) from electrum.i18n import _ from electrum.plugins import BasePlugin from electrum.transaction import deserialize @@ -22,9 +21,6 @@ class KeepKeyCompatibleKeyStore(Hardware_KeyStore): def get_derivation(self): return self.derivation - def is_segwit(self): - return self.derivation.startswith("m/49'/") - def get_client(self, force_pair=True): return self.plugin.get_client(self, force_pair) @@ -219,8 +215,8 @@ class KeepKeyCompatiblePlugin(HW_PluginBase): self.prev_tx = prev_tx self.xpub_path = xpub_path client = self.get_client(keystore) - inputs = self.tx_inputs(tx, True, keystore.is_segwit()) - outputs = self.tx_outputs(keystore.get_derivation(), tx, keystore.is_segwit()) + inputs = self.tx_inputs(tx, True) + outputs = self.tx_outputs(keystore.get_derivation(), tx) signed_tx = client.sign_tx(self.get_coin_name(), inputs, outputs, lock_time=tx.locktime)[1] raw = bh2u(signed_tx) tx.update_signatures(raw) @@ -234,11 +230,10 @@ class KeepKeyCompatiblePlugin(HW_PluginBase): derivation = wallet.keystore.derivation address_path = "%s/%d/%d"%(derivation, change, index) address_n = client.expand_path(address_path) - segwit = wallet.keystore.is_segwit() - script_type = self.types.SPENDP2SHWITNESS if segwit else self.types.SPENDADDRESS + script_type = self.types.SPENDADDRESS client.get_address(self.get_coin_name(), address_n, True, script_type=script_type) - def tx_inputs(self, tx, for_sig=False, segwit=False): + def tx_inputs(self, tx, for_sig=False): inputs = [] for txin in tx.inputs(): txinputtype = self.types.TxInputType() @@ -253,7 +248,7 @@ class KeepKeyCompatiblePlugin(HW_PluginBase): xpub, s = parse_xpubkey(x_pubkey) xpub_n = self.client_class.expand_path(self.xpub_path[xpub]) txinputtype.address_n.extend(xpub_n + s) - txinputtype.script_type = self.types.SPENDP2SHWITNESS if segwit else self.types.SPENDADDRESS + txinputtype.script_type = self.types.SPENDADDRESS else: def f(x_pubkey): if is_xpubkey(x_pubkey): @@ -269,7 +264,7 @@ class KeepKeyCompatiblePlugin(HW_PluginBase): signatures=map(lambda x: bfh(x)[:-1] if x else b'', txin.get('signatures')), m=txin.get('num_sig'), ) - script_type = self.types.SPENDP2SHWITNESS if segwit else self.types.SPENDMULTISIG + script_type = self.types.SPENDMULTISIG txinputtype = self.types.TxInputType( script_type=script_type, multisig=multisig @@ -301,7 +296,7 @@ class KeepKeyCompatiblePlugin(HW_PluginBase): return inputs - def tx_outputs(self, derivation, tx, segwit=False): + def tx_outputs(self, derivation, tx): outputs = [] has_change = False @@ -312,7 +307,7 @@ class KeepKeyCompatiblePlugin(HW_PluginBase): addrtype, hash_160 = b58_address_to_hash160(address) index, xpubs, m = info if len(xpubs) == 1: - script_type = self.types.PAYTOP2SHWITNESS if segwit else self.types.PAYTOADDRESS + script_type = self.types.PAYTOADDRESS address_n = self.client_class.expand_path(derivation + "/%d/%d"%index) txoutputtype = self.types.TxOutputType( amount = amount, @@ -320,7 +315,7 @@ class KeepKeyCompatiblePlugin(HW_PluginBase): address_n = address_n, ) else: - script_type = self.types.PAYTOP2SHWITNESS if segwit else self.types.PAYTOMULTISIG + script_type = self.types.PAYTOMULTISIG address_n = self.client_class.expand_path("/%d/%d"%index) nodes = map(self.ckd_public.deserialize, xpubs) pubkeys = [ self.types.HDNodePathType(node=node, address_n=address_n) for node in nodes] @@ -340,16 +335,13 @@ class KeepKeyCompatiblePlugin(HW_PluginBase): txoutputtype.script_type = self.types.PAYTOOPRETURN txoutputtype.op_return_data = address[2:] elif _type == TYPE_ADDRESS: - if is_segwit_address(address): - txoutputtype.script_type = self.types.PAYTOWITNESS + addrtype, hash_160 = b58_address_to_hash160(address) + if addrtype == NetworkConstants.ADDRTYPE_P2PKH: + txoutputtype.script_type = self.types.PAYTOADDRESS + elif addrtype == NetworkConstants.ADDRTYPE_P2SH: + txoutputtype.script_type = self.types.PAYTOSCRIPTHASH else: - addrtype, hash_160 = b58_address_to_hash160(address) - if addrtype == NetworkConstants.ADDRTYPE_P2PKH: - txoutputtype.script_type = self.types.PAYTOADDRESS - elif addrtype == NetworkConstants.ADDRTYPE_P2SH: - txoutputtype.script_type = self.types.PAYTOSCRIPTHASH - else: - raise BaseException('addrtype: ' + str(addrtype)) + raise BaseException('addrtype: ' + str(addrtype)) txoutputtype.address = address outputs.append(txoutputtype) diff --git a/plugins/ledger/ledger.py b/plugins/ledger/ledger.py index c323d684..a60e81dd 100644 --- a/plugins/ledger/ledger.py +++ b/plugins/ledger/ledger.py @@ -56,10 +56,6 @@ class Ledger_Client(): # This only happens once so it's bearable #self.get_client() # prompt for the PIN before displaying the dialog if necessary #self.handler.show_message("Computing master public key") - if xtype in ['p2wpkh', 'p2wsh'] and not self.supports_native_segwit(): - raise Exception("Firmware version too old for Segwit support. Please update at https://www.ledgerwallet.com") - if xtype in ['p2wpkh-p2sh', 'p2wsh-p2sh'] and not self.supports_segwit(): - raise Exception("Firmware version too old for Segwit support. Please update at https://www.ledgerwallet.com") splitPath = bip32_path.split('/') if splitPath[0] == 'm': splitPath = splitPath[1:] @@ -103,19 +99,11 @@ class Ledger_Client(): def supports_multi_output(self): return self.multiOutputSupported - def supports_segwit(self): - return self.segwitSupported - - def supports_native_segwit(self): - return self.nativeSegwitSupported - def perform_hw1_preflight(self): try: firmwareInfo = self.dongleObject.getFirmwareVersion() firmware = firmwareInfo['version'].split(".") self.multiOutputSupported = int(firmware[0]) >= 1 and int(firmware[1]) >= 1 and int(firmware[2]) >= 4 - self.segwitSupported = (int(firmware[0]) >= 1 and int(firmware[1]) >= 1 and int(firmware[2]) >= 10) or (firmwareInfo['specialVersion'] == 0x20 and int(firmware[0]) == 1 and int(firmware[1]) == 0 and int(firmware[2]) >= 4) - self.nativeSegwitSupported = int(firmware[0]) >= 1 and int(firmware[1]) >= 1 and int(firmware[2]) >= 10 if not checkFirmware(firmware): self.dongleObject.dongle.close() @@ -270,7 +258,6 @@ class Ledger_KeyStore(Hardware_KeyStore): output = None outputAmount = None p2shTransaction = False - segwitTransaction = False pin = "" self.get_client() # prompt for the PIN before displaying the dialog if necessary @@ -283,16 +270,6 @@ class Ledger_KeyStore(Hardware_KeyStore): if txin['type'] in ['p2sh']: p2shTransaction = True - if txin['type'] in ['p2wpkh-p2sh', 'p2wsh-p2sh']: - if not self.get_client_electrum().supports_segwit(): - self.give_error("Firmware version too old to support segwit. Please update at https://www.ledgerwallet.com") - segwitTransaction = True - - if txin['type'] in ['p2wpkh', 'p2wsh']: - if not self.get_client_electrum().supports_native_segwit(): - self.give_error("Firmware version too old to support native segwit. Please update at https://www.ledgerwallet.com") - segwitTransaction = True - pubkeys, x_pubkeys = tx.get_sorted_pubkeys(txin) for i, x_pubkey in enumerate(x_pubkeys): if x_pubkey in derivations: @@ -344,14 +321,7 @@ class Ledger_KeyStore(Hardware_KeyStore): # Get trusted inputs from the original transactions for utxo in inputs: sequence = int_to_hex(utxo[5], 4) - if segwitTransaction: - txtmp = bitcoinTransaction(bfh(utxo[0])) - tmp = bfh(utxo[3])[::-1] - tmp += bfh(int_to_hex(utxo[1], 4)) - tmp += txtmp.outputs[utxo[1]].amount - chipInputs.append({'value' : tmp, 'witness' : True, 'sequence' : sequence}) - redeemScripts.append(bfh(utxo[2])) - elif not p2shTransaction: + if not p2shTransaction: txtmp = bitcoinTransaction(bfh(utxo[0])) trustedInput = self.get_client().getTrustedInput(txtmp, utxo[1]) trustedInput['sequence'] = sequence @@ -368,12 +338,13 @@ class Ledger_KeyStore(Hardware_KeyStore): inputIndex = 0 rawTx = tx.serialize() self.get_client().enableAlternate2fa(False) - if segwitTransaction: - self.get_client().startUntrustedTransaction(True, inputIndex, - chipInputs, redeemScripts[inputIndex]) + while inputIndex < len(inputs): + self.get_client().startUntrustedTransaction(firstTransaction, inputIndex, + chipInputs, redeemScripts[inputIndex]) outputData = self.get_client().finalizeInputFull(txOutput) outputData['outputData'] = txOutput - transactionOutput = outputData['outputData'] + if firstTransaction: + transactionOutput = outputData['outputData'] if outputData['confirmationNeeded']: outputData['address'] = output self.handler.finished() @@ -382,38 +353,14 @@ class Ledger_KeyStore(Hardware_KeyStore): raise UserWarning() if pin != 'paired': self.handler.show_message(_("Confirmed. Signing Transaction...")) - while inputIndex < len(inputs): - singleInput = [ chipInputs[inputIndex] ] - self.get_client().startUntrustedTransaction(False, 0, - singleInput, redeemScripts[inputIndex]) + else: + # Sign input with the provided PIN inputSignature = self.get_client().untrustedHashSign(inputsPaths[inputIndex], pin, lockTime=tx.locktime) inputSignature[0] = 0x30 # force for 1.4.9+ signatures.append(inputSignature) inputIndex = inputIndex + 1 - else: - while inputIndex < len(inputs): - self.get_client().startUntrustedTransaction(firstTransaction, inputIndex, - chipInputs, redeemScripts[inputIndex]) - outputData = self.get_client().finalizeInputFull(txOutput) - outputData['outputData'] = txOutput - if firstTransaction: - transactionOutput = outputData['outputData'] - if outputData['confirmationNeeded']: - outputData['address'] = output - self.handler.finished() - pin = self.handler.get_auth( outputData ) # does the authenticate dialog and returns pin - if not pin: - raise UserWarning() - if pin != 'paired': - self.handler.show_message(_("Confirmed. Signing Transaction...")) - else: - # Sign input with the provided PIN - inputSignature = self.get_client().untrustedHashSign(inputsPaths[inputIndex], pin, lockTime=tx.locktime) - inputSignature[0] = 0x30 # force for 1.4.9+ - signatures.append(inputSignature) - inputIndex = inputIndex + 1 - if pin != 'paired': - firstTransaction = False + if pin != 'paired': + firstTransaction = False except UserWarning: self.handler.show_error(_('Cancelled by user')) return @@ -444,7 +391,6 @@ class LedgerPlugin(HW_PluginBase): ] def __init__(self, parent, config, name): - self.segwit = config.get("segwit") HW_PluginBase.__init__(self, parent, config, name) if self.libraries_available: self.device_manager().register_devices(self.DEVICE_IDS) diff --git a/plugins/trezor/plugin.py b/plugins/trezor/plugin.py index 363d7a78..027bb365 100644 --- a/plugins/trezor/plugin.py +++ b/plugins/trezor/plugin.py @@ -21,9 +21,6 @@ class TrezorCompatibleKeyStore(Hardware_KeyStore): def get_derivation(self): return self.derivation - def is_segwit(self): - return self.derivation.startswith("m/49'/") - def get_client(self, force_pair=True): return self.plugin.get_client(self, force_pair) @@ -231,8 +228,8 @@ class TrezorCompatiblePlugin(HW_PluginBase): self.prev_tx = prev_tx self.xpub_path = xpub_path client = self.get_client(keystore) - inputs = self.tx_inputs(tx, True, keystore.is_segwit()) - outputs = self.tx_outputs(keystore.get_derivation(), tx, keystore.is_segwit()) + inputs = self.tx_inputs(tx, True) + outputs = self.tx_outputs(keystore.get_derivation(), tx) signed_tx = client.sign_tx(self.get_coin_name(), inputs, outputs, lock_time=tx.locktime)[1] raw = bh2u(signed_tx) tx.update_signatures(raw) @@ -246,11 +243,10 @@ class TrezorCompatiblePlugin(HW_PluginBase): derivation = wallet.keystore.derivation address_path = "%s/%d/%d"%(derivation, change, index) address_n = client.expand_path(address_path) - segwit = wallet.keystore.is_segwit() - script_type = self.types.SPENDP2SHWITNESS if segwit else self.types.SPENDADDRESS + script_type = self.types.SPENDADDRESS client.get_address(self.get_coin_name(), address_n, True, script_type=script_type) - def tx_inputs(self, tx, for_sig=False, segwit=False): + def tx_inputs(self, tx, for_sig=False): inputs = [] for txin in tx.inputs(): txinputtype = self.types.TxInputType() @@ -265,7 +261,7 @@ class TrezorCompatiblePlugin(HW_PluginBase): xpub, s = parse_xpubkey(x_pubkey) xpub_n = self.client_class.expand_path(self.xpub_path[xpub]) txinputtype.address_n.extend(xpub_n + s) - txinputtype.script_type = self.types.SPENDP2SHWITNESS if segwit else self.types.SPENDADDRESS + txinputtype.script_type = self.types.SPENDADDRESS else: def f(x_pubkey): if is_xpubkey(x_pubkey): @@ -281,7 +277,7 @@ class TrezorCompatiblePlugin(HW_PluginBase): signatures=map(lambda x: bfh(x)[:-1] if x else b'', txin.get('signatures')), m=txin.get('num_sig'), ) - script_type = self.types.SPENDP2SHWITNESS if segwit else self.types.SPENDMULTISIG + script_type = self.types.SPENDMULTISIG txinputtype = self.types.TxInputType( script_type=script_type, multisig=multisig @@ -313,7 +309,7 @@ class TrezorCompatiblePlugin(HW_PluginBase): return inputs - def tx_outputs(self, derivation, tx, segwit=False): + def tx_outputs(self, derivation, tx): outputs = [] has_change = False @@ -324,7 +320,7 @@ class TrezorCompatiblePlugin(HW_PluginBase): addrtype, hash_160 = b58_address_to_hash160(address) index, xpubs, m = info if len(xpubs) == 1: - script_type = self.types.PAYTOP2SHWITNESS if segwit else self.types.PAYTOADDRESS + script_type = self.types.PAYTOADDRESS address_n = self.client_class.expand_path(derivation + "/%d/%d"%index) txoutputtype = self.types.TxOutputType( amount = amount, @@ -332,7 +328,7 @@ class TrezorCompatiblePlugin(HW_PluginBase): address_n = address_n, ) else: - script_type = self.types.PAYTOP2SHWITNESS if segwit else self.types.PAYTOMULTISIG + script_type = self.types.PAYTOMULTISIG address_n = self.client_class.expand_path("/%d/%d"%index) nodes = map(self.ckd_public.deserialize, xpubs) pubkeys = [ self.types.HDNodePathType(node=node, address_n=address_n) for node in nodes]