<pre>
  PIP: PIP-0032A
  Title: Atomic Swaps via Hash-Locked Accounts
  Type: Protocol
  Impact: Hard-Fork
  Author: Herman Schoenfeld <herman@sphere10.com>  
  Copyright: Herman Schoenfeld, 2019 (All Rights Reserved)
  License: GNU Public License 
  Comments-URI: https://discord.gg/sJqcgtD  (channel #pip-0032)
  Status: Proposed
  Created: 2019-05-30
</pre>

## Summary

A minor protocol change is proposed to enable atomic swap capability within the SafeBox.

## Motivation

Atomic swaps are a smart-contract technology that enable the exchange of one cryptocurrency for another without using intermediaries, such as 3rd party exchanges.  Atomic swaps occur as smart-contract events within the respective blockchains involving only the exchanging parties in a cryptographically secure manner.  Atomic swaps are the fundamental building block for decentralized exchanges (DEX). 

An atomic swap is performed using a type of smart-contract known as a _Hash-Locked-Time-Contract_ (HLTC). The "Hash-Locked" aspect of an HLTC requires that the funds within the contract be locked by a hash and that they only be unlocked by revealing the pre-image of that hash. The "Time-Contract" aspect of an HLTC requires that the contract be exclusively assigned to the other party for a fixed, public and immutable period of time. This time lock enables the party to unlock the funds within the time-frame without risk of being preempted by any other party. 

By using two matching HLTC's on two independent blockchains, cross-chain atomic swaps of cryptocurrency can be performed, without the involvement of intermediaries.  Since PascalCoin already implements "Time-Contracts" in the form of [in-protocol PASA exchange][2], only the "Hash-Locked" aspect of HLTCs require implementation.

The proposal here is to introduce the feature of "Hash Locked" accounts such that when combined with in-protocol PASA exchange, an HLTC is achieved suitable for cross-chain atomic swaps. With this simple change, the following atomic swap work-flow is enabled:

### Atomic Swap Work-flow

Suppose Alice has 100 PASC and Bob has 1 BTC, and they wish to perform an atomic swap between themselves. The below work-flow 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**

4. Alice owns account **X** and deposits 100 PASC into **X** and sets it for Private Sale to Bob as follows:
  
   - X.State = ***\<HLTC_A>*** 
   - X.Data = **CODE**
   - X.BuyerKey = **B**
   - X.SalePeriod = **3 weeks** ;/ specified in block numbers
   - X.Price = **0**   

----
_**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 "Hash Locked". When purchasing Hash Locked accounts, the purchasing operations Payload must hash to the target accounts data 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._

----

5. Alice gives Bob her public key **A**

6. 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:_
* _Alice can spend this 1 BTC so long as she publishes SECRET and signs with her key A._
* _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._

---

7. Once Alice detects **TXN1** on the BTC chain, she immediately spends its outputs to her own wallet via a **TXN2**. She thus takes possession of the 1 BTC, revealing **SECRET** in the process.

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

----

8. Bob detects the transaction **TXN2** and extracts **SECRET** from **TXN2**.

9. Bob publishes a Purchase Account operation on the PascalCoin chain for **X** and includes **SECRET** inside the Payload, thus taking possession of the **100 PASC**. 
 
10. **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 the 100 PASC by revealing SECRET at exact moment X's time-lock to Bob expires._
* _With this time difference in place, if after 2 weeks Alice has not revealed SECRET, Bob can determine Alice is acting in bad faith (or has abandoned the contract) thus 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_.
* _In practice, the HLTC's will use much shorter time-frames suitable for automated automic swap software.__

## Specification

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

#### New Account State

A new TAccountState called ```as_HLTC_PASA``` is required.

```pascal

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

```

This new state will result in behaviour identical to ```as_ForSale``` except with an additional consensus rule.

#### Operation Update(s): OP_Transaction, OP_BuyAccount


The consensus rules for OP_Data needs updating to execute  ```as_HLTC_PASA``` is identical to state ```as_ForSale``` but with the following additional checks

```pascal

let A = target PASA
let O = purchasing operation (can be either OP_BuyAccount or OP_Transaction)

...... same consensus rules for as_ForSale (in private mode) ....

  // PIP-0032A: Atomic Swap 
if (A.accountInfo.state = as_HLT  as_HLTC_PASA: begin
  if (A.accountInfo.new_publickey = CT_PublicKey_Nil) then
    Error 'Invalid PASA HLTC, account did not specify an endpoint key';

  ... implement same consensus rules for as_ForSale, assuming a private sale mode ...

  // Check hashlock
  if SHA2_256(O.payload) <> A.account_data then
    Error "Hash-locked accounts require correct hash pre-image when purchasing. Purchaser did not provide correct hash pre-image.";
end;

```

#### Misc Core Changes

Since a new account state is being introduced, the code-paths for as_ForSale cannot be re-used and must be copied/pasted, or altered to check for this condition. These details are left to the implementor.

## Rationale

As there are many approaches for implementing atomic swaps and HLTCs in PascalCoin, this PIP is post-fixed with "A" to allow alternative approaches "B", "C" and so on. 
However, PIP-0032A is by far the simplest and least impactful approach that naturally compliments the [in-protocol PASA exchange][2] features established in Version 2. 

In many ways, this proposal completes that functionality to enable "cross-chain exchange". It is the least impactful approach since it does not require changing the signature logic of client-side libraries such as JPascalCoin/NPascalCoin/SBX/FlutterLib/etc. 

In conclusion, due to the low cost vs the significant benefits of this change, this proposal is recommended for V5 implementation.

## Backwards Compatibility

This change is not backwards compatible and requires a hard-fork activation. 

## Acknowledgements

 * Albert Molina for suggesting use of account state rather than account type.

 
## Links

1. [Bitcoin Wiki - Atomic swap. Accessed 2019-05.][1]
2. [In-protocol PASA Exchange][2]

[1]: https://en.bitcoin.it/wiki/Atomic_swap
[2]: https://github.com/PascalCoin/PascalCoin/blob/master/PIP/PIP-0002.md