Bisq Manual Payout using bitcoin-core CLI

In case you want to have fun with the 2-of-2 multisig scheme of bisq...

1) Register the multisig

bitcoin-cli addmultisigaddress 2 '["$SellerMultiSigPubKeyHex","$BuyerMultiSigPubKeyHex"]' 'bisq_manual_payout1' 'bech32'

Where $BuyerMultiSigPubKeyHex and $SellerMultiSigPubKeyHex can be found in your bisq trade JSON contract:

  • Find your trade under PORTFOLIO.
  • Click the i icon next to the trade ID, and at the bottom click VIEW CONTRACT IN JSON FORMAT. At the end, you see the Buyer and Seller public keys:
BuyerMultiSigPubKeyHex: <hex value>
SellerMultiSigPubKeyHex: <hex value>

The command show return:

{
 "address": "bc1...",
 "redeemScript": "...",
 "descriptor": "..."
}

The address here is the address of the 2-of-2 multisig escrow account.

2) Validate the address of multisig escrow

bitcoin-cli validateaddress "$addressFrom1"

this should return:

[
   {
       "isvalid": true,
       "address": "bc1...",
       "scriptPubKey": "...",
       "isscript": true,
       "iswitness": true,
       "witness_version": 0,
       "witness_program": "..."
   }
]

find the transaction $txid and the output $index that outputs to the address $addressFrom1 with a blockchain explorer:

  • Pick your favorite blockchain explorer ex: mempool.space
  • Enter the validated address of the mutisig found previously
  • Retain the TXid for next step

3) Create the unsigned transaction

bitcoin-tx -create -json in=$txid:$index outaddr=$amount1:$address1 outaddr=$amount2:$address2

where:

  • $txid is the transaction found from the blockchain explorer
  • $index is the location of the escrow address in the transaction starting from 0
  • $amount1 and $address1 is the trade maker's peer
  • $amount2 and $address2 is the trade taker's peer

Notice that ($amount1 + $amount2) + fees = The amount of the address of the multisig escrow account found earlier in the blockchain explorer.

it will be the outputs of the manual payout.

The command should return:

{
   "txid": "...",
   "hash": "...",
   "version": ...,
   "size": ...,
   "vsize": ...,
   "weight": ...,
   "locktime": 0,
   "vin": [
       {
           "txid": "$txid",
           "vout": $index,
           "scriptSig": {
               "asm": "",
               "hex": ""
           },
           "sequence": ...
       }
   ],
   "vout": [
       {
           "value": $amount1,
           "n": 0,
           "scriptPubKey": {
               "asm": "...",
               "hex": "...",
               "reqSigs": 1,
               "type": "witness_v0_keyhash",
               "addresses": [
                   "$address1"
               ]
           }
       },
       {
           "value": $amount2,
           "n": 1,
           "scriptPubKey": {
               "asm": "...",
               "hex": "...",
               "reqSigs": 1,
               "type": "witness_v0_keyhash",
               "addresses": [
                   "$address2"
               ]
           }
       }
   ],
   "hex": "..."
}

Note The Vsize of the transaction should be around 170 vBytes, you should leave at least 500 satoshis (0.00000500 BTC) for fees for the transaction. 5000 satoshis is also good.

4) Signing the transaction with private keys

In order to manually collect the two peers' private keys, you must remove the encryption from your wallet:

To access your Bisq wallet private key

  • Press Ctrl + j, alt +j or cmd + j.
  • Check Include private keys and click COPY TO CLIPBOARD.
  • In the text editor, search for the public key value. You are looking for an entry that reads DeterministicKey{pub HEX=<hex value> where is the public key.
  • When you've found this entry, select and copy the priv WIF=<hex value> value that immediately follows the pub HEX value. This value is the private key.
  • retain this information.

Each peer of the trade will have their own MY_PRIV_KEY_IN_WIF in the multisig 2-of-2 wallet.
They will need to sign their side of the transaction:

bitcoin-cli signrawtransactionwithkey "$hexFrom3" '["MY_PRIV_KEY_IN_WIF"]' '[{ "txid": "$txid", "vout": $index, "scriptPubKey": "$scriptPubKeyFrom2", "witnessScript": "$redeemScriptFrom1", "amount": $2-of-2multisigAmount}]' "ALL"

where:

  • $2-of-2multisigAmount is the whole amount found in your block explorer for address
  • $addressFrom1 is address of the 2-of-2 multisig escrow account
  • $txid is the transaction id found in the blockchain explorer
  • $index is the location of the escrow address in the transaction starting from 0

this should return

{
 "hex": "...",
 "complete": false,
 "errors": [
   {
     "txid": "$txid",
     "vout": $index,
     "witness": [
       "",
       "...",
       "",
       "..."
     ],
     "scriptSig": "",
     "sequence": ...,
     "error": "CHECK(MULTI)SIG failing with non-zero signature (possibly need more signatures)"
   }
 ]
}

Now send the resulting $hexFrom4 to your trading counter party for their signature

5) verify and sign the other part with the other key

First verify the partitally signed transaction from the previous step:

bitcoin-cli decoderawtransaction $hexFrom4

This allow the counterparty to check that everything is in order.

Then,

bitcoin-cli signrawtransactionwithkey "$hexFrom4" '["YOUR_PRIV_KEY_IN_WIF"]' '[{ "txid": "$txid", "vout": $index, "scriptPubKey": "$scriptPubKeyFrom2", "witnessScript": "$redeemScriptFrom1", "amount": $2-of-2multisigAmount}]' "ALL"

where:

  • $2-of-2multisigAmount is the whole amount found in your block explorer for address
  • $addressFrom1 is address of the 2-of-2 multisig escrow account
  • $txid is the transaction id found in the blockchain explorer
  • $index is the location of the escrow address in the transaction starting from 0

that should returns:

{ 
   "hex": "...",
   "complete" true,
   ...
}

where "hex" is the signed transaction

6) broadcast the transaction

bitcoin-cli sendrawtransaction "$hexFrom5"

Where:

  • $hexFrom5 is the signed transaction from both peers from the previous step.

this should return the transaction id.
you can now check in a block explorer that your transaction is in the mempool.