DAMLの環境を構築する（Windows編）

# 記事の内容
スマートコントラクト記述言語であるDAMLをWindowsで環境構築します

# DAMLとは
DAML（Digital Asset Modeling Language）はDigital Asset社が開発しているスマートコントラクト言語です。
DAMLで記述されたアプリはHyperledger Fabric、Sawtooth、BESUにデプロイが可能とのことです。
いろいろなDLTへのインテグレートなど開発がかなり速いスピードで進んでおり、スマートコントラクトの記述言語がDAMLに統一される日が来るかもしれません。

# 環境
OS：Windows10

# 事前準備
事前に以下の２つをインストールしておく必要があります
[Java SDK 8](https://www.oracle.com/java/technologies/javase-downloads.html)
[yarn](https://classic.yarnpkg.com/ja/docs/install/#windows-stable)

#環境構築
## 1. DAMLのインストール
以下のリンクからDAMLのインストーラーをダウンロードし、インストールします。
インストーラーは下の方にあります。
[digital-asset/daml](https://github.com/digital-asset/daml/releases/tag/v1.1.1)

## 2. DAMLのビルド、インストール
まず、任意のディレクトリで以下のコマンドを実行します。
このコマンドでテンプレートのプロジェクトをインスタンス化します

~~~
daml new create-daml-app create-daml-app
~~~

次に作成されたディレクトリでdamlのbuildを行います。

~~~
cd create-daml-app
daml build
~~~

buildの結果、「.daml/dist/create-daml-app-0.1.0.dar」が作成されます

次はUIコードをDAMLに接続します。（イマイチ理解出来てません）

~~~
daml codegen js .daml/dist/create-daml-app-0.1.0.dar -o daml.js
~~~
このコマンドはyarnがインストールされてないと途中で失敗します。
失敗した場合、インストール後にやり直せばうまくいきます。

インストールをします

~~~
cd ui
yarn install
~~~

以下のコマンドでdamlを起動します
このコマンドは別ターミナルを起動し、「create-daml-app」ディレクトリ配下で実行します

~~~
daml start
~~~
以下のログが出力されたら正常終了しています。

~~~
INFO  com.daml.http.Main$ - Started server: ServerBinding(/127.0.0.1:7575)
~~~
この処理では以下のことが行われています
・　DAMLコードをDARファイルにコンパイルする
・　DARをロードして、開発に役立つメモリ内台帳であるサンドボックスのインスタンスを起動する
・　HTTP JSON APIのサーバーを起動する

次は以下のコマンドでインストールを行います

~~~
cd ui
yarn start
~~~

コンパイルが終了するとデフォルトブラウザで「http://localhost:3000」が開かれます

## 3. UIで動作確認
ブラウザでテスト用のSNSが起動されています。
以下の画面にアカウント名を入力するとログインできます

<img width="457" alt="create-daml-app-login-screen.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476876/5a9ecf30-c320-eaac-10d5-8ed2a10530ee.png">
ログインが完了すると以下の画面が表示されます
<img width="1440" alt="create-daml-app-main-screen-initial-view.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476876/f0dd91a1-e40a-b53e-5f58-cfbe619d8466.png">

ここで別のブラウザを起動し、localhost:3000を開きます。
別のアカウントでログインし、テキストボックスにアカウント名を入力するとアカウントのフォローができます
<img width="1440" alt="create-daml-app-alice-sees-bob.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476876/f204bf32-e1d6-1c36-2b32-c494eddb6bf4.png">

## 4. コードのテスト
まずは実行に必要となるツールのインストールをします

~~~
yarn add --dev puppeteer wait-on @types/jest @types/node @types/puppeteer @types/wait-on
~~~
この処理はnodeのバージョンが10.18.0以上じゃないと途中で失敗します

次にテスト用のコードを「ui/src」は以下に作成します

~~~ index.test.ts
test('log in as a new user, log out and log back in', async () => {
  const partyName = getParty();

  // Log in as a new user.
  const page = await newUiPage();
  await login(page, partyName);

  // Check that the ledger contains the new User contract.
  const {token} = computeCredentials(partyName);
  const ledger = new Ledger({token});
  const users = await ledger.query(User.User);
  expect(users).toHaveLength(1);
  expect(users[0].payload.username).toEqual(partyName);

  // Log out and in again as the same user.
  await logout(page);
  await login(page, partyName);

  // Check we have the same one user.
  const usersFinal = await ledger.query(User.User);
  expect(usersFinal).toHaveLength(1);
  expect(usersFinal[0].payload.username).toEqual(partyName);

  await page.close();
}, 20_000);
~~~

作成したら「ui」ディレクトリの配下で以下のコマンドを実行します

~~~
yarn test
~~~

サンプルで用意されているコードにエラーがあるみたいで、テストは失敗します

~~~
 FAIL  src/index.test.ts
  × log in as a new user, log out and log back in (3ms)

  ● log in as a new user, log out and log back in

    ReferenceError: getParty is not defined

      1 | test('log in as a new user, log out and log back in', async () => {
    > 2 |   const partyName = getParty();
        |                     ^
      3 |
      4 |   // Log in as a new user.
      5 |   const page = await newUiPage();

      at Object.<anonymous> (src/index.test.ts:2:21)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        3.02s, estimated 4s
Ran all test suites.

Watch Usage
 › Press f to quit "only failed tests" mode.
 › Press o to only run tests related to changed files.
 › Press q to quit watch mode.
 › Press p to filter by a filename regex pattern.
 › Press t to filter by a test name regex pattern.
 › Press Enter to trigger a test run.
~~~

一応、環境構築はこれで完了です

# 最後に
まだDAMLの実装については全く触れれていないのでなんとも言い難いですが、今後スマートコントラクトの開発言語が統一されたら面白いなと思うので使い方は引き続き学習していこうと思ってます。
ゆっくり学習したことは記事にしていきます。

# 参考
[DAML SDK Documentation](https://docs.daml.com/getting-started/installation.html)