Hans Schmidt :  July 27th 2021

hans_schm1dt@protonmail.com


Example of a HTLC P2SH Cross-Chain Atomic Swap Between a Ravencoin Asset and BTC
*Another step towards making Ravencoin a full-feature fair permissionless proof-of-work distributed exchange*



Overview:

The Proof-of-Concept (POC) shown here is an atomic swap in which tokens are purchased on the Ravencoin block chain in exchange for bitcoin on the bitcoin blockchain. Since this capability is not yet live on Ravencoin mainnet, this POC exchange is between Ravencoin testnet-7 and Bitcoin testnet-3.

How is this possible?:

This functionality is enabled by the new P2SH code currently running on testnet which is planned for mainnet release. This same code will also make it possible to lock assets into Multi-signature contracts.

The details:

All transactions were sent using:
-raven-qt from Raven Core version v4.7.0.0-c05c88147 (linux 64-bit) on Ravencoin testnet-7
    -which is currently available as an "artifact" from https://github.com/RavenProject/Ravencoin/pull/1063/checks
-bitcoin-qt from Bitcoin Core version v0.21.1 on Bitcoin testnet-3

The desired cross-chain atomic swap can be fully described as:
-Alice has 0.02 bitcoins and wants to buy 2 TEST_TOKEN ravencoin assets for 0.01 bitcoins total (0.005 bitcoins each)
    -Alice's 0.02 bitcoin are in alice_bitcoin_address. She will use this address to pay for the tokens and for any bitcoin fees
    -Alice also has 20 RVN in alice_ravencoin_address from which she will draw any RVN transaction fees
    -Alice wants her two purchased tokens to end up in in alice_ravencoin_address

-Bob has 5 TEST_TOKEN ravencoin assets and wants to sell 2 of them for .01 bitcoins total (0.005 bitcoins each)
    -Bob's 5 tokens are in bob_ravencoin_address.
    -Bob also has 10 RVN in bob_ravencoin_address from which he will draw any RVN transaction fees
    -Bob wants his bitcoin to end up in bob_bitcoin_address. Any bitcoin transaction fees will be substracted from his payment

For this POC, the following addresses were used and were initialized to hold BTC, RVN, and TEST_TOKEN assets as described above:   
alice_btc_address = 'n1BTMRfeWnZxfeVtd1zr3HkMA1hhHC5fPo'
alice_rvn_address = 'mfzGMgmZtnvZEETHSCnY7zfSGMKkGy25Bt'
bob_rvn_address = 'n1rL8uj6ZdP4c1SJtvk6HLoz1phoQS6NwA'
bob_btc_address = 'mqfu4jxaCF2H1Y2HjbRn2xsyVMd8GtkHN3'

The cross-chain atomic swap takes place in the following steps:

1) Alice starts the process by:
    a) Selecting a random 32-byte secret.
    b) Using bitcoin script to write an HTLC contract which will lock up her BTC payment for the tokens she wants to buy.
    c) She then calculates and sends the INITIATE transaction on the Bitcoin blockchain.
   
    Alice's transaction uses P2SH to lock her BTC payment into an HTLC contract.
    The HTLC scriptPubKey is written in such a way that it can be spent by a signature from Bob's BTC address key (if Bob completes the swap), or by Alice's BTC address key (if the swap is cancelled and Alice takes her refund). Spending to Bob is locked by Hash(secret), the hash of the secret Alice chose. Spending to herself is locked 48 hours into the future.
       
2) Alice then communicates with Bob by Direct-Messaging to send him:
    a) The transaction number of her INITIATE transaction, and
    b) The full code of her  HTLC contract stript
   
    In this POC, Alice's INITIATE transaction on the BTC blockchain is:
        d8cc99ba3531d69d2986bb71ce60246f3a4c8eb9c8eced29b8d917e76fdf8599
    which anyone can view at:
        https://bitpay.com/insight/#/BTC/testnet/tx/d8cc99ba3531d69d2986bb71ce60246f3a4c8eb9c8eced29b8d917e76fdf8599
    to see that it locks her 0.1 BTC payment into a P2SH contract at address:
        2MvgFdqypg9UPdyty7LPirTnRyWgFUJxVqS
   
    In this POC, the full code of Alice's HTLC contract is:
        63a6141373a1cacbb7ef1520cc3b81cde6c5a0085efb4b8876a9146f624e3d29d9caaeffefe0c9bb383af9d
        754484d6704ebe70261b17576a914d7b273f4b82ae919c21359dd5a2a159019bd75ce6888ac
       
    Bob can calculate that the Hash160 of that contract matches the Hash160 used in the P2SH of the INITIATE transaction, which proves that Alice indeed gave him the correct contract used in that transaction.
       
    Then Bob can examine the contract in his bitcoin-qt node using the "decodescript" command to see the contract code:
        OP_IF OP_RIPEMD160
        1373a1cacbb7ef1520cc3b81cde6c5a0085efb4b         = 20-byte Hash(secret)
        OP_EQUALVERIFY
        OP_DUP
        OP_HASH160
        6f624e3d29d9caaeffefe0c9bb383af9d754484d         = Hash160 of Bob's BTC REDEEM address
        1627580395                                                            = 48 hours in the future in Unix time
        OP_DROP
        OP_HASH160
        d7b273f4b82ae919c21359dd5a2a159019bd75ce     = Hash160 of Alice's BTC REFUND address
        OP_ENDIF
        OP_EQUALVERIFY
        OP_CHECKSIG
   
    So Bob was able to verify that the contract sends to the correct addresses.
    Bob was also able to see Hash(secret) which is locking up the BTC payment he wants to receive.
   
    Since Alice held up her end of the bargain, it is Bob's turn to proceed.
   
3) Bob then proceeds by:
    a) Using ravencoin script to write an HTLC contract which will lock up his TEST_TOKEN assets which he wants to sell
    b) He then calculates and sends the PARTICIPATE transaction on the Ravencoin blockchain    

    (See the next step for the details about the PARTICIPATE transaction.)

    Bob's transaction uses P2SH to lock his TEST_TOKEN assets into an HTLC contract.
    The HTLC scriptPubKey is written in such a way that it can be spent by a signature from Alice's RVN address key (if Alice completes the swap), or by Bob's RVN address key (if the swap is cancelled and Bob takes back his token refund).
        Spending to Alice is locked by the same Hash(secret) which Alice used. Bob doesn't know "secret", but he saw Hash(secret) in the contract.
        Spending to himself is locked 24 hours into the future.

4) Bob then communicates with Alice by Direct-Messaging to send her:
    a) The transaction number of his PARTICIPATE transaction, and
    b) The full code of his HTLC contract stript

    In this POC, Bob's PARTICIPATE transaction on the RVN blockchain is:
        e1b6b297c0ad01430776e92c8a459cf16c33a869a291d2d6f15f0d0737b5541c
    which anyone can view at:
        https://rvnt.cryptoscope.io/tx/?txid=e1b6b297c0ad01430776e92c8a459cf16c33a869a291d2d6f15f0d0737b5541c
    to see that it locks two of his TEST_TOKEN assets into a P2SH contract at address:
        2MvgFdqypg9UPdyty7LPirTnRyWgFUJxVqS
   
    In this POC, the full code of Bob's HTLC contract is:
        63a6141373a1cacbb7ef1520cc3b81cde6c5a0085efb4b8876a914052a4f138092893ca600055779
        f53a4d817e8ad867046c960161b17576a914df0ca6eab43a2cfd3660b8a2f5f36ea03093c3626888ac
       
    Alice can calculate that the Hash160 of that contract matches the Hash160 used in the P2SH of the PARTICIPATE transaction, which proves that Bob indeed gave her the correct contract used in that transaction.

    Alice can examine the contract using her raven-qt node "decodescript" command to verify that it contains the correct addresses and terms.
   
    Since Bob held up his end of the bargain, Alice can go ahead and do the deal.
   
5) Alice then calculates and sends her INITIATOR_REDEEM transaction on the Ravencoin blockchain, in which she take possession of the TEST_TOKEN assets she bought.

    In this POC, Alice's INITIATOR_REDEEM transaction on the RVN blockchain is:
        31d4c2f66d74ab466e736cd4bb9333490491ed5110dcc7211c04952ca9d6ba4a
    which anyone can view at:
        https://rvnt.cryptoscope.io/tx/?txid=31d4c2f66d74ab466e736cd4bb9333490491ed5110dcc7211c04952ca9d6ba4a
    to see that the 2 TEST_TOKEN assets she purchased have been transferred into her Ravencoin address
   
    If you carefully study this REDEEM transaction, you should focus on the scriptSig of input Vin[1] which is used to unlock Bob's P2SH contract.
   
    That scriptSig which Alice calculated has the following form:
        Signature using the key for Alice's RVN address
        SIGHASH_ALL
        The PubKey of Alice's RVN address
        The full 32-byte secret which Alice chose at the beginning
        OP_1 (a "True" which indicates that the first clause in the contract is being chosen)
        The full 81-byte contract which Bob provided
       
    Note that in order to take possession of the TEST_TOKEN asset which she purchase, Alice had to reveal the "secret" to the world by including it in plain text in this transaction.
       
6) Bob can now calculate and send his PARTICIPATOR_REDEEM transaction on the Bitcoin blockchain, in which he take possession of 0.01 Bitcoin which Alice paid for his TEST_TOKEN assets.
           
    In this POC, Bob's PARTICIPATOR_REDEEM transaction on the BTC blockchain is:
        d7872f41dc29c4407ea6755aae375ffd0fcaba8b6046b26729b13b0c573c5fae
    which anyone can view at:
        https://bitpay.com/insight/#/BTC/testnet/tx/d7872f41dc29c4407ea6755aae375ffd0fcaba8b6046b26729b13b0c573c5fae
    to see that the 0.01 BTC payment from Alice (minus a BTC transaction fee) has been transferred into his BTC address

THAT'S IT !!!  EASY-PEASY (well... sort of) !!!   Most importantly - No Trust Is Required

Note that if either Bob or Alice, or both, had become uncooperative or unavailable at any time during the swap, the activity could have been unwound using an INITIATOR_REFUND transaction (after 48 hours) and/or a PARTICIPATOR_REFUND transaction (after 24 hours).

The format of REFUND transactions are similar to the REDEEM transactions, except that the scriptSigs use OP_0 opcode (to select the 2nd clause in the contract), and don't need to include the "secret"


Copyright 2021 by Hans Schmidt