コード例 #1
0
ファイル: qt.py プロジェクト: bygage/electrum
    def on_receive(self, keyhash, message):
        self.print_error("signal arrived for", keyhash)
        for key, _hash, window in self.keys:
            if _hash == keyhash:
                break
        else:
            self.print_error("keyhash not found")
            return

        wallet = window.wallet
        if wallet.has_password():
            password = window.password_dialog('An encrypted transaction was retrieved from cosigning pool.\nPlease enter your password to decrypt it.')
            if not password:
                return
        else:
            password = None
            if not window.question(_("An encrypted transaction was retrieved from cosigning pool.\nDo you want to open it now?")):
                return

        xprv = wallet.keystore.get_master_private_key(password)
        if not xprv:
            return
        try:
            k = bh2u(bitcoin.deserialize_xprv(xprv)[-1])
            EC = bitcoin.EC_KEY(bfh(k))
            message = bh2u(EC.decrypt_message(message))
        except Exception as e:
            traceback.print_exc(file=sys.stdout)
            window.show_message(str(e))
            return

        self.listener.clear(keyhash)
        tx = transaction.Transaction(message)
        show_transaction(tx, window, prompt_if_unsaved=True)
コード例 #2
0
 def test_mnemonic_to_seed(self):
     for test_name, test in SEED_TEST_CASES.items():
         if test.words_hex is not None:
             self.assertEqual(test.words_hex, bh2u(test.words.encode('utf8')), msg=test_name)
         self.assertTrue(is_new_seed(test.words, prefix=test.seed_version), msg=test_name)
         m = mnemonic.Mnemonic(lang=test.lang)
         if test.entropy is not None:
             self.assertEqual(test.entropy, m.mnemonic_decode(test.words), msg=test_name)
         if test.passphrase_hex is not None:
             self.assertEqual(test.passphrase_hex, bh2u(test.passphrase.encode('utf8')), msg=test_name)
         seed = mnemonic.Mnemonic.mnemonic_to_seed(mnemonic=test.words, passphrase=test.passphrase)
         self.assertEqual(test.bip32_seed, bh2u(seed), msg=test_name)
コード例 #3
0
ファイル: qt.py プロジェクト: ahmedbodi/electrum
        def update(features):
            self.features = features
            set_label_enabled()
            if features.bootloader_hash:
                bl_hash = bh2u(features.bootloader_hash)
                bl_hash = "\n".join([bl_hash[:32], bl_hash[32:]])
            else:
                bl_hash = "N/A"
            noyes = [_("No"), _("Yes")]
            endis = [_("Enable Passphrases"), _("Disable Passphrases")]
            disen = [_("Disabled"), _("Enabled")]
            setchange = [_("Set a PIN"), _("Change PIN")]

            version = "%d.%d.%d" % (features.major_version,
                                    features.minor_version,
                                    features.patch_version)

            device_label.setText(features.label)
            pin_set_label.setText(noyes[features.pin_protection])
            passphrases_label.setText(disen[features.passphrase_protection])
            bl_hash_label.setText(bl_hash)
            label_edit.setText(features.label)
            device_id_label.setText(features.device_id)
            initialized_label.setText(noyes[features.initialized])
            version_label.setText(version)
            clear_pin_button.setVisible(features.pin_protection)
            clear_pin_warning.setVisible(features.pin_protection)
            pin_button.setText(setchange[features.pin_protection])
            pin_msg.setVisible(not features.pin_protection)
            passphrase_button.setText(endis[features.passphrase_protection])
            language_label.setText(features.language)
コード例 #4
0
ファイル: revealer.py プロジェクト: faircoin/electrumfair
 def gen_random_versioned_seed(cls):
     version = cls.LATEST_VERSION
     hex_seed = bh2u(os.urandom(16))
     checksum = cls.code_hashid(version + hex_seed)
     return VersionedSeed(version=version.upper(),
                          seed=hex_seed.upper(),
                          checksum=checksum.upper())
コード例 #5
0
ファイル: test_bitcoin.py プロジェクト: chrisrico/electrum
 def test_push_script(self):
     # https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#push-operators
     self.assertEqual(push_script(''), bh2u(bytes([opcodes.OP_0])))
     self.assertEqual(push_script('07'), bh2u(bytes([opcodes.OP_7])))
     self.assertEqual(push_script('10'), bh2u(bytes([opcodes.OP_16])))
     self.assertEqual(push_script('81'), bh2u(bytes([opcodes.OP_1NEGATE])))
     self.assertEqual(push_script('11'), '0111')
     self.assertEqual(push_script(75 * '42'), '4b' + 75 * '42')
     self.assertEqual(push_script(76 * '42'), bh2u(bytes([opcodes.OP_PUSHDATA1]) + bfh('4c' + 76 * '42')))
     self.assertEqual(push_script(100 * '42'), bh2u(bytes([opcodes.OP_PUSHDATA1]) + bfh('64' + 100 * '42')))
     self.assertEqual(push_script(255 * '42'), bh2u(bytes([opcodes.OP_PUSHDATA1]) + bfh('ff' + 255 * '42')))
     self.assertEqual(push_script(256 * '42'), bh2u(bytes([opcodes.OP_PUSHDATA2]) + bfh('0001' + 256 * '42')))
     self.assertEqual(push_script(520 * '42'), bh2u(bytes([opcodes.OP_PUSHDATA2]) + bfh('0802' + 520 * '42')))
コード例 #6
0
ファイル: trezor.py プロジェクト: faircoin/electrumfair
 def sign_transaction(self, keystore, tx, prev_tx, xpub_path):
     prev_tx = { bfh(txhash): self.electrum_tx_to_txtype(tx, xpub_path) for txhash, tx in prev_tx.items() }
     client = self.get_client(keystore)
     inputs = self.tx_inputs(tx, xpub_path, True)
     outputs = self.tx_outputs(keystore.get_derivation(), tx)
     details = SignTx(lock_time=tx.locktime, version=tx.version)
     signatures, _ = client.sign_tx(self.get_coin_name(), inputs, outputs, details=details, prev_txes=prev_tx)
     signatures = [(bh2u(x) + '01') for x in signatures]
     tx.update_signatures(signatures)
コード例 #7
0
ファイル: safe_t.py プロジェクト: ahmedbodi/electrum
 def sign_transaction(self, keystore, tx, prev_tx, xpub_path):
     self.prev_tx = prev_tx
     self.xpub_path = xpub_path
     client = self.get_client(keystore)
     inputs = self.tx_inputs(tx, True)
     outputs = self.tx_outputs(keystore.get_derivation(), tx)
     signatures = client.sign_tx(self.get_coin_name(), inputs, outputs, lock_time=tx.locktime)[0]
     signatures = [(bh2u(x) + '01') for x in signatures]
     tx.update_signatures(signatures)
コード例 #8
0
ファイル: plugin.py プロジェクト: chrisglass/electrum
 def sign_transaction(self, keystore, tx, prev_tx, xpub_path):
     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())
     signed_tx = client.sign_tx(self.get_coin_name(), inputs, outputs, lock_time=tx.locktime)[1]
     raw = bh2u(signed_tx)
     tx.update_signatures(raw)
コード例 #9
0
ファイル: qt.py プロジェクト: bygage/electrum
 def do_send(self, tx):
     for window, xpub, K, _hash in self.cosigner_list:
         if not self.cosigner_can_sign(tx, xpub):
             continue
         message = bitcoin.encrypt_message(bfh(tx.raw), bh2u(K)).decode('ascii')
         try:
             server.put(_hash, message)
         except Exception as e:
             traceback.print_exc(file=sys.stdout)
             window.show_message("Failed to send transaction to cosigning pool.")
             return
         window.show_message("Your transaction was sent to the cosigning pool.\nOpen your cosigner wallet to retrieve it.")
コード例 #10
0
ファイル: trezor.py プロジェクト: electrum-bch/electrum-bch
 def sign_transaction(self, keystore, tx, prev_tx, xpub_path):
     self.prev_tx = prev_tx
     self.xpub_path = xpub_path
     client = self.get_client(keystore)
     inputs = self.tx_inputs(tx, True)
     outputs = self.tx_outputs(keystore.get_derivation(), tx)
     signatures = client.sign_tx(self.get_coin_name(),
                                 inputs,
                                 outputs,
                                 lock_time=tx.locktime)[0]
     signatures = [(bh2u(x) + '01') for x in signatures]
     tx.update_signatures(signatures)
コード例 #11
0
 def open(self, *args, **kwargs):
     super(LightningOpenChannelDialog, self).open(*args, **kwargs)
     if self.lnaddr:
         fee = self.app.electrum_config.fee_per_kb()
         if not fee:
             fee = config.FEERATE_FALLBACK_STATIC_FEE
         self.amount = self.app.format_amount_and_units(self.lnaddr.amount *
                                                        constants.net.COIN +
                                                        fee * 2)
         self.pubkey = bh2u(self.lnaddr.pubkey.serialize())
     if self.msg:
         self.app.show_info(self.msg)
コード例 #12
0
 def sign_transaction(self, keystore, tx: PartialTransaction, prev_tx):
     self.prev_tx = prev_tx
     client = self.get_client(keystore)
     inputs = self.tx_inputs(tx, for_sig=True, keystore=keystore)
     outputs = self.tx_outputs(tx, keystore=keystore)
     signatures = client.sign_tx(self.get_coin_name(),
                                 inputs,
                                 outputs,
                                 lock_time=tx.locktime,
                                 version=tx.version)[0]
     signatures = [(bh2u(x) + '01') for x in signatures]
     tx.update_signatures(signatures)
コード例 #13
0
    def create_menu(self, position):
        selected = self.selected_column_0_user_roles()
        if not selected:
            return
        menu = QMenu()

        menu.addAction(_("Renew"), lambda: self.renew_selected_items())
        if len(selected) == 1:
            txid = selected[0].split(':')[0]
            tx = self.wallet.db.transactions.get(txid)
            if tx:
                label = self.wallet.get_label(
                    txid
                ) or None  # Prefer None if empty (None hides the Description: field in the window)
                menu.addAction(_("Configure"),
                               lambda: self.configure_selected_item())
                menu.addAction(
                    _("Transaction Details"),
                    lambda: self.parent.show_transaction(tx, tx_desc=label))

        # "Copy ..."

        idx = self.indexAt(position)
        col = idx.column()
        if col == self.Columns.NAME:
            selected_data = self.selected_column_0_user_role_identifiers()
            selected_data_type = "identifier"
        elif col == self.Columns.VALUE:
            selected_data = self.selected_column_0_user_role_values()
            selected_data_type = "value"
        else:
            selected_data = None

        if selected_data is not None and len(selected_data) == 1:
            data = selected_data[0]
            # data will be None if this row is a name_new that we haven't
            # queued a name_firstupdate for, so we don't know the identifier or
            # value.
            if data is not None:
                try:
                    copy_ascii = data.decode('ascii')
                    menu.addAction(
                        _("Copy {} as ASCII").format(selected_data_type),
                        lambda: self.parent.app.clipboard().setText(copy_ascii
                                                                    ))
                except UnicodeDecodeError:
                    pass
                copy_hex = bh2u(data)
                menu.addAction(
                    _("Copy {} as hex").format(selected_data_type),
                    lambda: self.parent.app.clipboard().setText(copy_hex))

        menu.exec_(self.viewport().mapToGlobal(position))
コード例 #14
0
ファイル: guess_seeds.py プロジェクト: HN-AG/puzzles
def checkPassphrase(line):
    passw = ""

    seed = util.bh2u(keystore.bip39_to_seed(line, passw))
    seed = util.bfh(seed)
    xprv, _xpub = bitcoin.bip32_root(seed, "standard")
    xprv, _xpub = bitcoin.bip32_private_derivation(xprv, "", "49'")
    xprv, _xpub = bitcoin.bip32_private_derivation(xprv, "", "0'")
    xprv, _xpub = bitcoin.bip32_private_derivation(xprv, "", "0'")
    xprv, _xpub = bitcoin.bip32_private_derivation(xprv, "", "0")
    for i in range(MAX_ADDR_IDX):
        deriveAddresses(line, xprv, i)
コード例 #15
0
 def do_send(self, tx):
     for window, xpub, K, _hash in self.cosigner_list:
         if not self.cosigner_can_sign(tx, xpub):
             continue
         message = bitcoin.encrypt_message(bfh(tx.raw), bh2u(K)).decode('ascii')
         try:
             server.put(_hash, message)
         except Exception as e:
             traceback.print_exc(file=sys.stdout)
             window.show_message("Failed to send transaction to cosigning pool.")
             return
         window.show_message("Your transaction was sent to the cosigning pool.\nOpen your cosigner wallet to retrieve it.")
コード例 #16
0
 def __init__(self, chan: Channel, app: 'ElectrumWindow', **kwargs):
     Popup.__init__(self, **kwargs)
     Logger.__init__(self)
     self.is_closed = chan.is_closed()
     self.can_be_deleted = chan.can_be_deleted()
     self.app = app
     self.chan = chan
     self.title = _('Channel details')
     self.node_id = bh2u(chan.node_id)
     self.channel_id = bh2u(chan.channel_id)
     self.funding_txid = chan.funding_outpoint.txid
     self.short_id = format_short_channel_id(chan.short_channel_id)
     self.capacity = self.app.format_amount_and_units(chan.get_capacity())
     self.state = chan.get_state_for_GUI()
     self.local_ctn = chan.get_latest_ctn(LOCAL)
     self.remote_ctn = chan.get_latest_ctn(REMOTE)
     self.local_csv = chan.config[LOCAL].to_self_delay
     self.remote_csv = chan.config[REMOTE].to_self_delay
     self.initiator = 'Local' if chan.constraints.is_initiator else 'Remote'
     feerate_kw = chan.get_latest_feerate(LOCAL)
     self.feerate = str(
         quantize_feerate(Transaction.satperbyte_from_satperkw(feerate_kw)))
     self.can_send = self.app.format_amount_and_units(
         chan.available_to_spend(LOCAL) // 1000)
     self.can_receive = self.app.format_amount_and_units(
         chan.available_to_spend(REMOTE) // 1000)
     self.is_open = chan.is_open()
     closed = chan.get_closing_height()
     if closed:
         self.closing_txid, closing_height, closing_timestamp = closed
     msg = ' '.join([
         _("Trampoline routing is enabled, but this channel is with a non-trampoline node."
           ),
         _("This channel may still be used for receiving, but it is frozen for sending."
           ),
         _("If you want to keep using this channel, you need to disable trampoline routing in your preferences."
           ),
     ])
     self.warning = '' if self.app.wallet.lnworker.channel_db or self.app.wallet.lnworker.is_trampoline_peer(
         chan.node_id) else _('Warning') + ': ' + msg
コード例 #17
0
 def sign_and_insert_remote_sig(self, tx: PartialTransaction, remote_pubkey,
                                remote_signature, pubkey, privkey):
     assert type(remote_pubkey) is bytes
     assert len(remote_pubkey) == 33
     assert type(remote_signature) is str
     assert type(pubkey) is bytes
     assert type(privkey) is bytes
     assert len(pubkey) == 33
     assert len(privkey) == 33
     tx.sign({bh2u(pubkey): (privkey[:-1], True)})
     tx.add_signature_to_txin(txin_idx=0,
                              signing_pubkey=remote_pubkey.hex(),
                              sig=remote_signature + "01")
コード例 #18
0
ファイル: trezor.py プロジェクト: futuro-coin/electrum-futuro
 def sign_transaction(self, keystore, tx, prev_tx, xpub_path):
     self.prev_tx = prev_tx
     self.xpub_path = xpub_path
     client = self.get_client(keystore)
     inputs = self.tx_inputs(tx, True, keystore.get_script_gen())
     outputs = self.tx_outputs(keystore.get_derivation(), tx,
                               keystore.get_script_gen())
     signed_tx = client.sign_tx(self.get_coin_name(),
                                inputs,
                                outputs,
                                lock_time=tx.locktime)[1]
     raw = bh2u(signed_tx)
     tx.update_signatures(raw)
コード例 #19
0
ファイル: test_mnemonic.py プロジェクト: phamels/electrum-nix
    def test_mnemonic_to_seed_japanese(self):
        words = SEED_WORDS_JAPANESE
        self.assertTrue(is_new_seed(words))

        m = mnemonic.Mnemonic(lang='ja')
        self.assertEqual(1938439226660562861250521787963972783469,
                         m.mnemonic_decode(words))

        seed = mnemonic.Mnemonic.mnemonic_to_seed(mnemonic=words,
                                                  passphrase='')
        self.assertEqual(
            'd3eaf0e44ddae3a5769cb08a26918e8b308258bcb057bb704c6f69713245c0b35cb92c03df9c9ece5eff826091b4e74041e010b701d44d610976ce8bfb66a8ad',
            bh2u(seed))
コード例 #20
0
ファイル: test_mnemonic.py プロジェクト: phamels/electrum-nix
    def test_mnemonic_to_seed_chinese(self):
        words = SEED_WORDS_CHINESE
        self.assertTrue(is_new_seed(words, prefix=SEED_PREFIX_SW))

        m = mnemonic.Mnemonic(lang='zh')
        self.assertEqual(3083737086352778425940060465574397809099,
                         m.mnemonic_decode(words))

        seed = mnemonic.Mnemonic.mnemonic_to_seed(mnemonic=words,
                                                  passphrase='')
        self.assertEqual(
            '0b9077db7b5a50dbb6f61821e2d35e255068a5847e221138048a20e12d80b673ce306b6fe7ac174ebc6751e11b7037be6ee9f17db8040bb44f8466d519ce2abf',
            bh2u(seed))
コード例 #21
0
 def sign_transaction(self, keystore, tx: PartialTransaction, prev_tx):
     prev_tx = {bfh(txhash): self.electrum_tx_to_txtype(tx) for txhash, tx in prev_tx.items()}
     client = self.get_client(keystore)
     inputs = self.tx_inputs(tx, for_sig=True, keystore=keystore)
     outputs = self.tx_outputs(tx, keystore=keystore)
     signatures, _ = client.sign_tx(self.get_coin_name(),
                                    inputs, outputs,
                                    lock_time=tx.locktime,
                                    version=tx.version,
                                    amount_unit=self.get_trezor_amount_unit(),
                                    prev_txes=prev_tx)
     signatures = [(bh2u(x) + '01') for x in signatures]
     tx.update_signatures(signatures)
コード例 #22
0
ファイル: qt.py プロジェクト: BushidoLab/electrum
    def on_receive(self, keyhash, message):
        self.print_error("signal arrived for", keyhash)
        for key, _hash, window in self.keys:
            if _hash == keyhash:
                break
        else:
            self.print_error("keyhash not found")
            return

        wallet = window.wallet
        if wallet.has_keystore_encryption():
            password = window.password_dialog(
                'An encrypted transaction was retrieved from cosigning pool.\nPlease enter your password to decrypt it.'
            )
            if not password:
                return
        else:
            password = None
            if not window.question(
                    _("An encrypted transaction was retrieved from cosigning pool.\nDo you want to open it now?"
                      )):
                return

        xprv = wallet.keystore.get_master_private_key(password)
        if not xprv:
            return
        try:
            k = bh2u(bitcoin.deserialize_xprv(xprv)[-1])
            EC = bitcoin.EC_KEY(bfh(k))
            message = bh2u(EC.decrypt_message(message))
        except Exception as e:
            traceback.print_exc(file=sys.stdout)
            window.show_message(str(e))
            return

        self.listener.clear(keyhash)
        tx = transaction.Transaction(message)
        show_transaction(tx, window, prompt_if_unsaved=True)
コード例 #23
0
 def details(self):
     chan = self.chan
     return {
         _('Short Chan ID'):
         format_short_channel_id(chan.short_channel_id),
         _('Initiator'):
         'Local' if chan.constraints.is_initiator else 'Remote',
         _('State'):
         chan.get_state(),
         _('Capacity'):
         self.app.format_amount_and_units(chan.constraints.capacity),
         _('Can send'):
         self.app.format_amount_and_units(
             chan.available_to_spend(LOCAL) // 1000),
         _('Current feerate'):
         str(chan.get_latest_feerate(LOCAL)),
         _('Node ID'):
         bh2u(chan.node_id),
         _('Channel ID'):
         bh2u(chan.channel_id),
         _('Funding TXID'):
         chan.funding_outpoint.txid,
     }
コード例 #24
0
 def __init__(self, chan: Channel, app: 'ElectrumWindow', **kwargs):
     Popup.__init__(self, **kwargs)
     Logger.__init__(self)
     self.is_closed = chan.is_closed()
     self.can_be_deleted = chan.can_be_deleted()
     self.app = app
     self.chan = chan
     self.title = _('Channel details')
     self.node_id = bh2u(chan.node_id)
     self.channel_id = bh2u(chan.channel_id)
     self.funding_txid = chan.funding_outpoint.txid
     self.short_id = format_short_channel_id(chan.short_channel_id)
     self.capacity = self.app.format_amount_and_units(chan.get_capacity())
     self.state = chan.get_state_for_GUI()
     self.local_ctn = chan.get_latest_ctn(LOCAL)
     self.remote_ctn = chan.get_latest_ctn(REMOTE)
     self.local_csv = chan.config[LOCAL].to_self_delay
     self.remote_csv = chan.config[REMOTE].to_self_delay
     self.initiator = 'Local' if chan.constraints.is_initiator else 'Remote'
     feerate_kw = chan.get_latest_feerate(LOCAL)
     self.feerate = str(
         quantize_feerate(Transaction.satperbyte_from_satperkw(feerate_kw)))
     self.can_send = self.app.format_amount_and_units(
         chan.available_to_spend(LOCAL) // 1000)
     self.can_receive = self.app.format_amount_and_units(
         chan.available_to_spend(REMOTE) // 1000)
     self.is_open = chan.is_open()
     closed = chan.get_closing_height()
     if closed:
         self.closing_txid, closing_height, closing_timestamp = closed
     msg = messages.MSG_NON_TRAMPOLINE_CHANNEL_FROZEN_WITHOUT_GOSSIP
     self.warning = '' if self.app.wallet.lnworker.channel_db or self.app.wallet.lnworker.is_trampoline_peer(
         chan.node_id) else _('Warning') + ': ' + msg
     self.is_frozen_for_sending = chan.is_frozen_for_sending()
     self.is_frozen_for_receiving = chan.is_frozen_for_receiving()
     self.channel_type = chan.storage['channel_type'].name_minimal
     self.update_action_dropdown()
コード例 #25
0
ファイル: channels_list.py プロジェクト: fiatjaf/electrum
 def new_channel_dialog(self):
     lnworker = self.parent.wallet.lnworker
     d = WindowModalDialog(self.parent, _('Open Channel'))
     d.setMinimumWidth(700)
     vbox = QVBoxLayout(d)
     h = QGridLayout()
     local_nodeid = QLineEdit()
     local_nodeid.setText(bh2u(lnworker.node_keypair.pubkey))
     local_nodeid.setReadOnly(True)
     local_nodeid.setCursorPosition(0)
     remote_nodeid = QLineEdit()
     local_amt_inp = BTCAmountEdit(self.parent.get_decimal_point)
     local_amt_inp.setAmount(200000)
     push_amt_inp = BTCAmountEdit(self.parent.get_decimal_point)
     push_amt_inp.setAmount(0)
     h.addWidget(QLabel(_('Your Node ID')), 0, 0)
     h.addWidget(local_nodeid, 0, 1)
     h.addWidget(
         QLabel(_('Remote Node ID or connection string or invoice')), 1, 0)
     h.addWidget(remote_nodeid, 1, 1)
     h.addWidget(QLabel('Local amount'), 2, 0)
     h.addWidget(local_amt_inp, 2, 1)
     h.addWidget(QLabel('Push amount'), 3, 0)
     h.addWidget(push_amt_inp, 3, 1)
     vbox.addLayout(h)
     ok_button = OkButton(d)
     ok_button.setDefault(True)
     vbox.addLayout(Buttons(CancelButton(d), ok_button))
     suggestion = lnworker.suggest_peer() or b''
     remote_nodeid.setText(bh2u(suggestion))
     remote_nodeid.setCursorPosition(0)
     if not d.exec_():
         return
     local_amt = local_amt_inp.get_amount()
     push_amt = push_amt_inp.get_amount()
     connect_contents = str(remote_nodeid.text()).strip()
     self.parent.open_channel(connect_contents, local_amt, push_amt)
コード例 #26
0
 def make_htlc_item(self, i: UpdateAddHtlc,
                    direction: Direction) -> HTLCItem:
     it = HTLCItem(
         _('Sent HTLC with ID {}' if Direction.SENT ==
           direction else 'Received HTLC with ID {}').format(i.htlc_id))
     it.appendRow(
         [HTLCItem(_('Amount')),
          HTLCItem(self.format(i.amount_msat))])
     it.appendRow(
         [HTLCItem(_('CLTV expiry')),
          HTLCItem(str(i.cltv_expiry))])
     it.appendRow(
         [HTLCItem(_('Payment hash')),
          HTLCItem(bh2u(i.payment_hash))])
     return it
コード例 #27
0
ファイル: trezor.py プロジェクト: huazhouwang/electrum
 def sign_transaction(self, keystore, tx: PartialTransaction, prev_tx):
     prev_tx = {bfh(txhash): self.electrum_tx_to_txtype(tx) for txhash, tx in prev_tx.items()}
     if not self.client:
         raise Exception("client is None")
     xpub = keystore.xpub
     derivation = keystore.get_derivation_prefix()
     if not self.force_pair_with_xpub(self.client, xpub, derivation):
         raise Exception("Can't Pair With You Device When Sign tx")
     inputs = self.tx_inputs(tx, for_sig=True, keystore=keystore)
     outputs = self.tx_outputs(tx, keystore=keystore)
     details = SignTx(lock_time=tx.locktime, version=tx.version)
     signatures, _ = self.client.sign_tx(self.get_coin_name(), inputs, outputs, details=details, prev_txes=prev_tx)
     signatures = [(bh2u(x) + '01') for x in signatures]
     tx.update_signatures(signatures)
     raise Exception("sign success")
コード例 #28
0
 def sign_transaction(self, keystore, tx, prev_tx, xpub_path):
     prev_tx = {
         bfh(txhash): self.electrum_tx_to_txtype(tx, xpub_path)
         for txhash, tx in prev_tx.items()
     }
     client = self.get_client(keystore)
     inputs = self.tx_inputs(tx, xpub_path, True)
     outputs = self.tx_outputs(keystore.get_derivation(), tx)
     details = SignTx(lock_time=tx.locktime, version=tx.version)
     signatures, _ = client.sign_tx(self.get_coin_name(),
                                    inputs,
                                    outputs,
                                    details=details,
                                    prev_txes=prev_tx)
     signatures = [(bh2u(x) + '01') for x in signatures]
     tx.update_signatures(signatures)
コード例 #29
0
ファイル: coldcard.py プロジェクト: neocogent/electrum
    def sign_transaction(self, tx, password):
        # Build a PSBT in memory, upload it for signing.
        # - we can also work offline (without paired device present)
        if tx.is_complete():
            return

        client = self.get_client()

        assert client.dev.master_fingerprint == self.ckcc_xfp

        raw_psbt = self.build_psbt(tx)

        #open('debug.psbt', 'wb').write(out_fd.getvalue())

        try:
            try:
                self.handler.show_message("Authorize Transaction...")

                client.sign_transaction_start(raw_psbt, True)

                while 1:
                    # How to kill some time, without locking UI?
                    time.sleep(0.250)

                    resp = client.sign_transaction_poll()
                    if resp is not None:
                        break

                rlen, rsha = resp
            
                # download the resulting txn.
                new_raw = client.download_file(rlen, rsha)

            finally:
                self.handler.finished()

        except (CCUserRefused, CCBusyError) as exc:
            print_error('[coldcard]', 'Did not sign:', str(exc))
            self.handler.show_error(str(exc))
            return
        except BaseException as e:
            traceback.print_exc(file=sys.stderr)
            self.give_error(e, True)
            return

        # trust the coldcard to re-searilize final product right?
        tx.update(bh2u(new_raw))
コード例 #30
0
ファイル: coldcard.py プロジェクト: ssolidus/electrum
    def sign_transaction(self, tx, password):
        # Build a PSBT in memory, upload it for signing.
        # - we can also work offline (without paired device present)
        if tx.is_complete():
            return

        client = self.get_client()

        assert client.dev.master_fingerprint == self.ckcc_xfp

        raw_psbt = self.build_psbt(tx)

        #open('debug.psbt', 'wb').write(out_fd.getvalue())

        try:
            try:
                self.handler.show_message("Authorize Transaction...")

                client.sign_transaction_start(raw_psbt, True)

                while 1:
                    # How to kill some time, without locking UI?
                    time.sleep(0.250)

                    resp = client.sign_transaction_poll()
                    if resp is not None:
                        break

                rlen, rsha = resp

                # download the resulting txn.
                new_raw = client.download_file(rlen, rsha)

            finally:
                self.handler.finished()

        except (CCUserRefused, CCBusyError) as exc:
            print_error('[coldcard]', 'Did not sign:', str(exc))
            self.handler.show_error(str(exc))
            return
        except BaseException as e:
            traceback.print_exc(file=sys.stderr)
            self.give_error(e, True)
            return

        # trust the coldcard to re-searilize final product right?
        tx.update(bh2u(new_raw))
コード例 #31
0
    def on_receive(self, keyhash, message):
        self.print_error("signal arrived for", keyhash)
        for key, _hash, window in self.keys:
            if _hash == keyhash:
                break
        else:
            self.print_error("keyhash not found")
            return

        wallet = window.wallet
        if isinstance(wallet.keystore, keystore.Hardware_KeyStore):
            window.show_warning(
                _('An encrypted transaction was retrieved from cosigning pool.'
                  ) + '\n' +
                _('However, hardware wallets do not support message decryption, '
                  'which makes them not compatible with the current design of cosigner pool.'
                  ))
            return
        elif wallet.has_keystore_encryption():
            password = window.password_dialog(
                _('An encrypted transaction was retrieved from cosigning pool.'
                  ) + '\n' + _('Please enter your password to decrypt it.'))
            if not password:
                return
        else:
            password = None
            if not window.question(
                    _("An encrypted transaction was retrieved from cosigning pool."
                      ) + '\n' + _("Do you want to open it now?")):
                return

        xprv = wallet.keystore.get_master_private_key(password)
        if not xprv:
            return
        try:
            k = bitcoin.deserialize_xprv(xprv)[-1]
            EC = ecc.ECPrivkey(k)
            message = bh2u(EC.decrypt_message(message))
        except Exception as e:
            traceback.print_exc(file=sys.stdout)
            window.show_error(_('Error decrypting message') + ':\n' + str(e))
            return

        self.listener.clear(keyhash)
        tx = transaction.Transaction(message,
                                     window.network.get_server_height())
        show_transaction(tx, window, prompt_if_unsaved=True)
コード例 #32
0
 def test_scrypt(self):
     #0200000011f1fe21e0b66dc214be46366465cb95d29830e31ddd225a11349a836a993bf7b5db36b3e5593d039779bff204d132b65ee029a2e499ebeb5a4b19cbe862eee2b623cc5276676c1c000e1c60
     header = {
         'block_height': 12095,
         'nonce': 1612451328,
         'timestamp': 1389110198,
         'version': 2,
         'prev_block_hash':
         'f73b996a839a34115a22dd1de33098d295cb65643646be14c26db6e021fef111',
         'merkle_root':
         'e2ee62e8cb194b5aebeb99e4a229e05eb632d104f2bf7997033d59e5b336dbb5',
         'bits': 476866422
     }
     powhash = rev_hex(bh2u(scryptGetHash(bfh(serialize_header(header)))))
     self.assertEqual(
         powhash,
         '00000000335c88172421df73a1c1f22f4d7c23d8ef34c78d728c4eff3ba24a34')
コード例 #33
0
ファイル: qt.py プロジェクト: Cessaa/electrum-auxpow
    def on_receive(self, keyhash, message):
        self.logger.info(f"signal arrived for {keyhash}")
        for key, _hash, window in self.keys:
            if _hash == keyhash:
                break
        else:
            self.logger.info("keyhash not found")
            return

        wallet = window.wallet
        if isinstance(wallet.keystore, keystore.Hardware_KeyStore):
            window.show_warning(
                _('An encrypted transaction was retrieved from cosigning pool.'
                  ) + '\n' +
                _('However, hardware wallets do not support message decryption, '
                  'which makes them not compatible with the current design of cosigner pool.'
                  ))
            return
        elif wallet.has_keystore_encryption():
            password = window.password_dialog(
                _('An encrypted transaction was retrieved from cosigning pool.'
                  ) + '\n' + _('Please enter your password to decrypt it.'))
            if not password:
                return
        else:
            password = None
            if not window.question(
                    _("An encrypted transaction was retrieved from cosigning pool."
                      ) + '\n' + _("Do you want to open it now?")):
                return

        xprv = wallet.keystore.get_master_private_key(password)
        if not xprv:
            return
        try:
            privkey = BIP32Node.from_xkey(xprv).eckey
            message = bh2u(privkey.decrypt_message(message))
        except Exception as e:
            self.logger.exception('')
            window.show_error(_('Error decrypting message') + ':\n' + str(e))
            return

        self.listener.clear(keyhash)
        tx = transaction.Transaction(message)
        show_transaction(tx, window, prompt_if_unsaved=True)
コード例 #34
0
 def test_push_script(self):
     # https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#push-operators
     self.assertEqual(push_script(''), bh2u(bytes([opcodes.OP_0])))
     self.assertEqual(push_script('07'), bh2u(bytes([opcodes.OP_7])))
     self.assertEqual(push_script('10'), bh2u(bytes([opcodes.OP_16])))
     self.assertEqual(push_script('81'), bh2u(bytes([opcodes.OP_1NEGATE])))
     self.assertEqual(push_script('11'), '0111')
     self.assertEqual(push_script(75 * '42'), '4b' + 75 * '42')
     self.assertEqual(
         push_script(76 * '42'),
         bh2u(bytes([opcodes.OP_PUSHDATA1]) + bfh('4c' + 76 * '42')))
     self.assertEqual(
         push_script(100 * '42'),
         bh2u(bytes([opcodes.OP_PUSHDATA1]) + bfh('64' + 100 * '42')))
     self.assertEqual(
         push_script(255 * '42'),
         bh2u(bytes([opcodes.OP_PUSHDATA1]) + bfh('ff' + 255 * '42')))
     self.assertEqual(
         push_script(256 * '42'),
         bh2u(bytes([opcodes.OP_PUSHDATA2]) + bfh('0001' + 256 * '42')))
     self.assertEqual(
         push_script(520 * '42'),
         bh2u(bytes([opcodes.OP_PUSHDATA2]) + bfh('0802' + 520 * '42')))
コード例 #35
0
    def test_should_reject_coinbase_root_too_late(self):
        header = self.deserialize_with_auxpow(header_without_mm)

        input_script = bfh(header['powdata']['auxpow']
                           ['parent_coinbase_tx'].inputs()[0]['scriptSig'])

        padded_script = bfh('00') * (
            auxpow.MAX_INDEX_PC_BACKWARDS_COMPATIBILITY + 4)
        padded_script += input_script

        header['powdata']['auxpow']['parent_coinbase_tx']._inputs[0][
            'scriptSig'] = bh2u(padded_script)

        self.clear_coinbase_outputs(header['powdata']['auxpow'])

        with self.assertRaises(auxpow.AuxPoWCoinbaseRootTooLate):
            blockchain.Blockchain.verify_header(header, prev_hash_without_mm,
                                                target_without_mm)
コード例 #36
0
 def append_lnaddr(self, it: HTLCItem, lnaddr: LnAddr):
     invoice = HTLCItem(_('Invoice'))
     invoice.appendRow([
         HTLCItem(_('Remote node public key')),
         HTLCItem(bh2u(lnaddr.pubkey.serialize()))
     ])
     invoice.appendRow([
         HTLCItem(_('Amount in sat')),
         HTLCItem(str(lnaddr.amount * COIN))
     ])  # might have a comma because mSAT!
     invoice.appendRow([
         HTLCItem(_('Description')),
         HTLCItem(dict(lnaddr.tags).get('d', _('N/A')))
     ])
     invoice.appendRow(
         [HTLCItem(_('Date')),
          HTLCItem(format_time(lnaddr.date))])
     it.appendRow([invoice])
コード例 #37
0
 def format_fields(self, chan):
     labels = {}
     for subject in (REMOTE, LOCAL):
         bal_minus_htlcs = chan.balance_minus_outgoing_htlcs(subject)//1000
         label = self.parent.format_amount(bal_minus_htlcs)
         other = subject.inverted()
         bal_other = chan.balance(other)//1000
         bal_minus_htlcs_other = chan.balance_minus_outgoing_htlcs(other)//1000
         if bal_other != bal_minus_htlcs_other:
             label += ' (+' + self.parent.format_amount(bal_other - bal_minus_htlcs_other) + ')'
         labels[subject] = label
     return [
         format_short_channel_id(chan.short_channel_id),
         bh2u(chan.node_id),
         labels[LOCAL],
         labels[REMOTE],
         chan.get_state()
     ]
コード例 #38
0
ファイル: qt.py プロジェクト: wahidmounir/electrum
 def do_send(self, tx):
     for window, xpub, K, _hash in self.cosigner_list:
         if not self.cosigner_can_sign(tx, xpub):
             continue
         raw_tx_bytes = bfh(str(tx))
         message = bitcoin.encrypt_message(raw_tx_bytes,
                                           bh2u(K)).decode('ascii')
         try:
             server.put(_hash, message)
         except Exception as e:
             traceback.print_exc(file=sys.stdout)
             window.show_error(
                 _("Failed to send transaction to cosigning pool") + ':\n' +
                 str(e))
             return
         window.show_message(
             _("Your transaction was sent to the cosigning pool.") + '\n' +
             _("Open your cosigner wallet to retrieve it."))
コード例 #39
0
    def test_compact_size(self):
        s = transaction.BCDataStream()
        values = [
            0, 1, 252, 253, 2**16 - 1, 2**16, 2**32 - 1, 2**32, 2**64 - 1
        ]
        for v in values:
            s.write_compact_size(v)

        with self.assertRaises(transaction.SerializationError):
            s.write_compact_size(-1)

        self.assertEqual(
            bh2u(s.input),
            '0001fcfdfd00fdfffffe00000100feffffffffff0000000001000000ffffffffffffffffff'
        )
        for v in values:
            self.assertEqual(s.read_compact_size(), v)

        with self.assertRaises(transaction.SerializationError):
            s.read_compact_size()
コード例 #40
0
 def sign_transaction(self, keystore, tx: PartialTransaction, prev_tx):
     prev_tx = {
         bfh(txhash): self.electrum_tx_to_txtype(tx)
         for txhash, tx in prev_tx.items()
     }
     client = self.get_client(keystore)
     inputs = self.tx_inputs(tx, for_sig=True, keystore=keystore)
     outputs = self.tx_outputs(tx, keystore=keystore)
     details = SignTx(version=tx.version,
                      overwintered=tx.overwintered,
                      version_group_id=tx.versionGroupId,
                      lock_time=tx.locktime,
                      expiry=tx.expiryHeight)
     signatures, _ = client.sign_tx(self.get_coin_name(),
                                    inputs,
                                    outputs,
                                    details=details,
                                    prev_txes=prev_tx)
     signatures = [(bh2u(x) + '01') for x in signatures]
     tx.update_signatures(signatures)
コード例 #41
0
ファイル: qt.py プロジェクト: bauerj/electrum
    def on_receive(self, keyhash, message):
        self.print_error("signal arrived for", keyhash)
        for key, _hash, window in self.keys:
            if _hash == keyhash:
                break
        else:
            self.print_error("keyhash not found")
            return

        wallet = window.wallet
        if isinstance(wallet.keystore, keystore.Hardware_KeyStore):
            window.show_warning(_('An encrypted transaction was retrieved from cosigning pool.') + '\n' +
                                _('However, hardware wallets do not support message decryption, '
                                  'which makes them not compatible with the current design of cosigner pool.'))
            return
        elif wallet.has_keystore_encryption():
            password = window.password_dialog(_('An encrypted transaction was retrieved from cosigning pool.') + '\n' +
                                              _('Please enter your password to decrypt it.'))
            if not password:
                return
        else:
            password = None
            if not window.question(_("An encrypted transaction was retrieved from cosigning pool.") + '\n' +
                                   _("Do you want to open it now?")):
                return

        xprv = wallet.keystore.get_master_private_key(password)
        if not xprv:
            return
        try:
            k = bitcoin.deserialize_xprv(xprv)[-1]
            EC = ecc.ECPrivkey(k)
            message = bh2u(EC.decrypt_message(message))
        except Exception as e:
            traceback.print_exc(file=sys.stdout)
            window.show_error(_('Error decrypting message') + ':\n' + str(e))
            return

        self.listener.clear(keyhash)
        tx = transaction.Transaction(message)
        show_transaction(tx, window, prompt_if_unsaved=True)
コード例 #42
0
ファイル: main_window.py プロジェクト: nvk/electrum
 def on_qr(self, data):
     from electrum.bitcoin import base_decode, is_address
     data = data.strip()
     if is_address(data):
         self.set_URI(data)
         return
     if data.startswith('bitcoin:'):
         self.set_URI(data)
         return
     # try to decode transaction
     from electrum.transaction import Transaction
     from electrum.util import bh2u
     try:
         text = bh2u(base_decode(data, None, base=43))
         tx = Transaction(text)
         tx.deserialize()
     except:
         tx = None
     if tx:
         self.tx_dialog(tx)
         return
     # show error
     self.show_error("Unable to decode QR data")
コード例 #43
0
ファイル: qt.py プロジェクト: faircoin/electrumfair
 def update(self, window):
     wallet = window.wallet
     if type(wallet) != Multisig_Wallet:
         return
     if self.listener is None:
         self.print_error("starting listener")
         self.listener = Listener(self)
         self.listener.start()
     elif self.listener:
         self.print_error("shutting down listener")
         self.listener.stop()
         self.listener = None
     self.keys = []
     self.cosigner_list = []
     for key, keystore in wallet.keystores.items():
         xpub = keystore.get_master_public_key()
         pubkey = BIP32Node.from_xkey(xpub).eckey.get_public_key_bytes(compressed=True)
         _hash = bh2u(crypto.sha256d(pubkey))
         if not keystore.is_watching_only():
             self.keys.append((key, _hash, window))
         else:
             self.cosigner_list.append((window, xpub, pubkey, _hash))
     if self.listener:
         self.listener.set_keyhashes([t[1] for t in self.keys])
コード例 #44
0
ファイル: qt.py プロジェクト: bygage/electrum
 def update(self, window):
     wallet = window.wallet
     if type(wallet) != Multisig_Wallet:
         return
     if self.listener is None:
         self.print_error("starting listener")
         self.listener = Listener(self)
         self.listener.start()
     elif self.listener:
         self.print_error("shutting down listener")
         self.listener.stop()
         self.listener = None
     self.keys = []
     self.cosigner_list = []
     for key, keystore in wallet.keystores.items():
         xpub = keystore.get_master_public_key()
         K = bitcoin.deserialize_xpub(xpub)[-1]
         _hash = bh2u(bitcoin.Hash(K))
         if not keystore.is_watching_only():
             self.keys.append((key, _hash, window))
         else:
             self.cosigner_list.append((window, xpub, K, _hash))
     if self.listener:
         self.listener.set_keyhashes([t[1] for t in self.keys])
コード例 #45
0
ファイル: test_network.py プロジェクト: chrisrico/electrum
 def mock_fork(self, bad_header):
     forkpoint = bad_header['block_height']
     b = blockchain.Blockchain(config=self.config, forkpoint=forkpoint, parent=None,
                               forkpoint_hash=bh2u(sha256(str(forkpoint))), prev_hash=bh2u(sha256(str(forkpoint-1))))
     return b
コード例 #46
0
 def test_mnemonic_to_seed_basic(self):
     # note: not a valid electrum seed
     seed = mnemonic.Mnemonic.mnemonic_to_seed(mnemonic='foobar', passphrase='none')
     self.assertEqual('741b72fd15effece6bfe5a26a52184f66811bd2be363190e07a42cca442b1a5bb22b3ad0eb338197287e6d314866c7fba863ac65d3f156087a5052ebc7157fce',
                      bh2u(seed))
コード例 #47
0
ファイル: qt.py プロジェクト: asfin/electrum
    def import_ecc_key_to_gpg(self, privkey: str, pubkey: str) -> bool:
        assert len(pubkey) == 130
        assert len(privkey) == 64

        param_key = [
            # Prime
            ("p", 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F),
            # Coefficient A
            ("a", 0x0000000000000000000000000000000000000000000000000000000000000000),
            # Coefficient B
            ("b", 0x0000000000000000000000000000000000000000000000000000000000000007),
            # Generator in 04 || x || y format
            ("g",
             0x0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8),
            # Order of generator
            ("n", 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141),
        ]

        def compute_keygrip(k):
            md = sha1()
            for e in k:
                (e_name, e_value) = e
                if e_value == -1:
                    l = 0
                    s = ""
                else:
                    l = (e_value.bit_length() + 7) // 8
                    s = e_value.to_bytes(l, byteorder='big')
                v = "(1:%s%d:" % (e_name, l)
                vb = v.encode('utf-8') + s + b")"
                md.update(vb)
            return md.digest()

        GCRYPT_SEXP_FMT = "(private-key(ecc(curve secp256k1)(q #%s#)(d #%s#)))"
        keydata_str = GCRYPT_SEXP_FMT % (pubkey, privkey)

        param_key.append(('q', int.from_bytes(bfh(pubkey), 'big')))
        grip = bh2u(compute_keygrip(param_key)).upper()

        self.pk_dir.mkdir(parents=True, exist_ok=True)
        keygrip = self.pk_dir / (grip + '.key')
        keygrip.open('w').write(keydata_str)
        key_spec = '''
%echo Generating a secp256k1 OpenPGP key ECDSA and subkey ECDH from {0}
Key-Type:  ECDSA
Key-Grip:  {0}
Key-Curve: secp256k1
Key-Usage: sign,auth
Creation-Date: 20171105T000000Z
Name-Real: bitcoin
Name-Email: [email protected]
# Name-Comment:
Expire-Date: 0
Subkey-Type:  ECDH
Subkey-Grip:  {0}
Subkey-Curve: secp256k1
Subkey-Usage: encrypt
# Passphrase: abc
%commit
%echo done
        '''
        key_spec = key_spec.format(grip)

        try:
            key = self._gpg.gen_key(key_spec)
            self.default_key = key.fingerprint
        except Exception as e:
            return False
        return True
コード例 #48
0
ファイル: qt.py プロジェクト: asfin/electrum
 def _get_key_address(self):
     root_xpub = self.wallet.keystore.xpub
     xpub = bip32_public_derivation(root_xpub, 'm/', 'm/0/0')
     pubk = bh2u(point_to_ser(ser_to_point(bfh(self._xpub_to_gpg_pub(xpub))), compressed=True))
     addr = pubkey_to_address('p2pkh', pubk)
     return addr
コード例 #49
0
ファイル: qt.py プロジェクト: asfin/electrum
 def _xpub_to_gpg_pub(xpub: str) -> str:
     _, _, _, _, _, pubk = deserialize_xpub(xpub)
     pubkey = bh2u(point_to_ser(ser_to_point(pubk), compressed=False))
     return pubkey
コード例 #50
0
ファイル: qt.py プロジェクト: asfin/electrum
 def _get_gpg_ecc_compat_keys(cls, xprv) -> (str, str):
     xprv, xpub = bip32_private_derivation(xprv, 'm/', 'm/0/0')
     _, _, _, _, c, pk = deserialize_xprv(xprv)
     pk = bh2u(pk)
     pubk = cls._xpub_to_gpg_pub(xpub)
     return pk, pubk
コード例 #51
0
ファイル: ledger.py プロジェクト: bauerj/electrum
    def sign_transaction(self, tx, password):
        if tx.is_complete():
            return
        client = self.get_client()
        inputs = []
        inputsPaths = []
        pubKeys = []
        chipInputs = []
        redeemScripts = []
        signatures = []
        preparedTrustedInputs = []
        changePath = ""
        changeAmount = None
        output = None
        outputAmount = None
        p2shTransaction = False
        segwitTransaction = False
        pin = ""
        self.get_client() # prompt for the PIN before displaying the dialog if necessary

        # Fetch inputs of the transaction to sign
        derivations = self.get_tx_derivations(tx)
        for txin in tx.inputs():
            if txin['type'] == 'coinbase':
                self.give_error("Coinbase not supported")     # should never happen

            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(MSG_NEEDS_FW_UPDATE_SEGWIT)
                segwitTransaction = True

            if txin['type'] in ['p2wpkh', 'p2wsh']:
                if not self.get_client_electrum().supports_native_segwit():
                    self.give_error(MSG_NEEDS_FW_UPDATE_SEGWIT)
                segwitTransaction = True

            pubkeys, x_pubkeys = tx.get_sorted_pubkeys(txin)
            for i, x_pubkey in enumerate(x_pubkeys):
                if x_pubkey in derivations:
                    signingPos = i
                    s = derivations.get(x_pubkey)
                    hwAddress = "%s/%d/%d" % (self.get_derivation()[2:], s[0], s[1])
                    break
            else:
                self.give_error("No matching x_key for sign_transaction") # should never happen

            redeemScript = Transaction.get_preimage_script(txin)
            txin_prev_tx = txin.get('prev_tx')
            if txin_prev_tx is None and not Transaction.is_segwit_input(txin):
                raise Exception(_('Offline signing with {} is not supported for legacy inputs.').format(self.device))
            txin_prev_tx_raw = txin_prev_tx.raw if txin_prev_tx else None
            inputs.append([txin_prev_tx_raw,
                           txin['prevout_n'],
                           redeemScript,
                           txin['prevout_hash'],
                           signingPos,
                           txin.get('sequence', 0xffffffff - 1),
                           txin.get('value')])
            inputsPaths.append(hwAddress)
            pubKeys.append(pubkeys)

        # Sanity check
        if p2shTransaction:
            for txin in tx.inputs():
                if txin['type'] != 'p2sh':
                    self.give_error("P2SH / regular input mixed in same transaction not supported") # should never happen

        txOutput = var_int(len(tx.outputs()))
        for txout in tx.outputs():
            output_type, addr, amount = txout
            txOutput += int_to_hex(amount, 8)
            script = tx.pay_script(output_type, addr)
            txOutput += var_int(len(script)//2)
            txOutput += script
        txOutput = bfh(txOutput)

        # Recognize outputs - only one output and one change is authorized
        if not p2shTransaction:
            if not self.get_client_electrum().supports_multi_output():
                if len(tx.outputs()) > 2:
                    self.give_error("Transaction with more than 2 outputs not supported")
            for _type, address, amount in tx.outputs():
                assert _type == TYPE_ADDRESS
                info = tx.output_info.get(address)
                if (info is not None) and len(tx.outputs()) > 1 \
                        and info[0][0] == 1:  # "is on 'change' branch"
                    index, xpubs, m = info
                    changePath = self.get_derivation()[2:] + "/%d/%d"%index
                    changeAmount = amount
                else:
                    output = address
                    outputAmount = amount

        self.handler.show_message(_("Confirm Transaction on your Ledger device..."))
        try:
            # Get trusted inputs from the original transactions
            for utxo in inputs:
                sequence = int_to_hex(utxo[5], 4)
                if segwitTransaction:
                    tmp = bfh(utxo[3])[::-1]
                    tmp += bfh(int_to_hex(utxo[1], 4))
                    tmp += bfh(int_to_hex(utxo[6], 8))  # txin['value']
                    chipInputs.append({'value' : tmp, 'witness' : True, 'sequence' : sequence})
                    redeemScripts.append(bfh(utxo[2]))
                elif not p2shTransaction:
                    txtmp = bitcoinTransaction(bfh(utxo[0]))
                    trustedInput = self.get_client().getTrustedInput(txtmp, utxo[1])
                    trustedInput['sequence'] = sequence
                    chipInputs.append(trustedInput)
                    redeemScripts.append(txtmp.outputs[utxo[1]].script)
                else:
                    tmp = bfh(utxo[3])[::-1]
                    tmp += bfh(int_to_hex(utxo[1], 4))
                    chipInputs.append({'value' : tmp, 'sequence' : sequence})
                    redeemScripts.append(bfh(utxo[2]))

            # Sign all inputs
            firstTransaction = True
            inputIndex = 0
            rawTx = tx.serialize()
            self.get_client().enableAlternate2fa(False)
            if segwitTransaction:
                self.get_client().startUntrustedTransaction(True, inputIndex,
                                                            chipInputs, redeemScripts[inputIndex])
                if changePath:
                    # we don't set meaningful outputAddress, amount and fees
                    # as we only care about the alternateEncoding==True branch
                    outputData = self.get_client().finalizeInput(b'', 0, 0, changePath, bfh(rawTx))
                else:
                    outputData = self.get_client().finalizeInputFull(txOutput)
                outputData['outputData'] = txOutput
                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..."))
                while inputIndex < len(inputs):
                    singleInput = [ chipInputs[inputIndex] ]
                    self.get_client().startUntrustedTransaction(False, 0,
                                                            singleInput, redeemScripts[inputIndex])
                    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])
                    if changePath:
                        # we don't set meaningful outputAddress, amount and fees
                        # as we only care about the alternateEncoding==True branch
                        outputData = self.get_client().finalizeInput(b'', 0, 0, changePath, bfh(rawTx))
                    else:
                        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
        except UserWarning:
            self.handler.show_error(_('Cancelled by user'))
            return
        except BTChipException as e:
            if e.sw == 0x6985:  # cancelled by user
                return
            elif e.sw == 0x6982:
                raise  # pin lock. decorator will catch it
            else:
                traceback.print_exc(file=sys.stderr)
                self.give_error(e, True)
        except BaseException as e:
            traceback.print_exc(file=sys.stdout)
            self.give_error(e, True)
        finally:
            self.handler.finished()

        for i, txin in enumerate(tx.inputs()):
            signingPos = inputs[i][4]
            Transaction.add_signature_to_txin(txin, signingPos, bh2u(signatures[i]))
        tx.raw = tx.serialize()
コード例 #52
0
ファイル: test_mnemonic.py プロジェクト: asfin/electrum
 def test_to_seed(self):
     seed = mnemonic.Mnemonic.mnemonic_to_seed(mnemonic='foobar', passphrase='none')
     self.assertEqual(bh2u(seed),
                       '741b72fd15effece6bfe5a26a52184f66811bd2be363190e07a42cca442b1a5b'
                       'b22b3ad0eb338197287e6d314866c7fba863ac65d3f156087a5052ebc7157fce')