<commit_before><pre>
  PIP: PIP-0032A
  Title: Atomic Swaps via Hash-Locked Accounts
  Type: Protocol
  Impact: Hard-Fork
  Author: <NAME> <<EMAIL>>  
  Copyright: <NAME>, 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 events within the respective blockchains and between the exchanging parties only in a cryptographically secure manner.  Atomic Swaps are a fundamental building block for implementation of decentralized exchanges, such as the planned Pascal DEX. 

An Atomic Swap is performed using a type of smart-contract called a _Hash-Locked-Time-Contract_ (HLTC). The "Hash-Lock" aspect requires that the funds within the contract be locked by a hash and that they can only be unlocked by revealing the pre-image of that hash. The "Time-Contract" aspect refers to the contract being exclusively assigned to another party for a fixed, public and immutable period of time. This enables the party to unlock the funds within this time-frame without risk of being pre-empted by any other party. 

By using two matching HLTC's on two independent blockchains, cryptographically-secure Atomic Swaps of cryptocurrency between those blockchains are possible without involving 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 "Hash Locked" accounts such that when used within an in-protocol PASA exchange, achieve an HLTC suitable for Atomic Swaps. With this simple change, the following cross-chain Atomic Swap workflow is possible:

### 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 creates picks a very large number and is 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.Type = ***\<Hash Locked>*** 
   - 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 for free. Except, there is an additional consensus rule applied since the account is typed "Hash Locked". Hash Locked accounts requires that the purchasing operation include the pre-image that when hashed matches the account data. 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. Specifically,_ 
```
X.Data = HASH(PurchaseOperation.Payload) 
```

_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 BTC chain, she immediately spends the outputs of **TXN1** to her own wallet and takes possesion of the 1 BTC. She does this with by publishing **TXN2** on BTC.

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

----

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

9. Bob immediately includes **SECRET** inside the Payload of his Purchase Account operation and takes posession of account **X**, containing **100 PASC**. 
 
10. **Atomic Swap Completed**


## 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.

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

... implement existing consensus rules ...

// PIP-0032A: Atomic Swap 
if (S.SaleType = PrivateSale) and (S.Type = <HashLocked>) then begin
  // It's an atomic swap private sale, sender must provide secret
  if SHA2_256(T.Payload) <> S.Data then
    Error "Hash-locked accounts require correct hash pre-image when purchasing. Purchaser did not provide correct hash pre-image.";
end;
```

**NOTE**: An Account Type number must be reserved for _\<HashLocked>_. The reservation of account type numbers is delegated to a future PIP.

## Rationale

There were various approaches for implementing Atomic Swap and HLTC, and this PIP suggests the most minimal-impact change. Only a minor change to consensus rules is required, not to any client libraries or signing logic. 
To accomodate other approaches this PIP is post-fixed with A, allowing alternative proposals to supercede and/or compliment this approach.

## Backwards Compatibility

This change is not backwards compatible and requires a hard-fork activation. 
 
## 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<commit_msg>PIP-0032A: added security analysis section in workflow<commit_after><pre>
  PIP: PIP-0032A
  Title: Atomic Swaps via Hash-Locked Accounts
  Type: Protocol
  Impact: Hard-Fork
  Author: <NAME> <<EMAIL>>  
  Copyright: <NAME>, 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 events within the respective blockchains and between the exchanging parties only in a cryptographically secure manner.  Atomic Swaps are a fundamental building block for implementation of decentralized exchanges, such as the planned Pascal DEX. 

An Atomic Swap is performed using a type of smart-contract called a _Hash-Locked-Time-Contract_ (HLTC). The "Hash-Lock" aspect requires that the funds within the contract be locked by a hash and that they can only be unlocked by revealing the pre-image of that hash. The "Time-Contract" aspect refers to the contract being exclusively assigned to another party for a fixed, public and immutable period of time. This enables the party to unlock the funds within this time-frame without risk of being pre-empted by any other party. 

By using two matching HLTC's on two independent blockchains, cryptographically-secure Atomic Swaps of cryptocurrency between those blockchains are possible without involving 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 "Hash Locked" accounts such that when used within an in-protocol PASA exchange, achieve an HLTC suitable for Atomic Swaps. With this simple change, the following cross-chain Atomic Swap workflow is possible:

### 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 creates picks a very large number and is 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.Type = ***\<Hash Locked>*** 
   - 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 for free. Except, there is an additional consensus rule applied since the account is typed "Hash Locked". Hash Locked accounts requires that the purchasing operation include the pre-image that when hashed matches the account data. 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. Specifically,_ 
```
X.Data = HASH(PurchaseOperation.Payload) 
```

_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 BTC chain, she immediately spends the outputs of **TXN1** to her own wallet and takes possesion of the 1 BTC. She does this with by publishing **TXN2** on BTC.

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

----

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

9. Bob immediately includes **SECRET** inside the Payload of his Purchase Account operation and takes posession of account **X**, containing **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 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_.

## 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.

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

... implement existing consensus rules ...

// PIP-0032A: Atomic Swap 
if (S.SaleType = PrivateSale) and (S.Type = <HashLocked>) then begin
  // It's an atomic swap private sale, sender must provide secret
  if SHA2_256(T.Payload) <> S.Data then
    Error "Hash-locked accounts require correct hash pre-image when purchasing. Purchaser did not provide correct hash pre-image.";
end;
```

**NOTE**: An Account Type number must be reserved for _\<HashLocked>_. The reservation of account type numbers is delegated to a future PIP.

## Rationale

There were various approaches for implementing Atomic Swap and HLTC, and this PIP suggests the most minimal-impact change. Only a minor change to consensus rules is required, not to any client libraries or signing logic. 
To accomodate other approaches this PIP is post-fixed with A, allowing alternative proposals to supercede and/or compliment this approach.

## Backwards Compatibility

This change is not backwards compatible and requires a hard-fork activation. 
 
## 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
{'fraction_non_alphanumeric': 0.07236504797480407, 'fraction_numerical': 0.014795283087966014, 'mean_word_length': 4.123452157598499, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3692312', 'n_tokens_mistral': 3939, 'n_tokens_neox': 3600, 'n_words': 1995}