mijinとSymbol間でクロスチェーンスワップをする

# 目的

異なるチェーン間でtokenをやり取りできるクロスチェーンスワップを実現する
https://nemtech.github.io/ja/concepts/cross-chain-swaps.html
Aliceのtoken(mijin)とBobのtoken(Symbol)を1:1で交換する。

## 登場人物

### Alice

* プライベートチェーン(mijin)でMosaicを持っている。
* パブリックチェーン(Symbol)ではアカウントだけある。

|項目|値|
|--:|:--|
|mijin Address| MCRZVRPITADLY6HBMXUOMQJV7GAPK3R5MGMKV2UQ|
|mijin Mosaic Id|4E5C77D56BC70971|
|Symbol Address|TBN7YNBZTVKMTB5OAELTKG7FRHF4XJKUF77VPRA6|

### Bob

* プライベートチェーン(mijin)ではアカウントだけある。
* パブリックチェーン(Symbol)でMosaicを持っている。 

|項目|値|
|--:|:--|
|mijin Address| MAWNN45GYIQXGZSDIHOLQ5ACMA5CT2R2KUCHVNZ6|
|Symbol Address|TAHOR7C4JVATS2PBOKX3ZJ453DP2LQLTMGT7RVKI|
|mijin Mosaic Id|2F8C4E34568AD99D|


## 流れ

1. (Alice) SecretとProofを作成する
1. (Alice)[mijin] Bob宛にMosaicを送るSecretLock Transactionを発行
1. (Alice) BobにSecretLock Transactionにて使用したSecretを渡す
1. (Bob)[Symbol] Alice宛にMosaicを送るSecretLock Transactionを発行
1. (Alice)[Symbol] SecretProof Transactionを発行
1. (Alice) BobにSecretを作成した際のProofを渡す
1. (Bob)[mijin] SecretProof Transactionを発行

() 実行者
[] 使用するチェーン

### (Alice) SecretとProofを作成する

以下を参考にしたが、Secretの作り方が間違っている？(4/15時点)
https://github.com/nemtech/symbol-docs/blob/master/source/resources/examples/typescript/secretlock/CrossChainSwap.ts

ProofからSecretを作らないと意味がないはずなので以下のようにする

```js
// クロスチェーンスワップ時に使用するproofとsecret
const random = crypto.randomBytes(10);
const hash = sha.sha3_256.create();
const proof = hash.update(random).hex().toUpperCase();
const secret = sha.sha3_256.create().update(Convert.hexToUint8(proof)).hex().toUpperCase();
```

### (Alice)[mijin] Bob宛にMosaicを送るSecretLock Transactionを発行

```js
    // SecretLockトランザクション作成
    const privateSecretLockTransaction = SecretLockTransaction.create(
      Deadline.create(),
      aliceMijinMosaic, // aliceが持っているmijinのMosaic
      UInt64.fromUint(100), // 100block内の期限
      HashType.Op_Sha3_256, // secretを暗号化した
      secret, // 作成したsecretのハッシュアルゴリズム
      bobMijinAccount.address, // Bob宛
      privateNetworkType,
    ).setMaxFee(minfeemultiplier);

    // Aliceで署名
    const signedPrivateSecretLockTransaction = aliceMijinAccount.sign(privateSecretLockTransaction, privateGhash);
```

AliceからBobへ送るSecretLock Transactionが作成できた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135107/433c3857-6b2a-bfd0-e960-535d5a01ba69.png)

### (Alice) BobにSecretLock Transactionにて使用したSecretを渡す

今回作成した値をBobへ渡す

```
Secret: 44BFE17A5265BAF2617852C3F7526FF8472CAF06513F4CB1BC82CEEA73ADE378
```

### (Bob)[Symbol] Alice宛にMosaicを送るSecretLock Transactionを発行

```js
    // SecretLockトランザクション作成
    const publicSecretLockTransaction = SecretLockTransaction.create(
      Deadline.create(),
      bobPublicMosaic, // Bobが持っているSymbolのMosaic
      UInt64.fromUint(100), // 100block内の期限
      HashType.Op_Sha3_256,　// もらったsecretのハッシュアルゴリズム
      secret, // もらったsecret
      alicePublicAccount.address, // Alice宛
      publicNetworkType,
    ).setMaxFee(minfeemultiplier);

    // Bobで署名
    const signedPublicSecretLockTransaction = bobPublicAccount.sign(publicSecretLockTransaction, publicGhash);
```

BobからAliceへ送るSecretLock Transactionが作成できた。

http://explorer.symboldev.network/transaction/76AE012427A9EA9FF4C70715F2BFD78AE512D0D7CFFBB021765A007480106A08

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135107/429824a6-bcc0-9c4a-8d53-d77a4554e93a.png)

### (Alice)[Symbol] SecretProof Transactionを発行

Alice自身が、パブリックチェーンでSecretProof Transactionを発行する
このとき、Proof値が必要

```js
    // SecretLockトランザクション作成
    const publicSecretProofTransaction = SecretProofTransaction.create(
      Deadline.create(),
      HashType.Op_Sha3_256, // secretのハッシュアルゴリズム
      secret, // 作成したSecret
      alicePublicAccount.address, //自分のアカウントを指定
      proof, // 作成したProof値
      publicNetworkType
    ).setMaxFee(minfeemultiplier);

    // Aliceで署名
    const signedPublicSecretProofTransaction = alicePublicAccount.sign(publicSecretProofTransaction, publicGhash);
```

SecretProof TransactionがConfirmされた

http://explorer.symboldev.network/transaction/58DE09AE3CBEB43ECFEC06F54B80136D8A01CB9AA5C1D6629DE24F3962B1C2C2

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135107/c411920b-199a-3bb4-4d6a-28a235d73287.png)

この時点で、パブリックチェーンのAliceにMosaicが送金されている
Aliceのアカウントで `2F8C4E34568AD99D` のMosaicを持っていることが確認できる

http://explorer.symboldev.network/account/TBN7YNBZTVKMTB5OAELTKG7FRHF4XJKUF77VPRA6

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135107/6ad3a333-8918-ee56-0aed-707bf35f370a.png)

### (Alice) BobにSecretを作成した際のProofを渡す

BobにProof値を渡す。
(Document的にはこの順番で記載されているが、もう一つ前の処理でいいのかも・・・)

```
Proof: 23315A5F6027E41614528238F5705ECFDC0EF60E4920DF753A4627747DE6CB7A
```

### (Bob)[mijin] SecretProof Transactionを発行

Bob自身が、プライベートチェーンでSecretProof Transactionを発行する
事前にAliceからもらったProof値が必要

```js
    // SecretLockトランザクション作成
    const privateSecretProofTransaction = SecretProofTransaction.create(
      Deadline.create(),
      HashType.Op_Sha3_256, // secretのハッシュアルゴリズム
      secret, // もらったsecretを指定
      bobMijinAccount.address, // 自分のアカウントを指定
      proof, // もらったproofを指定
      privateNetworkType,
    ).setMaxFee(minfeemultiplier);

    // Bobで署名
    const signedPrivateSecretProofTransaction = bobMijinAccount.sign(privateSecretProofTransaction, privateGhash);
```

SecretProof TransactionがConfirmされた

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135107/4114872f-a8e5-6cfd-759b-6cd150c3297e.png)

この時点で、プライベートチェーンのBobにMosaicが送金されている
Bobのアカウントで `4E5C77D56BC70971` のMosaicを持っていることが確認できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135107/47ed61b5-c533-8032-ade7-b174247005f0.png)

### 全トランザクションの送信時のログ

```shell
Proof: 23315A5F6027E41614528238F5705ECFDC0EF60E4920DF753A4627747DE6CB7A
Secret: 44BFE17A5265BAF2617852C3F7526FF8472CAF06513F4CB1BC82CEEA73ADE378
------------------- Tx1 mijin Alice to Bob --------------------------------
signedTransaction TransactionAnnounceResponse {
  message: 'packet 9 was pushed to the network via /transaction' }
------------------- Success tx1 --------------------------------
Success: announcedTransaction1 SecretLockTransaction {
  type: 16722,
  networkType: 96,
  version: 1,
  deadline:
   Deadline {
     value: LocalDateTime { _date: [LocalDate], _time: [LocalTime] } },
  maxFee: UInt64 { lower: 21000, higher: 0 },
  signature:
   'B04763ECE16010399BC4B5EDFBCFD0B79E7E746FD766EBF488CB1946E4598BB68579480081ACF0A2A0DDB3B154132419A92BBDB0F60F513515ED27078C187A05',
  signer:
   PublicAccount {
     publicKey:
      '2AD17D347CD7FC66529CE5BC883E09EEB0AD493423A789F0D20E38A4CAEAAD13',
     address:
      Address {
        address: 'MCRZVRPITADLY6HBMXUOMQJV7GAPK3R5MGMKV2UQ',
        networkType: 96 } },
  transactionInfo:
   TransactionInfo {
     height: UInt64 { lower: 618265, higher: 0 },
     index: undefined,
     id: undefined,
     hash:
      'E6EBAA1BDEFEC6EC41C7584DE72FDC593485CF8FA45178CED84FD05610DC1415',
     merkleComponentHash:
      'E6EBAA1BDEFEC6EC41C7584DE72FDC593485CF8FA45178CED84FD05610DC1415' },
  mosaic:
   Mosaic {
     id: MosaicId { id: [Id] },
     amount: UInt64 { lower: 10, higher: 0 } },
  duration: UInt64 { lower: 100, higher: 0 },
  hashType: 0,
  secret:
   '44BFE17A5265BAF2617852C3F7526FF8472CAF06513F4CB1BC82CEEA73ADE378',
  recipientAddress:
   Address {
     address: 'MAWNN45GYIQXGZSDIHOLQ5ACMA5CT2R2KUCHVNZ6',
     networkType: 96 } }
------------------------------------------------------------
------------------- Tx2 testnet Bob -> Alice --------------------------------
signedTransaction TransactionAnnounceResponse {
  message: 'packet 9 was pushed to the network via /transaction' }
------------------- Success tx2 --------------------------------
Success: announcedTransaction2 SecretLockTransaction {
  type: 16722,
  networkType: 152,
  version: 1,
  deadline:
   Deadline {
     value: LocalDateTime { _date: [LocalDate], _time: [LocalTime] } },
  maxFee: UInt64 { lower: 21000, higher: 0 },
  signature:
   '242520C5767E51E00A1E36F2785A7D8B89E034423B3D3B16F5085C7BAF9DFE5385D56D424DDB235269012FA06D2BEB9EA89ECC39BD833FA163851078396B5507',
  signer:
   PublicAccount {
     publicKey:
      'A4D8A3A11B6EF313B70058A782829B53610957B631A978B7BAE49F906BCB3749',
     address:
      Address {
        address: 'TAHOR7C4JVATS2PBOKX3ZJ453DP2LQLTMGT7RVKI',
        networkType: 152 } },
  transactionInfo:
   TransactionInfo {
     height: UInt64 { lower: 203070, higher: 0 },
     index: undefined,
     id: undefined,
     hash:
      '76AE012427A9EA9FF4C70715F2BFD78AE512D0D7CFFBB021765A007480106A08',
     merkleComponentHash:
      '76AE012427A9EA9FF4C70715F2BFD78AE512D0D7CFFBB021765A007480106A08' },
  mosaic:
   Mosaic {
     id: MosaicId { id: [Id] },
     amount: UInt64 { lower: 10, higher: 0 } },
  duration: UInt64 { lower: 100, higher: 0 },
  hashType: 0,
  secret:
   '44BFE17A5265BAF2617852C3F7526FF8472CAF06513F4CB1BC82CEEA73ADE378',
  recipientAddress:
   Address {
     address: 'TBN7YNBZTVKMTB5OAELTKG7FRHF4XJKUF77VPRA6',
     networkType: 152 } }
------------------------------------------------------------
------------------- Tx3 testnet Alice SecretProof --------------------------------
signedTransaction TransactionAnnounceResponse {
  message: 'packet 9 was pushed to the network via /transaction' }
------------------- Success tx3 --------------------------------
Success: announcedTransaction3 SecretProofTransaction {
  type: 16978,
  networkType: 152,
  version: 1,
  deadline:
   Deadline {
     value: LocalDateTime { _date: [LocalDate], _time: [LocalTime] } },
  maxFee: UInt64 { lower: 22000, higher: 0 },
  signature:
   'CB5EFF03E0A06E924A80EF110C344F788A03A80C6E0E22F06BAA255A3CF82588160187E2F2BE3850DF1E2BDE2109D8AF2D07209E2DAB96C2E73B570AC9B3A70A',
  signer:
   PublicAccount {
     publicKey:
      '863153440106FA3D2DC978CE3B56835D6243C4EAFFE2D9D9DDBA9683158AE45F',
     address:
      Address {
        address: 'TBN7YNBZTVKMTB5OAELTKG7FRHF4XJKUF77VPRA6',
        networkType: 152 } },
  transactionInfo:
   TransactionInfo {
     height: UInt64 { lower: 203071, higher: 0 },
     index: undefined,
     id: undefined,
     hash:
      '58DE09AE3CBEB43ECFEC06F54B80136D8A01CB9AA5C1D6629DE24F3962B1C2C2',
     merkleComponentHash:
      '58DE09AE3CBEB43ECFEC06F54B80136D8A01CB9AA5C1D6629DE24F3962B1C2C2' },
  hashType: 0,
  secret:
   '44BFE17A5265BAF2617852C3F7526FF8472CAF06513F4CB1BC82CEEA73ADE378',
  recipientAddress:
   Address {
     address: 'TBN7YNBZTVKMTB5OAELTKG7FRHF4XJKUF77VPRA6',
     networkType: 152 },
  proof:
   '23315A5F6027E41614528238F5705ECFDC0EF60E4920DF753A4627747DE6CB7A' }
------------------------------------------------------------
------------------- Tx4 mijin Bob SecretProof --------------------------------
signedTransaction TransactionAnnounceResponse {
  message: 'packet 9 was pushed to the network via /transaction' }
------------------- Success tx4 --------------------------------
Success: announcedTransaction4 SecretProofTransaction {
  type: 16978,
  networkType: 96,
  version: 1,
  deadline:
   Deadline {
     value: LocalDateTime { _date: [LocalDate], _time: [LocalTime] } },
  maxFee: UInt64 { lower: 22000, higher: 0 },
  signature:
   'C73504B13DC2483EC44A65D59D4AA63B467A493D2754583D9B5D6B15972D58D617FC6F361AEA662155477D422452C0F7FE9870FD896CA07BFCF454611490CA0D',
  signer:
   PublicAccount {
     publicKey:
      '52E483BFAACE6684D4878AD15F98CCAA951041EBF968FFDDAA6357B4EC45E6EC',
     address:
      Address {
        address: 'MAWNN45GYIQXGZSDIHOLQ5ACMA5CT2R2KUCHVNZ6',
        networkType: 96 } },
  transactionInfo:
   TransactionInfo {
     height: UInt64 { lower: 618272, higher: 0 },
     index: undefined,
     id: undefined,
     hash:
      'EA6A5BC3F35D0F42526B3D3C4B34DB64B840E6AEFDCC29F3AFA90FB17CF162BC',
     merkleComponentHash:
      'EA6A5BC3F35D0F42526B3D3C4B34DB64B840E6AEFDCC29F3AFA90FB17CF162BC' },
  hashType: 0,
  secret:
   '44BFE17A5265BAF2617852C3F7526FF8472CAF06513F4CB1BC82CEEA73ADE378',
  recipientAddress:
   Address {
     address: 'MAWNN45GYIQXGZSDIHOLQ5ACMA5CT2R2KUCHVNZ6',
     networkType: 96 },
  proof:
   '23315A5F6027E41614528238F5705ECFDC0EF60E4920DF753A4627747DE6CB7A' }
------------------------------------------------------------
---------------------- ALL END --------------------------------
```