3

I know this subject has been discussed quite a lot, but after several days looking for this to work, I give up.

I want to create a transaction on a view-only wallet which is connected to the internet and synced, then sign this transaction on a "cold" offline machine that has the private key, then send this transaction on the view-only wallet.

View-only wallet will be [VOW]

Offline cold wallet will be [OCW]

Some other bitcoin wallet will be [SOW] (on another 3rd machine, that will play the peer)

First let's simulate the nodes, with one node on each machine:

[VOW] bitcoind -regtest -wallet=/path/daemon1.dat -datadir=/path/.bitcoin1 -rpcport=18334 -port=18434 -addnode=127.0.0.1:18435
[SOW] bitcoind -regtest -wallet=/path/daemon2.dat -datadir=/path/.bitcoin2 -rpcport=18335 -port=18435 -addnode=127.0.0.1:18434
[OCW] bitcoind -regtest  -datadir=/path2/.bitcoin -wallet=/path2/wallet -rpcport=18336 -port=18436

With these aliases to call the bitcoin-cli:

alias BITVOW='bitcoin-cli -regtest -datadir=/path/.bitcoin1 -rpcport=18334'
alias BITSOW='bitcoin-cli -regtest -datadir=/path/.bitcoin2 -rpcport=18335'
alias BITOCW='bitcoin-cli -regtest -rpcport=18336'

So the two [VOW] and [SCW] connect to each other, no problem with that (they form a small 2 nodes network).

On the offline machine, I do this:

$ BITOCW getnewaddress
2Mz6H8BU3Gg4Nmrv1LyZPm4KcaKj8EjZXxL
$ BITOCW dumpprivkey
2Mz6H8BU3Gg4Nmrv1LyZPm4KcaKj8EjZXxL
cQgMpjZKVnYon1cfKaMuSpAsNQS3rw49BKUmmWV3n3UbEc1ywcQj

I want to send 500 BTC to 2Mz6H8BU3Gg4Nmrv1LyZPm4KcaKj8EjZXxL, so I generate funds to the "other" wallet, to pay my wallet, with a generate to validate the transaction:

$ BITSOW generate X
$ BITSOW getbalance
550.00000000
$ BITSOW sendtoaddress 2Mz6H8BU3Gg4Nmrv1LyZPm4KcaKj8EjZXxL 500
33f30a3efd7d9b14be28b727f61884cba22bfd69a6fa1b1a475d384fbe2db5f1
$ BITSOW generate 1
$ BITSOW getnewaddress
2NF64kzg5R4wdA3bjJAtVyvKmvgbo1FJ8SM

I will use this address 2NF64kzg5R4wdA3bjJAtVyvKmvgbo1FJ8SM to receive funds from my main wallet with an offline signature.

I import the bitcoin address on a wallet-view wallet, and check the balance:

$ BITVOW importaddress  2Mz6H8BU3Gg4Nmrv1LyZPm4KcaKj8EjZXxL
$ BITVOW getbalance "*" 0 true
500.00000000

Perfect. Now comes the part where I want to send thoses 500 back to 2NF64kzg5R4wdA3bjJAtVyvKmvgbo1FJ8SM using an offline transaction signing.

First let's identify the TX that can be used:

$ BITVOW listunspent 1 99999999 '["2Mz6H8BU3Gg4Nmrv1LyZPm4KcaKj8EjZXxL"]'
[
  {
    "txid": 
    "33f30a3efd7d9b14be28b727f61884cba22bfd69a6fa1b1a475d384fbe2db5f1",
    "vout": 0,
    "address": "2Mz6H8BU3Gg4Nmrv1LyZPm4KcaKj8EjZXxL",
    "label": "",
    "scriptPubKey": "a9144b17c1384ded51b51a60915fa56be6cc7d00212087",
    "amount": 500.00000000,
    "confirmations": 1,
    "spendable": false,
    "solvable": false,
    "safe": true
  }
]
$ BITVOW createrawtransaction '[{"txid":"33f30a3efd7d9b14be28b727f61884cba22bfd69a6fa1b1a475d384fbe2db5f1","vout":0,"scriptPubKey":"a9144b17c1384ded51b51a60915fa56be6cc7d00212087"}]' '{"2NF64kzg5R4wdA3bjJAtVyvKmvgbo1FJ8SM":499.9999}'

This gets as a raw transaction (that I put in $RAW_TRANSACTION for example):

0200000001f1b52dbe4f385d471a1bfaa669fd2ba2cb8418f627b728be149b7dfd3e0af3330000000000ffffffff01f04c3ba40b00000017a9144b17c1384ded51b51a60915fa56be6cc7d0021208700000000

Then, on the offline machine, I want to sign this using the private key:

$ BITOCW signrawtransactionwithwallet $RAW_TRANSACTION
{
    "hex": "0200000001f1b52dbe4f385d471a1bfaa669fd2ba2cb8418f627b728be149b7dfd3e0af3330000000000ffffffff01f04c3ba40b00000017a9144b17c1384ded51b51a60915fa56be6cc7d0021208700000000",
    "complete": false,
    "errors": [
   {
   "txid": "33f30a3efd7d9b14be28b727f61884cba22bfd69a6fa1b1a475d384fbe2db5f1",
  "vout": 0,
  "witness": [
  ],
  "scriptSig": "",
  "sequence": 4294967295,
  "error": "Input not found or already spent"
}
]
}

Thank you very much for your help!

[EDIT]:I also tried this:

$ BITOCW signrawtransactionwithwallet $RAW_TRANSACTION '[{"txid":"33f30a3efd7d9b14be28b727f61884cba22bfd69a6fa1b1a475d384fbe2db5f1","vout":0,"scriptPubKey":"a9144b17c1384ded51b51a60915fa56be6cc7d00212087"}]'
error code: -3
error message:
Missing amount for CTxOut(nValue=21000000.00000000, scriptPubKey=a9144b17c1384ded51b51a60915fa5)

[EDIT]

Here is what I tried using the provided solutions (2) and (3) from Pieter Wuille:

(2) I tried this on the offline system [OCW], in order to get RedeemScript for the signing process:

BITOCW getaddressinfo 2Mz6H8BU3Gg4Nmrv1LyZPm4KcaKj8EjZXxL{
  "address": "2Mz6H8BU3Gg4Nmrv1LyZPm4KcaKj8EjZXxL",
  "scriptPubKey": "a9144b17c1384ded51b51a60915fa56be6cc7d00212087",
  "ismine": true,
  "iswatchonly": false,
  "isscript": true,
  "iswitness": false,
  "script": "witness_v0_keyhash",
  "hex": "0014dd296fa290135a7c18c3002c41cf020324538d5f",
  "pubkey": "02ff5d370a78346d3fbac9750375a3d773aac9a1daadf870b887712d37c222d2b6",
  "embedded": {
    "isscript": false,
    "iswitness": true,
    "witness_version": 0,
    "witness_program": "dd296fa290135a7c18c3002c41cf020324538d5f",
    "pubkey": "02ff5d370a78346d3fbac9750375a3d773aac9a1daadf870b887712d37c222d2b6",
    "address": "bcrt1qm55klg5szdd8cxxrqqkyrnczqvj98r2l8m5l0f",
    "scriptPubKey": "0014dd296fa290135a7c18c3002c41cf020324538d5f"
  },
  "label": "",
  "timestamp": 1540018166,
  "hdkeypath": "m/0'/0'/4'",
  "hdseedid": "fc9ec97f45384df39d95fc424d5a5349951d5bde",
  "hdmasterkeyid": "fc9ec97f45384df39d95fc424d5a5349951d5bde",
  "labels": [
    {
      "name": "",
      "purpose": "receive"
    }
  ]
}

Maybe I am missing something, but I could not find a proper RedeemScript for signing.

(3) First of all, I didn't know it was possible to do such a thing without doing the coin selection myself. If it is, I'd rather have the "online watch-only" wallet make the coin selection automatically so that I don't have to programmatically select the suitable inputs.

Then, following your advice, this is what i've tried so far, after the same createrawtransaction as above, on the online system:

BITVOW converttopsbt 0200000001f1b52dbe4f385d471a1bfaa669fd2ba2cb8418f627b728be149b7dfd3e0af3330000000000ffffffff01f04c3ba40b00000017a9144b17c1384ded51b51a60915fa56be6cc7d0021208700000000
cHNidP8BAFMCAAAAAfG1Lb5POF1HGhv6pmn9K6LLhBj2J7covhSbff0+CvMzAAAAAAD/////AfBMO6QLAAAAF6kUSxfBOE3tUbUaYJFfpWvmzH0AISCHAAAAAAAAAA==

And:

BITVOW walletprocesspsbt cHNidP8BAFMCAAAAAfG1Lb5POF1HGhv6pmn9K6LLhBj2J7covhSbff0+CvMzAAAAAAD/////AfBMO6QLAAAAF6kUSxfBOE3tUbUaYJFfpWvmzH0AISCHAAAAAAAAAA==
{
  "psbt": "cHNidP8BAFMCAAAAAfG1Lb5POF1HGhv6pmn9K6LLhBj2J7covhSbff0+CvMzAAAAAAD/////AfBMO6QLAAAAF6kUSxfBOE3tUbUaYJFfpWvmzH0AISCHAAAAAAABAP0lBQIAAAALfARlDuNzSr0JSrElwpd+izM03irULESrdcQzBmKw8CQAAAAASEcwRAIgKRmcygxX+LVIzMLYpwHVPbTSNYYQjZaMXUyQCBIDBLICIFFntYpDI+G0yUH+yL7b/4YIrYjDUk08q/4A+I/2hh84Af7///+n2vDIPJrmbmA2RRL2RMtbVp+Sf4AU/JUUm53K1JOoJwAAAABIRzBEAiBOLc842GEgXdiq0gagWZ5Vvni5e6DiFGZYG+m6xGrA0QIgf1mtao/3/dGA3u6LvgI2s7bLMtDAr+cxCU/lNJ1PC8cB/v///6ePR81CkwFcpxZub36mqRIemlMGNfvWhNxlDPPZW5LyAAAAAEhHMEQCIEEl9vU7Ezn4zApn1bgUS7DR3Wvz3J9YMEzvVKgmbRaXAiA3Xv8Q5bDbLKEJ/tHn+Adr1u+EUsaKdp8LnWM8cLajHwH+////unzoFharwYU9mElHKsCWwwmoqvbtEbzL8i2dzUFq8RcAAAAASEcwRAIgVoSlc5RumxBU/O4gDzrFdXcxuCBDt30DczglDmuvSegCIFkZIqu1OS5UNncEThnNS8th+38lFf71PDa9Og2n3TKFAf7////Zq7QRMc7AhtcyGYE/HdvSAR146Dv659BXuzrHycdrcQAAAABIRzBEAiBctxeVGCoN8zlKnG19Tgs4GKnQ1r/Ge6Hjr/kIX0LJSQIgNHhYFpt2aabQEWA06apQpTcscoBH1hkDO9b9P3kNBKsB/v///0dInKhhB5SbX3zsU4+I8irL8UFXYDWqM2njZ8cDJQw4AAAAAEhHMEQCIEy0Fm9FwnEMSm6Cx37tMs8VFKNWypz3iXDZGinXpoGLAiAtH98TAw71JPde6+85VXuy5iuFa1AHt+wkF7kNipEMLQH+////4bM2jf15ocNZ2pgM9vFpX4WcMkfA2Ynvjs66xsnCGZ8AAAAASEcwRAIgaRsu6KSp27b3WZBWBv64sSWpDLywr2c7/JFwQ3yEHqwCIAC6OvBe4nMKxKu05HQADoT8e+KWLpUdrUkjM1UaM4jbAf7////8b5WwVRpa4j9w73Dg1cy3zygIu4YGBCGnFujB2T/QagAAAABIRzBEAiBKVpF+WbZJ2TJMYkujmLxEhkTAwV35Z4FgNBlYt0d28gIgCQbediJ7kTw6Hr94o4I2IiwaD3xHFN8qQI0aNl5Bjh4B/v///zPoBvkyeie1HxFTJRUrG/J7pE67/XCDa8t+uxpZKwQ8AAAAAEhHMEQCIAo5RI1TtAoOSjUfHLiBi1rZN7e9v+4cNKfiEjXvaqCYAiAAq/59k9LxVFjf8mkSs7u49wDR127cFd1vLU3bk3vifQH+////XTiaFEkYHocUhIg+XmbMi3nnpSw1qgKYKbZh1oS7dlsAAAAASEcwRAIgc/2/mN/evEi/hBA4JtTw/82mndVSuISAeTcqDQ5yyfQCIADnr/yfLKbOVj3hbqjUwewVu44xRSoBeHt3ptEwB02BAf7///87CVHCCJ4KsgaiAtMhT2h38YkXIqFy9cYDmU/IthPSmgAAAABIRzBEAiAfkNsXRjf7sPjyknV38nY1WLQ4K7oV8iqP+nhI8/jV5gIgDpJCo3VPg2M4GT9uSuDKlp4w6BqDnJsIyGdZ6XRj0SUB/v///wIAdDukCwAAABepFEsXwThN7VG1GmCRX6Vr5sx9ACEghxyLBSoBAAAAF6kULDnWiZNlc9lyYG7jv4tHeqBx1H6HbwAAAAAA",
  "complete": false
}

Then I exported this on the offline system and did:

BITOCW  walletprocesspsbt "cHNidP8BAFMCAAAAAfG1Lb5POF1HGhv6pmn9K6LLhBj2J7covhSbff0+CvMzAAAAAAD/////AfBMO6QLAAAAF6kUSxfBOE3tUbUaYJFfpWvmzH0AISCHAAAAAAABAP0lBQIAAAALfARlDuNzSr0JSrElwpd+izM03irULESrdcQzBmKw8CQAAAAASEcwRAIgKRmcygxX+LVIzMLYpwHVPbTSNYYQjZaMXUyQCBIDBLICIFFntYpDI+G0yUH+yL7b/4YIrYjDUk08q/4A+I/2hh84Af7///+n2vDIPJrmbmA2RRL2RMtbVp+Sf4AU/JUUm53K1JOoJwAAAABIRzBEAiBOLc842GEgXdiq0gagWZ5Vvni5e6DiFGZYG+m6xGrA0QIgf1mtao/3/dGA3u6LvgI2s7bLMtDAr+cxCU/lNJ1PC8cB/v///6ePR81CkwFcpxZub36mqRIemlMGNfvWhNxlDPPZW5LyAAAAAEhHMEQCIEEl9vU7Ezn4zApn1bgUS7DR3Wvz3J9YMEzvVKgmbRaXAiA3Xv8Q5bDbLKEJ/tHn+Adr1u+EUsaKdp8LnWM8cLajHwH+////unzoFharwYU9mElHKsCWwwmoqvbtEbzL8i2dzUFq8RcAAAAASEcwRAIgVoSlc5RumxBU/O4gDzrFdXcxuCBDt30DczglDmuvSegCIFkZIqu1OS5UNncEThnNS8th+38lFf71PDa9Og2n3TKFAf7////Zq7QRMc7AhtcyGYE/HdvSAR146Dv659BXuzrHycdrcQAAAABIRzBEAiBctxeVGCoN8zlKnG19Tgs4GKnQ1r/Ge6Hjr/kIX0LJSQIgNHhYFpt2aabQEWA06apQpTcscoBH1hkDO9b9P3kNBKsB/v///0dInKhhB5SbX3zsU4+I8irL8UFXYDWqM2njZ8cDJQw4AAAAAEhHMEQCIEy0Fm9FwnEMSm6Cx37tMs8VFKNWypz3iXDZGinXpoGLAiAtH98TAw71JPde6+85VXuy5iuFa1AHt+wkF7kNipEMLQH+////4bM2jf15ocNZ2pgM9vFpX4WcMkfA2Ynvjs66xsnCGZ8AAAAASEcwRAIgaRsu6KSp27b3WZBWBv64sSWpDLywr2c7/JFwQ3yEHqwCIAC6OvBe4nMKxKu05HQADoT8e+KWLpUdrUkjM1UaM4jbAf7////8b5WwVRpa4j9w73Dg1cy3zygIu4YGBCGnFujB2T/QagAAAABIRzBEAiBKVpF+WbZJ2TJMYkujmLxEhkTAwV35Z4FgNBlYt0d28gIgCQbediJ7kTw6Hr94o4I2IiwaD3xHFN8qQI0aNl5Bjh4B/v///zPoBvkyeie1HxFTJRUrG/J7pE67/XCDa8t+uxpZKwQ8AAAAAEhHMEQCIAo5RI1TtAoOSjUfHLiBi1rZN7e9v+4cNKfiEjXvaqCYAiAAq/59k9LxVFjf8mkSs7u49wDR127cFd1vLU3bk3vifQH+////XTiaFEkYHocUhIg+XmbMi3nnpSw1qgKYKbZh1oS7dlsAAAAASEcwRAIgc/2/mN/evEi/hBA4JtTw/82mndVSuISAeTcqDQ5yyfQCIADnr/yfLKbOVj3hbqjUwewVu44xRSoBeHt3ptEwB02BAf7///87CVHCCJ4KsgaiAtMhT2h38YkXIqFy9cYDmU/IthPSmgAAAABIRzBEAiAfkNsXRjf7sPjyknV38nY1WLQ4K7oV8iqP+nhI8/jV5gIgDpJCo3VPg2M4GT9uSuDKlp4w6BqDnJsIyGdZ6XRj0SUB/v///wIAdDukCwAAABepFEsXwThN7VG1GmCRX6Vr5sx9ACEghxyLBSoBAAAAF6kULDnWiZNlc9lyYG7jv4tHeqBx1H6HbwAAAAAA"
{
  "psbt": "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",
  "complete": true
}

I was happy when I saw complete = true, but then here's what happened:

BITOCW finalizepsbt "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"
error code: -22
error message:
TX decode failed PSBT is not sane.: iostream error

I found that issue #14473 on github bitcoin project seems to be related to that, but I'm not sure (https://github.com/bitcoin/bitcoin/issues/14473).

[EDIT]:

About (2): I got scriptPubKey inside the embedded field as suggested, which is 0014dd296fa290135a7c18c3002c41cf020324538d5f, and also the amount, as it is not in the raw transaction (as advised by Peter):

BITOCW -named signrawtransactionwithkey hexstring=$RAW_TRANSACTION prevtxs='[{"txid":"33f30a3efd7d9b14be28b727f61884cba22bfd69a6fa1b1a475d384fbe2db5f1","vout":0,"scriptPubKey":"0014dd296fa290135a7c18c3002c41cf020324538d5f", "amount":499.9999}]' privkeys='["cQgMpjZKVnYon1cfKaMuSpAsNQS3rw49BKUmmWV3n3UbEc1ywcQj"]'
{
  "hex": "02000000000101f1b52dbe4f385d471a1bfaa669fd2ba2cb8418f627b728be149b7dfd3e0af3330000000000ffffffff01f04c3ba40b00000017a914ef9751cb4e8dbe30f6070c546cb5fa6538231f56870246304302204385ab257825a678365ed1dfd9e06dd8c0f31ecf1f12ffd8058dff9cb952a98f021f7b0919da9ba57d94b0b5f24eaa27bcf6902460008e7db0f51890761e291c2b012102ff5d370a78346d3fbac9750375a3d773aac9a1daadf870b887712d37c222d2b600000000",
  "complete": true
}

Then I can broadcast the signed transaction on online machine, but:

BITVOW sendrawtransaction 02000000000101f1b52dbe4f385d471a1bfaa669fd2ba2cb8418f627b728be149b7dfd3e0af3330000000000ffffffff01f04c3ba40b00000017a914ef9751cb4e8dbe30f6070c546cb5fa6538231f56870246304302204385ab257825a678365ed1dfd9e06dd8c0f31ecf1f12ffd8058dff9cb952a98f021f7b0919da9ba57d94b0b5f24eaa27bcf6902460008e7db0f51890761e291c2b012102ff5d370a78346d3fbac9750375a3d773aac9a1daadf870b887712d37c222d2b600000000
error code: -26
error message: mandatory-script-verify-flag-failed (Operation not valid with the current stack size) (code 16)

About the coin selection with fundrawtransaction, I created an empty transaction and tried to fund it, from the online "view-only" wallet:

$ BITVOW createrawtransaction '[]' '{"2NF64kzg5R4wdA3bjJAtVyvKmvgbo1FJ8SM":1}'02000000000100e1f5050000000017a914ef9751cb4e8dbe30f6070c546cb5fa6538231f568700000000
$ BITVOW fundrawtransaction 02000000000100e1f5050000000017a914ef9751cb4e8dbe30f6070c546cb5fa6538231f568700000000 '{"includeWatching":true}'
error code: -4
error message:
Insufficient funds

Is includeWatching enough to make it take the watch-only address into account? To be sure, I tried :

$ BITVOW fundrawtransaction 02000000000100e1f5050000000017a914ef9751cb4e8dbe30f6070c546cb5fa6538231f568700000000 '{"includeWatching":true, "changeAddress":"2Mz6H8BU3Gg4Nmrv1LyZPm4KcaKj8EjZXxL"}'

And it made my bitcoind abort with error:

2018-10-27T18:55:19Z New outbound peer connected: version: 70015, blocks=112, peer=0 bitcoind: policy/feerate.cpp:25: CAmount CFeeRate::GetFee(size_t) const: Assertion `nBytes_ <= uint64_t(std::numeric_limits::max())' failed. Aborted

About the coin selection with walletcreatefundedpsbt, I gives me:

$ BITVOW walletcreatefundedpsbt '[]' '{"2NF64kzg5R4wdA3bjJAtVyvKmvgbo1FJ8SM":499}'
error code: -4
error message:
Insufficient funds

3 Answers 3

4

signrawtransactionwithwallet uses the wallet for two purposes:

  • Finding the private keys necessary to sign with (which you dealt with by importing)
  • Finding the transaction outputs that are being spent (without this information you can't construct a valid transaction, and the offline wallet, being offline, does not have access to the transactions that credited you).

There are a number of solutions for this, in order of increasing practicality:

  • Copy the wallet.dat from the online system to the offline system, so it sees the transaction history (do not transfer it back, as it will contain private keys)
  • Use the signrawtransactionwithkey RPC, which lets you specify the private key and the UTXO information in the RPC call, so no importing is needed anymore on the offline system.
  • Use the PSBT style RPC calls; use walletcreatefundedpsbt on the offline system, sign it on the online system using walletprocesspsbt, extract a finished transaction using finalizepsbt, which you can broadcast using sendrawtransaction. The PSBT files contain all metadata needed for signing, including the old transaction (outputs) being spent.
12
  • Thank you for your quick and precise answer. About solution 2 : I tried this before, and signrawtransactionwithkey gives me error code: -3 = "Missing redeemScript". About solution 3, which I didn't know at all, walletcreatefundedpsbt gives me "Insufficient funds" error. Oct 26, 2018 at 16:35
  • About (2): If you're spending from a P2SH address you also need to provide signrawtransactionwithkey with the redeemScript (can be found using getaddressinfo). PSBT also stores this information directly. Oct 26, 2018 at 16:49
  • 3
    About (3), sorry my advice was bad as you're doing the coin selection yourself. You can use createrawtransaction like you're doing now, then call converttopsbt on the result, then call walletprocesspsbt on the online system (which will add redeemscript and UTXO information), and then walletprocesspsbt on the offline system to sign, followed by finalizepsbt and sendrawtransaction. If this works I'll update my answer. Oct 26, 2018 at 16:51
  • 1
    Thanks again Pieter, I just edited my question to allow a more precise output, as I could not get that to work. Oct 27, 2018 at 8:30
  • About (2), what you need is the "scriptPubKey" inside the "embedded" field; it gives the script that's wrapped in P2SH. Without it, the signer doesn't know what you're actually trying to sign (as it's only given a hash of the script). Oct 27, 2018 at 17:35
1

I have a very old Greg Maxwell tutorial for this slightly old question
https://web.archive.org/web/20171124193914/https://people.xiph.org/~greg/signdemo.txt
The tutorial uses 'bitcoind' as the command because it was written before 'bitcoin-cli' became the correct command. Apart from this detail, the tutorial should still work with a recent Bitcoin Core version

I'm not sure why this discussion diverged to "PSBT does this better" without answering the question that was written, but I won't argue against "PSBT does this better"

The question is now hard to follow, has been altered in a train of thought manner, so it's possible I missed something

The question uses 'signrawtransactionwithwallet'
The tutorial uses 'signrawtransaction'

The questioner tries to use 'getaddressinfo' to find the RedeemScript
The tutorial uses 'decoderawtransaction' to expose the RedeemScript

Unless I'm reading the flow of advice incorrectly, the problem is that a cold wallet can not know the RedeemScript, and this is why 'signrawtransactionwithwallet' fails to work. 'signrawtransaction' accepts the RedeemScript as a parameter, and 'decoderawtransaction' exposes the RedeemScript

I haven't tried the method in the Greg Maxwell tutorial, but I hope this small contribution is useful to understanding the problem better

If I cannot find a newer offline signing tutorial, I will try to put aside some time to write a fresh version

0

I do not have enough reputation to reply on Pieter Wuille's answer, but I have tested using PSBT (solution 3) with bitcoin-core v0.18.0, it now works well for this. In my case, using PSBT was a lot easier than using signrawtransactionwithkey. The steps I've used are:

  1. createrawtransaction on watch-only wallet.
  2. fundrawtransaction on watch-only wallet.
  3. converttopsbt on watch-only wallet.
  4. walletprocesspsbt on watch-only wallet. Not sure why this is necessary but it does change the PSBT string. I thought converttopsbt would do whatever this step does.
  5. walletprocesspsbt on offline wallet.
  6. finalizepsbt on offline wallet.

It shouldn't make a difference, but for the record I've used the RPC API, not the command-line.

4
  • I think step 5 should be done on offline wallet.
    – Thalis K.
    Aug 22, 2019 at 8:15
  • The reason why step 4 is needed, is because the inputs are referenced by txid:vout and the offline wallet cannot know how to get the details needed (e.g. scriptPubKey) since it doesn't have any blocks. So walletprocesspsbt on the watch-only (onlline) wallet fills in this information (in particular the psbt's inputs[] part).
    – Thalis K.
    Aug 22, 2019 at 12:10
  • @ThalisK. You're right, sorry for the typo ! And about step 4, I understand that and agree, but I don't see why step 3 isn't already doing this. But anyway, it's not a problem to do it in two steps.
    – Clément
    Aug 23, 2019 at 6:30
  • As far as I understand converttopsbt literally does the conversion from one structure format (tx) to the other (psbt). It doesn't do lookup and filling in of data. walletprocesspsbt does the lookup and filling in. Separation of concerns keeps each command simple and focused.
    – Thalis K.
    Aug 23, 2019 at 10:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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