Bitcoin Forum
May 04, 2024, 04:43:25 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Air-gapping old legacy non-descriptor wallets, migration to descriptor wallet  (Read 98 times)
af_newbie (OP)
Legendary
*
Offline Offline

Activity: 2688
Merit: 1468



View Profile WWW
November 14, 2023, 07:38:52 AM
Last edit: November 14, 2023, 02:43:30 PM by af_newbie
Merited by LoyceV (12), ABCbits (9), NotATether (5), Husna QA (2), seek3r (2), DdmrDdmr (1)
 #1

I thought I share my experience migrating old legacy non-descriptor wallets to descriptor wallets
and setting the corresponding watch wallets for them. I wish there was an easier way to do this.

I used Bitcoin Core version 25.1

You need two 'bitcoin only' dedicated computers: OFFLINE and ONLINE.

On the OFFLINE computer:
-------------------------------

1. Restore your legacy, non-descriptor wallet in bitcoin-qt, name it "legacyNoDesc"
2. Open the console and run

Code:
	migratewallet "legacyNoDesc" "password"
   
   Backup the wallet as "legacyDesc".
  
3. To get the range descriptors, run listdescriptors, make note of all the descriptors:

   for 1* addresses, the range descriptor looks like "pkh(***44'***)***", there are two, copy both of them
   for 3* addresses, the range descriptor looks like "sh(wpkh(***49'***))***", there are two, copy both of them
   for bc1q* addresses, the range descriptor looks like "wpkh(***84'***)***", there are two, copy both of them
   for bc1p* addresses, the range descriptor looks like "tr(***86'***)***", there are two, copy both of them
  
4. To get the one2one descriptors, run listaddressgroupings, and then listunspent command in the console
for each address you want to monitor. Look for descriptors in the format "***(***/0'***)***".

Those are ONE address <-> ONE descriptor, no range descriptors. You can run

Code:
deriveaddresses "pkh(***0'***)***"

to see/validate which address they derive.

For range descriptors create two commands for each address type:

Code:
importdescriptors "[{\"desc\": \"pkh(***44'***)..."\, "\range\": [0,999], \"timestamp\": 0, \"internal\": false, \"watchonly\": true, \"active\": true}]"
importdescriptors "[{\"desc\": \"pkh(***44'***)???"\, "\range\": [0,999], \"timestamp\": 0, \"internal\": true, \"watchonly\": true, \"active\": true}]"
Code:
importdescriptors "[{\"desc\": \"sh(wpkh(***49'***))..."\, "\range\": [0,999], \"timestamp\": 0, \"internal\": false, \"watchonly\": true, \"active\": true}]"
importdescriptors "[{\"desc\": \"sh(wpkh(***49'***))???"\, "\range\": [0,999], \"timestamp\": 0, \"internal\": true, \"watchonly\": true, \"active\": true}]"
Code:
importdescriptors "[{\"desc\": \"wpkh(***84'***)..."\, "\range\": [0,999], \"timestamp\": 0, \"internal\": false, \"watchonly\": true, \"active\": true}]"
importdescriptors "[{\"desc\": \"wpkh(***84'***)???"\, "\range\": [0,999], \"timestamp\": 0, \"internal\": true, \"watchonly\": true, \"active\": true}]"
Code:
importdescriptors "[{\"desc\": \"tr(***86'***)..."\, "\range\": [0,999], \"timestamp\": 0, \"internal\": false, \"watchonly\": true, \"active\": true}]"
importdescriptors "[{\"desc\": \"tr(***86'***)???"\, "\range\": [0,999], \"timestamp\": 0, \"internal\": true, \"watchonly\": true, \"active\": true}]"
  

You can leave timestamp 0 (if you want to rescan the whole chain, or put the current time.
Use https://www.epochconverter.com/ to pick the date/time you want as a starting point.

For the non-range descriptors the commands will be shorter:

Code:
importdescriptors "[{\"desc\": \"pkh(***0'***)..."\, "\range\": [0,999], \"timestamp\": 0}]"
importdescriptors "[{\"desc\": \"sh(wpkh(***0'***))..."\, "\range\": [0,999], \"timestamp\": 0}]"
importdescriptors "[{\"desc\": \"wpkh(***0'***)..."\, "\range\": [0,999], \"timestamp\": 0}]"
importdescriptors "[{\"desc\": \"tr(***0'***)..."\, "\range\": [0,999], \"timestamp\": 0}]"

Import descriptors for all addresses listed in listaddressgroupings command, or just the ones that have coins in them.

Save the above importdescriptors in a text file. You will run them in your WATCH wallet in step 7.

Now, on the ONLINE computer:
-------------------------------------

5. Sync up your client.
6. Create an EMPTY/BLANK descriptor wallet with NO PRIVATE keys. This will be your WATCH wallet.
7. Run the commands created in step 4.
   (If you use timestamp set to 0, each command will be re-scanning the whole chain.)

You can also import them with one command:

Code:
importdescriptors "[{***},{***},{***}]"

(replace *** with the descriptors your want to import)

Wait for the wallet to sync up, and your WATCH wallet should show the correct balance of your COLD wallet.

Now you can create unsigned transactions in your WATCH wallet (on the ONLINE computer),
and sign them in the COLD wallet (on the OFFLINE computer).

The OFFLINE computer should never be connected to any network, preferably have no WiFi/WAN
and Ethernet hardware. Never put any software on it, other than some hardened OS and the Bitcoin Core.

Same goes for the ONLINE computer, install some hardened OS on it, block all in/out connections, except out
TCP 53, 8333 for bitcoin-qt executable ONLY. Use some other safe computer to download binaries from
https://bitcoincore.org/en/download/ and verify the checksum before copying core binaries
to your 'bitcoin only' computers.

PS. I wish someone would add "createwatchwallet" command to the Bitcoin Core so that we don't have to
do this manually, maybe something like this:

Code:
createwatchwallet "cold_wallet_name" "watch_wallet_name"

1714841005
Hero Member
*
Offline Offline

Posts: 1714841005

View Profile Personal Message (Offline)

Ignore
1714841005
Reply with quote  #2

1714841005
Report to moderator
1714841005
Hero Member
*
Offline Offline

Posts: 1714841005

View Profile Personal Message (Offline)

Ignore
1714841005
Reply with quote  #2

1714841005
Report to moderator
1714841005
Hero Member
*
Offline Offline

Posts: 1714841005

View Profile Personal Message (Offline)

Ignore
1714841005
Reply with quote  #2

1714841005
Report to moderator
"With e-currency based on cryptographic proof, without the need to trust a third party middleman, money can be secure and transactions effortless." -- Satoshi
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1714841005
Hero Member
*
Offline Offline

Posts: 1714841005

View Profile Personal Message (Offline)

Ignore
1714841005
Reply with quote  #2

1714841005
Report to moderator
1714841005
Hero Member
*
Offline Offline

Posts: 1714841005

View Profile Personal Message (Offline)

Ignore
1714841005
Reply with quote  #2

1714841005
Report to moderator
achow101
Moderator
Legendary
*
Offline Offline

Activity: 3388
Merit: 6581


Just writing some code


View Profile WWW
November 14, 2023, 05:23:15 PM
Merited by LoyceV (6), ABCbits (5), Husna QA (2)
 #2

You don't need to construct the descriptor import command, listdescriptors already gives it to you. It was designed so that you can just take the entirety of the "descriptors" field and pass it straight to importdescriptors.

Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!