Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: Forsyth Jones on May 29, 2024, 06:31:46 PM



Title: [HOW-TO] Import privkeys into a Bitcoin Core descriptor wallet
Post by: Forsyth Jones on May 29, 2024, 06:31:46 PM
Since bitcoin core v21 (https://achow101.com/2020/10/0.21-wallets), the structure for generating public addresses has changed to output descriptors and the RPC commands for importing private keys such as: importprivkey or importwallet are obsolete if you are on a descriptive wallet (only legacy wallets are supported by this command).

Bitcoin Core generated BIP32 deterministic wallets at Derivation Path: (m/0'/0') for the three types of scripts: legacy (pkh), p2sh-segwit (sh(wpkh)) and bech32 (wpkh). In other words, they didn't use the standard paths: (m/44'/0'/0'/0), (m/49'/0'/0'/0), (m/84'/0'/0' /0)...

In other words, when generating a new receiving address in Bitcoin Core on legacy wallets, regardless of the address provided, the 3 types of addresses corresponded to the same private key and public key. For those who don't know, the same private key can generate all types of addresses, example below:

Disclaimer: The privkey examples used in this topic are for example demonstration only, do not use this private key or addresses represented here, use your own. Also, make sure you read and understand the purpose of this thread, if you have any questions, don't continue, just reply to this thread and I or others should respond here (be careful with any help received in your PM).

https://www.talkimg.com/images/2024/05/29/LjI85.png (https://www.talkimg.com/image/LjI85)

https://www.talkimg.com/images/2024/05/29/Lj3Az.png (https://privatekeyfinder.io/mnemonic-converter/)

Before we continue: you can import a private key in 2 ways:

If you want to import all scripts belonging to this key (p2pkh, p2wpkh-p2sh and p2wpkh), we use the "combo" command

If you only have a balance in one of these scripts, we use: legacy (pkh), p2sh-segwit (sh(wpkh)), bech32 (wpkh) and taproot (tr).

Initially, let's use the 'combo' command as an example.

With Bitcoin Core running, open the console and follow the steps:

1. In the console, enter your wallet password (if password protected) with
Code:
walletpassphrase "your_hard_passwd" 600

The number 600 is equivalent to the seconds that your wallet is unlocked, it could be any number, for example, 1 minute (60) and so on. Once you have finished importing your privkeys (or handling any sensitive data from or to this wallet), type 'walletlock' on the console to lock the wallet.

2. First you must type "getdescriptorinfo" followed by the type of script (address) you want to be imported, such as "combo" to import a combo of 3 addresses at once that correspond to the same private key, this command is necessary to obtain the checksum, example below:

Code:
getdescriptorinfo "combo(L4Mt9ChtjGHfDT99vWzQ12wMeix2EGa4aY4r8f4tC7Ggov3325nD)"

https://www.talkimg.com/images/2024/05/29/Lj47w.png (https://www.talkimg.com/image/Lj47w)

The information we need is: "checksum": "59sqdw96"

3. Type: importdescriptors '[{"desc":"combo(Your_WIF-Key_here)#Checksum","timestamp":"now"}]'

Code:
importdescriptors '[{"desc":"combo(L4Mt9ChtjGHfDT99vWzQ12wMeix2EGa4aY4r8f4tC7Ggov3325nD)#59sqdw96","timestamp":"now"}]'

https://www.talkimg.com/images/2024/05/29/LjBLa.png (https://www.talkimg.com/image/LjBLa)

Addendum: optionally, you can add a label for this address to be imported, such as "paperwallet". You can add a label after or at the time of import:

Code:
importdescriptors '[{"desc":"combo(L4Mt9ChtjGHfDT99vWzQ12wMeix2EGa4aY4r8f4tC7Ggov3325nD)#59sqdw96","timestamp":"now","label":"paperwallet"}]'

After that, in the Receiving Addresses Tab, you will see the imported addresses together with their key pair:

https://www.talkimg.com/images/2024/05/29/Ljgeo.md.png (https://www.talkimg.com/image/Ljgeo)

After that, if this key had already received some balance before, you must give the command rescanblockhain + the block number in which the transaction was validated + block number for Bitcoin Core to stop scanning. Example, if I received a transaction for this imported address, and the transaction was validated at block 555555, just give the rescanblockchain command and some other random block number to stop scanning (otherwise the core will scan up to the current number of blocks of your blockchain), example below:

Code:
rescanblockchain 555555 555558

By this time, if your transaction is included in one of these blocks specified when giving the command above, the balance will have already been updated in your wallet after scanning.
If you have a balance in legacy addresses, segwit addresses, etc. After this command, you will see the balance in all address scripts for your newly imported private key.

If you haven't done so yet, type: "walletlock" in the console to lock this wallet, press CTRL + L or click the X in the upper right corner of the console window to clear any sensitive data entered into the console.


Title: Re: [HOW-TO] Import privkeys into a Bitcoin Core descriptor wallet
Post by: Forsyth Jones on May 29, 2024, 06:32:18 PM
I made this guide to be complete, so continuing... If you want to import a private key with just one type of address, like I said:

If you only have a balance in one of these scripts, we use: legacy (pkh), p2sh-segwit (sh(wpkh)), bech32 (wpkh) and taproot (tr).

If you only have a balance in one of these scripts, we use: legacy (pkh), p2sh-segwit (sh(wpkh)), bech32 (wpkh) and taproot (tr).

Keep in mind that when importing only one address script type of the associated privkey, Bitcoin Core will only read the address type you used to import the key.

Always remember to obtain the checksum for the descriptor to be imported:
Quote
2. First you must type "getdescriptorinfo" followed by the type of script (address) you want to be imported

1. Importing a private key to legacy address:

Code:
getdescriptorinfo "pkh(L4Mt9ChtjGHfDT99vWzQ12wMeix2EGa4aY4r8f4tC7Ggov3325nD)"

Checksum=pn9t7xpf

Code:
importdescriptors '[{"desc":"pkh(L4Mt9ChtjGHfDT99vWzQ12wMeix2EGa4aY4r8f4tC7Ggov3325nD)#pn9t7xpf","timestamp":"now"}]'

Addr_refreshed=1MzrTBgEqyHXpsyfci9PzfNYCctr8C1g3P

2. Importing a private key to p2sh-segwit:

Code:
getdescriptorinfo "sh(wpkh(L4Mt9ChtjGHfDT99vWzQ12wMeix2EGa4aY4r8f4tC7Ggov3325nD))"

Checksum=9k8pcre0

Code:
importdescriptors '[{"desc":"sh(wpkh(L4Mt9ChtjGHfDT99vWzQ12wMeix2EGa4aY4r8f4tC7Ggov3325nD))#9k8pcre0","timestamp":"now"}]'

Addr_refreshed=3EGckQh7RVDz4tskcRQLbm28A3c79MSyAV

3. Importing a private key to bech32 native-segwit bc1 addr:

Code:
getdescriptorinfo "wpkh(L4Mt9ChtjGHfDT99vWzQ12wMeix2EGa4aY4r8f4tC7Ggov3325nD)"

Checksum=qwns7c0u

Code:
importdescriptors '[{"desc":"wpkh(L4Mt9ChtjGHfDT99vWzQ12wMeix2EGa4aY4r8f4tC7Ggov3325nD)#qwns7c0u","timestamp":"now"}]'

Addr_refreshed=bc1quefczeahw2f9v3hzaqnxfgp8j6wdzs8hqwe5wa

4. Importing a private key to taproot addr:

Code:
getdescriptorinfo "tr(L4Mt9ChtjGHfDT99vWzQ12wMeix2EGa4aY4r8f4tC7Ggov3325nD)"

Checksum=lrle38p8

Code:
importdescriptors '[{"desc":"tr(L4Mt9ChtjGHfDT99vWzQ12wMeix2EGa4aY4r8f4tC7Ggov3325nD)#lrle38p8","timestamp":"now"}]'

Addr_refreshed=bc1p3ne0p654zueu3ytjgc8j4hhk5ed4xkethzp40mqu65lprz5glzyq5dsz4n



To import a bunch of keys:

Code:
importdescriptors '[{"desc":"wpkh(L1JYXmcqxi7qSf4GbjiurKypjCwe58b7CAqKt7e4LKzwPZyy5keX)#xa7sthaq","timestamp":"now"}, {"desc":"wpkh(KxZABocQzBdgSgD43YGyciXqZkaWiSAcfgFedaQopTE7QmY5Ze2b)#vpnlelw8","timestamp":"now"}, {"desc":"wpkh(L3SLqPexiUaTCX7Eh12S49qoKJ3rFR23JCFwTrB5A8tnysKrfLeq)#9gtpne59","timestamp":"now"}]'