【ILP 連載 - 2】ILP の仕様を理解するための下準備　ASN.1 編

# 前書き
　この記事は連載の一部となっています。連載インデックスは [【ILP 連載】自分で ILP を実装してみよう！](https://qiita.com/dora-gt/items/51774984953c82912b13) をご覧下さい。

　なかなか連載を更新できずにすみませんでした🙇‍♂️ ここ最近は ILP の次期バージョン候補である ILPv4 についての勉強がメインとなっており、実装はあまり進めていませんでした。というのも、ILPv4 では**そもそもの思想がかなり大きく変わっている**事もあり、当然仕様もかなり変わっています。そのため、現状の仕様で実装してもちょっともったいないなと感じたためです。

　ILPv4 の仕様はまさに今策定中という感じですが、様々な資料からその全体像を掴んでいく事が必要です。私が参考にしているのは、下記の様な資料です。

- W3C の Community Group でシェア・検討されている資料
- [Interledger のリポジトリ](https://github.com/interledger)
    - ILP の RFC が読める
- [InterlegerJS のリポジトリ](https://github.com/interledgerjs)
    - ILP を実際に JS で実装したサンプルが色々置いてある

　THE これです。みたいな資料は正直ないので、断片的な情報から想像・理解していくしかなさそうです。いずれ、私なりの理解をシェアする場は設けたいと思っていますので、期待せずにお待ち下さい（笑）

　パケットがそもそもどういう形に変更されているのかを見てみたかったのでリポジトリをチェックしていたのですが、**ASN.1** という規格で仕様が書かれていました。お恥ずかしながら私はこれまでのエンジニア人生で ASN.1 というものに触れた事がありませんでした。今回はこの ASN.1 という言語について、**ちょっと調べただけでは分からないが、ILP を理解する上では必要になるもの**、をご紹介できればと思います。

# ASN.1 について学ぶ
## ASN.1 の基礎
　今回は、ちょっと調べれば分かるくらいの事は他のサイトの参照を示すという形でさらっと流しておこうと思います。下記のサイトを読むと、だいたい ASN.1 がどういったものなのかは分かると思いますので、リンクさせて頂きます。

- [Abstract Syntax Notation One](https://ja.wikipedia.org/wiki/Abstract_Syntax_Notation_One)
- [ＡＳＮ．１概要](http://www5d.biglobe.ne.jp/stssk/asn1/index.html)
- [ASN.1 Made Simple — What is ASN.1?](http://www.oss.com/asn1/resources/asn1-made-simple/introduction.html)

　概略だけ一応書いておくと、下記の様になると思います。

- ASN.1 とは Abstract Syntax Notation One の略で、情報の構造と制約を定義するものである
    - どの様なフィールドがあり、そのフィールドがどういうデータ型で、どういう制約を持っているか
- 実際にその情報をどうバイナリにするのかの規格は別途定義されている
    - 例えばパケットに乗せて転送する時にどうバイナリにすればよいか
    - BER, CER, DER などがある
    - ILP では [OER](http://www.oss.com/asn1/resources/books-whitepapers-pubs/Overview%20of%20OER.pdf) が利用されている

## ILP を理解する上で必要なもの
　上記のサイトをちらっと流し読みするだけだと、[ILP の ASN.1 のリポジトリ](https://github.com/interledger/rfcs/tree/master/asn1)を読んでいても意味がよく分からないものが出てきます。下記の様なものです。

- `CLASS` とは何か？
- `&` とか `.&` とか `@` とは何か？

　これらは、上記の OSS Nokalva のサイトをじっくり読むと意味が分かってきます。これらは、簡単に言うと簡易的なデータベースを定義して、そこから値を参照できる様にする時に使います。具体的にはデータベースのテーブルの型を定義するのに `CLASS` と `&` を使い、そのテーブルから値を参照する時に `.&` や `@` を使います。

　これだけだと分かりにくいので、上記の OSS Nokalva のサンプルを引用させて頂きます。

```Product.asn
-- PRODUCT というテーブル型を定義している
-- & でテーブル型のカラムの名前と型を定義している
PRODUCT ::= CLASS {
  &code         INTEGER (1..99999) UNIQUE,
  &description  VisibleString (SIZE (1..100)),
  &price        REAL
} WITH SYNTAX { CODE &code , DESCRIPTION &description , PRICE &price}

-- PRODUCT 型のインスタンスを ProductCatalog という名前で作成している
-- key-value になっているが、key は CLASS の WITH SYNTAX で与えられている
ProductCatalog PRODUCT ::= {
  {CODE 101, DESCRIPTION "iPhone v4", PRICE 250.00} |
  {CODE 102, DESCRIPTION "Android Galaxy", PRICE 250.00} |
  {CODE 103, DESCRIPTION "Win7 Nokia", PRICE 150.00}
}
```
```Item.asn
-- Item 型を作成しているが、その時に制約として ProductCatalog のインスタンス内にデータがある事を指定している
-- @itemCode で itemCode をキーとしてレコードを引っ張ってきて、その中の値を .&description などで指定している
Item ::= SEQUENCE {
  itemCode         PRODUCT.&code ({ProductCatalog}),
  itemDescription  PRODUCT.&description ({ProductCatalog}{@itemCode}),
  quantity         INTEGER (1..1000),
  unitPrice        PRODUCT.&price ({ProductCatalog}{@itemCode}),
  itemTotal        REAL,
  isTaxable        BOOLEAN
}
```

　上記のサイトに載っている事とこのあたりの事が分かれば、ILP のリポジトリに置いてある asn ファイルはほぼ読めるのではないかと思います。また、上記の OSS Nokalva では [C や Java 向けにツール](http://www.oss.com/asn1/products/asn1-download.html)も作っていたりする様です。気になった方は使ってみてはいかがでしょうか。

## おまけ
（2018/02/25 追記） 今になって気づきましたが、RFC に [0000-notes-on-oer-encoding.md](https://github.com/interledger/rfcs/blob/docs/st-oer/0000-notes-on-oer-encoding/0000-notes-on-oer-encoding.md) というものが追加されようとしている様です。参考までに。

# 終わり
　随分とライトな内容になってしまいました😅 が、私はこの辺が分からずちょっと苦労したので、少しでも参考になれば幸いです。また、何か間違いなどありましたらコメント頂けますと幸いです。

　私は最近 ILPv4 まわりについて色々調べたりしているのですが、やはり世界レベルでプロトコルを定義していっている人たちの仕事は非常に勉強になります。ASN.1 も知らなかったですし、InterledgerJS のリポジトリを見ていると色々と新しい事をやっていたりして、会社では得られないものを得られます。

　もちろん彼らの仕事を盲信する訳ではないのですが、触れてみてその価値を知る事自体は、意味のある事だと思います。普段仕事で精一杯になっているとこういった事をする時間も気力もなくなってしまうものですが、この年になって OSS の面白さがやっと分かってきた気がします（遅すぎる）。今後は、読んで勉強するだけではなくてコードで貢献していきたいですね。

　それではみなさま、よい ILP ライフを（笑）