def test_wallet_multisig_sorted_keys(self):
     if os.path.isfile(DATABASEFILE_UNITTESTS):
         os.remove(DATABASEFILE_UNITTESTS)
     key1 = HDKey()
     key2 = HDKey()
     key3 = HDKey()
     w1 = HDWallet.create_multisig('w1', [
         key1,
         key2.account_multisig_key().public(),
         key3.account_multisig_key().public()
     ],
                                   sigs_required=2,
                                   sort_keys=True,
                                   databasefile=DATABASEFILE_UNITTESTS)
     w2 = HDWallet.create_multisig('w2', [
         key1.account_multisig_key().public(), key2,
         key3.account_multisig_key().public()
     ],
                                   sigs_required=2,
                                   sort_keys=True,
                                   databasefile=DATABASEFILE_UNITTESTS)
     w3 = HDWallet.create_multisig('w3', [
         key1.account_multisig_key().public(),
         key2.account_multisig_key().public(), key3
     ],
                                   sigs_required=2,
                                   sort_keys=True,
                                   databasefile=DATABASEFILE_UNITTESTS)
     for _ in range(10):
         address1 = w1.new_key().address
         address2 = w2.new_key().address
         address3 = w3.new_key().address
         self.assertTrue((address1 == address2 == address3),
                         'Different addressed generated: %s %s %s' %
                         (address1, address2, address3))
    def test_wallet_multisig_2of2_different_database(self):
        """
        Same unittest as before (test_wallet_multisig_sign_2_different_wallets) but now with 2
        separate databases to check for database inteference.

        """
        if os.path.isfile(DATABASEFILE_UNITTESTS):
            os.remove(DATABASEFILE_UNITTESTS)
        if os.path.isfile(DATABASEFILE_UNITTESTS_2):
            os.remove(DATABASEFILE_UNITTESTS_2)

        keys = [
            HDKey(
                'YXscyqNJ5YK411nwB4wzazXjJn9L9iLAR1zEMFcpLipDA25rZregBGgwXmprsvQLeQAsuTvemtbCWR1AHaPv2qmvkartoiFUU6'
                'qu1uafT2FETtXT',
                network='bitcoinlib_test'),
            HDKey(
                'YXscyqNJ5YK411nwB4EyGbNZo9eQSUWb64vAFKHt7E2LYnbmoNz8Gyjs6xc7iYAudcnkgf127NPnaanuUgyRngAiwYBcXKGsSJ'
                'wadGhxByT2MnLd',
                network='bitcoinlib_test')
        ]

        msw1 = HDWallet.create_multisig('msw1', [
            keys[0], keys[1].subkey_for_path("m/45'/9999999'/0'").wif_public()
        ],
                                        network='bitcoinlib_test',
                                        sort_keys=False,
                                        sigs_required=2,
                                        databasefile=DATABASEFILE_UNITTESTS)
        msw2 = HDWallet.create_multisig('msw2', [
            keys[0].subkey_for_path("m/45'/9999999'/0'").wif_public(), keys[1]
        ],
                                        network='bitcoinlib_test',
                                        sort_keys=False,
                                        sigs_required=2,
                                        databasefile=DATABASEFILE_UNITTESTS_2)
        msw1.new_key()
        msw2.new_key()
        msw1.utxos_update()
        msw2.utxos_update()
        utxos = msw1.utxos()
        output_arr = [('21KnydRNSmqAf8Py74mMiwRXYHGxW27zyDu',
                       utxos[0]['value'] - 50000)]
        input_arr = [(utxos[0]['tx_hash'], utxos[0]['output_n'],
                      utxos[0]['key_id'], utxos[0]['value'])]
        t = msw1.transaction_create(output_arr,
                                    input_arr,
                                    transaction_fee=50000)
        t = msw1.transaction_sign(t)
        t2 = msw2.transaction_import(t.raw())
        t2 = msw2.transaction_sign(t2)
        self.assertEqual(msw2.transaction_send(t2),
                         'succesfull_test_sendrawtransaction')
    def test_wallet_multisig_2of2(self):
        """
        Create 2 cosigner wallets with 1 own private key a public key from other cosigner
        Then create and sign transaction if first wallet, import and sign it in second wallet
        and verify created transaction.

        """
        if os.path.isfile(DATABASEFILE_UNITTESTS):
            os.remove(DATABASEFILE_UNITTESTS)

        keys = [
            HDKey(
                'YXscyqNJ5YK411nwB4wzazXjJn9L9iLAR1zEMFcpLipDA25rZregBGgwXmprsvQLeQAsuTvemtbCWR1AHaPv2qmvkartoiFUU6'
                'qu1uafT2FETtXT',
                network='bitcoinlib_test'),
            HDKey(
                'YXscyqNJ5YK411nwB4EyGbNZo9eQSUWb64vAFKHt7E2LYnbmoNz8Gyjs6xc7iYAudcnkgf127NPnaanuUgyRngAiwYBcXKGsSJ'
                'wadGhxByT2MnLd',
                network='bitcoinlib_test')
        ]

        msw1 = HDWallet.create_multisig('msw1', [
            keys[0], keys[1].subkey_for_path("m/45'/9999999'/0'").wif_public()
        ],
                                        network='bitcoinlib_test',
                                        sort_keys=False,
                                        sigs_required=2,
                                        databasefile=DATABASEFILE_UNITTESTS)
        msw2 = HDWallet.create_multisig('msw2', [
            keys[0].subkey_for_path("m/45'/9999999'/0'").wif_public(), keys[1]
        ],
                                        network='bitcoinlib_test',
                                        sort_keys=False,
                                        sigs_required=2,
                                        databasefile=DATABASEFILE_UNITTESTS)
        msw1.new_key()
        msw2.new_key()
        msw1.utxos_update()
        msw2.utxos_update()
        utxos = msw1.utxos()
        output_arr = [('21KnydRNSmqAf8Py74mMiwRXYHGxW27zyDu',
                       utxos[0]['value'] - 50000)]
        input_arr = [(utxos[0]['tx_hash'], utxos[0]['output_n'],
                      utxos[0]['key_id'], utxos[0]['value'])]
        t = msw1.transaction_create(output_arr,
                                    input_arr,
                                    transaction_fee=50000)
        t = msw1.transaction_sign(t)
        t2 = msw2.transaction_import(t.raw())
        t2 = msw2.transaction_sign(t2)
        self.assertTrue(t2.verify())
    def test_wallet_multisig_2of2_with_single_key(self):
        if os.path.isfile(DATABASEFILE_UNITTESTS):
            os.remove(DATABASEFILE_UNITTESTS)
        keys = [
            HDKey(network='bitcoinlib_test'),
            HDKey(network='bitcoinlib_test', key_type='single')
        ]
        key_list = [keys[0], keys[1].public()]

        wl = HDWallet.create_multisig('multisig_expk2',
                                      key_list,
                                      sigs_required=2,
                                      network='bitcoinlib_test',
                                      databasefile=DATABASEFILE_UNITTESTS)
        wl.new_key()
        wl.new_key()
        wl.new_key_change()
        wl.utxos_update()

        self.assertEqual(wl.keys()[0].name, 'Multisig Key 8/7')
        self.assertEqual(wl.keys()[1].name, 'Multisig Key 10/7')
        self.assertEqual(wl.keys()[2].name, 'Multisig Key 12/7')

        t = wl.transaction_create(
            [(HDKey(network='bitcoinlib_test').key.address(), 6400000)],
            min_confirms=0)
        t = wl.transaction_sign(t, keys[1])
        self.assertEqual(wl.transaction_send(t),
                         'succesfull_test_sendrawtransaction')
    def test_wallet_multisig_bitcoinlib_testnet_transaction_send(self):
        if os.path.isfile(DATABASEFILE_UNITTESTS):
            os.remove(DATABASEFILE_UNITTESTS)

        key_list = [
            'Pdke4WfXvALPdbrKEfBU9z9BNuRNbv1gRr66BEiZHKcRXDSZQ3gV',
            'PhUTR4ZkZu9Xkzn3ee3xMU1TxbNx6ENJvUjX4wBaZDyTCMrn1zuE',
            'PdnZFcwpxUSAcFE6MHB78weVAguwzSTUMBqswkqie7Uxfxsd77Zs'
        ]

        # Create wallet and generate key
        wl = HDWallet.create_multisig('multisig_test_simple',
                                      key_list,
                                      sigs_required=2,
                                      network='bitcoinlib_test',
                                      databasefile=DATABASEFILE_UNITTESTS)
        wl.new_key()

        # Sign, verify and send transaction
        wl.utxos_update(
        )  # In bitcoinlib_test network this generates new UTXO's
        t = wl.transaction_create([('21DBmFUMQMP7A6KeENXgZQ4wJdSCeGc2zFo',
                                    100000)])
        t = wl.transaction_sign(t)
        self.assertTrue(t.verify())
        self.assertEqual(wl.transaction_send(t),
                         'succesfull_test_sendrawtransaction')
    def _multisig_test(sigs_required, number_of_sigs, sort_keys, network):
        # Create Keys
        key_dict = {}
        for key_id in range(number_of_sigs):
            key_dict[key_id] = HDKey(network=network)
        random_output_address = HDKey(network=network).key.address()

        # Create wallets with 1 private key each
        wallet_dict = {}
        wallet_keys = {}
        for wallet_id in range(number_of_sigs):
            wallet_name = 'multisig-%d' % wallet_id
            key_list = []
            for key_id in key_dict:
                if key_id == wallet_id:
                    key_list.append(key_dict[key_id])
                else:
                    key_list.append(key_dict[key_id].subkey_for_path(
                        "m/45'/%d'/0'" %
                        Network(network).bip44_cointype).wif_public())
            wallet_dict[wallet_id] = HDWallet.create_multisig(
                wallet_name,
                key_list,
                sigs_required=sigs_required,
                network=network,
                sort_keys=sort_keys,
                databasefile=DATABASEFILE_UNITTESTS)
            wallet_keys[wallet_id] = wallet_dict[wallet_id].new_key()
            wallet_dict[wallet_id].utxos_update()

        # Create transaction in one random wallet
        wallet_ids = [i for i in range(0, number_of_sigs)]
        shuffle(wallet_ids)
        transaction_fee = 50000
        wallet_id = wallet_ids.pop()
        wlt = wallet_dict[wallet_id]
        utxos = wlt.utxos()
        output_arr = [(random_output_address,
                       utxos[0]['value'] - transaction_fee)]
        input_arr = [(utxos[0]['tx_hash'], utxos[0]['output_n'],
                      utxos[0]['key_id'], utxos[0]['value'])]
        t = wlt.transaction_create(output_arr,
                                   input_arr,
                                   transaction_fee=transaction_fee)
        t = wlt.transaction_sign(t)
        n_signs = 1

        # Sign transaction with other wallets until required number of signatures is reached
        while wallet_ids and n_signs < sigs_required:
            wallet_id = wallet_ids.pop()
            t = wallet_dict[wallet_id].transaction_import(t.raw())
            t = wallet_dict[wallet_id].transaction_sign(t)
            n_signs += 1
        return t
Exemple #7
0
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_multisig(name=wallet_name, keys=key_list, sigs_required=sigs_required,
                                        network=args.network, databasefile=databasefile, sort_keys=True,
                                        witness_type=args.witness_type)
    elif args.create_from_key:
        return HDWallet.create(name=wallet_name, network=args.network, keys=args.create_from_key,
                               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(name=wallet_name, network=args.network, keys=hdkey, witness_type=args.witness_type,
                               databasefile=databasefile)
Exemple #8
0
def create_wallet(wallet_name, args, databasefile):
    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) < 3:
            clw_exit(
                "Please enter multisig creation parameter in the following format: "
                "<number-of-signatures-required> <key-0> <key-1> [<key-2> ... <key-n>]"
            )
        try:
            sigs_required = int(args.create_multisig[0])
        except ValueError:
            clw_exit(
                "Number of signatures required (first argument) must be a numeric value. %s"
                % args.create_multisig[0])
        key_list = args.create_multisig[1:]
        return HDWallet.create_multisig(name=wallet_name,
                                        key_list=key_list,
                                        sigs_required=sigs_required,
                                        network=args.network,
                                        databasefile=databasefile)
    else:
        passphrase = args.passphrase
        if passphrase is None:
            inp_passphrase = Mnemonic('english').generate(
                args.passphrase_strength)
            print("\nYour mnemonic private key sentence is: %s" %
                  inp_passphrase)
            print(
                "\nPlease write down on paper and backup. With this key you can restore your wallet and all keys"
            )
            passphrase = inp_passphrase.split(' ')
            inp = input(
                "\nType 'yes' if you understood and wrote down your key: ")
            if inp not in ['yes', 'Yes', 'YES']:
                clw_exit("Exiting...")
        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(name=wallet_name,
                               network=args.network,
                               key=hdkey.wif(),
                               databasefile=databasefile)
 def test_wallet_multisig_create_2_cosigner_wallets(self):
     if os.path.isfile(DATABASEFILE_UNITTESTS):
         os.remove(DATABASEFILE_UNITTESTS)
     pk_wif1 = 'tprv8ZgxMBicQKsPdvHCP6VxtFgowj2k7nBJnuRiVWE4DReDFojkLjyqdT8mtR6XJK9dRBcaa3RwvqiKFjsEQVhKfQmHZCCY' \
               'f4jRTWvJuVuK67n'
     pk_wif2 = 'tprv8ZgxMBicQKsPdkJVWDkqQQAMVYB2usfVs3VS2tBEsFAzjC84M3TaLMkHyJWjydnJH835KHvksS92ecuwwWFEdLAAccwZ' \
               'KjhcA63NUyvDixB'
     pk1 = HDKey(pk_wif1, network='testnet')
     pk2 = HDKey(pk_wif2, network='testnet')
     wl1 = HDWallet.create_multisig(
         'multisig_test_wallet1',
         [pk_wif1, pk2.subkey_for_path("m/45'/1'/0'").wif_public()],
         sigs_required=2,
         network='testnet',
         databasefile=DATABASEFILE_UNITTESTS)
     wl2 = HDWallet.create_multisig(
         'multisig_test_wallet2',
         [pk1.subkey_for_path("m/45'/1'/0'").wif_public(), pk_wif2],
         sigs_required=2,
         network='testnet',
         databasefile=DATABASEFILE_UNITTESTS)
     wl1_key = wl1.new_key()
     wl2_key = wl2.new_key()
     self.assertEqual(wl1_key.address, wl2_key.address)
Exemple #10
0
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) < 3:
            clw_exit(
                "Please enter multisig creation parameter in the following format: "
                "<number-of-signatures-required> <key-0> <key-1> [<key-2> ... <key-n>]"
            )
        try:
            sigs_required = int(args.create_multisig[0])
        except ValueError:
            clw_exit(
                "Number of signatures required (first argument) must be a numeric value. %s"
                % args.create_multisig[0])
        key_list = args.create_multisig[1:]
        return HDWallet.create_multisig(name=wallet_name,
                                        key_list=key_list,
                                        sigs_required=sigs_required,
                                        network=args.network,
                                        databasefile=databasefile,
                                        sort_keys=True)
    elif args.create_from_key:
        return HDWallet.create(name=wallet_name,
                               network=args.network,
                               key=args.create_from_key,
                               databasefile=databasefile)
    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(name=wallet_name,
                               network=args.network,
                               key=hdkey.wif(),
                               databasefile=databasefile)
        if hdkey.is_private:
            cosigners_private.append(cosigner['name'])
        cosigner['hdkey'] = hdkey
        key_list.append(hdkey)

    # YOU SHOULD ENABLE THIS CHECK FOR REAL WALLETS
    # if len(cosigners_private) > 1:
    #    raise ValueError("It is strongly advised to use not more then 1 private key per wallet.")

    if len(key_list) != SIGS_N:
        raise ValueError(
            "Number of cosigners (%d) is different then expected. SIG_N=%d" %
            (len(key_list), SIGS_N))
    wallet3o5 = HDWallet.create_multisig(WALLET_NAME,
                                         key_list,
                                         SIGS_REQUIRED,
                                         sort_keys=True,
                                         network=NETWORK)
    wallet3o5.new_key()

    print("\n\nA multisig wallet with 1 key has been created on this system")
else:
    wallet3o5 = HDWallet(WALLET_NAME)

print("\nUpdating UTXO's...")
wallet3o5.utxos_update()
wallet3o5.info()
utxos = wallet3o5.utxos()

# Creating transactions just like in a normal wallet, then send raw transaction to other cosigners. They
# can sign the transaction with there on key and pass it on to the next signer or broadcast it to the network.
Exemple #12
0
            % 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)
        else:
            key_list.append(public_account)
            key_list_thispc.append(public_account.public())

    thispc_wallet = HDWallet.create_multisig(WALLET_NAME,
                                             key_list_thispc,
                                             SIGNATURES_REQUIRED,
                                             sort_keys=True,
                                             network=NETWORK)
    thispc_wallet.new_key()

    print("\n\nA multisig wallet has been created on this system")
    thispc_wallet.info()

    print("\n---> Please create a wallet on your Other PC like this:")
    print("from bitcoinlib.wallets import HDWallet")
    print("from bitcoinlib.keys import HDKey")
    print("")
    print("key_list = [")
    print("    '%s'," % key_list[0].account_multisig_key().wif_public())
    print("    '%s'," % key_list[1].wif())
    print("    HDKey('%s', key_type='single')" % key_list[2].wif_public())
Exemple #13
0
            % 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)
        else:
            key_list.append(public_account)
            key_list_thispc.append(public_account.public())

    thispc_wallet = HDWallet.create_multisig(WALLET_NAME,
                                             key_list_thispc,
                                             SIGNATURES_REQUIRED,
                                             sort_keys=True,
                                             witness_type=WITNESS_TYPE,
                                             network=NETWORK)
    thispc_wallet.new_key()

    print("\n\nA multisig wallet has been created on this system")
    thispc_wallet.info()

    print("\n---> Please create a wallet on your Other PC like this:")
    print("from bitcoinlib.wallets import HDWallet")
    print("from bitcoinlib.keys import HDKey")
    print("")
    print("key_list = [")
    print("    '%s'," % key_list[0].account_multisig_key().wif_public())
    print("    '%s'," % key_list[1].wif())
    print("    HDKey('%s', key_type='single', witness_type='%s')" %