実践DID:Symbol 2.証明書を作ろう

DIDで有名なユースケースVerifiable Credentials(VC)を参考にしつつ、Symbolで簡単な証明書を作ってみます。

前回の記事はこちらです。

https://qiita.com/nem_takanobu/items/53b4edb954a208789ff5

# 登場人物 

まず証明書のやりとりにかかわる登場人物について説明します。
いろいろな場面で出て来るのでぜひ覚えてください。

- 発行者(Issuer)
- 所有者(Holder)
- 検証者(Verifier)

よくあるたとえ話で学校の卒業証明書で説明してみます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/0a8b31b0-b83e-dc98-434a-aed6c5016f4f.png)

発行者は学校。卒業証書を所有者である学生に付与します。
検証者である企業は学生の提示した卒業証書を検証して学生が学校を卒業したことを確認します。

この卒業証書はとある就活サービス限定の話ではなく、
どこで誰にみせても通用する紙の卒業証明書と同様に、
LinkedInでもFacebookでもどこで提示しても大丈夫な証明書を目指します。


# テキストによる証明書


もっとも簡単な証明書は発行者から所有者へトランザクションを投げてそのメッセージに証明書内容を記述することです。
たとえば速習Symbolの修了証を以下の様に表記します。

```json
{
    "type": ["credential"],
    "credentialSubject": {
        "degree": {
            "name": "quick_learning_symbol"
        }
    }
}
```

type : **credential**
credentialSubject.degree.name : **quick_learning_symbol**

としました。実際にトランザクションを発行してみましたので以下のエクスプローラーよりご確認ください。

https://symbol.fyi/transactions/14609FE94B8BB626064D13415D21D5002AC636929B6383B3F79A9775BB6F6CFA

この書き方は以下の様なVerifiable Credentialのフォーマットを一部流用しています。

https://www.w3.org/TR/vc-data-model/#example-usage-of-the-proof-property-on-a-verifiable-credential

```json:EXAMPLE11
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://www.w3.org/2018/credentials/examples/v1"
  ],
  "id": "http://example.edu/credentials/3732",
  "type": ["VerifiableCredential", "UniversityDegreeCredential"],
  "issuer": "https://example.edu/issuers/565049",
  "issuanceDate": "2010-01-01T00:00:00Z",
  "credentialSubject": {
    "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
    "degree": {
      "type": "BachelorDegree",
      "name": "Bachelor of Science and Arts"
    }
  },
  "proof": {
    "type": "Ed25519Signature2020",
    "signature": "8eGWSiTiWtEA8WnBwX4T259STpxpRKuk...kpFnikqqSP3GMW7mVxC4chxFhVs",
  }
}
```

このVCのデータモデルを構成する大部分がSymbolトランザクションの属性値で代用可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/7b598a7a-ea79-b56b-af05-041d4db147f9.png)


- id : **Hash**
    - VCのidはトランザクションハッシュ値を使用する
- issuer : **From**
    - 発行者の情報は送信者DID:Symbolを使用する
- issuanceDate : **Timestamp**
    - 発行日はトランザクションが承認されたタイムスタンプを使用する
- credentialSubject.id : **To**
    - 証明書IDは受信者DID:Symbolを使用する
- proof.signature : **Signature**
    - 署名はトランザクション署名を使用する

did:symbolというDID識別子の先頭部分でどういった @context や proof.type を使用するかを決めてしまっておけばSymbolブロックチェーンの転送トランザクションのメッセージをVC準拠の証明書として利用することができます。

例えば、以下のようなプログラムでトランザクションをVCと同じデータモデルに整形することが可能です。(DIDのidなどはURLでないといけないなどの制約がありますが、そこは無視してDID:Symbolの識別子としています)

```js

tx = await txRepo.getTransactionsById(
  ["14609FE94B8BB626064D13415D21D5002AC636929B6383B3F79A9775BB6F6CFA"],
  sym.TransactionGroup.Confirmed
).toPromise();

message = JSON.parse(tx[0].message.payload);

vc = {
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://www.w3.org/2018/credentials/examples/v1"
  ],
  "id": tx[0].transactionInfo.hash,
  "type": message.type,
  "issuer": "did:symbol:" + tx[0].signer.address.plain(),
  "issuanceDate": new Date((tx[0].transactionInfo.timestamp.compact() + 1615853185 * 1000 ) ).toISOString(),
  "credentialSubject": {
    "id": "did:symbol:" + tx[0].recipientAddress.plain(),
    "degree": message.credentialSubject.degree
  },
  "proof": {
    "type": "Ed25519Signature2020",
    "signature": tx[0].signature,
  }
}

JSON.stringify(vc);

```
出力結果がこちら
```json
{
"@context":["https://www.w3.org/2018/credentials/v1","https://www.w3.org/2018/credentials/examples/v1"],
"id":"14609FE94B8BB626064D13415D21D5002AC636929B6383B3F79A9775BB6F6CFA",
"type":["credential"],
"issuer":"did:symbol:NBVHIH5E25AFIRQUYOEMZ35FKEOI275O36YMLZI",
"issuanceDate":"2023-04-18T14:43:54.073Z",
"credentialSubject":{
  "id":"did:symbol:NBVHIH5E25AFIRQUYOEMZ35FKEOI275O36YMLZI",
  "degree":{"name":"quick_learning_symbol"}
},
"proof":{
  "type":"Ed25519Signature2020",
  "signature":"35590F774A63156062AA61428EF2ECDBFF41591CC20055EBBF75EF2807D
    06B65FA8FA90F92DE0979172A311458F07AAAC0A5B62CFE187B0617DAC45BD02F0D0F"}
}
```

要するに、SymbolのトランザクションはいつでもVCモデルにコンバートできるということなので、今後データフォーマットに関する言及はしません。


# モザイクによる証明書

次に証明書をモザイクで作成してみます。

さきほどテキストメッセージで作成した証明書。分解してみると以下の２つのパラメータを差し替えることでさまざまな証明書を作ることが可能です。

type : **credntial**
credentialSubject.degree.name : **quick_learning_symbol**

そうです、この[type]と[credentialSubject.degree.name]をつなげたものをネームスペースで定義してしまい、モザイクに割り当てます。

xembook.credential.quick_learning_symbol

https://symbol.fyi/namespaces/xembook.certificate.quick_learning_symbol

ネームスペースのレンタル期間が終了してしまわない様にご注意ください。

### モザイク証明書のメリット

証明書をモザイクで運用すると以下のようなメリットがあります。

- 検索しやすい
- スペルミスを起こしにくい
- 没収設定可能
- モザイクを送信するだけで証明書付与
- 所有確認が簡単

デメリット

- フォーマットを逸脱した証明書を作れない
- ネームスペースの管理が必要
- 暗号化できない


# 他にも考えられる証明書の形

### メタデータ

証明書の項目をメタデータに記載することで証明書とすることができます。
この場合は証明書が変更可能なことに注意する必要があります。
また、変更には書き換え先アドレスの所有者の署名が必要となるため、
保有者のメタデータに書き込んだ場合は、無断で修正できないことの証明になります。
一方で、所有者の署名なしで証明書を送りつけることはできません。

### アカウント

基本的には上記、トランザクション、モザイク、メタデータのどれかで証明書を記録することになりますが、その器として新規アカウントを準備します。
新規に作成したアカウントに証明書を紐づけることでその証明書自体がDID:Symbolと同じ振る舞いをできるようになり、さらに活用の幅が広がりますがこれはまた後ほど解説します。



# 最後に

まずは簡単に証明書を作成しました。
ぜひみなさんもお試し下さい。