Skip to content

Atomic Swaps: Trading Apples for Bananas

Or, when Andy decides to swap his apples with Barb's bananas.

The Challenge

Andy has some apples. Barb has some bananas. Andy agrees to give Barb two apples in exchange for one banana. In order to make sure both parties hold up their end of the deal they need to create a single transaction that sends assets both directions.

Inputs: Finding the Right Ingredients

We'll need to find 3 UTXOs to use as inputs. Andy's apples, Barb's bananas and some Chavinci to pay the network fee (Andy will pay).

Andy's Apple UTXO:

Andy uses listunspent to find a suitable txid and vout:

{
  "txid": "73cff8d5595d9134841e252aa95a01a408cc1473cc8ef590cdd81e819e62fccc",
  "vout": 1,
  "address": "cj6iUJQvVZrd4wxeijebcivC6a4Y53qVgR",
  "scriptPubKey": "21027e1fde02d2cbfac3629aeaf669abd156d0c4dfbf52f6a5e4dd6664e81a621045ac",
  "amount": 1,
  "confirmations": 3088,
  "spendable": true,
  "solvable": true,
  "safe": true
}

Then each party uses listmyassets with verbose=true to find asset UTXOs:

Andy: listmytokens APPLES true:

{
  "APPLES": {
    "balance": 1000,
    "outpoints": [
      {
        "txid": "744c61abe6d237939c3567bc44b912ff4c375984229908c964be44f36dec79e3",
        "vout": 3,
        "amount": 1000
      }
    ]
  }
}

Barb: listmytokens BANANAS true:

{
  "BANANAS": {
    "balance": 1000,
    "outpoints": [
      {
        "txid": "8468ef5193b1f5d6a7bd501f5f8ef5aec7c3d86fa87cec5a0b6f6d86fba78a4f",
        "vout": 3,
        "amount": 1000
      }
    ]
  }
}

Extracting the txids and vouts gives us our raw inputs:

[
  {
    "txid":"73cff8d5595d9134841e252aa95a01a408cc1473cc8ef590cdd81e819e62fccc",
    "vout":1
  }, 
  {
    "txid":"744c61abe6d237939c3567bc44b912ff4c375984229908c964be44f36dec79e3",
    "vout":3
  }, 
  {
    "txid":"8468ef5193b1f5d6a7bd501f5f8ef5aec7c3d86fa87cec5a0b6f6d86fba78a4f",
    "vout":3
  }
]

The Outputs

We'll be using 5 new Chavinci addresses:

Andy's Raven change address: cZzymtqctNdW4fWhLdWKRYUDGXP3KzG8Y9

Andy's banana receive address: ciNMHYArytp2D6jQSPHrGd7rq3qAxvpdt5

Barb's banana change address: cdahQMGWTJgFjziWadqejMU7gYAvpumzkk

Barb's apple receive address: ctPia5TPzjw1XibYh3de3RKxcpq9gusCBu

Andy's apple change address: ceW8oMzwyQZbgME9Tm633TDRV8bW347tEM

All asset transfers have to be balanced. Since we have 1000 APPLES coming in, we have to have 1000 going out. So Andy will send 2 to Barb's receive address and the rest (998) to his change address. The Chavinci will pay 0.001 for the network fee as normal.

{
  "KZzymtqctNdW4fWhLdWKRYUDGXP3KzG8Y9":4.8827125, 
  "ciNMHYArytp2D6jQSPHrGd7rq3qAxvpdt5":{"transfer":{"BANANAS":1}}, 
  "cdahQMGWTJgFjziWadqejMU7gYAvpumzkk":{"transfer":{"BANANAS":999}}, 
  "ctPia5TPzjw1XibYh3de3RKxcpq9gusCBu":{"transfer":{"APPLES":2}}, 
  "ceW8oMzwyQZbgME9Tm633TDRV8bW347tEM":{"transfer":{"APPLES":998}}
}

Creating the Transaction: Mixing the Fruits

Andy can now use createrawtransaction, passing in the inputs and outputs and receiving the transaction hex:

createrawtransaction '[{"txid":"631cf1566165803f0b89fbfb169d8f0c89129ec3f8536a48e4c4f0f3c4081cff","vout":0},{"txid":"744c61abe6d237939c3567bc44b912ff4c375984229908c964be44f36dec79e3","vout":3},{"txid":"8468ef5193b1f5d6a7bd501f5f8ef5aec7c3d86fa87cec5a0b6f6d86fba78a4f","vout":3}]' '{"cZzymtqctNdW4fWhLdWKRYUDGXP3KzG8Y9":4.8827125,"ciNMHYArytp2D6jQSPHrGd7rq3qAxvpdt5":{"transfer":{"BANANAS":1}},"cdahQMGWTJgFjziWadqejMU7gYAvpumzkk":{"transfer":{"BANANAS":999}},"ctPia5TPzjw1XibYh3de3RKxcpq9gusCBu":{"transfer":{"APPLES":2}},"ceW8oMzwyQZbgME9Tm633TDRV8bW347tEM":{"transfer":{"APPLES":998}}}'
0200000003ff1c08c4f3f0c4e4486a53f8c39e12890c8f9d16fbfb890b3f80656156f11c630000000000ffffffffe379ec6df344be64c90899228459374cff12b944bc67359c9337d2e6ab614c740300000000ffffffff4f8aa7fb866d6f0b5aec7ca86fd8c3c7aef58e5f1f50bda7d6f5b19351ef68840300000000ffffffff05926d1a1d000000001976a914a1d62b4f8a6710ad43d56f656c27966513ae8fbf88ac00000000000000003076a91483b7a59ce25d8159fdc2ab70320512d2bc07a1c488acc01472766e740742414e414e415300e1f505000000007500000000000000003076a91430f446c2ac37dc072516603e44e86aea7af2bf6788acc01472766e740742414e414e415300078142170000007500000000000000002f76a914cf084a93cf87d3030b74a1939d9c8f02f6152c8c88acc01372766e74064150504c455300c2eb0b000000007500000000000000002f76a914d18967e005ff7208cc6a9c483b028c7c72ca2d6e88acc01372766e74064150504c455300268b3c170000007500000000

Signing the Transaction: Unlocking the Fruits

Ok, the structure of the transaction is set. Now each party needs to sign it in order to unlock the inputs. Here are the steps:

  • Andy signs it using signrawtransaction. This will alter the hex, using his wallet to insert the signatures.

Note

Since Andy doesn't have the keys for all of the inputs he will see an error: "Unable to sign input, invalid stack size (possibly missing key)" This is normal and expected.

  • Andy sends the signed hex to Barb.
  • Barb uses signrawtransaction to sign the rest of the inputs. Again capture the hex output.

Submitting the Transaction: Fruity Transaction on the Way

Almost there. Barb now passes the fully signed hex to sendrawtransaction! It will be communicated to the network and put into the next block.

Note: Note: Make sure to watch out for confirmation on the network for the transaction to be considered complete!