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
def check_from_x(self, x, prv): node = BIP32Node.from_xkey(x) self.assertEqual(self.xtype, node.xtype) self.assertEqual(1, node.depth) self.assertEqual(self.master_fpr, bh2u(node.fingerprint)) self.assertEqual(self.child_num, bh2u(node.child_number)) self.assertEqual(self.chain_code, bh2u(node.chaincode)) self.assertEqual(self.pub_key, node.eckey.get_public_key_hex()) if prv: self.assertEqual(self.sec_key, bh2u(node.eckey.get_secret_bytes()))
def check_deserialized(self, deserialized, prv): xtype, depth, fpr, child_number, c, K = deserialized self.assertEqual(self.xtype, xtype) self.assertEqual(1, depth) self.assertEqual(self.master_fpr, bh2u(fpr)) self.assertEqual(self.child_num, bh2u(child_number)) self.assertEqual(self.chain_code, bh2u(c)) if prv: self.assertEqual(self.sec_key, bh2u(K)) else: self.assertEqual(self.pub_key, bh2u(K))
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)
def test_dsa_msg(self): msg = AxeDsaMsg.from_hex(DSA_MSG) assert msg.nDenom == 2 assert type(msg.txCollateral) == str tx = Transaction(msg.txCollateral) assert type(tx) == Transaction assert bh2u(msg.serialize()) == DSA_MSG
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())
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)
def update(self, window): wallet = window.wallet if type(wallet) != Multisig_Wallet: return if self.listener is None: self.logger.info("starting listener") self.listener = Listener(self) self.listener.start() elif self.listener: self.logger.info("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])
def test_to_seed(self): seed = mnemonic.Mnemonic.mnemonic_to_seed(mnemonic='foobar', passphrase='none') self.assertEqual( bh2u(seed), '741b72fd15effece6bfe5a26a52184f66811bd2be363190e07a42cca442b1a5b' 'b22b3ad0eb338197287e6d314866c7fba863ac65d3f156087a5052ebc7157fce')
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')))
def test_dsq_msg(self): msg = AxeDsqMsg.from_hex(DSQ_MSG) assert msg.nDenom == 2 assert type(msg.masternodeOutPoint) == TxOutPoint assert msg.nTime == 1567673683 assert msg.fReady assert len(msg.vchSig) == 96 assert bh2u(msg.serialize()) == DSQ_MSG
def test_dssu_msg(self): msg = AxeDssuMsg.from_hex(DSSU_MSG) assert msg.sessionID == 67305985 assert msg.state == 5 assert msg.entriesCount == 3 assert msg.statusUpdate == 1 assert msg.messageID == 21 assert bh2u(msg.serialize()) == DSSU_MSG
def test_dsi_msg(self): msg = AxeDsiMsg.from_hex(DSI_MSG) assert len(msg.vecTxDSIn) == 2 for txin in msg.vecTxDSIn: assert type(txin) == CTxIn assert type(msg.txCollateral) == str tx = Transaction(msg.txCollateral) assert type(tx) == Transaction assert len(msg.vecTxDSOut) == 2 for txout in msg.vecTxDSOut: assert type(txout) == CTxOut assert bh2u(msg.serialize()) == DSI_MSG
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)
def test_bip32_extended_version_bytes(self, mock_write): seed_words = 'crouch dumb relax small truck age shine pink invite spatial object tenant' self.assertEqual(keystore.bip39_is_checksum_valid(seed_words), (True, True)) bip32_seed = keystore.bip39_to_seed(seed_words, '') self.assertEqual( '0df68c16e522eea9c1d8e090cfb2139c3b3a2abed78cbcb3e20be2c29185d3b8df4e8ce4e52a1206a688aeb88bfee249585b41a7444673d1f16c0d45755fa8b9', bh2u(bip32_seed)) def create_keystore_from_bip32seed(xtype): ks = keystore.BIP32_KeyStore({}) ks.add_xprv_from_seed(bip32_seed, xtype=xtype, derivation='m/') return ks ks = create_keystore_from_bip32seed(xtype='standard') self.assertEqual( '033a05ec7ae9a9833b0696eb285a762f17379fa208b3dc28df1c501cf84fe415d0', ks.derive_pubkey(0, 0)) self.assertEqual( '02bf27f41683d84183e4e930e66d64fc8af5508b4b5bf3c473c505e4dbddaeed80', ks.derive_pubkey(1, 0)) ks = create_keystore_from_bip32seed(xtype='standard') # p2pkh w = WalletIntegrityHelper.create_standard_wallet(ks) self.assertEqual( ks.xprv, 'xprv9s21ZrQH143K3nyWMZVjzGL4KKAE1zahmhTHuV5pdw4eK3o3igC5QywgQG7UTRe6TGBniPDpPFWzXMeMUFbBj8uYsfXGjyMmF54wdNt8QBm' ) self.assertEqual( ks.xpub, 'xpub661MyMwAqRbcGH3yTb2kMQGnsLziRTJZ8vNthsVSCGbdBr8CGDWKxnGAFYgyKTzBtwvPPmfVAWJuFmxRXjSbUTg87wDkWQ5GmzpfUcN9t8Z' ) self.assertEqual(w.get_receiving_addresses()[0], 'PHFgPTyNtbnSEcn4tTAdUowFMK8w5bHghd') self.assertEqual(w.get_change_addresses()[0], 'PMphGbxt4mGpXpK5yffckyuHcPFZm3f5Cq') ks = create_keystore_from_bip32seed(xtype='standard') # p2sh w = WalletIntegrityHelper.create_multisig_wallet([ks], '1of1') self.assertEqual( ks.xprv, 'xprv9s21ZrQH143K3nyWMZVjzGL4KKAE1zahmhTHuV5pdw4eK3o3igC5QywgQG7UTRe6TGBniPDpPFWzXMeMUFbBj8uYsfXGjyMmF54wdNt8QBm' ) self.assertEqual( ks.xpub, 'xpub661MyMwAqRbcGH3yTb2kMQGnsLziRTJZ8vNthsVSCGbdBr8CGDWKxnGAFYgyKTzBtwvPPmfVAWJuFmxRXjSbUTg87wDkWQ5GmzpfUcN9t8Z' ) self.assertEqual(w.get_receiving_addresses()[0], '7fnRbKn5baDQxGTny63XNWPCcBs5dQEBtK') self.assertEqual(w.get_change_addresses()[0], '7nrNkWYwmyavE9K3SgexxwshHhS9DvyeGK')
def test_bip32_extended_version_bytes(self, mock_write): seed_words = 'crouch dumb relax small truck age shine pink invite spatial object tenant' self.assertEqual(keystore.bip39_is_checksum_valid(seed_words), (True, True)) bip32_seed = keystore.bip39_to_seed(seed_words, '') self.assertEqual( '0df68c16e522eea9c1d8e090cfb2139c3b3a2abed78cbcb3e20be2c29185d3b8df4e8ce4e52a1206a688aeb88bfee249585b41a7444673d1f16c0d45755fa8b9', bh2u(bip32_seed)) def create_keystore_from_bip32seed(xtype): ks = keystore.BIP32_KeyStore({}) ks.add_xprv_from_seed(bip32_seed, xtype=xtype, derivation='m/') return ks ks = create_keystore_from_bip32seed(xtype='standard') self.assertEqual( '033a05ec7ae9a9833b0696eb285a762f17379fa208b3dc28df1c501cf84fe415d0', ks.derive_pubkey(0, 0)) self.assertEqual( '02bf27f41683d84183e4e930e66d64fc8af5508b4b5bf3c473c505e4dbddaeed80', ks.derive_pubkey(1, 0)) ks = create_keystore_from_bip32seed(xtype='standard') # p2pkh w = WalletIntegrityHelper.create_standard_wallet(ks) self.assertEqual( ks.xprv, 'tprv8ZgxMBicQKsPecD328MF9ux3dSaSFWci7FNQmuWH7uZ86eY8i3XpvjK8KSH8To2QphiZiUqaYc6nzDC6bTw8YCB9QJjaQL5pAApN4z7vh2B' ) self.assertEqual( ks.xpub, 'tpubD6NzVbkrYhZ4Y5Epun1qZKcACU6NQqocgYyC4RYaYBMWw8nuLSMR7DvzVamkqxwRgrTJ1MBMhc8wwxT2vbHqMu8RBXy4BvjWMxR5EdZroxE' ) self.assertEqual(w.get_receiving_addresses()[0], 'yUyx5hJsEwAukTdRy7UihU57rC37Y4y2ZX') self.assertEqual(w.get_change_addresses()[0], 'yZYxxqJNR6fJ3fAT4Kyhye3A7G9kC19B9q') ks = create_keystore_from_bip32seed(xtype='standard') # p2sh w = WalletIntegrityHelper.create_multisig_wallet([ks], '1of1') self.assertEqual( ks.xprv, 'tprv8ZgxMBicQKsPecD328MF9ux3dSaSFWci7FNQmuWH7uZ86eY8i3XpvjK8KSH8To2QphiZiUqaYc6nzDC6bTw8YCB9QJjaQL5pAApN4z7vh2B' ) self.assertEqual( ks.xpub, 'tpubD6NzVbkrYhZ4Y5Epun1qZKcACU6NQqocgYyC4RYaYBMWw8nuLSMR7DvzVamkqxwRgrTJ1MBMhc8wwxT2vbHqMu8RBXy4BvjWMxR5EdZroxE' ) self.assertEqual(w.get_receiving_addresses()[0], '8soEYefwj7c3QZt43M3UptCZVhduigoYNs') self.assertEqual(w.get_change_addresses()[0], '8zsBhqSouWyYgSjJWwevRKh4BDCySjizKi')
def test_tx_outpoint(self): # test normal outpoint o = TxOutPoint(bfh(TEST_HASH)[::-1], 1) assert o.is_null == False assert o.hash_is_null == False assert str(o) == TEST_HASH + ':1' ser = o.serialize() assert bh2u(ser) == bh2u(bfh(TEST_HASH)[::-1]) + '01000000' s = BCDataStream() s.write(ser) o2 = TxOutPoint.read_vds(s) assert str(o2) == str(o) # test null outpoint o = TxOutPoint(b'\x00' * 32, -1) assert o.is_null == True assert o.hash_is_null == True assert str(o) == '0' * 64 + ':-1' ser = o.serialize() assert bh2u(ser) == '0' * 64 + 'f' * 8 s = BCDataStream() s.write(ser) o2 = TxOutPoint.read_vds(s) assert str(o2) == str(o) # test null hash o = TxOutPoint(b'\x00' * 32, 0) assert o.is_null == False assert o.hash_is_null == True assert str(o) == '0' * 64 + ':0' ser = o.serialize() assert bh2u(ser) == '0' * 64 + '00000000' s = BCDataStream() s.write(ser) o2 = TxOutPoint.read_vds(s) assert str(o2) == str(o)
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)
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)
def test_version_msg(self): msg = AxeVersionMsg.from_hex(VERSION_MSG) assert msg.version == 70216 assert msg.services == 5 assert msg.timestamp == 1586713440 assert msg.recv_services == 5 assert msg.recv_ip == IPv6Address('::ffff:95f8:3d95') assert msg.recv_port == 19937 assert msg.trans_services == 5 assert msg.trans_ip == IPv6Address('::') assert msg.trans_port == 0 assert msg.nonce == 9991039126381119619 assert msg.user_agent == b'/Axe Core:1.5.0.1/' assert msg.start_height == 47164 assert msg.relay == 1 assert msg.mnauth_challenge == bfh('c60f1b0590d4151a5cac6414ba4683df' '2a5ba3b2cc6f7336a1b70907eaeff2ce') assert msg.fMasternode == 0 assert bh2u(msg.serialize()) == VERSION_MSG
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()
def on_qr(self, data): from electrum_axe.bitcoin import base_decode, is_address data = data.strip() if is_address(data): self.set_URI(data) return if data.startswith('axe:'): self.set_URI(data) return # try to decode transaction from electrum_axe.transaction import Transaction from electrum_axe.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")
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])
def test_dss_msg(self): msg = AxeDssMsg.from_hex(DSS_MSG) assert len(msg.inputs) == 2 for txin in msg.inputs: assert type(txin) == CTxIn assert bh2u(msg.serialize()) == DSS_MSG
def sign_transaction(self, tx, password): if tx.is_complete(): return client = self.get_client() inputs = [] inputsPaths = [] pubKeys = [] chipInputs = [] redeemScripts = [] signatures = [] preparedTrustedInputs = [] changePath = "" output = None p2shTransaction = 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 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: 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 (for hw.1 and nano) # - at most one output can bypass confirmation (~change) (for all) 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") has_change = False any_output_on_change_branch = is_any_tx_output_on_change_branch(tx) for o in tx.outputs(): assert o.type == TYPE_ADDRESS info = tx.output_info.get(o.address) if (info is not None) and len(tx.outputs()) > 1 \ and not has_change: index = info.address_index on_change_branch = index[0] == 1 # prioritise hiding outputs on the 'change' branch from user # because no more than one change address allowed if on_change_branch == any_output_on_change_branch: changePath = self.get_derivation( )[2:] + "/%d/%d" % index has_change = True else: output = o.address else: output = o.address if not self.get_client_electrum().canAlternateCoinVersions: v, h = b58_address_to_hash160(address) if v == constants.net.ADDRTYPE_P2PKH: output = hash160_to_b58_address(h, 0) 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 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_to_network() self.get_client().enableAlternate2fa(False) 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] tx.add_signature_to_txin(i, signingPos, bh2u(signatures[i])) tx.raw = tx.serialize()
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))
def test_dsc_msg(self): msg = AxeDscMsg.from_hex(DSC_MSG) assert msg.sessionID == 67305985 assert msg.messageID == 21 assert bh2u(msg.serialize()) == DSC_MSG
def test_dsf_msg(self): msg = AxeDsfMsg.from_hex(DSF_MSG) assert msg.sessionID == 7 assert type(msg.txFinal) == Transaction assert bh2u(msg.serialize()) == DSF_MSG