4

I am setting up a cold wallet. How can I generate a signed raw transaction from bitcoin core wallet that controls some bitcoins?

PS: I generated the wallet using getnewaddress in console from the bitcoin-qt GUI

2 Answers 2

7

The easiest way to do this by importing the address you generated on the offline Bitcoin Core client into an online fully synced Bitcoin-Core. The command is: bitcoin-cli importaddress <address>. The benefit of importing this address into the synced Bitcoin-Core machine is that you can use it as a watch-only address which will allow you to see all the UTXOs related to it. You can then use the command bitcoin-cli listunspent to show you all the UTXOs and then you can use the ones related to the address in question.

Note: Below txids and amounts are made up.
Now, using the UTXOs that were shown in the listunspent output you can create a transaction on the online client using the createrawtransaction command. I deliberately used two UTXOs to show how this can be done for multiple UTXOs and also to show how other commands will look like if one of the outpoints in the inputs belong to a legacy address and the other outpoint belongs to a P2SH-P2WPKH address.

bitcoin-cli createrawtransaction '[{"txid":"27893ad827ddd94c442c561b1d3bf3d0f60571d6518e4941698e5778b25e1991","vout":0},{"txid":"776be22ff789a86283b247f99f7b2c6f7f53185cb765570bc65c6e6bb7ed8558","vout":1}]' '{"12WJykFa1hqJUJ65QbFB8dS5XNJaR22w2S":0.1}' 

This would give you the below hexstring that you can copy over to your offline machine.

output: 020000000291195eb278578e6941498e51d67105f6d0f33b1d1b562c444cd9dd27d83a89270000000000ffffffff5885edb76b6e5cc60b5765b75c18537f6f2c7b9ff947b28362a889f72fe26b770100000000ffffffff0180969800000000001976a9141083323e89f0f734c448cd16d5a5513afb841b1788ac00000000

Copy over that output on the offline machine in order to sign the transaction. Now signrawtransaction command was deprecated in v0.17 and removed since v0.18. In place of that we now have signrawtransactionwithwallet and signrawtransactionwithkey. You will use the former when you want to sign the transaction from a key belonging to your wallet in Bitcoin Core and use the latter when you want to sign a transaction with a key not in your wallet by passing the private key along with the command.

Since your address was generated from a key in the wallet, we will use the first command. After copying over the output of the createrawtransaction command we had got on the online client, we also need to provide the sciptPubKey and redeemScript. This is done so that the offline client knows what the locking script is for the outpoints and which key it needs to use as it does not have access to the transactions (since it is offline).

Now, use the command:

bitcoin-cli signrawtransactionwithwallet "020000000291195eb278578e6941498e51d67105f6d0f33b1d1b562c444cd9dd27d83a89270000000000ffffffff5885edb76b6e5cc60b5765b75c18537f6f2c7b9ff947b28362a889f72fe26b770100000000ffffffff0180969800000000001976a9141083323e89f0f734c448cd16d5a5513afb841b1788ac00000000" 
'[{"txid":"27893ad827ddd94c442c561b1d3bf3d0f60571d6518e4941698e5778b25e1991","vout":0,"scriptPubKey":"76a914623ff66fb88ff802fe1b8eaff666ba52307eecb088ac","amount":0.09},
{"txid":"776be22ff789a86283b247f99f7b2c6f7f53185cb765570bc65c6e6bb7ed8558","vout":1, "scriptPubKey":"a914de7dad83bb2d6e9638d347dcb3c53fe238773c9387","redeemScript":"0014df7bcc159ade813e6bd6290d97ed0bc8987dc084", "amount":0.011}]' 
"ALL"

This would give you a signed transaction as an output. Let's call it hexoutput. A couple of things to note. If you pay close attention you will see that the second outpoint used in the input contains redeemScript. This is because it belonged to a P2SH-P2WPKH transaction and hence you need to provide the redeemScript next to the scriptPubKey field. For more info you can refer the documentation here.

Now copy this hexoutput over to your online Bitcoin-core client and use the below command to relay it over the network.

bitcoin-cli sendrawtransaction hexoutput

This will give you a txid of the transaction as an output that you can use to monitor your transaction.

1
  • Why initiate the raw transaction on the online machine? Why not just make and sign the transaction on the offline machine, and copy the signed transaction over just for the broadcast? Commented Mar 3, 2022 at 0:44
1

It can be done offline and with no synced data.

Start:

.\bitcoind.exe -datadir=c:\bitcoin -prune=550 -noconnect

Create transaction:

.\bitcoin-cli.exe -datadir=c:\bitcoin createrawtransaction '[{\"txid\":\"some taxid\",\"vout\":0}]' '{\"some target address\":a_number}'

To not spend all the sum, of course, add a returning address:

,\"a returning address\":a_number

vout is the output in the input taxid, for example 1 input, 2 outputs(first for someone else, second is for returning coins at owner) then: \"vout\":1 , etc.

Count the returning number of characters: ~190 for 1 input 1 output, ~230 1 input 2 outputs,etc.

Then calculate the fee, for example, 10 satoshis per byte will be ~2300 for 1 input and 2 outputs. Then: sum - to_address - returning_address = fee

Sign the transaction:

.\bitcoin-cli.exe -datadir=c:\bitcoin signrawtransactionwithkey "from create" '[\"the private key\"]' [{\"txid\":\"some taxid\",\"vout\":1,\"scriptPubKey\":\"explained below\",\"redeemScript\":\"\",\"amount\":taxid_exact_input}]'

Get scriptPubKey for example from here: https://live.blockcypher.com/btc/tx/here_is_the_taxid/ then "Advanced Details", then "API Call", then at the source output (1 in this case), the "script" value (76a9148a598937f5ffb018fd71520b7c9459391744e28688ac at my case).

Push the signed transaction, for example, from here: https://live.blockcypher.com/btc/pushtx/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.