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
- (ion/bin/index.ts#L8): yargs(コマンドラインパーサー)でコマンドを定義
- (ion/bin/OperationCommand.ts#L12): createOperationを作成する一連のコードを実行
- (sidetree/tests/generators/OperationGenerator.ts#L226): update, recover, 署名用のキーペアとcreateOperation作成する
- (sidetree/lib/core/versions/latest/util/Jwk.ts#L15): JWKキーペアの作成
- (sidetree/tests/generatorsrationGenerator.ts#82): SECP256K1のキーペアを作成
- (sidetree/tests/generatorsrationGenerator.ts#L335): APIにPOSTする用のリクエストを作成する
- (sidetree/lib/core/versions/latest/CreateOperation.ts#L32): parseして正しいフォーマットか確認?
- (sidetree/lib/core/versions/latest/Did.ts#L104): DID unique suffixを作成
- (ion/bin/OperationCommand.ts#L22~38): recover, 署名用キーファイルを作成し、create request body, suffix data, Decoded deltaをコマンドラインに出力
POST /operations
- (ion/src/core.ts#L59):
/operation
エンドポイント。SidetreeのhandleOperationRequestを呼び出す。 - (sidetree/lib/core/VersionManager.ts#L121)
- (sidetree/lib/core/Core.ts#L121):
- (sidetree/lib/core/VersionManager.ts#L87): Versionと一致したRequestHandlerインスタンスの生成
5. (sidetree/lib/core/versions/latest/RequestHandler.ts#L152): handleResolveRequest関数を実行
6. (sidetree/lib/core/versions/latest/Did.ts#L75): DIDを生成する一連のコードを実行
7. (sidetree/lib/core/versions/latest/Did.ts#L35): shortFormのDidを作成
8. (sidetree/lib/core/versions/latest/Did.ts#L123): createOperationを生成 - (sidetree/lib/core/versions/latest/RequestHandler.ts#L36):
- (sidetree/lib/core/versions/latest/RequestHandler.ts#L81): OperationTypeによって処理を分岐
CreateOperation
- (sidetree/lib/core/versions/latest/RequestHandler.ts #L124): createOperationを処理する一連の処理を実行
- (sidetree/lib/core/versions/latest/RequestHandler.ts #L223): アンカリングに使用するデータを生成
- (sidetree/lib/core/versions/latest/OperationProcessor.ts#L24):
- (sidetree/lib/core/versions/latest/OperationProcessor.ts#L81): newDidStateを生成
- (sidetree/lib/core/versions/latest/RequestHandler.ts#L137): 新しいDidStateを元にDid.createを実行
- (sidetree/lib/core/versions/latest/Did.ts#L75): DIDを生成する一連のコードを実行~~
- (sidetree/lib/core/versions/latest/Did.ts#L35): shortFormのDidを作成
- (sidetree/lib/core/versions/latest/DocumentComposer.ts#L25): DID documentの生成
- (sidetree/lib/core/versions/latest/RequestHandler.ts#L102)->(sidetree/lib/core/versions/latest/MongoDbOperationQueue.ts #L39): OperationQueに追加
- (ion/src/core.ts#L61): {status: status, document: document }がレスポンスとして返る
メモ:
- 8で作成したoperationWithMockedAnchorTimeはPOST /anchor/transactions/first-varlidのrequestBodyのフォーマットと同じ
-
15でOperationQueに追加するのがわかった。しかしbatchWriterを実行するのはどのタイミング?定期的に実行される?いつ?APIを叩く必要あり?
-> 後述
UpdateOperation
RecoverOperation
DeactiveOperation
BatchWriterについて
- (ion/src/core.ts#96): ion起動時にsidetreeのCore.tsの
initilize()
を実行 - (sidetree/lib/core/Core.ts): initilize()を実行
- (sidetree/lib/core/Core.ts#L107)->(sidetree/lib/core/BatchScheduler.ts#29):
startPeriodicBatchWriting()
でsetImmediate()
使用してバッチ処理ループ - (sidetree/lib/core/BatchScheduler.ts#L31)->(sidetree/lib/core/BatchScheduler.ts#L46): エラーハンドリング、ログ出力等をしながらバッチ処理と関係する一連の処理を実行
- (sidetree/lib/core/BatchScheduler.ts#L56)->(sidetree/lib/core/versions/latest/BatchWriter.ts#36): casへ投げるファイルの生成、casへのブロードキャスト、トランザクションの生成、トランザクションのブロードキャストなど全ての書き込み処理を行う。
Blockchain
bitcore-libのbuildDataOutを使って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] } ]
}