ION /Sidetreeコードリーディングメモ


# ION/Sidetree コードリーディングメモ

## 関連リンク
DID Sidetree Protocol
https://identity.foundation/sidetree/spec/#hashing-process

Sidetree REST API
https://identity.foundation/sidetree/api/

[Swagger] Sidetree REST API
https://identity.foundation/sidetree/swagger/

[Github] Sidetree
https://github.com/decentralized-identity/sidetree

[Github] ION
https://github.com/decentralized-identity/ion


## Command: ion create operation

1. ([ion/bin/index.ts#L8](https://github.com/decentralized-identity/ion/blob/d2ffaf395f2ad6cf24f91005bd6d954a2a500b06/bin/index.ts#L8)): [yargs](https://github.com/yargs/yargs)(コマンドラインパーサー)でコマンドを定義
2. ([ion/bin/OperationCommand.ts#L12](https://github.com/decentralized-identity/ion/blob/d2ffaf395f2ad6cf24f91005bd6d954a2a500b06/bin/OperationCommand.ts#L12)): createOperationを作成する一連のコードを実行
3. ([sidetree/tests/generators/OperationGenerator.ts#L226](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/tests/generators/OperationGenerator.ts#L226)): update, recover, 署名用のキーペアとcreateOperation作成する
4. ([sidetree/lib/core/versions/latest/util/Jwk.ts#L15](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/util/Jwk.ts#L15)): JWKキーペアの作成
5. ([sidetree/tests/generatorsrationGenerator.ts#82](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/tests/generators/OperationGenerator.ts#L82)): SECP256K1のキーペアを作成
6. ([sidetree/tests/generatorsrationGenerator.ts#L335](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/tests/generators/OperationGenerator.ts#L355)): APIにPOSTする用のリクエストを作成する
7. ([sidetree/lib/core/versions/latest/CreateOperation.ts#L32](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/CreateOperation.ts#L31)): parseして正しいフォーマットか確認?
8. ([sidetree/lib/core/versions/latest/Did.ts#L104](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/Did.ts#L104)): DID unique suffixを作成
9. ([ion/bin/OperationCommand.ts#L22~38](https://github.com/decentralized-identity/ion/blob/d2ffaf395f2ad6cf24f91005bd6d954a2a500b06/bin/OperationCommand.ts#L22)): recover, 署名用キーファイルを作成し、create request body, suffix data, Decoded deltaをコマンドラインに出力

## POST /operations

1. ([ion/src/core.ts#L59](https://github.com/decentralized-identity/ion/blob/d2ffaf395f2ad6cf24f91005bd6d954a2a500b06/src/core.ts#L59)): `/operation`エンドポイント。SidetreeのhandleOperationRequestを呼び出す。
2. ([sidetree/lib/core/VersionManager.ts#L121](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/VersionManager.ts#L121))
3. ([sidetree/lib/core/Core.ts#L121](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/Core.ts#L121)): 
4. ([sidetree/lib/core/VersionManager.ts#L87](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/VersionManager.ts#L87)): Versionと一致したRequestHandlerインスタンスの生成
~~5. ([sidetree/lib/core/versions/latest/RequestHandler.ts#L152](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/RequestHandler.ts#L152)): handleResolveRequest関数を実行~~
~~6. ([sidetree/lib/core/versions/latest/Did.ts#L75](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/Did.ts#L75)):　DIDを生成する一連のコードを実行~~
~~7. ([sidetree/lib/core/versions/latest/Did.ts#L35](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/Did.ts#L35)):  shortFormのDidを作成~~
~~8. ([sidetree/lib/core/versions/latest/Did.ts#L123](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/Did.ts#L123)): createOperationを生成~~
5. ([sidetree/lib/core/versions/latest/RequestHandler.ts#L36](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/RequestHandler.ts#L36)): 
6. ([sidetree/lib/core/versions/latest/RequestHandler.ts#L81](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/RequestHandler.ts#L81)): OperationTypeによって処理を分岐

### CreateOperation

7. ([sidetree/lib/core/versions/latest/RequestHandler.ts #L124](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/RequestHandler.ts#L124)): createOperationを処理する一連の処理を実行
8. ([sidetree/lib/core/versions/latest/RequestHandler.ts #L223](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/RequestHandler.ts#L233)): アンカリングに使用するデータを生成
9. ([sidetree/lib/core/versions/latest/OperationProcessor.ts#L24](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/OperationProcessor.ts#L24)): 
10. ([sidetree/lib/core/versions/latest/OperationProcessor.ts#L81](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/OperationProcessor.ts#L81)): newDidStateを生成
11. ([sidetree/lib/core/versions/latest/RequestHandler.ts#L137](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/RequestHandler.ts#L137)): 新しいDidStateを元にDid.createを実行
12.  ([sidetree/lib/core/versions/latest/Did.ts#L75](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/Did.ts#L75)):　DIDを生成する一連のコードを実行~~
13. ([sidetree/lib/core/versions/latest/Did.ts#L35](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/Did.ts#L35)):  shortFormのDidを作成
14. ([sidetree/lib/core/versions/latest/DocumentComposer.ts#L25](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/DocumentComposer.ts#L25)): DID documentの生成
15. ([sidetree/lib/core/versions/latest/RequestHandler.ts#L102](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/RequestHandler.ts#L102))->([sidetree/lib/core/versions/latest/MongoDbOperationQueue.ts #L39](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/MongoDbOperationQueue.ts#L39)): OperationQueに追加
16. ([ion/src/core.ts#L61](https://github.com/decentralized-identity/ion/blob/d2ffaf395f2ad6cf24f91005bd6d954a2a500b06/src/core.ts#L61)): {status: status, document: document }がレスポンスとして返る

メモ:
- 8で作成した[operationWithMockedAnchorTime](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/RequestHandler.ts#L234)は[POST /anchor/transactions/first-varlid](https://identity.foundation/sidetree/swagger/#/Anchor/getFirstValidTransactions)のrequestBodyのフォーマットと同じ
- ~~15でOperationQueに追加するのがわかった。しかしbatchWriterを実行するのはどのタイミング?定期的に実行される?いつ?APIを叩く必要あり?~~
    -> 後述

### UpdateOperation





### RecoverOperation





### DeactiveOperation





## BatchWriterについて
1. ([ion/src/core.ts#96](https://github.com/decentralized-identity/ion/blob/d2ffaf395f2ad6cf24f91005bd6d954a2a500b06/src/core.ts#L96)): ion起動時にsidetreeのCore.tsの`initilize()`を実行
2. ([sidetree/lib/core/Core.ts](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/Core.ts#L79)): initilize()を実行
3. ([sidetree/lib/core/Core.ts#L107](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/Core.ts#L107))->([sidetree/lib/core/BatchScheduler.ts#29](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/BatchScheduler.ts#L29)): `startPeriodicBatchWriting()`で`setImmediate()`使用してバッチ処理ループ
5. ([sidetree/lib/core/BatchScheduler.ts#L31](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/BatchScheduler.ts#L31))->([sidetree/lib/core/BatchScheduler.ts#L46](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/BatchScheduler.ts#L46)): エラーハンドリング、ログ出力等をしながらバッチ処理と関係する一連の処理を実行
6. ([sidetree/lib/core/BatchScheduler.ts#L56](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/BatchScheduler.ts#L56))->([sidetree/lib/core/versions/latest/BatchWriter.ts#36](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/BatchWriter.ts#L36)): **[casへ投げるファイルの生成](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/BatchWriter.ts#L58)、[casへのブロードキャスト](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/BatchWriter.ts#L85)、[トランザクションの生成](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/BatchWriter.ts#L94)、[トランザクションのブロードキャスト](https://github.com/decentralized-identity/sidetree/blob/54b4288a1f2cea1df22f89f803a88f34ecf9f76c/lib/core/versions/latest/BatchWriter.ts#L98)など全ての書き込み処理を行う。**


## Blockchain


[bitcore-libのbuildDataOut](https://github.com/bitpay/bitcore-lib/blob/master/docs/script.md#data-output)を使ってOP_RETURNでAnchor Stringを記録している。


## まとめ
### create処理
`ion create operation`コマンドでcreateOperationを作成し、それをPOST /operationsするとcreateOperationの内容がキュー(MongoDB)に保存される。
IONを起動時にbatchWriterのループが回っており、キューに保存されたOperationの内容を元にTx, Fileを生成しBitcoinやCASへ書き込みする、と言った順序で処理されている。

### create Operation例
```
DID: did:ion:EiB5F_Xnq4kce4NrLcRyBka80j7pjv-6VOMLjvlD2akaZQ
Recovery private key saved as: EiB5F_Xnq4kce4NrLcRyBka80j7pjv-6VOMLjvlD2akaZQ-RecoveryPrivateKey.json
Siging private key saved as: EiB5F_Xnq4kce4NrLcRyBka80j7pjv-6VOMLjvlD2akaZQ-SigningPrivateKey.json
Create request body:
{
  "type": "create",
  "suffixData": {
    "deltaHash": "EiCxv8SvCSTAXLVUjxWBpA00SE5gC03Zy7sTVikwN-E1Mw",
    "recoveryCommitment": "EiC7c2OaUQzEwHl2yIzdM3Q7-KTa-Dz4KHVvMoqFwfAi9A"
  },
  "delta": {
    "updateCommitment": "EiAsgr1H9RC4Z6N7s7THsAiGJ_w2s0RddtSCLeu5aVH_jg",
    "patches": [
      {
        "action": "replace",
        "document": {
          "publicKeys": [
            {
              "id": "signingKey",
              "type": "EcdsaSecp256k1VerificationKey2019",
              "publicKeyJwk": {
                "kty": "EC",
                "crv": "secp256k1",
                "x": "9lyeJxTw308yrezgfwRIJpD0yThfHoWtrfzVtX_Uxvc",
                "y": "4whWUiYXhPSCNXYFAORqMZMC3hvLJMV0q_xV6tRqd5U"
              },
              "purposes": [
                "authentication",
                "assertionMethod",
                "capabilityInvocation",
                "capabilityDelegation",
                "keyAgreement"
              ]
            }
          ],
          "services": [
            {
              "id": "serviceId123",
              "type": "someType",
              "serviceEndpoint": "https://www.url.com"
            }
          ]
        }
      }
    ]
  }
}
Decoded suffix data:
{
  deltaHash: 'EiCxv8SvCSTAXLVUjxWBpA00SE5gC03Zy7sTVikwN-E1Mw',
  recoveryCommitment: 'EiC7c2OaUQzEwHl2yIzdM3Q7-KTa-Dz4KHVvMoqFwfAi9A'
}
Decoded delta:
{
  updateCommitment: 'EiAsgr1H9RC4Z6N7s7THsAiGJ_w2s0RddtSCLeu5aVH_jg',
  patches: [ { action: 'replace', document: [Object] } ]
}
```