Hyperledger Indyで綴るAliceの物語

# Aliceの物語
Hyperledger Indyのgetting-startedにはAliceという女性が大学卒業後、自らのIdentity情報を適切に扱い、立派に社会人として巣立っていく素晴らしい(?)物語が綴られています。Indyを動かすことができればそれを追体験してSelf-Sovereign Identityの神髄を理解できると思うのですが、何しろIndyは情報が少なく、getting-startedさえ動かすの大変でした。（私も一回断念した）。
ところが！ですよ。@koinoriがIndyを始めるにあたり素晴らしくまとまった記事を書いてくれました！->[【2019年3月版】Hyperledger Indy 事始め](https://qiita.com/koinori/items/4c97098754c7d78a3ea6)
もうこれでAliceの物語をだれもが体験することができるのです。なんと素敵なんでしょう！

## 本稿の目的
既にIndyを始めるにあたり十分な量の情報は供給されました。
そこで本記事では、Aliceの大学卒業後の人生を見守りながら、Indyプロジェクトが実現しようとしている次世代のIdentity管理というものをSelf-Sovereignという視点で理解していこうと思います。概念的な話が多くなると思うので、画像多めで臨みます（私の理解のため）。

なお、筆者は英語が得意ではありません。頑張って本家のドキュメントを読んでgetting-startedの実行結果を読み取り、自分が理解できるようにまとめているつもりですが、残念な結果になっているかもしれません。おかしいな？とお思いになられたらご指摘いただけると幸いです。
（また、自分自身で間違いに気づいたら適宜修正もします）

## 物語の登場人物
以下の説明は一部私による脳内拡張設定がありますが、ご容赦ください。

| 人や組織       |       イメージ |    説明    |
|:------------:|:------------:|:------------------|
|Alice（主人公）             | ![alice.png](https://qiita-image-store.s3.amazonaws.com/0/180436/25f679c2-1d98-16f7-1f29-4fd7fbfc71e7.png)              |Faber Collegeをこの春卒業したばかりの社会人1年生。彼氏募集中。        |
|Faber大学           |![daigaku_toudai.png](https://qiita-image-store.s3.amazonaws.com/0/180436/9e682e6b-4da6-e9db-af72-8e103aa616c9.png)         |Aliceが通っていた大学です。先進的な大学のようで、Indyの提供するDigital transcriptに対応しているとのこと       |
|Acme社             | ![company_character1_baby.png](https://qiita-image-store.s3.amazonaws.com/0/180436/62b1a662-3a47-f7ea-ef98-ff84cdcc44be.png) |Aliceが入社を希望している会社です。何の会社かは知りませんが、最近ここもIndyを導入したようです。        |
|Thrift銀行               | ![tatemono_bank_money.png](https://qiita-image-store.s3.amazonaws.com/0/180436/726e6e62-41e8-6cd2-4c92-5a6e4db9ac01.png) |Aliceがローンを申請する銀行です。他の登場人物と同様にReady for Indyです。         |
|Government         |![building_shiyakusyo.png](https://qiita-image-store.s3.amazonaws.com/0/221091/d270fdc8-fa40-d0fa-e3ac-4f30badd558c.png) |市役所なのかどうかは知りませんが、まあ行政です。Indy導入してるなんて進んでますね。 |
|Indy |   ![projectavatar.png](https://qiita-image-store.s3.amazonaws.com/0/221091/ce5d44f7-5092-0880-6b8f-e06c86867af3.png)  |この物語の陰の主役です。本稿の中では主にStewardという名のノードとして登場します。　|

## main.jsの実行
本稿で実施する手順はたったこれだけ。これにより、[indy-workthrough](https://github.com/hyperledger/indy-sdk/blob/master/docs/getting-started/indy-walkthrough.md#about-alice)に示されたAliceの物語が一挙に実行される寸法です。

`/opt/indy-sdk/samples/nodejs# node src/main.js
`
実行結果はかなり長くなるので、各ステップに分けて下で見ていくことにします。
で、実行したmain.jsの中はこんな感じ。gettingStartedとanoncreadsRevocationをそれぞれrun()してるだけですね。

`main.js`

```
const gettingStarted = require("./gettingStarted")
const anoncredsRevocation = require("./anoncredsRevocation")

run()

async function run() {
    await gettingStarted.run()
    await anoncredsRevocation.run()
}
```

## それでは見ていきましょう
### 事前準備：各組織のtrust anchor証明の取得
#### onboading
Faber大学やacme社が、Aliceにindyを用いた素晴らしい認証体験を提供するには、事前にこれらの組織がindyを使う準備をしておく必要があります。indyはwalletにDID(分散ID。表記上はDIDとしますが、要はIDってことだと思います)や鍵を保持するため、始めるにはまずwalletを作成する必要があります。それはgettingStarted.jsの冒頭にある以下コードで実現しています。

`gettingStarted.js`

```
    console.log("==============================");
    console.log("=== Getting Trust Anchor credentials for Faber, Acme, Thrift and Government  ==");
    console.log("------------------------------");

    console.log("\"Sovrin Steward\" -> Create wallet");
    let stewardWalletConfig = {'id': 'stewardWalletName'}
    let stewardWalletCredentials = {'key': 'steward_key'}
    try {
        await indy.createWallet(stewardWalletConfig, stewardWalletCredentials)
    } catch(e) {
        if(e.message !== "WalletAlreadyExistsError") {
            throw e;
        }
    }

    let stewardWallet = await indy.openWallet(stewardWalletConfig, stewardWalletCredentials);

    console.log("\"Sovrin Steward\" -> Create and store in Wallet DID from seed");
    let stewardDidInfo = {
        'seed': '000000000000000000000000Steward1'
    };

    let [stewardDid, stewardKey] = await indy.createAndStoreMyDid(stewardWallet, stewardDidInfo);
```

実行結果は以下のようになります。そのまんまですね。
ちなみにSovrin Stewardの「Steward」とは、indyにおける特権ノードであるStewardを表しているものと思われます（今回はデモ実行なのでnodeはひとつだけ）。
また、ここで作成したwalletの持ち主はstewardのようです。

```
==============================
=== Getting Trust Anchor credentials for Faber, Acme, Thrift and Government  ==
\------------------------------
"Sovrin Steward" -> Create wallet
"Sovrin Steward" -> Create and store in Wallet DID from seed
```

準備の手始めとして、政府機関のトラストアンカーを取得するようです。IndyでDIDを発行するには、そのDIDの持ち主がトラストアンカー[^1]になる必要があります。

`gettingStarted.js`

```
    console.log("==============================");
    console.log("== Getting Trust Anchor credentials - Government Onboarding  ==");
    console.log("------------------------------");

    let governmentWalletConfig = {'id': 'governmentWallet'}
    let governmentWalletCredentials = {'key': 'government_key'}
    let [governmentWallet, stewardGovernmentKey, governmentStewardDid, governmentStewardKey] = await onboarding(poolHandle, "Sovrin Steward", stewardWallet, stewardDid, "Government", null, governmentWalletConfig, governmentWalletCredentials);
```

これに対する実行結果はこちら

```
==============================
== Getting Trust Anchor credentials - Government Onboarding  ==
------------------------------
"Sovrin Steward" > Create and store in Wallet "Sovrin Steward Government" DID
"Sovrin Steward" > Send Nym to Ledger for "Sovrin Steward Government" DID
"Sovrin Steward" > Send connection request to Government with "Sovrin Steward Government" DID and nonce
"Government" > Create wallet"
"Government" > Create and store in Wallet "Government Sovrin Steward" DID
"Government" > Get key for did from "Sovrin Steward" connection request
"Government" > Anoncrypt connection response for "Sovrin Steward" with "Government Sovrin Steward" DID, verkey and nonce
"Government" > Send anoncrypted connection response to "Sovrin Steward"
"Sovrin Steward" > Anondecrypt connection response from "Government"
"Sovrin Steward" > Authenticates "Government" by comparision of Nonce
"Sovrin Steward" > Send Nym to Ledger for "Government Sovrin Steward" DID
```
onboardingというやつが何やらいろいろやっているようです。
indy業界における「onboading」とは、2者間の接続プロセスを指すそうです。
この場合はstewardとgovernmentとが接続されたという理解と思われます。

その後のlogから推測すると、onboadingの中ではどうやら以下の処理を行っていると理解できます。

1. Stewardが、GovernmentのDID(以下DIDと略）を生成し、walletの中に保存
![step1-1.png](https://qiita-image-store.s3.amazonaws.com/0/221091/17d714b8-4883-2e0d-bd91-59a50784fd49.png)


1. Nym(DIDをledgerに格納するトランザクションのことをnymトランザクションというらしい）の実行
![step1-2.png](https://qiita-image-store.s3.amazonaws.com/0/221091/667c796a-57d4-a1fc-a2d6-882490419f26.png)

1. StewardからGovernmentに対し、DIDに基づいた接続を要求
1. （Stewardからの接続要求に対し）Governmentが初めにwalletを作成 
![1-3.png](https://qiita-image-store.s3.amazonaws.com/0/221091/6dcc937a-4c69-44f2-31e2-34d9ff48e925.png)

1. GovernmentもDIDをwalletに保存
![step1-5.png](https://qiita-image-store.s3.amazonaws.com/0/221091/edb5b188-8765-bf4d-e0ef-9dfeb972ee56.png)

1. GovernmentがDIDの鍵リクエストをStewardに送信
1. GovernmentがStewardにレスポンスを返す
![step1-7.png](https://qiita-image-store.s3.amazonaws.com/0/221091/a3eec915-fada-1906-cdf8-dd921bb9ff9e.png)

1. StewardがGovernmentからレスポンスを受信
1. StewardがNonceを照合し、Governmentを認証許可する
1. 再びnymトランザクションを実行 
![step1-2.png](https://qiita-image-store.s3.amazonaws.com/0/221091/667c796a-57d4-a1fc-a2d6-882490419f26.png)

こうしてindyのドキュメント読みながら図解してても、なにしてるんだか理解が難しいですが、これがまだ序盤というのがグッときます。

#### Verinymの取得
onboardingが完了し、GovermentとStewardが安全に通信を行えるようになりました。先の手順でGovermentはDIDをchainに書き込みましたが、このDIDはあくまでもonboadingで使用するためのもので、Self-Sovereign IdentityなIDではないため、本来の目的であるDIDを発行します。このDIDはVerinym[^2]と呼ばれています。

`gettingStarted.js`

```
    console.log("==============================");
    console.log("== Getting Trust Anchor credentials - Government getting Verinym  ==");
    console.log("------------------------------");

    let governmentDid = await getVerinym(poolHandle, "Sovrin Steward", stewardWallet, stewardDid,
        stewardGovernmentKey, "Government", governmentWallet, governmentStewardDid,
        governmentStewardKey, 'TRUST_ANCHOR');
```

コード上はgetVerinymをいろんな引数付けて呼んでるだけですね。
とりあえず概要理解で進めたいので引数を調べるのはまたいずれ・・・。

で、その結果が以下

```
==============================
== Getting Trust Anchor credentials - Government getting Verinym  ==
------------------------------
"Government" > Create and store in Wallet "Government" new DID"
"Government" > Authcrypt "Government DID info" for "Sovrin Steward"
"Government" > Send authcrypted "Government DID info" to Sovrin Steward
"Sovrin Steward" > Authdecrypted "Government DID info" from Government
"Sovrin Steward" > Authenticate Government by comparision of Verkeys
"Sovrin Steward" > Send Nym to Ledger for "Government DID" with TRUST_ANCHOR Role
```

まずGovermentのwalletにVerinymとなるDIDを生成し、それをStewardにAuthCryptoとして送信してます。stewardはそれをdecryptしてnymトランザクションをトラストアンカーとして実行してるようです。

これでGovermentがIndyを利用する準備が整いました。
getting-startedでは、同様にFaber大学、Acme社、Thrift銀行もonboading->verinymの発行を実施していますが、本稿ではそこは割愛します。

さあ、いよいよAliceの物語を読み解くための準備がそろったわけですが、筆者が力尽きた[^3]ので続きは次回以降にします。

[^1]: 一般的に言う電子証明局的な意味の[トラストアンカー](https://www.nic.ad.jp/ja/basics/terms/trust-anchor.html)ではない模様。もう少し緩い概念を指しているらしい。
[^2]: DIDは大別してverinymとpseudonymの二つがあり、verinymは法的なIdentityのようなイメージを指していて、トラストアンカーにより承認されたDIDとしてチェーンに記録される。pseudonymはpseudo(偽の）の名前の通り、より匿名化されたDIDであり、2者間の接続時にのみ意味を持つIDとなる。（OIDCにおけるclaim_idみたいなもの？）。onboadingで生成したDIDもpseudonymだと思われるが、今のところ明確な記載は見つけられず。
[^3]: 業務の傍らとは言え、たったこれだけを読み解くのにものすごい時間がかかってしまった。。。本当は一回で書くつもりだったんですが、このままだと先に進まなくてお蔵入りしそうなので、ここまでで一旦公開させていただきました。