How to migrate an old wallet?


I had an old blockstack installation and upgraded it. When I ran blockstack setup_wallet it just backed up my old wallet.json and created a new one. Meaning I don’t have access to my old names.

I have tried blockstack import_wallet but am unsure of the values I should provide. My wallet has the following fields: owner_addresses, encrypted_master_private_key, data_pubkey, payment_addresses and data_pubkeys.

How should I migrate my wallet?
Many thanks.

The setup_wallet command should back up your old wallet and generate a new one with equivalent data. It’s just a JSON blob, so you can inspect it with cat ~/.blockstack/wallet.json | jq. Does the new wallet have the same owner and payment addresses?

Nope, they are different. It seems setup_wallet only backs up the old one, and ignores it when creating the new one.

Can you try the following from a Python shell?

$ python
Python 2.7.14 (default, Dec 14 2017, 15:51:29)
[GCC 6.4.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import blockstack_client.wallet as w
>>> w.load_wallet(wallet_path="/path/to/your/.blockstack/wallet.json", include_private=True)                                                                                                                                                                                                                                     
Enter wallet password:

If all goes well, you should be prompted for your wallet password and the code snippit should print out an up-to-date wallet. If this works for you, then you can manually create a new wallet by running blocksatck import_wallet and answering the prompts with the data the above code printed out.

Thanks for the code. It executes without error but the output owner and payment address are different from my wallet file. So when I run import_wallet with the output data I do not own my names…

What is “interesting” is that the output addresses are the same ones generated when I run setup_wallet. Is this supposed to happen? I thought that a name is linked to an address, so having a different address necessarily means owning different names.

It could be the case that the private keys derived from your old wallet are uncompressed, whereas the private keys that the code above produced are compressed.

When the load_wallet() method gives you back some JSON, can you check and see what the compressed and uncompressed public key addresses are with this code?

Here’s an example with the private key a9557507705dd216633dc405333b1fcd855328ade314e9f2e22ce6fbc215e14901:

$ python
Python 2.7.14 (default, Dec 14 2017, 15:51:29)
[GCC 6.4.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import virtualchain
>>> virtualchain.lib.ecdsalib.ecdsa_private_key('a9557507705dd216633dc405333b1fcd855328ade314e9f2e22ce6fbc215e14901', compressed=True).public_key().address()                                                                                                                                                                  
>>> virtualchain.lib.ecdsalib.ecdsa_private_key('a9557507705dd216633dc405333b1fcd855328ade314e9f2e22ce6fbc215e14901', compressed=False).public_key().address()                                                                                                                                                                

What is “interesting” is that the output addresses are the same ones generated when I run setup_wallet. Is this supposed to happen?

The setup_wallet directive calls load_wallet() internally to attempt to migrate it. What I suspect is happening is that somewhere along the line the private keys from your old wallet are being used to generate an uncompressed public key address (which will be different than the address of the compressed public key).

Indeed, when using compressed=True I get the proper addresses (those in my legacy wallet.json). If I use compressed=False, then the result is that of setup_wallet.

What should I do? :blush:

Interesting. Glad to hear that you were able to derive your owner and payment keys!

Can you try the following?

  1. Move your old ~/.blockstack/wallet.json file out of the way
  2. Run blockstack import_wallet YOUR_PAYMENT_KEY YOUR_OWNER_KEY [some random ECDSA key that won't be used] Be sure that the values of YOUR_PAYMENT_KEY and YOUR_OWNER_KEY are 66 bytes and end in 01 to indicate that the code should use the compressed public key address.
1 Like


I have my names back ;). If I can see them I guess all is ok, right?

So I actually just added “01” at the end of my two private keys, and used the above random ECDSA key (the one in your previous reply). Is this ok?

It’s probably best if you use a random key you generate yourself, but you’re safe as long as you don’t use any of the profile-affecting methods (like put_profile or sign_profile). The third key is the data-signing private key, and is no longer used anywhere else. If you do need to use put_profile or sign_profile, you’ll want to pass your owner private key explicitly in order to sign with it instead.

Ok, I will use a random one. Must a keep a backup of it though?

Thanks again :slight_smile:

Glad it’s working now!

I’d recommend keeping the wallet backup(s) on a USB stick (or some other cold storage) until you’re sure you don’t need them again :slight_smile: It’s all but impossible to recover a name if the wallet goes missing.