def test_wallet_key_import_and_sign_multisig(self): if os.path.isfile(DATABASEFILE_UNITTESTS): os.remove(DATABASEFILE_UNITTESTS) network = 'bitcoinlib_test' words = 'square innocent drama' seed = Mnemonic().to_seed(words, 'password') hdkey = HDKey.from_seed(seed, network=network) hdkey.key_type = 'single' key_list = [ HDKey(network=network).account_multisig_key().public(), HDKey(network=network), hdkey.public() ] wallet = HDWallet.create_multisig('Multisig-2-of-3-example', key_list, 2, sort_keys=True, network=network, databasefile=DATABASEFILE_UNITTESTS) wallet.new_key() wallet.utxos_update() wallet.import_key(hdkey) wt = wallet.send_to('n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi', 10000000) self.assertIsNone(wt.error)
def test_wallet_multisig_sign_with_external_single_key(self): if os.path.isfile(DATABASEFILE_UNITTESTS): os.remove(DATABASEFILE_UNITTESTS) NETWORK = 'bitcoinlib_test' words = 'square innocent drama' seed = Mnemonic().to_seed(words, 'password') hdkey = HDKey.from_seed(seed, network=NETWORK) hdkey.key_type = 'single' key_list = [ HDKey(network=NETWORK).account_multisig_key().public(), HDKey(network=NETWORK), hdkey.public() ] wallet = HDWallet.create_multisig('Multisig-2-of-3-example', key_list, 2, network=NETWORK, databasefile=DATABASEFILE_UNITTESTS) wallet.new_key() wallet.utxos_update() res = wallet.send_to('n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi', 10000000) t = res['transaction'].raw_hex() t2 = wallet.transaction_import(t) self.assertFalse(t2.verify()) t2 = wallet.transaction_sign(t2, hdkey) self.assertTrue(t2.verify())
def _check_list(self, language, vectors): mnemo = Mnemonic(language) for v in vectors: if v[0]: phrase = mnemo.to_mnemonic(v[0]) else: phrase = v[1] seed = change_base(mnemo.to_seed(phrase, v[4]), 256, 16) print("Test %s => %s" % (v[0], phrase)) self.assertEqual(v[1], phrase) self.assertEqual(v[2], seed) k = HDKey.from_seed(seed) self.assertEqual(k.extended_wif(), v[3])
def _check_list(self, language, vectors): mnemo = Mnemonic(language) for v in vectors: if v[0]: phrase = mnemo.to_mnemonic(v[0]) else: phrase = v[1] seed = change_base(mnemo.to_seed(phrase, v[4]), 256, 16) print("Test %s => %s" % (v[0], phrase)) self.assertEqual(v[1], phrase) self.assertEqual(v[2], seed) k = HDKey.from_seed(seed) self.assertEqual(k.wif(), v[3])
def _check_list(self, language, vectors): mnemo = Mnemonic(language) for v in vectors: if v[0]: phrase = mnemo.to_mnemonic(v[0], check_on_curve=False) else: phrase = v[1] seed = change_base(mnemo.to_seed(phrase, v[4], validate=False), 256, 16) # print("Test %s => %s" % (v[0], phrase)) self.assertEqual(v[1], phrase) self.assertEqual(v[2], seed) k = HDKey.from_seed(seed) self.assertEqual(k.wif(is_private=True), v[3])
def main(): print("Command Line Wallet for BitcoinLib\n") # --- Parse commandline arguments --- args = parse_args() databasefile = DEFAULT_DATABASE if args.database: databasefile = os.path.join(BCL_DATABASE_DIR, args.database) if args.generate_key: passphrase = get_passphrase(args) passphrase = ' '.join(passphrase) seed = binascii.hexlify(Mnemonic().to_seed(passphrase)) hdkey = HDKey.from_seed(seed, network=args.network) print( "Private master key, to create multisig wallet on this machine: %s" % hdkey.wif()) print( "Public account key, to share with other cosigner multisig wallets: %s" % hdkey.public_master(witness_type=args.witness_type, multisig=True)) print("Network: %s" % hdkey.network.name) clw_exit() # List wallets, then exit if args.list_wallets: print("BitcoinLib wallets:") for w in wallets_list(databasefile=databasefile): if 'parent_id' in w and w['parent_id']: continue print("[%d] %s (%s) %s" % (w['id'], w['name'], w['network'], w['owner'])) clw_exit() # Delete specified wallet, then exit if args.wallet_remove: if not wallet_exists(args.wallet_name, databasefile=databasefile): clw_exit("Wallet '%s' not found" % args.wallet_name) inp = input( "\nWallet '%s' with all keys and will be removed, without private key it cannot be restored." "\nPlease retype exact name of wallet to proceed: " % args.wallet_name) if inp == args.wallet_name: if wallet_delete(args.wallet_name, force=True, databasefile=databasefile): clw_exit("\nWallet %s has been removed" % args.wallet_name) else: clw_exit("\nError when deleting wallet") else: clw_exit("\nSpecified wallet name incorrect") wlt = None if args.wallet_name and not args.wallet_name.isdigit( ) and not wallet_exists(args.wallet_name, databasefile=databasefile): if not args.create_from_key and input( "Wallet %s does not exist, create new wallet [yN]? " % args.wallet_name).lower() != 'y': clw_exit('Aborted') wlt = create_wallet(args.wallet_name, args, databasefile) args.wallet_info = True else: try: wlt = HDWallet(args.wallet_name, databasefile=databasefile) if args.passphrase is not None: print( "WARNING: Using passphrase option for existing wallet ignored" ) if args.create_from_key is not None: print( "WARNING: Using create_from_key option for existing wallet ignored" ) except WalletError as e: clw_exit("Error: %s" % e.msg) if wlt is None: clw_exit("Could not open wallet %s" % args.wallet_name) if args.import_private: if wlt.import_key(args.import_private): clw_exit("Private key imported") else: clw_exit("Failed to import key") if args.wallet_recreate: wallet_empty(args.wallet_name) print("Removed transactions and generated keys from this wallet") if args.update_utxos: wlt.utxos_update() if args.update_transactions: wlt.scan(scan_gap_limit=5) if args.export_private: if wlt.scheme == 'multisig': for w in wlt.cosigner: if w.main_key and w.main_key.is_private: print(w.main_key.wif) elif not wlt.main_key or not wlt.main_key.is_private: print("No private key available for this wallet") else: print(wlt.main_key.wif) clw_exit() if args.network is None: args.network = wlt.network.name tx_import = None if args.import_tx_file: try: fn = args.import_tx_file f = open(fn, "r") except FileNotFoundError: clw_exit("File %s not found" % args.import_tx_file) try: tx_import = ast.literal_eval(f.read()) except (ValueError, SyntaxError): tx_import = f.read() if args.import_tx: try: tx_import = ast.literal_eval(args.import_tx) except (ValueError, SyntaxError): tx_import = args.import_tx if tx_import: if isinstance(tx_import, dict): wt = wlt.transaction_import(tx_import) else: wt = wlt.transaction_import_raw(tx_import, network=args.network) wt.sign() if args.push: res = wt.send() if res: print("Transaction pushed to network. Transaction ID: %s" % wt.hash) else: print("Error creating transaction: %s" % wt.error) wt.info() print("Signed transaction:") print_transaction(wt) clw_exit() if args.receive: keys = wlt.get_key(network=args.network, number_of_keys=args.receive) if args.receive != 1: keys += wlt.get_key_change(network=args.network, number_of_keys=args.receive) keys = [keys] if not isinstance(keys, list) else keys print("Receive address(es):") for key in keys: addr = key.address print(addr) if QRCODES_AVAILABLE and args.receive == 1: qrcode = pyqrcode.create(addr) print(qrcode.terminal()) if not QRCODES_AVAILABLE and args.receive == 1: print( "Install qr code module to show QR codes: pip install pyqrcode" ) clw_exit() if args.create_transaction == []: clw_exit("Missing arguments for --create-transaction/-t option") if args.create_transaction: if args.fee_per_kb: clw_exit("Fee-per-kb option not allowed with --create-transaction") try: wt = create_transaction(wlt, args.create_transaction, args) except WalletError as e: clw_exit("Cannot create transaction: %s" % e.msg) wt.sign() print("Transaction created") wt.info() if args.push: wt.send() if wt.pushed: print("Transaction pushed to network. Transaction ID: %s" % wt.hash) else: print("Error creating transaction: %s" % wt.error) else: print( "\nTransaction created but not send yet. Transaction dictionary for export: " ) print_transaction(wt) clw_exit() if args.sweep: if args.fee: clw_exit("Fee option not allowed with --sweep") offline = True print("Sweep wallet. Send all funds to %s" % args.sweep) if args.push: offline = False wt = wlt.sweep(args.sweep, offline=offline, network=args.network, fee_per_kb=args.fee_per_kb) if not wt: clw_exit( "Error occurred when sweeping wallet: %s. Are UTXO's available and updated?" % wt) wt.info() if args.push: if wt.pushed: print("Transaction pushed to network. Transaction ID: %s" % wt.hash) elif not wt: print("Cannot sweep wallet, are UTXO's updated and available?") else: print("Error sweeping wallet: %s" % wt.error) else: print( "\nTransaction created but not send yet. Transaction dictionary for export: " ) print_transaction(wt) clw_exit() # print("Updating wallet") if args.network == 'bitcoinlib_test': wlt.utxos_update() print("Wallet info for %s" % wlt.name) wlt.info()
def create_wallet(wallet_name, args, databasefile): if args.network is None: args.network = DEFAULT_NETWORK print("\nCREATE wallet '%s' (%s network)" % (wallet_name, args.network)) if args.create_multisig: if not isinstance(args.create_multisig, list) or len(args.create_multisig) < 2: clw_exit( "Please enter multisig creation parameter in the following format: " "<number-of-signatures> <number-of-signatures-required> " "<key-0> <key-1> [<key-2> ... <key-n>]") try: sigs_total = int(args.create_multisig[0]) except ValueError: clw_exit( "Number of total signatures (first argument) must be a numeric value. %s" % args.create_multisig[0]) try: sigs_required = int(args.create_multisig[1]) except ValueError: clw_exit( "Number of signatures required (second argument) must be a numeric value. %s" % args.create_multisig[1]) key_list = args.create_multisig[2:] keys_missing = sigs_total - len(key_list) assert (keys_missing >= 0) if keys_missing: print("Not all keys provided, creating %d additional keys" % keys_missing) for _ in range(keys_missing): passphrase = get_passphrase(args) passphrase = ' '.join(passphrase) seed = binascii.hexlify(Mnemonic().to_seed(passphrase)) key_list.append(HDKey.from_seed(seed, network=args.network)) return HDWallet.create(wallet_name, key_list, sigs_required=sigs_required, network=args.network, databasefile=databasefile, witness_type=args.witness_type) elif args.create_from_key: return HDWallet.create(wallet_name, args.create_from_key, network=args.network, databasefile=databasefile, witness_type=args.witness_type) else: passphrase = args.passphrase if passphrase is None: passphrase = get_passphrase(args) elif not passphrase: passphrase = input("Enter Passphrase: ") if not isinstance(passphrase, list): passphrase = passphrase.split(' ') elif len(passphrase) == 1: passphrase = passphrase[0].split(' ') if len(passphrase) < 12: clw_exit("Please specify passphrase with 12 words or more") passphrase = ' '.join(passphrase) seed = binascii.hexlify(Mnemonic().to_seed(passphrase)) hdkey = HDKey.from_seed(seed, network=args.network) return HDWallet.create(wallet_name, hdkey, network=args.network, witness_type=args.witness_type, databasefile=databasefile)
print("\n=== Import and Decrypt BIP38 Key ===") k = Key('6PRVWUbkzzsbcVac2qwfssoUJAN1Xhrg6bNk8J7Nzm5H7kxEbn2Nh2ZoGg', passphrase='TestingOneTwoThree') print("Private key %s" % k.wif()) print("Is Compressed %s\n" % k.compressed) # # Hierarchical Deterministic Key Class and Child Key Derivation Examples # print("\n=== Generate random HD Key on testnet ===") hdk = HDKey(network='testnet') print("Random BIP32 HD Key on testnet %s" % hdk.wif()) print("\n=== Import HD Key from seed ===") k = HDKey.from_seed('000102030405060708090a0b0c0d0e0f') print("HD Key WIF for seed 000102030405060708090a0b0c0d0e0f: %s" % k.wif()) print("Key type is : %s" % k.key_type) print("\n=== Generate random Litecoin key ===") lk = HDKey(network='litecoin') lk.info() print("\n=== Generate random Dash key ===") lk = HDKey(network='dash') lk.info() print("\n=== Import simple private key as HDKey ===") k = HDKey('L5fbTtqEKPK6zeuCBivnQ8FALMEq6ZApD7wkHZoMUsBWcktBev73') print( "HD Key WIF for Private Key L5fbTtqEKPK6zeuCBivnQ8FALMEq6ZApD7wkHZoMUsBWcktBev73: %s"
print("Hex %s" % pk) print("Checksum bin %s" % Mnemonic().checksum(pk)) print("Mnemonic %s" % words) print("Seed for HD Key %s" % to_hexstring(Mnemonic().to_seed(words, 'test'))) print("Back to Entropy %s" % to_hexstring(Mnemonic().to_entropy(words))) # Generate a random Mnemonic HD Key print("\nGenerate a random Mnemonic HD Key") entsize = 128 words = Mnemonic('english').generate(entsize) print("Your Mnemonic is %s" % words) print(" (An avarage of %d tries is needed to brute-force this password)" % ((2**entsize) // 2)) seed = Mnemonic().to_seed(words) hdk = HDKey.from_seed(seed) print("Seed for HD Key %s" % to_hexstring(seed)) print("HD Key WIF is %s" % hdk.wif()) print("HD Key WIF is %s (method 2)" % HDKey.from_passphrase(words).wif()) # Generate a key from a Mnemonic passphrase print("\nGenerate a key from a Mnemonic passphrase") words = "type fossil omit food supply enlist move perfect direct grape clean diamond" print("Your Mnemonic is %s" % words) seed = Mnemonic().to_seed(words) hdk = HDKey.from_seed(seed) print("Seed for HD Key %s" % to_hexstring(seed)) print("HD Key WIF is %s" % hdk.wif()) # Let's talk Spanish print("\nGenerate a key from a Spanish Mnemonic passphrase")
input = raw_input except NameError: pass WALLET_NAME = "Multisig_3of5" wlt = HDWallet(WALLET_NAME) # If you want to sign on an offline PC, export utxo dictionary to offline PC # utxos = {...} # wlt.utxos_update(utxos=utxos) wlt.utxos_update() wlt.info() # Paste your raw transaction here or enter in default input raw_tx = '' if not raw_tx: raw_tx = input("Paste raw transaction hex: ") passphrase = input("Enter passphrase: ") password = input("Enter password []:") seed = Mnemonic().to_seed(passphrase, password) hdkey = HDKey.from_seed(seed, network=wlt.network.network_name) t = wlt.transaction_import_raw(raw_tx) t.sign(hdkey) print("Raw signed transaction: ") print(t.raw_hex())
"\n- With 1 private key a wallet on this Offline PC is created" "\n- Use private key 2 to create a wallet on the Online PC" "\n- Store key 3 on a Paper in a safe in case one of the PC's is not available anymore" ) key_lists = {} w_id = 0 for cosigner in cosigners: print("\n") words = Mnemonic().generate(KEY_STRENGTH) password = '' if cosigner[2] == 'password': password = input("Please give password for cosigner '%s': " % cosigner[0]) seed = Mnemonic().to_seed(words, password) hdkey = HDKey.from_seed(seed, network=NETWORK, key_type=cosigner[1], witness_type=WITNESS_TYPE) if cosigner[1] == 'bip32': public_account = hdkey.public_master_multisig( witness_type=WITNESS_TYPE) else: public_account = hdkey print( "Key for cosigner '%s' generated. Please store both passphrase and password carefully!" % cosigner[0]) print("Passphrase: %s" % words) print("Password: %s" % ('*' * len(password))) print("Share this public key below with other cosigner") print("Public key: %s" % public_account.wif_public()) for w in cosigners:
print("\n=== Create Dash wallet ===") dash_wallet = HDWallet.create( db_uri=test_database, name='Dash Wallet', network='dash') dash_wallet.new_key() dash_wallet.info(detail=3) del dash_wallet print("\n=== Create Litecoin testnet Wallet from Mnemonic Passphrase ===") words = 'blind frequent camera goddess pottery repair skull year mistake wrist lonely mix' # Or use generate method: # words = Mnemonic('english').generate() print("Generated Passphrase: %s" % words) seed = Mnemonic().to_seed(words) hdkey = HDKey.from_seed(seed, network='litecoin_testnet') wallet = HDWallet.create(name='Mnemonic Wallet', network='litecoin_testnet', keys=hdkey.wif(), db_uri=test_database) wallet.new_key("Input", 0) wallet.utxos_update() wallet.info(detail=3) print("\n=== Test import Litecoin key in Bitcoin wallet (should give error) ===") w = HDWallet.create( name='Wallet Error', db_uri=test_database) try: w.import_key(key='T43gB4F6k1Ly3YWbMuddq13xLb56hevUDP3RthKArr7FPHjQiXpp', network='litecoin') except WalletError as e: print("Import litecoin key in bitcoin wallet gives an EXPECTED error: %s" % e)
# w.info() # t = w.sweep(w.new_key().address, 10000, fee=1000) # raw_tx = t.raw_hex() # t.info() # Raw partially signed transaction transaction raw_tx = '' if not raw_tx: raw_tx = input("Paste raw transaction hex: ") t = Transaction.import_raw(raw_tx) key_str = input("Enter private key or mnemonic passphrase: ") if len(key_str.split(" ")) < 2: hdkey = HDKey(key_str) else: password = input("Enter password []:") seed = Mnemonic().to_seed(key_str, password) hdkey = HDKey.from_seed(seed, network=network) t.sign(hdkey) t.info() print("Raw signed transaction: ") print(t.raw_hex()) if input("Try to send transaction [y/n] ") in ['y', 'Y']: srv = Service(network=network) res = srv.sendrawtransaction(t.raw()) pprint(res)
"\n- With 1 private key a wallet on This PC is created" "\n- Use private key 2 to create a wallet on an Offline PC" "\n- Store key 3 on a Paper in a safe in case one of the PC's is not available anymore" "\nPLEASE NOTE: THIS IS AN EXAMPLE. In real life do not generate all private keys on a " "single instance") key_list = [] key_list_thispc = [] for cosigner in cosigners: print("\n") words = Mnemonic().generate(KEY_STRENGTH) password = '' if cosigner[2] == 'password': password = input("Please give password for cosigner '%s': " % cosigner[0]) seed = Mnemonic().to_seed(words, password) hdkey = HDKey.from_seed(seed, network=NETWORK, key_type=cosigner[1]) if cosigner[1] == 'bip44': public_account = hdkey.account_multisig_key() else: public_account = hdkey print( "Key for cosigner '%s' generated. Please store both passphrase and password carefully!" % cosigner[0]) print("Passphrase: %s" % words) print("Password: %s" % ('*' * len(password))) print("Share this public key below with other cosigner") print("Public key: %s" % public_account.wif_public()) if cosigner[3] == 'private': key_list.append(hdkey) key_list_thispc.append(hdkey)
# -*- coding: utf-8 -*- # # BitcoinLib - Python Cryptocurrency Library # # Multisig 3-of-5 wallet with Mnemonic passphrase keys # # © 2017 November - 1200 Web Development <http://1200wd.com/> # from bitcoinlib.mnemonic import Mnemonic from bitcoinlib.keys import HDKey NETWORK = 'testnet' KEY_STRENGHT = 128 words = Mnemonic().generate(KEY_STRENGHT) print( "A Mnemonic passphrase has been generated. Please write down and store carefully: \n%s" % words) password = input( "\nEnter a password if you would like to protect passphrase []: ") seed = Mnemonic().to_seed(words, password) hdkey = HDKey.from_seed(seed, network=NETWORK) public_account_wif = hdkey.public_master_multisig() print("\nPrivate key: \n%s" % hdkey.wif_private()) # print("Public key: \n%s" % hdkey.wif_public()) print( "Public account key to share with other cosigners for a multisig BIP45 wallet: \n%s" % public_account_wif.wif())