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
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 txid
s 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.
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/