def test_electrum_multisig_seed_standard(self, mock_write): seed_words = 'blast uniform dragon fiscal ensure vast young utility dinosaur abandon rookie sure' self.assertEqual(bitcoin.seed_type(seed_words), 'standard') ks1 = keystore.from_seed(seed_words, '', True) self._check_seeded_keystore_sanity(ks1) self.assertTrue(isinstance(ks1, keystore.BIP32_KeyStore)) self.assertEqual( ks1.xpub, 'xpub661MyMwAqRbcGNEPu3aJQqXTydqR9t49Tkwb4Esrj112kw8xLthv8uybxvaki4Ygt9xiwZUQGeFTG7T2TUzR3eA4Zp3aq5RXsABHFBUrq4c' ) ks2 = keystore.from_xpub( 'xpub661MyMwAqRbcGfCPEkkyo5WmcrhTq8mi3xuBS7VEZ3LYvsgY1cCFDbenT33bdD12axvrmXhuX3xkAbKci3yZY9ZEk8vhLic7KNhLjqdh5ec' ) self._check_xpub_keystore_sanity(ks2) self.assertTrue(isinstance(ks2, keystore.BIP32_KeyStore)) w = self._create_multisig_wallet(ks1, ks2) self.assertEqual( w.get_receiving_addresses()[0], Address.from_string('32ji3QkAgXNz6oFoRfakyD3ys1XXiERQYN')) self.assertEqual( w.get_change_addresses()[0], Address.from_string('36XWwEHrrVCLnhjK5MrVVGmUHghr9oWTN1'))
def test_bip39_multisig_seed_bip45_standard(self, mock_write): seed_words = 'treat dwarf wealth gasp brass outside high rent blood crowd make initial' self.assertEqual(keystore.bip39_is_checksum_valid(seed_words), (True, True)) ks1 = keystore.from_bip39_seed(seed_words, '', "m/45'/0") self.assertTrue(isinstance(ks1, keystore.BIP32_KeyStore)) self.assertEqual( ks1.xpub, 'xpub69xafV4YxC6o8Yiga5EiGLAtqR7rgNgNUGiYgw3S9g9pp6XYUne1KxdcfYtxwmA3eBrzMFuYcNQKfqsXCygCo4GxQFHfywxpUbKNfYvGJka' ) ks2 = keystore.from_xpub( 'xpub6Bco9vrgo8rNUSi8Bjomn8xLA41DwPXeuPcgJamNRhTTyGVHsp8fZXaGzp9ypHoei16J6X3pumMAP1u3Dy4jTSWjm4GZowL7Dcn9u4uZC9W' ) self._check_xpub_keystore_sanity(ks2) self.assertTrue(isinstance(ks2, keystore.BIP32_KeyStore)) w = self._create_multisig_wallet(ks1, ks2) self.assertEqual( w.get_receiving_addresses()[0], Address.from_string('3H3iyACDTLJGD2RMjwKZcCwpdYZLwEZzKb')) self.assertEqual( w.get_change_addresses()[0], Address.from_string('31hyfHrkhNjiPZp1t7oky5CGNYqSqDAVM9'))
def test_tx_signed(self): expected = { 'inputs': [{'address': Address.from_string('13Vp8Y3hD5Cb6sERfpxePz5vGJizXbWciN'), 'num_sig': 1, 'prevout_hash': 'ed6a4d07e546b677abf6ba1257c2546128c694f23f4b9ebbd822fdfe435ef349', 'prevout_n': 1, 'pubkeys': ['03b5bbebceeb33c1b61f649596b9c3611c6b2853a1f6b48bce05dd54f667fa2166'], 'scriptSig': '473044022025bdc804c6fe30966f6822dc25086bc6bb0366016e68e880cf6efd2468921f3202200e665db0404f6d6d9f86f73838306ac55bb0d0f6040ac6047d4e820f24f46885412103b5bbebceeb33c1b61f649596b9c3611c6b2853a1f6b48bce05dd54f667fa2166', 'sequence': 4294967294, 'signatures': ['3044022025bdc804c6fe30966f6822dc25086bc6bb0366016e68e880cf6efd2468921f3202200e665db0404f6d6d9f86f73838306ac55bb0d0f6040ac6047d4e820f24f4688541'], 'type': 'p2pkh', 'x_pubkeys': ['03b5bbebceeb33c1b61f649596b9c3611c6b2853a1f6b48bce05dd54f667fa2166']}], 'lockTime': 507231, 'outputs': [{'address': Address.from_string('1MYXdf4moacvaEKZ57ozerpJ3t9xSeN6LK'), 'prevout_n': 0, 'scriptPubKey': '76a914e158fb15c888037fdc40fb9133b4c1c3c688706488ac', 'type': 0, 'value': 20112408}], 'version': 1 } tx = transaction.Transaction(signed_blob) self.assertEqual(tx.deserialize(), expected) self.assertEqual(tx.deserialize(), None) self.assertEqual(tx.as_dict(), {'hex': signed_blob, 'complete': True, 'final': True}) self.assertEqual(tx.serialize(), signed_blob) tx.update_signatures(signed_blob) self.assertEqual(tx.estimated_size(), 191)
def test_address_to_pubkey(self): addr = Address.from_string('1KXf5PUHNaV42jE9NbJFPKhGGN1fSSGJNK') pubkey = imported_keystore.address_to_pubkey(addr) assert pubkey.to_hex() == ( '04e7dd15b4271f8308ff52ad3d3e472b652e78a2c5bc6ed10250a543d28c0128894ae' '863d086488e6773c4589be93a1793f685dd3f1e8a1f1b390b23470f7d1095') addr = Address.from_string('1JYPZWn7YbJJ8LpNknU1EVxs3JXuVzc7Rd') assert imported_keystore.address_to_pubkey(addr) is None
def create_menu(self, position): menu = QMenu() selected = self.selectedItems() if not selected: menu.addAction(_("New contact"), self.parent.new_contact_dialog) menu.addAction(_("Import file"), self.import_contacts) else: keys = [item.text(1) for item in selected] column = self.currentColumn() column_title = self.headerItem().text(column) column_data = '\n'.join([item.text(column) for item in selected]) menu.addAction( _("Copy {}").format(column_title), lambda: self.parent.app.clipboard().setText(column_data)) if column in self.editable_columns: item = self.currentItem() menu.addAction( _("Edit {}").format(column_title), lambda: self.editItem(item, column)) menu.addAction(_("Pay to"), lambda: self.parent.payto_contacts(keys)) menu.addAction(_("Delete"), lambda: self.parent.delete_contacts(keys)) URLs = [ web.BE_URL(self.config, 'addr', Address.from_string(key)) for key in keys if Address.is_valid(key) ] if URLs: menu.addAction(_("View on block explorer"), lambda: [webbrowser.open(URL) for URL in URLs]) menu.exec_(self.viewport().mapToGlobal(position))
def test_bip39_seed_bip44_standard(self, mock_write): seed_words = 'treat dwarf wealth gasp brass outside high rent blood crowd make initial' self.assertEqual(keystore.bip39_is_checksum_valid(seed_words), (True, True)) ks = keystore.from_bip39_seed(seed_words, '', "m/44'/0'/0'") self.assertTrue(isinstance(ks, keystore.BIP32_KeyStore)) self.assertEqual(ks.xpub, 'xpub6DFh1smUsyqmYD4obDX6ngaxhd53Zx7aeFjoobebm7vbkT6f9awJWFuGzBT9FQJEWFBL7UyhMXtYzRcwDuVbcxtv9Ce2W9eMm4KXLdvdbjv') w = self._create_standard_wallet(ks) self.assertEqual(w.get_receiving_addresses()[0], Address.from_string('16j7Dqk3Z9DdTdBtHcCVLaNQy9MTgywUUo')) self.assertEqual(w.get_change_addresses()[0], Address.from_string('1GG5bVeWgAp5XW7JLCphse14QaC4qiHyWn'))
def test_electrum_seed_standard(self, mock_write): seed_words = 'cycle rocket west magnet parrot shuffle foot correct salt library feed song' self.assertEqual(bitcoin.seed_type(seed_words), 'standard') ks = keystore.from_seed(seed_words, '', False) self._check_seeded_keystore_sanity(ks) self.assertTrue(isinstance(ks, keystore.BIP32_KeyStore)) self.assertEqual(ks.xpub, 'xpub661MyMwAqRbcFWohJWt7PHsFEJfZAvw9ZxwQoDa4SoMgsDDM1T7WK3u9E4edkC4ugRnZ8E4xDZRpk8Rnts3Nbt97dPwT52CwBdDWroaZf8U') w = self._create_standard_wallet(ks) self.assertEqual(w.get_receiving_addresses()[0], Address.from_string('1NNkttn1YvVGdqBW4PR6zvc3Zx3H5owKRf')) self.assertEqual(w.get_change_addresses()[0], Address.from_string('1KSezYMhAJMWqFbVFB2JshYg69UpmEXR4D'))
def test_electrum_seed_old(self, mock_write): seed_words = 'powerful random nobody notice nothing important anyway look away hidden message over' self.assertEqual(bitcoin.seed_type(seed_words), 'old') ks = keystore.from_seed(seed_words, '', False) self._check_seeded_keystore_sanity(ks) self.assertTrue(isinstance(ks, keystore.Old_KeyStore)) self.assertEqual(ks.mpk, 'e9d4b7866dd1e91c862aebf62a49548c7dbf7bcc6e4b7b8c9da820c7737968df9c09d5a3e271dc814a29981f81b3faaf2737b551ef5dcc6189cf0f8252c442b3') w = self._create_standard_wallet(ks) self.assertEqual(w.get_receiving_addresses()[0], Address.from_string('1FJEEB8ihPMbzs2SkLmr37dHyRFzakqUmo')) self.assertEqual(w.get_change_addresses()[0], Address.from_string('1KRW8pH6HFHZh889VDq6fEKvmrsmApwNfe'))
def test_tx_unsigned(self): expected = { 'inputs': [{'address': Address.from_string('13Vp8Y3hD5Cb6sERfpxePz5vGJizXbWciN'), 'num_sig': 1, 'prevout_hash': 'ed6a4d07e546b677abf6ba1257c2546128c694f23f4b9ebbd822fdfe435ef349', 'prevout_n': 1, 'pubkeys': ['03b5bbebceeb33c1b61f649596b9c3611c6b2853a1f6b48bce05dd54f667fa2166'], 'scriptSig': '01ff4c53ff0488b21e0000000000000000004f130d773e678a58366711837ec2e33ea601858262f8eaef246a7ebd19909c9a03c3b30e38ca7d797fee1223df1c9827b2a9f3379768f520910260220e0560014600002300', 'sequence': 4294967294, 'signatures': [None], 'type': 'p2pkh', 'value': 20112600, 'x_pubkeys': ['ff0488b21e0000000000000000004f130d773e678a58366711837ec2e33ea601858262f8eaef246a7ebd19909c9a03c3b30e38ca7d797fee1223df1c9827b2a9f3379768f520910260220e0560014600002300']}], 'lockTime': 507231, 'outputs': [{'address': Address.from_string('1MYXdf4moacvaEKZ57ozerpJ3t9xSeN6LK'), 'prevout_n': 0, 'scriptPubKey': '76a914e158fb15c888037fdc40fb9133b4c1c3c688706488ac', 'type': 0, 'value': 20112408}], 'version': 1} tx = transaction.Transaction(unsigned_blob) calc = tx.deserialize() self.assertEqual(calc, expected) self.assertEqual(tx.deserialize(), None) self.assertEqual(tx.as_dict(), {'hex': unsigned_blob, 'complete': False, 'final': True}) self.assertEqual(tx.get_outputs(), [(Address.from_string('1MYXdf4moacvaEKZ57ozerpJ3t9xSeN6LK'), 20112408)]) self.assertEqual(tx.get_output_addresses(), [Address.from_string('1MYXdf4moacvaEKZ57ozerpJ3t9xSeN6LK')]) self.assertTrue(tx.has_address(Address.from_string('1MYXdf4moacvaEKZ57ozerpJ3t9xSeN6LK'))) self.assertTrue(tx.has_address(Address.from_string('13Vp8Y3hD5Cb6sERfpxePz5vGJizXbWciN'))) self.assertFalse(tx.has_address(Address.from_string('1CQj15y1N7LDHp7wTt28eoD1QhHgFgxECH'))) self.assertEqual(tx.serialize(), unsigned_blob)
def test_pubkeys_to_address(self, tmp_storage, network): coin = network.COIN privkey = PrivateKey.from_random() WIF = privkey.to_WIF(coin=coin) wallet = ImportedPrivkeyWallet.from_text(tmp_storage, WIF, None) public_key = privkey.public_key pubkey_hex = public_key.to_hex() address = public_key.to_address(coin=coin).to_string() assert wallet.pubkeys_to_address(pubkey_hex) == Address.from_string(address)
def on_update(self): self.wallet = self.parent.wallet # hide receive tab if no receive requests available b = len(self.wallet.receive_requests) > 0 self.setVisible(b) self.parent.receive_requests_label.setVisible(b) if not b: self.parent.expires_label.hide() self.parent.expires_combo.show() # update the receive address if necessary current_address_string = self.parent.receive_address_e.text().strip() current_address = (Address.from_string(current_address_string) if len(current_address_string) else None) domain = self.wallet.get_receiving_addresses() addr = self.wallet.get_unused_address() if not current_address in domain and addr: self.parent.set_receive_address(addr) self.parent.new_request_button.setEnabled(addr != current_address) # clear the list and fill it again self.clear() for req in self.wallet.get_sorted_requests(self.config): address = req['address'] if address not in domain: continue timestamp = req.get('time', 0) amount = req.get('amount') expiration = req.get('exp', None) message = req.get('memo', '') date = format_time(timestamp) status = req.get('status') signature = req.get('sig') requestor = req.get('name', '') amount_str = self.parent.format_amount(amount) if amount else "" item = QTreeWidgetItem([ date, address.to_ui_string(), '', message, amount_str, pr_tooltips.get(status, '') ]) item.setData(0, Qt.UserRole, address) if signature is not None: item.setIcon(2, QIcon(":icons/seal.png")) item.setToolTip(2, 'signed by ' + requestor) if status is not PR_UNKNOWN: item.setIcon(6, QIcon(pr_icons.get(status))) self.addTopLevelItem(item)
#!/usr/bin/env python3 # create a BIP70 payment request signed with a certificate import sys import tlslite # pylint: disable=import-error from electrumsv.transaction import Transaction # from electrumsv import paymentrequest from electrumsv import paymentrequest_pb2 as pb2 from electrumsv.address import Address chain_file = 'mychain.pem' cert_file = 'mycert.pem' amount = 1000000 address = Address.from_string("18U5kpCAU4s8weFF8Ps5n8HAfpdUjDVF64") memo = "blah" out_file = "payreq" with open(chain_file, 'r') as f: chain = tlslite.X509CertChain() chain.parsePemList(f.read()) # pylint: disable=no-member certificates = pb2.X509Certificates() certificates.certificate.extend(map(lambda x: str(x.bytes), chain.x509List)) with open(cert_file, 'r') as f: rsakey = tlslite.utils.python_rsakey.Python_RSAKey.parsePEM(f.read()) script = bytes.fromhex(Transaction.pay_script(address))
def _parse_address(self, line): address = self._parse_address_text(line) return Address.from_string(address)
"tx_pos": 3, }, ], } result_S = ([{ 'height': 437146, 'value': 45318048, 'tx_hash': '9f2c45a12db0144909b5db269415f7319179105982ac70ed80d76ea79d923ebf', 'tx_pos': 0, 'address': Address.from_string("1KXf5PUHNaV42jE9NbJFPKhGGN1fSSGJNK"), 'type': 'p2pkh', 'prevout_hash': '9f2c45a12db0144909b5db269415f7319179105982ac70ed80d76ea79d923ebf', 'prevout_n': 0, 'pubkeys': [ '04e7dd15b4271f8308ff52ad3d3e472b652e78a2c5bc6ed10250a543d28c0128894ae863d086488e6773c4589be93a1793f685dd3f1e8a1f1b390b23470f7d1095' ], 'x_pubkeys': [ '04e7dd15b4271f8308ff52ad3d3e472b652e78a2c5bc6ed10250a543d28c0128894ae863d086488e6773c4589be93a1793f685dd3f1e8a1f1b390b23470f7d1095' ], 'signatures': [None], 'num_sig': 1
#!/usr/bin/env python3 import sys import time from electrumsv.simple_config import SimpleConfig from electrumsv.network import Network from electrumsv.util import json_encode from electrumsv.address import Address try: addr = Address.from_string(sys.argv[1]) except Exception: print("usage: watch_address <bitcoin_address>") sys.exit(1) # start network c = SimpleConfig() network = Network(c) network.start() # wait until connected while network.is_connecting(): time.sleep(0.1) if not network.is_connected(): print("daemon is not connected") sys.exit(1) # 2. send the subscription sh = addr.to_scripthash_hex() callback = lambda response: print(json_encode(response.get('result')))
def parse_address(self, line): r = line.strip() m = re.match(RE_ALIAS, r) address = m.group(2) if m else r return Address.from_string(address)
def test_parse_xpub(self): res = xpubkey_to_address('fe4e13b0f311a55b8a5db9a32e959da9f011b131019d4cebe6141b9e2c93edcbfc0954c358b062a9f94111548e50bde5847a3096b8b7872dcffadb0e9579b9017b01000200') self.assertEqual(res, ('04ee98d63800824486a1cf5b4376f2f574d86e0a3009a6448105703453f3368e8e1d8d090aaecdd626a45cc49876709a3bbb6dc96a4311b3cac03e225df5f63dfc', Address.from_string('19h943e4diLc68GXW7G75QNe2KWuMu7BaJ')))
def test_address_to_scripthash(self): for priv_details in self.priv_pub_addr: addr = Address.from_string(priv_details['address']) sh = addr.to_scripthash_hex() self.assertEqual(priv_details['scripthash'], sh)
#!/usr/bin/env python3 import sys from electrumsv.network import Network from electrumsv.util import json_encode from electrumsv.address import Address try: addr = sys.argv[1] except Exception: print("usage: get_history <bitcoin_address>") sys.exit(1) n = Network() n.start() sh = Address.from_string(addr).to_scripthash_hex() h = n.synchronous_get(('blockchain.scripthash.get_history', [sh])) print(json_encode(h))
def test_get_addresses(self): assert imported_keystore.get_addresses() == [ Address.from_string(addr) for addr in ('1KXf5PUHNaV42jE9NbJFPKhGGN1fSSGJNK', '1LoVGDgRs9hTfTNJNuXKSpywcbdvwRXpmK') ]
], # 5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ (uncompressed) "2df53273de1b740e6f566eba00d90366e53afd2c6af896a9488515f8ef5abbd8": [ ], # 5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ (P2PK) "7149d82068249701104cd662bfe8ebc0af131ce6e781b124cc6297f45f7f6de5": [ { "height": 50000, "value": 1804376, "tx_hash": "3f5a1badfe1beb42b650f325b20935f09f3ab43a3c473c5be18f58308fc7eff1", "tx_pos": 3, }, ], } result_S = ([{'height': 437146, 'value': 45318048, 'tx_hash': '9f2c45a12db0144909b5db269415f7319179105982ac70ed80d76ea79d923ebf', 'tx_pos': 0, 'address': Address.from_string("1KXf5PUHNaV42jE9NbJFPKhGGN1fSSGJNK"), 'type': 'p2pkh', 'prevout_hash': '9f2c45a12db0144909b5db269415f7319179105982ac70ed80d76ea79d923ebf', 'prevout_n': 0, 'pubkeys': ['04e7dd15b4271f8308ff52ad3d3e472b652e78a2c5bc6ed10250a543d28c0128894ae863d086488e6773c4589be93a1793f685dd3f1e8a1f1b390b23470f7d1095'], 'x_pubkeys': ['04e7dd15b4271f8308ff52ad3d3e472b652e78a2c5bc6ed10250a543d28c0128894ae863d086488e6773c4589be93a1793f685dd3f1e8a1f1b390b23470f7d1095'], 'signatures': [None], 'num_sig': 1}], {'04e7dd15b4271f8308ff52ad3d3e472b652e78a2c5bc6ed10250a543d28c0128894ae863d086488e6773c4589be93a1793f685dd3f1e8a1f1b390b23470f7d1095': (b'\x98\xe3\x15\xc3%j\x97\x17\xd4\xdd\xea0\xeb*\n-V\xa1d\x93yN\xb0SSf\xea"\xd8i\xa3 ', False), '03e7dd15b4271f8308ff52ad3d3e472b652e78a2c5bc6ed10250a543d28c012889': (b'\x98\xe3\x15\xc3%j\x97\x17\xd4\xdd\xea0\xeb*\n-V\xa1d\x93yN\xb0SSf\xea"\xd8i\xa3 ', True)}) result_K = ([{'height': 500000, 'value': 18043706, 'tx_hash': 'bcf7ae875b585e00a61055372c1e99046b20f5fbfcd8659959afb6f428326bfa', 'tx_pos': 1, 'address': Address.from_string("1LoVGDgRs9hTfTNJNuXKSpywcbdvwRXpmK"), 'type': 'p2pkh', 'prevout_hash': 'bcf7ae875b585e00a61055372c1e99046b20f5fbfcd8659959afb6f428326bfa', 'prevout_n': 1, 'pubkeys': ['02d0de0aaeaefad02b8bdc8a01a1b8b11c696bd3d66a2c5f10780d95b7df42645c'], 'x_pubkeys': ['02d0de0aaeaefad02b8bdc8a01a1b8b11c696bd3d66a2c5f10780d95b7df42645c'], 'signatures': [None], 'num_sig': 1}], {'02d0de0aaeaefad02b8bdc8a01a1b8b11c696bd3d66a2c5f10780d95b7df42645c': (b"\x0c(\xfc\xa3\x86\xc7\xa2'`\x0b/\xe5\x0b|\xae\x11\xec\x86\xd3\xbf\x1f\xbeG\x1b\xe8\x98'\xe1\x9dr\xaa\x1d", True)}) result_5 = ([{'height': 50000, 'value': 1804376, 'tx_hash': '3f5a1badfe1beb42b650f325b20935f09f3ab43a3c473c5be18f58308fc7eff1', 'tx_pos': 3, 'address': PublicKey.from_hex("04d0de0aaeaefad02b8bdc8a01a1b8b11c696bd3d66a2c5f10780d95b7df42645cd85228a6fb29940e858e7e55842ae2bd115d1ed7cc0e82d934e929c97648cb0a"), 'type': 'p2pk', 'prevout_hash': '3f5a1badfe1beb42b650f325b20935f09f3ab43a3c473c5be18f58308fc7eff1', 'prevout_n': 3, 'pubkeys': ['04d0de0aaeaefad02b8bdc8a01a1b8b11c696bd3d66a2c5f10780d95b7df42645cd85228a6fb29940e858e7e55842ae2bd115d1ed7cc0e82d934e929c97648cb0a'], 'x_pubkeys': ['04d0de0aaeaefad02b8bdc8a01a1b8b11c696bd3d66a2c5f10780d95b7df42645cd85228a6fb29940e858e7e55842ae2bd115d1ed7cc0e82d934e929c97648cb0a'], 'signatures': [None], 'num_sig': 1}], {'04d0de0aaeaefad02b8bdc8a01a1b8b11c696bd3d66a2c5f10780d95b7df42645cd85228a6fb29940e858e7e55842ae2bd115d1ed7cc0e82d934e929c97648cb0a': (b"\x0c(\xfc\xa3\x86\xc7\xa2'`\x0b/\xe5\x0b|\xae\x11\xec\x86\xd3\xbf\x1f\xbeG\x1b\xe8\x98'\xe1\x9dr\xaa\x1d", False)}) @pytest.mark.parametrize("privkey,answer", ( ("SZEfg4eYxCJoqzumUqP34g", result_S), ("KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617", result_K), ("5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ", result_5), )) def test_sweep_preparations(privkey,answer): def get_utxos(script_hash): return sweep_utxos[script_hash] result = sweep_preparations([privkey], get_utxos) assert result == answer
def test_xpubkey_to_address(): privkey = PrivateKey.from_random() public_key = privkey.public_key x_pubkey = 'fd' + public_key.P2PKH_script().to_hex() assert xpubkey_to_address(x_pubkey) == ( x_pubkey, Address.from_string(public_key.to_address().to_string()))
def address_to_script(addr): return Address.from_string(addr).to_script_hex()