デフォルトプロジェクトを探索する

もし クイックスタート の DFINITY Canister Software Development Kit (SDK) ツアーを始めているなら、すでに Internet Computer 上に Dapps を作成する基本ワークフローを見たことでしょう。ここでは今から新規プロジェクト作成時に、ワークスペースに追加されるデフォルトファイルとデフォルトフォルダを、詳しく見ていきましょう。

概要を掴めるように、コンピュータ上でローカルに Internet Computer を動かす開発のワークフローを以下の図に示しています。

Development work flow

始める前に

このチュートリアルを始める前に、以下のことを確認してください:

  • インターネット接続があり、macOS もしくは Linux コンピュータのシェルターミナルへアクセスできること

  • もしプロジェクトのフロントエンド開発でデフォルトテンプレートファイルを取り込みたいのであれば、node.js を既にインストールしていること

  • ダウンロードとインストール に記載されている DFINITY Canister SDK パッケージをダウンロードしてインストールをしていること

  • IDE として Visual Studio Code を使用しているのであれば、言語別エディタプラグインをインストールする に記載されている Motoko 専用プラグインをインストールしていること

  • ローカルコンピュータ上で走るすべてのローカル Canister 実行環境プロセスを止めていること

このチュートリアルの所要時間は20分程度です。

新しいプロジェクトを作成する

クイックスタート でも話したとおり、Internet Computer での Dapps は、あなたが作るプロジェクトとして始まります。コマンドライン(CLI)上で dfx コマンドを実行することでプロジェクトを作成することができます。

デフォルトでプロジェクトに含まれているファイルやフォルダを詳しく見るために、実際に新しいプロジェクトを作っていきましょう。

新しいプロジェクトを作る:

  1. ローカルコンピュータ上でターミナルシェルを、まだ開いていなければ開きます。

  2. 別のワーキングフォルダを利用しているなら、Internet Computer プロジェクトで使うフォルダに移動します。

  3. 以下のコマンドを実行して、新しいプロジェクトを作成します。

    dfx new explore_hello

    dfx new explore_hello コマンドは、新しいプロジェクト名直下のデフォルトプロジェクト構造と新しい Git リポジトリを含めた explore_hello プロジェクトを作成します。もし node.js をローカルにインストールしていれば、新規のプロジェクトを作成することでテンプレートフロントエンドコードと依存ライブラリも追加されます。

    JavaScript や Motoko または別の環境で、プロジェクト名が有効であることを保証するために、英数字とアンダースコアのみを使うべきです。ダッシュやいかなる特殊文字は、含めることができません。

  4. 以下のコマンドを実行して、デフォルトディレクトリ構成を見ていきます。

    ls -l explore_hello

    デフォルトでのプロジェクトディレクトリ構成は、少なくとも1つのソースサブディレクトリ、テンプレート README.md ファイル、また dfx.json 設定ファイルを含んでいます。

    node.js をインストールしているかどうかで、以下のファイルを一部もしくは全て含んでいるかが変わります。

    explore_hello/
    ├── README.md      # デフォルトプロジェクトのドキュメント
    ├── dfx.json       # プロジェクトの設定ファイル
    ├── node_modules   # フロントエンド開発のライブラリ
    ├── package-lock.json
    ├── package.json
    ├── src            # ソースファイルディレクトリ
    │   ├── explore_hello
    │   │   └── main.mo
    │   └── explore_hello_assets
    │       ├── assets
    │       │   ├── logo.png
    │       │   ├── main.css
    │       │   └── sample-asset.txt
    │       └── src
    │           ├── index.html
    │           └── index.js
    └── webpack.config.js

    最小単位では、デフォルトプロジェクトのディレクトリは、以下のフォルダやファイルを含みます。

    • リポジトリのプロジェクトを説明する README ファイル

    • プロジェクトのオプションを設定する dfx.json 設定ファイル

    • Dapp に必要なすべてのソースファイルを持つ src ディレクトリ

    デフォルトの src ディレクトリは、テンプレートファイルである main.mo を含んでおり、ファイルを修正したり、自分のプログラミングロジックへと置き換えることができます。

このチュートリアルでは、始める上での基本に重点を置いているので、main.mo ファイルだけを使うことになります。もし node.js をインストールしているなら、プロジェクトディレクトリは、Dapp のフロントエンドインターフェースを定義するのに使える追加のファイルとディレクトリを含んでいます。フロントエンド開発と assets フォルダにあるテンプレートファイルについては、少し後に話します。

デフォルト設定を確認する

デフォルトで、新しいプロジェクトを作成すると、プロジェクトディレクトリにいくつかのテンプレートファイルが追加されます。プロジェクトの設定をカスタマイズする、もしくは開発サイクルを加速するために自身のコードを取り込むのに、これらのテンプレートファイルを編集することができます。

プロジェクトのデフォルト設定ファイルを確認する:

  1. ローカルコンピュータ上でターミナルシェルを、まだ開いていなければ開きます。

  2. 以下のコマンドを実行して、プロジェクトディレクトリに移動します。

    cd explore_hello
  3. デフォルト設定を確認するために、テキストエディタで dfx.json 設定ファイルを開きます。

    例:

    {
        "canisters": {
            "explore_hello": {
                "main": "src/explore_hello/main.mo",
                "type": "motoko"
            },
            "explore_hello_assets": {
                "dependencies": [
                    "explore_hello"
                ],
                "frontend": {
                    "entrypoint": "src/explore_hello_assets/src/index.js"
                },
                "source": [
                    "src/explore_hello_assets/assets",
                    "dist/explore_hello_assets/"
                ],
                "type": "assets"
            }
        },
        "defaults": {
            "build": {
                "packtool": ""
            }
        },
        "dfx": "0.9.3",
        "networks": {
            "local": {
                "bind": "127.0.0.1:8000",
                "type": "ephemeral"
            }
        },
        "version": 1
    }

    いくつかデフォルト設定を見ていきましょう。

    • settings セクションでは、プロジェクトの WebAssembly モジュールの名前を指定します。今回は explore_hello になります。

    • canisters.explore_hello キーは、メイン設定に指定されたパス上に、コンパイルされるメインプログラムが位置していることを明記しています、今回のケースでは、src/explore_hello/main.motype 設定が、これは Motoko プログラムであることを示しています。

    • canisters.explore_hello_assets キーは、プロジェクトのフロントエンドアセットの詳細設定を指定します。今、こちらは飛ばしましょう。

    • dfx 設定は、プロジェクト作成時のソフトウェアバージョンを識別するのに使われます。

    • networks セクションは、あなたがつなげているネットワーク情報を指定します。デフォルトの設定では、ローカル Canister 実行環境は、ローカルホストアドレス 127.0.0.1 と ポート番号を 8000 に結びついています。

      もし別の Internet Computer ネットワークプロバイダへのアクセスできるのであれば、networks セクションは、そのプロバイダ接続を行うネットワークエイリアスと URLs を持ちます。

    デフォルト設定のままにすることもできます。

  4. dfx.json ファイルを閉じて、次に進みます。

デフォルトプログラムコードを確認する

新しいプロジェクトは、常にテンプレート main.mo ソースコードファイルを含んでいます。開発サイクルを加速する自身のコードを埋め込むために、このファイルを編集することができます。

Motoko プログラミング言語を使った Dapp を作るスタート地点として、main.mo デフォルトテンプレートファイルのサンプルプログラムを見ていきましょう。

プロジェクトのデフォルトサンプルプログラムを確認する:

  1. 以下のコマンドを実行して、プロジェクトでのあなたの現在地を確認しましょう。

    pwd
  2. テキストエディタで src/explore_hello/main.mo ファイルを開き、テンプレートのコードを確認します。

    actor {
        public func greet(name : Text) : async Text {
            return "Hello, " # name # "!";
        };
    };

    このプログラムのキーとなるいくつかの要素を見ていきましょう。

    • このサンプルコードは、ある一部のプログラミング言語が必要とする main 関数の代わりに actor を定義しているのに気づいたかもしれません。Motoko では、main 関数はそのファイル単体では動作しません。

    • 伝統的な "Hello, World!" プログラムは、print または println 関数を使って文字列を表示する方法を説明しますが、その伝統的なプログラムは、Internet Computer 上で動く Motoko Dapps の典型的なユースケースを提示することはしないでしょう。

    • print 関数の代わりに、このサンプルプログラムは、Text 型の name 引数を受けるパブリックの greet 関数を用いて actor を定義します。

    • そのプログラムは、"Hello, "# 演算子、name 引数、また "!" を連結した文字列から成る非同期メッセージを返すことをを示すのに async キーワードを使います。

    actor オブジェクトと非同期メッセージ処理を使用するコードを探検するのは、もう少し後になります。今は次のセクションに進みましょう。

  3. main.mo ファイルを閉じて、次に進みます。

ローカル Canister 実行環境を起動する

デフォルトプロジェクトをデプロイする前に、ローカル Canister 環境もしくは Internet Computer ブロックチェーンメインネットに接続する必要があります。

ローカル Canister 実行環境を起動するには、dfx.json ファイルが必要になります、そのため現在地がプロジェクトのルートディレクトリ直下であることを確認してください。このチュートリアルでは、分離している2つのターミナルシェルを開いておくと良いです。1つのターミナルシェルでネットワーク処理を行い、もう1つの方でプロジェクトを管理するのが良いです。

ローカル Canister 実行環境を起動する:

  1. 新しいターミナルウィンドウまたは新しいターミナルタブを、ローカルコンピュータ上で開きます。

  2. 必要であればプロジェクトのルートディレクトリ直下に移動します。

    • 2つのターミナル を開いておくと良いです。

    • 現在のワーキングディレクトリ を、プロジェクトディレクトリ としておくと良いです。

  3. 以下のコマンドを実行して、ローカル Cansiter 実行環境を起動します。

    dfx start

    プラットフォームやローカルセキュリティ設定によっては、警告の表示が出るかもしれません。もしネットワーク接続の許可もしくは拒否の選択を促されているなら、Allow をクリックしましょう。

    ローカル Canister 実行環境を起動した後は、ネットワーク処理を表示するターミナルとプロジェクトに関連したタスクを表示するもう1つのターミナルを持つことになります。

  4. ネットワーク処理を表示するターミナルはそのままにしておいて、新しく作成したプロジェクトの場所を表示するターミナルに重点を置き変えます。

Canister ID を登録する

ローカル Canister 実行環境に接続した後に、あなたのプロジェクトをユニークなネットワーク固有の Canister ID を生成することでネットワークに登録できます。

クイックスタート では、このステップは dfx deploy コマンドワークフローの一部として扱われました。このチュートリアルでは、独立してそれぞれの処理をどう扱うかを説明します。

ローカルネットワークに対して Canister ID を登録する:

  1. プロジェクトディレクトリに位置することを確認します、必要であれば移動します。

  2. 以下のコマンドを実行して、プロジェクトの Canister に対しユニークな Canister ID を登録します。

    dfx canister create --all

    そのコマンドは dfx.json 環境設定ファイルで定義される Canisters のネットワーク固有の Canister ID を表示します。

    Creating a wallet canister on the local network.
    The wallet canister on the "local" network for user "pubs-id" is "rwlgt-iiaaa-aaaaa-aaaaa-cai"
    Creating canister "explore_hello"...
    "explore_hello" canister created with canister id: "rrkah-fqaaa-aaaaa-aaaaq-cai"
    Creating canister "explore_hello_assets"...
    "explore_hello_assets" canister created with canister id: "ryjl3-tyaaa-aaaaa-aaaba-cai"

    ローカル Canister 実行環境に接続したので、これらの Canister ID は、ローカルでのみ有効かつ .dfx/local/canister_ids.json ファイルに保管されます。

    例:

    {
      "explore_hello": {
        "local": "rrkah-fqaaa-aaaaa-aaaaq-cai"
      },
      "explore_hello_assets": {
        "local": "ryjl3-tyaaa-aaaaa-aaaba-cai"
      }
    }

Dapp をビルドする

デフォルト環境設定やプログラムコードを探検して、ローカル Canister 実行環境を動かしてきたので、デフォルトプログラムを実行可能な WebAssembly モジュールにコンパイルしましょう。

プログラムを実行可能にビルドする:

  1. ローカルコンピューターのターミナルシェルで explore_hello プロジェクトディレクトリに移動します。

    そのプロジェクトディレクトリ構成の内側から dfx build コマンドを実行する必要があります。

  2. 以下のコマンドを実行して、Canister を実行可能にビルドします。

    dfx build

    以下のような出力を見ることになるでしょう。

    Building canisters...
    Building frontend...

    ローカル canister 実行環境に接続されたので、dfx build コマンドは、プロジェクトの .dfx/local/ ディレクトリ直下に canisters ディレクトリを追加します。

  3. 以下のコマンドを実行して、dfx build コマンドで作成された .dfx/local/canisters/explore_hello ディレクトリが WebAssembly や関連アプリケーションファイルを含んでいることを確認します。

    ls -l .dfx/local/canisters/explore_hello/

    例えば、そのコマンドは以下のような出力を返します。

    -rw-r--r--  1 pubs  staff     178 Apr  6 14:25 explore_hello.d.ts
    -rw-r--r--  1 pubs  staff      41 Apr  6 14:25 explore_hello.did
    -rw-r--r--  1 pubs  staff     155 Apr  6 14:25 explore_hello.did.js
    -rw-r--r--  1 pubs  staff     142 Apr  6 14:25 explore_hello.js
    -rw-r--r--  1 pubs  staff  157613 Apr  6 14:25 explore_hello.wasm

    canisters/explore_hello ディレクトリは、以下のキーとなるファイルを含みます。

    • メイン Dapp のインターフェースの説明を持っている explore_hello.did ファイル

    • Dapp の関数の Canister インターフェースの JavaScript 表示を持っている explore_hello.did.js ファイル

    • Dapp の Canister インターフェースの JavaScript 表示を持っている explore_hello.js ファイル

    • プロジェクトで使用されるコンパイルされた WebAssembly のアセットを持っている explore_hello.wasm ファイル

    canisters/explore_hello_assets ディレクトリは、プロジェクトのフロントエンドアセットを表示するファイルを含みます。

    canisters/explore_hellocanisters/explore_hello_assets ディレクトリにあるファイルに加えて、dfx build コマンドは、idl ディレクトリを作成します。

  4. src/declarations というディレクトリが作成されたことを確認します。

    このフォルダは Wasm を除いた .dfx/local のフォルダのコピーを含みます。そのコピーはどんな秘密も含まないので、これらのファイルと一緒に残りのソースコードをコミットすることを薦めます。

ローカルでプロジェクトをデプロイする

dfx build コマンドでプロジェクトの Canister ディレクトリに加工されたものを作成するのを見たことでしょう。Internet Computer ネットワーク上に Dapp をデプロイするためには、WebAssembly モジュールと canister_manifest.json ファイルが必要になります。

ローカル Canister 実行環境をデプロイする:

  1. ローカルコンピューターの explore_hello プロジェクトディレクトリにターミナルシェルで移動します。

  2. 以下のコマンドを実行して、ローカルネットワークに explore_hello プロジェクトをデプロイします。

    dfx canister install --all

    そのコマンドは、以下のような出力を表示します。

    Installing code for canister explore_hello, with canister_id rrkah-fqaaa-aaaaa-aaaaq-cai
    Installing code for canister explore_hello_assets, with canister_id ryjl3-tyaaa-aaaaa-aaaba-cai
    Authorizing our identity (pubs-id) to the asset canister...
    Uploading assets to asset canister...
      /index.html 1/1 (480 bytes)
      /index.js 1/1 (296836 bytes)
      /main.css 1/1 (484 bytes)
      /sample-asset.txt 1/1 (24 bytes)
      /logo.png 1/1 (25397 bytes)
      /index.js.map 1/1 (964679 bytes)
      /index.js.LICENSE.txt 1/1 (499 bytes)
  3. dfx canister call コマンドを実行して、Dapp を指定して関数を呼び出します。

    dfx canister call explore_hello greet '("everyone": text)'

    このコマンドは、以下を指定します:

    • explore_hello は、コールしたい スマートコントラクト Canister もしくは Dapp の名前

    • greet は、コールした意特定の関数

    • everyone は、greet 関数に渡す引数

  4. そのコマンドが、greet 関数の返り値を表示するのを確認します。

    例:

    ("Hello, everyone!")

デフォルトのフロントエンドを確認する

もし開発環境に node.js をインストールしているのであれば、あなたのプロジェクトは、ブラウザで Dapp にアクセスするのに index.js JavaScript ファイルを使う単純なフロントエンドの例を含んでいます。

デフォルトのフロントエンドテンプレートを探検する:

  1. ローカルコンピューターでターミナルシェルを開いていなければ開き、また explore_hello プロジェクトディレクトリに移動します。

  2. テキストエディタで src/explore_hello_assets/src/index.js ファイルを開き、テンプレートスクリプトのコードを確認します。

    import { explore_hello } from "../../declarations/explore_hello";
    
    document.getElementById("clickMeBtn").addEventListener("click", async () => {
      const name = document.getElementById("name").value.toString();
      // Interact with explore_hello actor, calling the greet method
      const greeting = await explore_hello.greet(name);
    
      document.getElementById("greeting").innerText = greeting;
    });

    テンプレート index.js は、新しく作成した declarations ディレクトリから explore_hello エージェントをインポートします。そのエージェントは、自動的に Main.mo で作成したインターフェースと親和性があるように構成され、ユーザーが greeting ボタンをクリックした時に AnonymousIdentity を使って Canister にコールします。

    このファイルはテンプレート index.html ファイルと組み合わせて、greet 関数の画像アセット、入力欄、ボタンを備えた HTML ページを表示するよう機能します。

  3. index.js ファイルを閉じて、次に進みます。

  4. 以下のコマンドを実行して、プロジェクトのフロントエンドアセットを確認します。

    ls -l .dfx/local/canisters/explore_hello_assets/

    そのコマンドは、以下のような出力を表示します。

    drwxr-xr-x  9 pubs  staff     288 Apr  6 14:25 assets
    -r--r--r--  1 pubs  staff    2931 Dec 31  1969 assetstorage.did
    -r--r--r--  1 pubs  staff  265823 Dec 31  1969 assetstorage.wasm
    -rw-r--r--  1 pubs  staff    3651 Apr  6 14:25 explore_hello_assets.d.ts
    -rw-rw-rw-  1 pubs  staff    2931 Dec 31  1969 explore_hello_assets.did
    -rw-r--r--  1 pubs  staff    4236 Apr  6 14:25 explore_hello_assets.did.js
    -rw-r--r--  1 pubs  staff     149 Apr  6 14:25 explore_hello_assets.js
    -rw-rw-rw-  1 pubs  staff  265823 Dec 31  1969 explore_hello_assets.wasm

    node モジュールと index.js ファイルテンプレートを使う dfx build コマンドによって、これらのファイルは自動的に作成されます。

  5. npm start コマンドで開発サーバーを起動します。

  6. ブラウザを開き、 local ネットアドレスとポート番号を +127.0.0.1:8080 に指定します。

  7. サンプルアプリケーションの HTML ページが見えることを確認します。

    例:

    Sample HTML entry page

  8. あいさつを打ち込みます、それから Click Me をクリックすることで、あいさつが返されます。

    例:

    Return the name argument

ローカル Canister 実行環境を止める

Dapp を使った実験を終えたら、ローカル Canister 実行環境を、バックグラウンドで動かし続けないために止めます。

ローカル Canister 実行環境を止める:

  1. ネットワーク処理を表示するターミナルで、ローカルネットワークでのプロセスを中断するためにControl-C を押します。

  2. 以下のコマンドを実行することで、ローカル Canister 実行環境を止めます。

    dfx stop