# 高速なL2 <=> LNのアトミックスワップについて
## クリアしたい課題
- チェーンAとチェーンBのアトミックスワップを考えた場合、両者のチェーンのSetupを待ってから取引されるのが一般的である
- そのため両方のチェーンが高速ではない限り時間がかかる(イメージとしてはブリッジが近そう)
- 今回LNは高速であるものの、受けるこちらがわが最低20分間隔であるためこれをまつのはあまりよくない
- そのため今回はIntMax側のsetup処理を待たずにスワップを完了できる仕組みを目指す。
## 条件付き送金
- LNとのやり取りにおいては以下の条件をつけた条件付き送金を利用する
1. 相手方のアドレスと同一のアドレスによる送金であること
2. 送信者と同根のアドレスであり、かつ指定したブロック高より現在のブロック高が大きいこと(キャンセルTx)
```mermaid
sequenceDiagram
actor S as Sender
participant I as Intmax Network
actor R as Receiver
autonumber
S --> I : Lock Token via Conditional Tx
I --> I : Comsume OneTimeAddress Hash(Sender Pub + nonce)
R --> I : Submit Tx with Sender's Proof
I --> I : Check if Receiver's Tx fullfills Sender's condition
S --> R : Send Sender's Token
I --> S : Send Receipt with OneTimeAddress Hash(Sender Pub + nonce + Suffix)
```
### 支払側の条件付き送金
条件付き送金では、まず支払い側が空のアドレスに送金する支払いTxを発行する(この際、資金はLockされる)。
このとき、OneTimeAddressである```Hash(Privkey + nonce)```を消費する。
支払い側は通常のProofにくわえて
$$ Condtions = (Target Block Height, Target OneTimeAddress, PreImage Hash) $$<br />
$$ payerSignature = Sig(Hash(assetID + amount + Conditions), payerPrivkey) $$<br />
$$C_{verifySignedPayment}(txHash, payerOneTimeAddress, Condtions, oldState, newState),\\ (payerPublicKey, payerSignature)) \\ \to \{true,false\}$$<br />
$$zkProve((txHash, payerOneTimeAddress, Conditions, oldState, newState), \\ (payerPublicKey, payerSignature), C_{verifySignedPayment}) \\ \to zkProof_{Payer}$$<br />
となり条件を満たすことを確認する。
### Proofの各種パラメータの説明
|name|説明|
| :--: | :-- |
|Target Block Height|そのTxが取り込まれる予定,もしくはその次のブロック高|
|Target OneTimeAddress|受取人のOneTimeAddress|
|PreImage Hash|InvoiceのPreImageのハッシュ|
|payerSignature|送金者の署名。条件付き送金の条件と送金内容を署名する|
|assetId|送金対象となるトークンに一意につけられたID|
|$$C_{verifySignedPayment}$$|この回路は <br />1. payerSignatureが正しいことを公開鍵無しで判定する<br />2. このTxが取り込まれた後、Payerの残高がamount分減っていること<br />の2つを判定する|
|newState, oldState|Tx前後のステート。回路で真贋を判定する|
という条件付き支払いの条件や送金の内容についての署名を検証するZkProofを提出する。
### 受け取り側の条件付き送金(受け取りTx)
受け取り側は受け取りTxを用意し、このTxは支払いTxをInputにしてTxを実行する。
Inputにした支払いTxのProofの条件が、受け取りTxによって満たされていることが確認されれば、受け取りTxのオーナーに対して支払いが行われる。
このとき、送金Txを送付したPayer側のOneTimeAddressである```Hash(Hash(Payer's Priv key + nonce) + suffix)```を消費する。このOneTimeAddressはnonceは同じであるものの、Lock時とは異なるOneTimeAddressであり、衝突しない。
(そのため、MarketMakerは板を出している間に他のTxを打つことが出来、ユーザビリティの向上に寄与する)
また、次のOneTimeAddressとも衝突しないのでMakerの他Txには影響されない。
このとき受け取りTxが提出するProofは
$$ receiverSignature = Sig(Hash(receiveTxHash + payerOneTimeAddress), receiverPrivkey) $$<br />
$$C_{verifyReceive}((receiveTxhash, receiverOneTimeAddress, receiverSignature, \\ payerEntryAddress, payerFinishAddress, preimage, payerTxData, payerTxHash,\\ oldState, newState, addressSMTRoot, addressSMTSiblings), \\ (receiverPublicKey)) \to \{true,false\}$$<br />
$$zkProve((receiveTxhash, receiverOneTimeAddress, receiverSignature, \\ payerEntryAddress, payerFinishAddress, preimage, payerTxData, payerTxHash,\\ oldState, newState, addressSMTRoot, addressSMTSiblings), (receiverPublicKey), C_{verifyReceive}) \\ \to zkProof_{Receiver}$$<br />
### Proofの各種パラメータの説明
|name|説明|
| :--: | :-- |
|receiverSignature|受け取りTxを提出する際の署名。受け取りたい条件付き送金のoneTimeAddressを含んでいる|
|receiveTxHash|受け取りTxの内容をハッシュしたもの|
|payerEntryAddress|送金Txを作成する際に送金側が使用したOneTimeAddress|
|payerFinishAddress|送金Txを利用後に消費されるOneTimeAddress。PayerEntryAddressから生成可能|
|$$C_{verifyReceive}$$|この回路は<br /> 1. receiverSignatureが正しいことを公開鍵を明かさずに証明する<br /> 2. payerTxDataで指定されたInvoice HashとPreimageが同一であること<br /> 3. payerTxDataで指定されたOneTimeAddress、もしくはそれと同根のアドレスからのTxであること<br />4. payerTxDataとpayerEntryAddressからPayerTxHashが導けること、payerEntryAddressからpayerFinishAddress導けることを証明する<br />4.newStateがoldStateから条件付き送金を達成した状態になっていることを証明する<br />5.payerEntryAddressとpayerTxHashの組がSMTに存在すること<br/>の5点を検証する|
|preimage|InvoiceのPreimage|
|payerEntryAddress|支払いTxで利用されたOneTimeAddress|
|payerFinishAddress|受け取りTxが実行されると消費され、OneTimeAddress SMTに記録されるOneTimeAddress。payerEntryAddressから誰でも導出可能である必要がある|
|payerTxData|送金TxのtxData|
|addressSMTRoot|oneTimeAddressのRoot|
|addressSMTSiblings|計算に必要なsiblings|
また、このときOneTimeAddressのSMTでは以下の2点が証明される
1. 支払いTxを提出したときのOneTimeAddress(payerEntryAddress)は使用されていること
2. 支払いTxの完了OneTimeAddress(payerFinishAddress)が使用されていないこと
### 送金側によるTxのキャンセル
送金キャンセルの場合はキャンセルTxを提出したアドレスが送金Txを提出したアドレスと同じ秘密鍵から生成できることを証明すれば良い。
したがって以下のProofを提出する
$$ cancelSignature = Sig((calcelTxHash+ payerOneTimeAddress), privkey) $$<br />
$$ C_{verifyCancel}((oneTimeAddress, payerTxData, payerTxHash, addressSMTRoot, addressSMTSiblings, oldState, newState, currentBlockHeight), \\(Publickey, nonce)) $$ <br />
$$ zkProve((oneTimeAddress, payerTxData, payerTxHash, addressSMTRoot, addressSMTSiblings, oldState, newState, currentBlockHeight), \\ (publickey, nonce), C_{verifyCancel}) \to zkProof_{Calcel} $$
### Proofの各種パラメータの説明
|name|説明|
| :--: | :-- |
|CancelSignature|キャンセルTxの署名。送金TxのOneTimeAddressを含む|
| Current Block Height|現在のブロック高。|
|$$ C_{verifyCancel}$$|この回路は<br />1. cancelSignatureが正しいことを公開鍵を明かさずに証明する<br />2. 送金TxのCalcelできる送金者のOneTimeAddressと今回のOneTimeAddressが同じ秘密鍵から生成できることを証明する<br />3. 現在のブロック高が支払いTxで指定したブロック高より大きいことを証明する|
## 課題点
1. LNの受けてはLNを受け取ってから支払うまでの間にOneTimeAddressを使い潰すことでRevertさせることができる
2. 特に受けてとOperatorが同一人物の場合、このような攻撃は容易になる
3. 受けては相手が支払うまで次のTxが打てない
## Operatorに責任を押し付ける提案
空のTxにOperatorのSignatureを追加する。
~~1. もし一定期間以内に送りてがTxを実行不可能な状態に追い込んだ場合、Claimできる。
=> ただし受け取りTxを講師しなければいいだけのはなしでは?~~
2. これはそのTxを次のブロックまでに取り込むことを了承する署名
Operatorは受け取り側に対して署名
$$OPSIG = Signature(\\Hash(Receiver Address, payer OneTimeAddress, Payment TxHash), \\Operator Privkey)$$
を提出する。もし支払いTxをそのブロック高までに取り込まない場合はその署名とPreImageをL1に提出することで実際に支払いTxが取り込まれていないことを確認し、取り込んでいなければSlashする。
メリット: この署名はL2は全く関与しない。また、受け取りTxの取り込みを約束するものなので、支払側も安心して次のTxをうつことができ、OneTimeAddress消費問題も解決する。受け取り側も支払いTxがネットワークに乗ることを所与として考えられるため、安心して0confできる。
```mermaid
sequenceDiagram
actor S as Sender
actor O as Operator
participant I as Intmax Network
actor R as Receiver
autonumber
S --> R : Send L2 Token Price in BTC
R --> S : Send Taker's Address
S --> O : Send Conditional Payment Tx with Taker's address
O --> R : Send Operator's signature
O --> I : Submit Payment Tx until target block height
S --> R : Send Invoice
R --> I : Comfirm Maker's Tx
R --> S : Pay BTC by LN
S --> R : send Preimage
R --> O : Submit Receive Tx with Preimage
O --> I : Submit Receive Tx
I --> R : Transfer L2 Token
```