PIP-0032B.md 8.7 KB

  PIP: PIP-0032B  (Based on PIP-0032A)
  Title: Atomic Swaps via Hash-Locked Accounts
  Type: Protocol
  Impact: Hard-Fork
  Authors: Herman Schoenfeld   Albert Molina 
  Copyright: Herman Schoenfeld, Albert Molina, 2019 (All Rights Reserved)
  License: GNU Public License 
  Comments-URI: https://discord.gg/sJqcgtD  (channel #pip-0032)
  Status: Proposed
  Created: 2019-05-30

Summary

A minor protocol change is proposed to enable Atomic Swap capability within the SafeBox

This PIP is a small modification specified in PIP-0032A without use independent fields Account.Data or Account.Type

Motivation

As defined in PIP-0032A

PIP-0032B vs PIP-0032A

Based on current PascalCoin source core and implementation of In-protocol PASA Exchange also called "public or private Account sell", this PIP-0032B extension will use a similar approach than PIP-0032A but reusing current source code implemented fields and without use independent fields Account.Data or Account.Type The current core defined data types are:

  TAccountState = (as_Unknown, as_Normal, as_ForSale);

  TAccountInfo = Record
    state : TAccountState;
    accountKey: TAccountKey;
    // Trade info, only when state=as_ForSale
    locked_until_block : Cardinal; // 0 = Not locked
    price : UInt64;                // 0 = invalid price
    account_to_pay : Cardinal;     // <> itself
    new_publicKey : TAccountKey;
  end;
  
  TAccount = Record
    account: Cardinal;        
    accountInfo : TAccountInfo;
	... other ...
    account_type : Word;      // Protocol 2. Layer 2 use case
    account_data : TRawBytes; // Protocol 5. PIP-0024 RAW data information
  End;  

PIP-0032B will not use fields TAccount.account_type (TYPE) nor TAccount.account_data (DATA) for a SimpleSwap (Used in PIP-0032A proposal)

Instead of use those fields, this PIP implements same workaround but adding needed fields inside TAccountInfo data type, allowing the external TAccount data type use other fields for free without limitation

So, proposal is introduce just one new field and improve current fields workaround, starting for upgrade the TAccountState definition type adding as_AtomicSwap:

  TAccountState = (as_Unknown, as_Normal, as_ForSale, as_AtomicSwap);

  TAccountInfo = Record
    state : TAccountState;
    accountKey: TAccountKey;
    // Trade info, only when state in [as_ForSale or as_AtomicSwap]
    locked_until_block : Cardinal; // 0 = Not locked
    price : UInt64;                // Fixed 0 when as_AtomicSwap, >0 when as_ForSale
    account_to_pay : Cardinal;     // Not used for as_AtomicSwap, <> itself when as_ForSale
    new_publicKey : TAccountKey;
    hashed_secret : TRawBytes;     // Not used for as_ForSale, 32 bytes length when as_AtomicSwap
  end;

Note

We can set optional value for new_publicKey field, that means that we can have 2 different workarounds for AtomicSwap: Private AtomicSwap and Public AtomicSwap

  • Private AtomicSwap: The new public key of the account must be fixed prior to start process, that means that only "Bob" (owner of new public key) will receive this account
  • Public AtomicSwap: The new public key of the account can be anyone, so, no need to define "who is Bob" prior to start process: Example, a quiz where the solution is HASH(SECRET) = TAccountInfo.hashed_secret
  • Note than Private AtomicSwap is the default usage defined in PIP-0032A, and Public AtomicSwap is an extra usage where Bob has not guaranteed to be the receiver of this account

Atomic Swap Workflow

Suppose Alice has 100 PASC and Bob has 1 BTC, and they wish to perform an Atomic Swap between themselves. The below workflow can be employed:

  1. Alice picks a very large random number known as SECRET

  2. Alice calculates CODE = HASH(SECRET)

  3. Bob gives Alice his public key B (Not this field is Optional, Private AtomicSwap if provided)

  4. Alice owns account X and deposits 100 PASC into X and sets it for AtomicSwap to Bob as follows:

    • X.accountInfo.state = as_AtomicSwap
    • X.accountInfo.hashed_secret = CODE
    • X.accountInfo.locked_until_block = 3 weeks ;/ specified in block numbers
    • X.accountInfo.new_publicKey = B ;/ Optional, only if is a Private AtomicSwap so only Bob will receive this account, otherwise new_publicKey is not defined

_NOTE At this point Bob has the ability to acquire account X containing 100 PASC at no cost. However, there is now an additional requirement now that he must supply SECRET in the payload of the purchasing operation. This new consensus rule is only applied for accounts typed "AtomicSwap". When purchasing Hash Locked accounts, the purchasing operations Payload must hash to the target accounts hashedsecret field. In other words, Bob needs to include SECRET in the Payload since it hashes to CODE. If the Payload does not Hash to the account data, the purchase operation is invalid.

This rule forces Bob to know SECRET before buying this account for nothing. If he does not know SECRET, he cannot buy X.

At this point, no one has exchanged anything yet. However, Bob knows he is guaranteed 100 PASC if and only if he learns SECRET within 3 weeks. If he does not learn secret in 3 weeks, Alice can take her 100 PASC back.


  1. Alice gives Bob her BTC public key A (Note, PascalCoin public A does not need to match BTC address A, but the owner is Alice in both cases)

  2. Bob creates a BTC transaction TXN1 with output:

    Pay 1 BTC to A if 
    (x for H(x)=CODE and signed by A) OR 
    (Signed by B after two weeks from now)
    

    NOTE At this point, Bob has published a BTC transaction that says:

  3. Alice can spend this 1 BTC so long as she publishes SECRET and signs with her key A.

  4. If after 2 weeks Alice hasn't done that, Bob reserves the right to take back this 1 BTC.

The swap has still not occured yet but is setup bi-directionally.


  1. Once Alice detects TXN1 on the BTC chain, she immediately spends it's outputs via a TXN2 to her own wallet. She thus takes possesion of the 1 BTC, revealing SECRET in the process.

NOTE In the process of spending TXN1, Alice reveals the SECRET inside of TXN2, which was a necessary condition of the smart-contract defined in TXN1, in particular the x for H(x) = CODE portion.


  1. Bob detects the transaction TXN2 and extracts SECRET from TXN2.

  2. Bob createas a Purchase Account operation for X and includes SECRET inside the Payload, thus taking possession of X containing the 100 PASC.

  3. Atomic Swap Completed

IMPORTANT

Notice that Alice's offer to Bob was locked for 3 weeks, yet Bob's offer to Alice was locked for only 2 weeks.

  • A time-lock differential is necessary to avoid the scenario where Alice takes both the 1 BTC and account X containing 100 PASC by revealing the SECRET at the moment the time-lock of X to Bob expires.
  • With this time difference, if after 2 weeks Alice has not revealed SECRET, Bob can determine Alice is acting in bad faith (or has abandoned the contract) giving him 1 week to safely cancel the swap and reclaim his 1 BTC.
  • In this eventuality, Alice does not lose her PASC since she never revealed SECRET. She can safely reclaim her PASC after account X's time-lock to Bob expires in 3 weeks.
  • This example is only valid when Private Atomic Swap, otherwise everybody would be able to execute step 9 because everybody will be able to provide new Public Key.

Specification

The following changes are required to implement this type of HLTC in PascalCoin.

Operation Update(s): OP_BuyAccount and OP_Transaction

The consensus rule when purchasing an account listed for private sale requires a minor change. This rule applied for both OP_BuyAccount and OP_Transaction.

let S = target PASA
let T = purchasing operation (can be either OP_BuyAccount or OP_Transaction)

... implement existing consensus rules ...

... Allow (S.accountInfo.state = as_AtomicSwap) cases with S.accountInfo.price = 0

// PIP-0032B: Atomic Swap rule
if (S.accountInfo.state = as_AtomicSwap) then begin
  // It's an atomic swap private sale, sender must provide secret
  if SHA2_256(T.Payload) <> S.accountInfo.hashed_secret then
    Error "Hash-locked accounts require correct hash pre-image when purchasing. Purchaser did not provide correct hash pre-image.";
end;

Links

  1. Bitcoin Wiki - Atomic swap. Accessed 2019-05.
  2. In-protocol PASA Exchange
  3. PIP-0032A