Hello World! Rust CDK クイックスタート

DFINITY Canister Development Kit (CDK) for Rust は、分散型の Internet Computer メインネット上で動作する Dapps を作成するためのツールとサンプルコードとドキュメントを提供しています。 Hello World! Rust CDK クイックスタート では、DFINITY Rust CDK を初めてインストールすることを想定しています。

初めての方の助けとなるように、このチュートリアルでは、よくある "Hello World" という最初の Dapp を DFINITY Rust CDK を使うように修正する方法を説明します。 このシンプルな Dapp は、ターミナルにテキストを出力する関数が1つ定義されているだけですが、 Internet Computer にデプロイする Dapp を Rust で書く際のワークフローを理解するための良いモデルとなります。

はじめる前に

プロジェクトをはじめる前に、以下を確認してください:

  • インターネットに接続しており、ローカルの macOS または Linux コンピュータでターミナルにアクセスできること。

  • Rust のインストール方法 にあるように、Rust プログラミング言語と Cargo が OS にダウンロードされ、インストールされていること。

    curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh

    Rust のバージョンは 1.46.0 より新しい必要があります。

  • ダウンロードとインストールの説明に従って、DFINITY Canister Software Development Kit (SDK) パッケージのダウンロードとインストールが済んでいること。

  • cmake のインストールが済んでいること。例えば、macOS では Homebrew を使って以下のコマンドを実行します:

    brew install cmake

    Homebrew をインストールする方法については、Homebrew のドキュメントを参照してください。

  • コンピュータ上の ローカル実行環境 プロセスが停止していること。

ローカルコンピュータ上で新たなターミナルを開く方法や、ターミナルでコマンドを実行する方法や、インストールパッケージを確認する方法がわからない場合には、初めての人のための準備を参照してください。 既に必要な前提条件を満たしている場合には、新しいプロジェクトの作成 へと進んでください。

新しいプロジェクトの作成

Internet Computer 用のアプリケーション開発は プロジェクト の作成から始まります。 DFINITY Canister SDK を使用して Internet Computer の新しいプロジェクトを作成することができます。 Internet Computer にデプロイするプロジェクトを作成するため、本チュートリアルでは、親コマンドである dfx とそのサブコマンドを使って Rust プログラムを作成・ビルド・デプロイする方法を中心に説明します。

DFINITY Canister SDK を使って新しいプロジェクトを作成する手順は以下になります:

  1. ローカル PC でターミナルを開きます。

  2. 以下のコマンドを実行し、rust_hello という名前の Rust Canister を持つ新しいプロジェクトを作成します。

    dfx new --type=rust rust_hello

    dfx new --type=rust rust_hello コマンドは rust_hello プロジェクトのディレクトリとテンプレートファイルと rust_hello の Git リポジトリを新たに生成します。

  3. 以下のコマンドで、プロジェクトディレクトリに移動します。

    cd rust_hello

プロジェクトファイルを一通り確認する

プロジェクトをコンパイルし、Internet Computer にデプロイする準備ができました。 デプロイする前に、プロジェクトファイルを見てみましょう。

dfx.json

プロジェクトディレクトリに含まれるテンプレートファイルの一つに、dfx.json 設定ファイルがあります。 このファイルには Internet Computer で動かすプロジェクトをビルドするために必要な設定が含まれています。 これは Cargo.toml ファイルが Rust プログラムのビルドやパッケージ管理の設定を含んでいるのと同じです。

設定ファイルは次のようなものです。

{
  "canisters": {
    "rust_hello": {
      "candid": "src/rust_hello/rust_hello.did",
      "package": "rust_hello",
      "type": "rust"
    },
    "rust_hello_assets": {
      "dependencies": [
        "rust_hello"
      ],
      "frontend": {
        "entrypoint": "src/rust_hello_assets/src/index.html"
      },
      "source": [
        "src/rust_hello_assets/assets",
        "dist/rust_hello_assets/"
      ],
      "type": "assets"
    }
  },
  "defaults": {
    "build": {
      "args": "",
      "packtool": ""
    }
  },
  "networks": {
    "local": {
      "bind": "127.0.0.1:8000",
      "type": "ephemeral"
    }
  },
  "version": 1
}

canisters キーの下に、rust_hello Canister のデフォルト設定があることに注意してください。

  1. "type": "rust "rust_hellorust タイプの Canister であることを指定します。

  2. "candid": "src/rust_hello/rust_hello.did " は、Canister に使用する Candid インターフェース記述ファイルの場所を指定します。

  3. "package": "rust_hello " は、Rust クレートのパッケージ名を指定します。Cargo.toml ファイルに記述されているものと同じである必要があります。

Cargo.toml

ルートディレクトリには、Cargo.toml というファイルがあります。

これは、各 Rust クレートのパスを指定することで、Rust ワークスペースを定義しています。 Rust タイプの Canister は、WebAssembly にコンパイルされた Rust クレートにすぎません。 ここでは、src/rust_hello に一つのメンバーを持っており、これが唯一の Rust Canister です。

[workspace]
members = [
    "src/rust_hello",
]

src/rust_hello/

さて、Rust Canister を見ていきましょう。標準的な Rust クレートと同様に Cargo.toml ファイルがあり、Rust クレートをビルドするための詳細な設定をしています。

src/rust_hello/Cargo.toml

[package]
name = "rust_hello"
version = "0.1.0"
edition = "2018"

[lib]
path = "lib.rs"
crate-type = ["cdylib"]

[dependencies]
ic-cdk = "0.3"
ic-cdk-macros = "0.3"

crate-type = ["cdylib"] の行に注目してください。これは、この Rust プログラムを WebAssembly モジュールにコンパイルするために必要なものです。

src/rust_hello/lib.rs

デフォルトのプロジェクトでは、DFINITY Rust CDK query マクロを使用したシンプルな greet 関数が用意されています。

#[ic_cdk_macros::query]
fn greet(name: String) -> String {
    format!("Hello, {}!", name)
}

src/rust_hello/rust_hello.did

Candid は、Internet Computer で動作する Canister と対話するためのインターフェース記述言語(IDL)です。 Candid ファイルは、Canister が定義する各関数の名前・引数・返し値のフォーマットやデータ型など、Canister のインターフェースを言語に依存しないように記述したものです。

Candid ファイルをプロジェクトに追加することで、Rust で定義されたデータが Internet Computer 上で安全に実行されるために適切に変換されることを保証します。

Candid インターフェース記述言語の構文の詳細は Candid ガイドCandid クレートのドキュメントをご覧ください。

service : {
    "greet": (text) -> (text) query;
}

これは、greet 関数が text データを入力として受け取り text データを返す query メソッドであることを指定します。

ローカル実行環境 を立ち上げる

プロジェクトをビルドする前に、ローカル実行環境 か、Internet Computer メインネットに接続する必要があります。

ローカル実行環境 を立ち上げるには、以下のようにします:

  1. 自分がプロジェクトのルートディレクトリにいることを確認します。

  2. ローカル実行環境 をバックグラウンドで立ち上げるために、以下のコマンドを実行します:

    dfx start --background

    プラットフォームやローカルのセキュリティ設定によっては、警告が表示される場合があります。 ネットワーク接続を許可するかどうかの確認画面が表示された場合は、Allow をクリックします。

プロジェクトの登録・ビルド・デプロイ

開発環境で立ち上がっている ローカル実行環境 に接続した後に、プロジェクトの登録・ビルド・デプロイをローカル環境で行うことができます。 登録・ビルド・デプロイを行うためには、以下のようにします:

  1. プロジェクトのルートディレクトリにいることを確認します。

  2. 以下のコマンドを実行し、wasm32-unknown-unknown がインストールされていることを確認します:

    rustup target add wasm32-unknown-unknown
  3. dfx.json に指定されている Canister を以下のコマンドで、登録・ビルド・デプロイします:

    dfx deploy

    dfx deploy コマンドを実行すると、以下のような実行結果に関しての情報が表示されます。

    Creating a wallet canister on the local network.
    The wallet canister on the "local" network for user "default" is "rwlgt-iiaaa-aaaaa-aaaaa-cai"
    Deploying all canisters.
    Creating canisters...
    Creating canister "rust_hello"...
    "rust_hello" canister created with canister id: "rrkah-fqaaa-aaaaa-aaaaq-cai"
    Creating canister "rust_hello_assets"...
    "rust_hello_assets" canister created with canister id: "ryjl3-tyaaa-aaaaa-aaaba-cai"
    Building canisters...
    Executing: "cargo" "build" "--target" "wasm32-unknown-unknown" "--release" "-p" "rust_hello"
        Updating crates.io index
       Compiling unicode-xid v0.2.2
       ...
    Building frontend...
    Installing canisters...
    Creating UI canister on the local network.
    The UI canister on the "local" network is "r7inp-6aaaa-aaaaa-aaabq-cai"
    Installing code for canister rust_hello, with canister_id rrkah-fqaaa-aaaaa-aaaaq-cai
    ...
    Deployed canisters.

Dapp のテスト

ローカルでデプロイした Dapp をテストするには、以下のようにします:

  1. プロジェクトのルートディレクトリにいることを確認します。

  2. Dpp の greet 関数を以下のコマンドで呼び出します:

    dfx canister call rust_hello greet world
  3. rust_hello+` Canister の greet 関数の呼び出しがテキストメッセージである ("Hello, world!") を返すことを確認します。

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

アプリケーションのテストをした後は、ローカル実行環境 がバックグラウンドで稼働し続けないように、以下の手順で停止します:

  1. ネットワークの稼働状況が表示されている端末で、Control-C を押して ローカル実行環境 を止めてください。

  2. 以下のコマンドを用いて ローカル実行環境 を停止してください:

    dfx stop