<pre>
  PIP: PIP-0017
  Title: Anonymity via Transaction Mixing (phase-1)
  Type: Protocol
  Impact: Hard-Fork
  Author: Herman Schoenfeld <i>&lt;herman@sphere10.com&gt;</i>
  Comments-URI: https://discord.gg/sJqcgtD  (channel #pip-0017)
  Status: Active
  Created: 2018-01-04
</pre>

## Summary

A new operation called MULTI-TRANSACTION is proposed that allows a transfer of PASC from N accounts to M accounts and a transfer of U PASA to U new keys. This will immediately provide "better-than-DASH-level" anonymity and serve as foundational component for subsequent full anonymity. It will also facilitate Layer-2 applications such as decentralized exchanges in a manner that other cryptocurrencies cannot achieve!

## Motivation

Currently, PascalCoin transactions occur between publically visible accounts. Of all the cryptocurrencies, PascalCoin is the least anonymous. Anonymity is intrinsically connected to fungibility, a crucial aspect of any currency. Without fungibility, adoption will be stunted. This proposal immediately delivers DASH-level anonymity into the protocol, and will allow users to perform:

**Client-Server Mixing**

Use a web-driven mixer UI similar similar to how Bitcoin Cash transactions are mixed today (but not Bitcoin Core, due to high fees).

**Network-protocol Mixing**

As phase-2 of anonymity, the network protocol will be upgraded via soft-fork to support mixing directly between wallet-to-wallet, in a virtually seamless manner as sending a transaction now.

**Chaining Multi-Transactions**

Immediately and improved in phase-2, users will be able to chain multiple Multi-Transactions together delivering indecipherable complexity between transfers

**Decentralized Exchanging**

This operation, in combination with PascalCoin Asset Tokens (to be added in future), will facilitate Layer-2 decentralized cryptocurrency exchange protocols. This is because a MULTI-TRANSACTION allows market makers and market makers to negotiate and orechestrate an exchange of PASC/PASA/Tokens between themselves in a trust-free and off-line manner. As a result, a MULTI-TRANSACTION operation will serve as a fundamental building block for an infinitely-scalable Layer-2 decentralised exchange protocol running over the PascalCoin network planned by Sphere 10 Software (company of Author).

**Monetized-API Mixing**

As a CPU-mining community arises from [PIP-0009][1], those node operators will be able to earn extra income by running a **Layer-2 node** (similar to a Masternode in DASH), that can participate in totally secure phase-2 anon, among various other Layer-2 applications such as smart-contract and marketplace platforms.

## Specification

A new operation called MULTI-TRANSACTION is proposed as follows:

### New Operation: MULTI-TRANSACTION

- SenderCount: Word - number of sender accounts (N)
- SenderAccount_1: DWord - first sender account
- SenderQuantity_1: QWord - amount first sender is sending
- SenderNOperation: DWord - the new N_OPERATION value of first senders account

    .
    .
    .

- SenderAccount_N : DWord - N'th sender account
- SenderQuantity_N : QWord - amount N'th sender is sending
- SenderNOperation_N: DWord - the new N_OPERATION value of N'th senders account 
- RecipientCount: DWord - number of recipient accounts (M)
- RecipientAccount_1: DWord - first recipient account
- RecipientQuantity_1 : QWord - amount first recipient is receiving

    .
    .
    .

- RecipientAccount_M : DWord - M'th recipient
- RecipientQuantity_M : QWord - amount M'th recipient is receiving
- Fee: QWORD - network fee payable to the miner
- ChangeKeyCount : DWord - the number of accounts that will be changing key (U)
- ChangeKeyAccount_1 : DWord - the first account that will have key changed
- ChangeKeyAccountNOperation_1 : DWord - resulting NOperation of ChangeKeyAccount_1

    .
    .
    .

- ChangeKeyAccount_U : DWord - the U'th account that will have key changed
- ChangeKeyAccountNOperation_U : DWord - resulting NOperation of ChangeKeyAccount_U
- NewKey_1 - the new key associated to ChangeKeyAccount_1

    .
    .
    .

- NewKey_U - the new key associated to ChangeKeyAccount_U
- Payload: operation payload
- SenderSignature_1: signature blob of first sender

    .
    .
    .

- SenderSignature_N: signature blob of N'th sender
- ChangeKeySignature_1: signature blob of first sender

    .
    .
    .

- ChangeKeySignature_N: signature blob of N'th sender

**Consensus Rules**

- Ensure no duplicate sender or change key accounts
```
Length( SELECT SenderAccount FROM MULTI-TRANSACTION ) = Length( SELECT DISTINCT SenderAccount FROM MULTI-TRANSACTION )

Length( SELECT ChangeKeyAccount FROM MULTI-TRANSACTION ) = Length( SELECT DISTINCT ChangeKeyAccount FROM MULTI-TRANSACTION )
```
**NOTE** The above protocol does allow a sender X and then change key of X, but only 1 of each.

- Ensure fee covers all operations
```
Fee >= (SenderCount + RecipientCount + ChangeKeyCount) * MIN_FEE   
where
   MIN_FEE = 0.0001 (current protocol)
```

**NOTE**: ChangeAccountKey entries do **not** pay a fee directly. In practice, their fee portion is covered by a separate SenderAccount entry that pays the fee for both itself and the ChangeKeyAccount entry. Alternatively, a single user could decide to cover someone/everyone elses fee's. The Fee is merely the difference between SUM(SenderQuantity) - SUM(ReceiverQuantity) and must account for all the entries in the multi-transaction. 

- Ensure at least 1 sender
```
SenderCount > 0
```

- Ensure at least 1 recipient
```
RecipientCount > 0
```

- Ensure all senders have enough to send
```
for-all s in Senders 
    SafeBox.Accounts[s.Account].Balance >= s.Quantity
```

- Ensure the amount being spent balances the amount being received
```
SUM( select Quantity from Senders ) = SUM( select Quantity from Recipients ) + Fee
```

- Ensure the sender N_OPERATION values are correct 
```
for-all s in Senders
    s.NOperation = SafeBox.Accounts[s.Account].NOperation + 1
```

- Ensure the change key N_OPERATION values are correct 
```
for-all c in ChangeKeyAccounts
    var expectedNOperation = SafeBox.Accounts[c.Account].NOperation + 1
    if Senders.Contains(c.Account)
       expectedNOperation = expectedNOperation + 1
    
    c.NOperation = expectedNOperation
```

- Ensure that all senders and key changers sign the entire message **except the signature portion**
```
let signedPortion = select bytes from (SenderCount...Payload) portion of MULTI-TRANSACTION
for i := 1 to SenderCount
    let sender := SafeBox[SenderAccount_i]
    ECDSA_VerifySignature(SenderSignature_i, signedPortion, sender.PublicKey) = True 

for i := 1 to ChangeKeyCount
    let changer = SafeBox[ChangeKeyAccount_i]
    ECDSA_VerifySignature(ChangeKeySignature_i, signedPortion, changer.PublicKey) = True     
```

#### Segregated Signatures during OPHASH ###

In order to allow a sender to know the OPHASH of the Multi-Transaction before the **next sender** signs, it's important that the signature portion of the Multi-Transaction be omitted from the RIPEMD160-portion of the OPHASH calculation
```
OPHASH(MultiTransaction) = RIPEMD160 ( select bytes (SenderCount...Payload)  from MultiTransaction ) 
```

Otherwise it will not be possible for a Sender to determine the OPHASH until it finally reaches a block. This will break high-frequency mixing.

## Rationale

Other methods of anonymity are in development and will either rely or benefit from this proposal. As a result, implementing this PIP delivers an overwhelming gain for virtually zero costs. 

## Backwards Compatibility

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

## Links

1. [PIP-009: RandomHash: GPU & ASIC Resistant Hash Algorithm][1]

[1]: https://github.com/PascalCoin/PascalCoin/blob/master/PIP/PIP-0009.md
