オプトインは何してるの？

# オプトイン

Symbolの新しいブロックチェーンに、現行のNEMのチェーンの残高を引き継ぐためには、オプトインという作業が必要です。

Symbolでは、秘密鍵からアドレスまでの導出方法が変わりましたので、同じ秘密鍵を使っても異なる公開鍵やアドレスが生成されます。

なのでもう、Symbol用に新しく秘密鍵を生成して、そのアカウント情報を現行NEMのブロックチェーンに書き込むことによって、新旧のアカウントの紐づけを行うようになりました（推測）。

オプトイン作業の中で、このような画面でSymbolのアカウントが生成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/bbbabe2a-6f69-e662-7c19-954c10b51980.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/4c494df5-59f1-0a7e-19e2-34605cac0f66.png)

で、オプトインでは新しいアカウント情報を含んだトランザクションが送信されるのですが、それがどんな形なのかちゃんと見たことはなかったので、この機会に見ていこうと思います。


# ちょっとやってみる

## VRFなしで普通のアカウント

このようなアカウントが生成されました

```yaml
mnemonic: (himitsu)
address: NANWI6-5UYYB3-B5SZKM-ZVIDVM-XZQ5KS-6KSMTN-4PI
publicKey: D8ADEF6ED85EDAEE06763A9C29504DD354ECB155C17F8DE06923C91BE095EC4F
```

[公開鍵の導出方法](https://gist.github.com/planethouki/7717d112d55e01cd5ae7f1d2b6838d6a)

オプトイントランザクションを送信してみます

[35f292b6880834948cabc80c20d982254e343037150cb2226da142e821e047c6](https://explorer.nemtool.com/#/s_tx?hash=35f292b6880834948cabc80c20d982254e343037150cb2226da142e821e047c6)

こんなメッセージが入った転送トランザクションが送信されました。

```json
{
  "type": 1,
  "destination": "D8ADEF6ED85EDAEE06763A9C29504DD354ECB155C17F8DE06923C91BE095EC4F"
}
```

`type`が`1`で、`destination`に何か入っていますね。

見比べてみると、オプトイン時に生成されたアカウントの公開鍵だということがわかります。

これで、このトランザクションの送信者のアカウント（現行NEMアカウント）と、このメッセージに書かれているアカウントの情報（Symbolアカウント）が紐づけられました。

## VRFありの普通のアカウント

オプトイン作業に、ハーベストがどうこうとかいって、VRFアカウントを作るかを聞かれます。

これをチェックしたら何か変わるのかやってみます。

このようなアカウントが生成されました

```yaml
mnemonic: (himitsu)
address: NBVC4Q-LNWH7R-SKQHXL-F5NZQY-ERZSDS-DCZX6T-2TA
publicKey: 717082D8AFB7E9CDED9A1281F96CFB90C985752E19178503BDABA596B0721567
VrfPublicAddress: ND6QGD-27KHW5-YMBIOM-J7NEH2-OVRF2R-ZGWCUX-GEA
VrfPrivateKey: (himitsu)
VrfPublicKey: 93EC5F71BE10DA46CF092724FD0B63F95D4521301FDE424004CFE25AFF917FC5
```

[公開鍵の導出方法](https://gist.github.com/planethouki/7717d112d55e01cd5ae7f1d2b6838d6a)

オプトイントランザクションを送信してみます

２つ送信されました。

### type 1

[4be498c0321de706f8abee91dbed60ee55ff6020c7b61ff9a1e33fc85c023fb2](https://explorer.nemtool.com/#/s_tx?hash=4be498c0321de706f8abee91dbed60ee55ff6020c7b61ff9a1e33fc85c023fb2)

```json
{
  "type": 1,
  "destination": "717082D8AFB7E9CDED9A1281F96CFB90C985752E19178503BDABA596B0721567"
}
```

こちらは先ほどと同じで、`type`が`1`で、`destination`がオプトイン時に生成されたアカウントの公開鍵です。

### type 6

2つ目のトランザクションです。

[cce5929a70044535379b3df7df236430a2fcb4b7ba444c81ccb4ed6f1fdbc946](https://explorer.nemtool.com/#/s_tx?hash=cce5929a70044535379b3df7df236430a2fcb4b7ba444c81ccb4ed6f1fdbc946)

```json
{
  "type": 6,
  "destination": "717082D8AFB7E9CDED9A1281F96CFB90C985752E19178503BDABA596B0721567",
  "payload": "A100000000000000489C21A3793B079454E6964FE46F30DD967558DEFFCC2BD54532FF0DA7CF13A60BFA8504A415363BB5195477FC833F5EA93C2A435CB06BC34D478CB82EC3F700717082D8AFB7E9CDED9A1281F96CFB90C985752E19178503BDABA596B072156700000000016843420000000000000000010000000000000093EC5F71BE10DA46CF092724FD0B63F95D4521301FDE424004CFE25AFF917FC501",
  "hash": "3CFF9BCAB2E3E9403681EA2CE20137E2F8B42AAC780DD463C97B024C7D77CDA3"
}
```

なんかいろいろあります。

`destination`は、オプトイン時に生成されたアカウントの公開鍵です。

`payload`は何だかSymbolのトランザクションのように見えました。ということは、`hash`はトランザクションハッシュかもしれません。

`payload`を分解してみました。

```yaml
size: A1000000
reserve: 00000000
signature: 489C21A3793B079454E6964FE46F30DD967558DEFFCC2BD54532FF0DA7CF13A60BFA8504A415363BB5195477FC833F5EA93C2A435CB06BC34D478CB82EC3F700
publicKey: 717082D8AFB7E9CDED9A1281F96CFB90C985752E19178503BDABA596B0721567
reserve: 00000000
version: 0168
type: 4342
fee: 0000000000000000
deadline: 0100000000000000
linkedPublicKey: 93EC5F71BE10DA46CF092724FD0B63F95D4521301FDE424004CFE25AFF917FC5
linkAction: 01
```

`type`が`0x4243`なので、[symbol-sdk](https://github.com/nemtech/symbol-sdk-typescript-javascript/blob/v0.21.0/src/model/transaction/TransactionType.ts#L152)を参考に、VRFキーリンクトランザクションであることがわかります。

オプトインの時に表示されたSymbolアカウントとVRFアカウントとリンクするトランザクションですね。

後は、手数料が無しで、期限が`0x01`であるところから、これがそのままSymbolチェーンのネメシスブロックに入りそうです。

[試しにこのトランザクションのハッシュを計算してみると](https://gist.github.com/planethouki/e10231205d2ec45fd8559f95500ba507)、ぴったり`hash`の値と一致しましたので、VRFキーリンクトランザクションのハッシュであることがわかりました。

この記事を書いている頃（2020年12月）では、委任ハーベストをするには、VRFリンクとアカウントリンクとノードリンクが必要なので、このトランザクションにはどれほどの意味があるのかはわかりません。

## マルチシグ

1of1のマルチシグを作ってオプトインしました。基本的には連署者がオプトインするのですが、まず、連署者が自らのオプトインを完了している必要があるので、それを終わらせてから、マルチシグのオプトインをしました。

現行NEMのアカウントと、生成されたSymbolアカウントはこんな感じです。

```yaml
nem1:
  multisig:
    address: NAZDWW2RWOVTBHTTLKQU6M5KCSSJTTEADCZYE5TS
    publicKey: 9bf8307e9f1b288cc0bc4a7279a151a2bb81b64fdd0561d7e912769f76997371
  cosigner:
    address: NBHRY4FDBJFZTP7MW3JBOBML7YEUNF6AGFRMHWVI
    publicKey: 0e00873e0efa602221440c2f3450982b76c2ba90f2d421893963401b268c7441
symbol:
  multisig:
    mnemonic: (himitsu)
    address: NDC2MR-SLL5FC-7AECLV-EB2AN7-SOIWXO-MPQZ5A-BTA
    publicKey: 01B4CC3E5E735C31187857CDDD00B6417C4689D8DD7A8120BADA6A1E38C58371
  cosigner:
    mnemonic: (himitsu)
    address: NBVC4Q-LNWH7R-SKQHXL-F5NZQY-ERZSDS-DCZX6T-2TA
    addressHex: 686a2e416db1ff192a07bacbd6e618247321c862cdfd3d4c
    publicKey: 717082D8AFB7E9CDED9A1281F96CFB90C985752E19178503BDABA596B0721567
```

[公開鍵の導出方法](https://gist.github.com/planethouki/7717d112d55e01cd5ae7f1d2b6838d6a)

オプトインすると、トランザクションが３つ送信されました。

### type 2

https://explorer.nemtool.com/#/s_tx?hash=39fb471e00cb1ff515589816e18a4e9166ffca2493db408c0fb7ecf562e47dde

```json
{
  "type": 2,
  "destination": "01B4CC3E5E735C31187857CDDD00B6417C4689D8DD7A8120BADA6A1E38C58371",
  "multisig": "9bf8307e9f1b288cc0bc4a7279a151a2bb81b64fdd0561d7e912769f76997371"
}
```

`destination`にマルチシグアカウントの方のSymbolの公開鍵、`multisig`にはマルチシグアカウントの方のnem1の公開鍵がありました。

type1のマルチシグ版という感じですね。

### type 3

https://explorer.nemtool.com/#/s_tx?hash=347e4d048fd0895538d130e29fc2865b6a5cf12e88bc911a138598f6616e14c2

```json
{
  "type": 3,
  "d": "01B4CC3E5E735C31187857CDDD00B6417C4689D8DD7A8120BADA6A1E38C58371",
  "p": "F800000000000000EA349EB7107F9F07C338EFA92D689CBDF951942CC98E2165A7884050561DEC2A87BF957478758EB2DE107A080EB433E3B51205A57050E08F9CFBB52307A8E30B01B4CC3E5E735C31187857CDDD00B6417C4689D8DD7A8120BADA6A1E38C58371000000000168414100000000000000000100000000000000EA45E6D0778D60D930BBE461E8309642003DCD68F70DDE4CE9FEE147B8B099015000000000000000500000000000000001B4CC3E5E735C31187857CDDD00B6417C4689D8DD7A8120BADA6A1E38C5837100000000016855410101010000000000686A2E416DB1FF192A07BACBD6E618247321C862CDFD3D4C",
  "h": "17F752A6399550727919EB2EFFAC178D6F1DE964F06BABD711113020AD71D1DB"
}
```

たぶんSymbolでマルチシグアカウント作成するトランザクションを作っていると思います。`d`がdestinationで`p`がpayloadで`h`がhashだと思います。

文字が省略されているのは、payloadが長いからだと思います。1of1で655文字あるんですが、連署者が増えていくとどうなるんでしょう。

nem1の転送トランザクションのメッセージの長さって、[APIドキュメント](https://nemproject.github.io/)の3によると

> The payload is allowed to have a maximal size of 1024 bytes.

ってあるけど、足りるのかな。

Symbolのマルチシグの連署者は、最大で15人だったはず。

1人の連署者で655バイト必要っで、14人を追加するとしたら、アドレスが24バイトだったと思うので、14*24=336バイト増加、合計991バイトなので、ギリギリ入るような気がしますね。

気を取り直して`p`を見ていきます。

```yaml
size: F8000000
reserved: 00000000
signature: EA349EB7107F9F07C338EFA92D689CBDF951942CC98E2165A7884050561DEC2A87BF957478758EB2DE107A080EB433E3B51205A57050E08F9CFBB52307A8E30B
publicKey: 01B4CC3E5E735C31187857CDDD00B6417C4689D8DD7A8120BADA6A1E38C58371
reserved: 00000000
version: 0168
type: 4141
fee: 0000000000000000
deadline: 0100000000000000
aggregateHash: EA45E6D0778D60D930BBE461E8309642003DCD68F70DDE4CE9FEE147B8B09901
payloadSize: 50000000
reserved: 00000000
transactions:
  size: 50000000
  reserved: 00000000
  publicKey: 01B4CC3E5E735C31187857CDDD00B6417C4689D8DD7A8120BADA6A1E38C58371
  reserved: 00000000
  version: 0168
  type: 5541
  minRemovalDelta: 01
  minApprovalDelta: 01
  addressAdditionsCount: 01
  addressDeletionsCount: 00
  reserved: 00000000
  addressAdditions: 686A2E416DB1FF192A07BACBD6E618247321C862CDFD3D4C
cosignatures:
```
Symbol側でマルチシグアカウントを設定するようなトランザクションになっています。

`type: 0x4141`のアグリゲートコンプリートでラップして、中身は`type: 0x4155`がのマルチシグモディフィケーショントランザクションです。

このトランザクションのハッシュを計算すると、`h`の値になりました。


### type 4

https://explorer.nemtool.com/#/s_tx?hash=df404125dc4e4f548e5f0ae893d37332d96c6cd3a2d3fe803cbf3e08e886cdfe

```json
{
  "type": 4,
  "multisig": "01B4CC3E5E735C31187857CDDD00B6417C4689D8DD7A8120BADA6A1E38C58371",
  "signature": "BF51455E759C3CF55C1104B2699183328181EBAD68FD7B53DF53A88F99F633CFAC08C9D2D6E8B3EABEC0B6F017017737440AB6C0C92B74BA7B1EE2B71475BD06"
}
```

ちょっとよくわかりませんでした。

Symbolでは、マルチシグアカウントを構成する際、連署者の全員の署名がないと、マルチシグにできないのですが、上記のトランザクションでは連署者の署名がありません。

なので、それを追加しているのではないかと思ったのですが、署名検証をうまく成功させることができませんでした。

https://gist.github.com/planethouki/8bf1217f40cd5a4ff08e5aacbba5fd95

もしかしたら、メッセージ欄の1024バイトの制限があったので、連署者の署名をわける必要があったのかもしれません。type3のトランザクションがアグリゲートコンプリートなのに、連署者の署名がないところからも、そういうにおいがしてきます。


## type 5

ここまで３種類のオプトインをやってきて、トランザクションのメッセージにある`type`について、1,2,3,4,6が出たのですが、5がありません。

結論から言うと、これはネームスペースのオプトインです。ネームスペースを持っていないこと、借りるのに100XEM必要なので、試すのはやめました。

なので既にあるトランザクションを見ていきます。

https://explorer.nemtool.com/#/s_tx?hash=b4d8a1494c3a1497fb8b2501e2a2a2180042aba5055ebcbbd08d06cf27a54dc5

```json
{
  "type": 5,
  "destination": "8BCCF5FE753DE2F7848125F1CDB2DC2FE951B7E24A2234D3EDE0A5A609923264",
  "payload": "9700000000000000C39FD375377937ED4A476C92F30763831CD6B37F89D292FF3A772718186C36C3487D3FAC288BA844D129343348869658E59FBB06AD394CE668C5B983F14C86028BCCF5FE753DE2F7848125F1CDB2DC2FE951B7E24A2234D3EDE0A5A6099232640000000001684E4100000000000000000100000000000000801420000000000019DB28864028E2860005636F6D7361",
  "hash": "DE95921B8365072EE28B2DECA75ABE3E1B7213EE36239AD5E360B2BD6670A88D"
}
```

```yaml
size: 97000000
reserved: 00000000
signature: C39FD375377937ED4A476C92F30763831CD6B37F89D292FF3A772718186C36C3487D3FAC288BA844D129343348869658E59FBB06AD394CE668C5B983F14C8602
publicKey: 8BCCF5FE753DE2F7848125F1CDB2DC2FE951B7E24A2234D3EDE0A5A609923264
reserved: 00000000
version: 0168
type: 4E41
fee: 0000000000000000
deadline: 0100000000000000
duration/parentId: 8014200000000000
namespaceId: 19DB28864028E286
NamespaceRegistrationType: 00
nameSize: 05
name: 636F6D7361
```

このネームスペースは、「636F6D7361」、utf8で「comsa」でした。

## VRFアカウントについて

ここのソースを見る限り、オプトインをしたときに生成されたSymbolのニーモニックをもとに生成されています。

https://github.com/NemProject/NanoWallet/blob/2.4.7-optin/src/app/modules/catapultOptin/catapultOptin/catapultOptin.controller.js#L15-L16

オプトイン後のアカウントが`m/44'/4343'/0'/0'/0'`で導出されるのに対し、VRFは`m/44'/4343'/0'/1'/0'`で導出されているようです。

## オプトイントランザクションの宛先アドレスについて

何回かやってみた感じ、すべて同じ宛先に送られました。

[NAQ7RCYM4PRUAKA7AMBLN4NPBJEJMRCHHJYAVA72](https://explorer.nemtool.com/#/s_account?account=NAQ7RCYM4PRUAKA7AMBLN4NPBJEJMRCHHJYAVA72)

おそらくどこかにハードコーディングされているのでしょう。

このアドレスをNanoWalletのGitHubのソースを検索してみましたが、出てきませんでした。

https://github.com/NemProject/NanoWallet/tree/2.4.7-optin

しかし、NanoWalletのビルドしたものを検索すると、ハードコーディングしてあるのがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/fc72326c-ead0-d5df-9c22-49a20ce3d5b8.png)