3

I have stored my bitcoins on Bitcoin Core in a few P2PKH addresses with many UTXOs. I would like to have a plan, how these bitcoins can be moved air-gapped to a more up-to-date setup (not discussed here).

I have not touched this computer (OFFLINE) for many years and I am afraid to connect it to the internet.

I assume that I need to have access to the lastest UTXO set and then create air-gapped transactions. But how exactly can this be done?

Is it possible to setup a Bitcoin Core on another online computer (ONLINE) and import the addresses using "importaddress"?
Is it (and how) possible to create an unsigned transaction on this ONLINE computer including all UTXOs of one of the imported (watch-only) addresses?
And then move this unsigned transaction to the old offline computer (OFFLINE) with the old wallet.dat file and sign the transaction?

Is this possible or is there another way to do this air-gapped?

Has anyone documented all the necessary steps?

Thanks for your help!

-A frightened hodler

hodddl
  • 101
  • 7
  • You can create a raw transaction, sign it and get the hex value offline https://bitcoin.stackexchange.com/questions/69842/create-a-raw-transaction-and-broadcast-it-to-blockchain-using-bitcoin-core Next you can broadcast it using other node on another machine which is online. –  Aug 26 '20 at 17:10
  • Thank you. But manually creating a transaction with many inputs seems too error-prone to me. Is this possible using the GUI? – hodddl Aug 26 '20 at 18:40
  • Maybe you can create a watch-only wallet https://i.imgur.com/IFrWWGc.png on another machine to create unsigned transaction which spends the UTXOs. Sign this tx on machine which has offline wallet with private keys and broadcast it later from other machine. Last two things may need console. –  Aug 26 '20 at 20:46
  • Yes, that's my idea. But is this really possible using Bitcoin Core? Are you aware of any documentation/videos? – hodddl Aug 27 '20 at 05:56
  • Yes its possible. No but you can try and ask question here if you get error at any step or unable to complete. –  Aug 27 '20 at 07:26
  • @Prayank I tried and I am stuck here: I've done `importaddress` on the ONLINE computer, `getaddressinfo` shows that the address is `iswatchonly`, not `ismine` and not `solvable`. What do I have to do now to create an unsigned PSBT tx using the GUI? – hodddl Sep 15 '20 at 12:14
  • 1
    I have asked one question related to this issue: https://bitcoin.stackexchange.com/questions/99046/how-to-create-unsigned-tx-in-a-watch-only-wallet –  Sep 16 '20 at 07:17
  • By setting up a wallet with disabled private keys and importing the `p2pkh` address using `importmulti` it's now possible to click on `Create Unsigned` but I'm now stuck like you at [The amount exceeds your balance](https://bitcoin.stackexchange.com/questions/99046/how-to-create-unsigned-tx-in-a-watch-only-wallet) Have you managed to get it to work? I guess the issues is somehow the missing output script. How can I import it? – hodddl Sep 18 '20 at 16:06
  • 1
    https://bitcoin.stackexchange.com/a/99112/ –  Sep 19 '20 at 08:45
  • @Prayank Great. But how do you create a descriptor when using a `p2pkh` address? – hodddl Sep 22 '20 at 10:24
  • You can use [getdescriptorinfo](https://bitcoincore.org/en/doc/0.20.0/rpc/util/getdescriptorinfo/) and mention the public key of the address https://i.stack.imgur.com/wlKVi.png –  Sep 22 '20 at 11:27
  • @Prayank Thank you, but `getaddressinfo` does not return the `pubkey` required by `getdescriptorinfo`. Did you manage to test it using a `p2pkh`address? – hodddl Sep 22 '20 at 14:12
  • yes its working for me and the json output even has a desc field with some string apart from pubkey –  Sep 23 '20 at 13:29

3 Answers3

2

Update Aug 1, 2021: this answer covers Bitcoin Core <= 0.20.1. For Bitcoin Core >= 0.21.0 using the GUI-integration for PSBTs check the second answer.

Yes, it's possible using descriptors and PSBTs.

How to spend/sweep p2pkh UTXOs air-gapped using Bitcoin Core's GUI and PSBTs.

Here are the required steps, most of them have to be entered into Bitcoin Core's console.

OFFLINE

  • export the descriptor of the p2pkh address:

     getaddressinfo ADDRESS
  • copy the "desc": "pkh([....", output to the ONLINE computer

ONLINE

  • optional: create a new wallet in Bitcoin Core
  • import the descriptor from above into Bitcoin Core:
     importmulti '[{ "desc": "pkh([....", "timestamp":0, "label":"import", "watchonly":true }]'
  • optional: check that the following is now "solvable":
     getaddressinfo ADDRESS
  • now create the unsigned PSBT using Bitcoin Core's GUI
  • copy the unsigned PSBT (YOUR-PSBT) to the OFFLINE computer

OFFLINE

  • if needed unlock your wallet
    walletpassphrase "YOUR_WALLET-PASSWORD" 600
  • optional: check the PSBT
     decodepsbt YOUR-PSBT
    and
     analyzepsbt YOUR-PSBT
  • sign your PSBT:
    walletprocesspsbt YOUR-PSBT
  • finalize your PSBT:
    finalizepsbt OUTPUT-FROM-WALLETPROCESSPSBT-ABOVE
  • copy the hex output from above to your ONLINE computer

ONLINE

  • send the raw transaction using
    sendrawtransaction HEX-FROM-ABOVE
  • optional: copy the raw transaction into an block explorer like blockstream.info instead

Done!

Feedback is welcome!

hodddl
  • 101
  • 7
  • Hi hodddl, am i understanding correctly that the difference between your two answers is that one is CLI-based and the other GUI-based? I think it might make sense to combine them both in one answer where give both variants for the offline step, as the two answers do not look obviously different to a skimming reader in the first place. – Murch Jul 15 '21 at 21:43
  • Hi Murch, thank you for your feedback. The first answer covers Bitcoin Core <= 0.20.1 and required a lot of CLI commands. The second answer is an update covering Bitcoin Core >= 0.21.0 using the GUI-integration for PSBTs. – hodddl Jul 28 '21 at 13:21
  • Maybe you could add a little pointer at the top of this answer in which case people should read the other answer instead. :) – Murch Jul 28 '21 at 17:16
1

Yes, it's even easier using Bitcoin Core 0.21.0, descriptors and PSBTs.

How to spend/sweep p2pkh UTXOs air-gapped using Bitcoin Core's 0.21.0 GUI and PSBTs.

Here are the required steps, many of them have to be entered into Bitcoin Core's console.

OFFLINE (best to use a laptop booted from a Ubuntu USB-stick and no internet connected)

  • export the descriptor of the p2pkh address:

     getaddressinfo ADDRESS
  • copy the "desc": "pkh([....", output to the ONLINE computer

ONLINE

  • optional: create a new wallet in Bitcoin Core
  • import the descriptor from above into Bitcoin Core:
     importmulti '[{ "desc": "pkh([....", "timestamp":0, "label":"import", "watchonly":true }]'
  • optional: check that the following is now "solvable":
     getaddressinfo ADDRESS
  • now create the unsigned PSBT using Bitcoin Core's GUI: "Send", "Create Unsigned", "Create Unsigned" and "Save"
  • copy the file containing the unsigned PSBT to the OFFLINE computer

OFFLINE

  • if needed unlock your wallet
    walletpassphrase "YOUR_WALLET-PASSWORD" 600
  • now import the file from above and sign the unsigned PSBT using Bitcoin Core's GUI: "File->Load PSBT from file"
  • double check the transaction and "Sign Tx"
  • then select "Copy to Clipboard"
  • copy this hex output (now in your Clipboard) from above to your ONLINE computer

ONLINE

  • send the raw transaction using
    sendrawtransaction HEX-FROM-ABOVE
  • optional: copy the raw transaction into an block explorer like blockstream.info instead

Done!

Feedback is welcome!

hodddl
  • 101
  • 7
0

With Bitcoin Core 22.0 it is even easier since it adds the command "listdescriptors".

OFFLINE:

  • Create a wallet with descriptors true.
  • In console type: listdescriptors.
  • Copy the desired descriptors. ( You will see descriptors with internal:false and internal:true. Internal false will provide the information needed for the watch-only wallet to generate receiving addresses while internal true is for the change addresses).

ONLINE:

  • Create a watch only
  • Import descriptors with the command "importdescriptors"

After this the watch wallet only it is fully functional allowing to receive payments and create unsigned transactions.

For payments:

ONLINE: Create Unsigned, save the PSBT file

OFFLINE: File→Load PSBT from file and sign

ONLINE: File→Load psbt from file and broadcast signed tx