"Hello World" Dapp を10分間でデプロイする
"Hello World" Dapp を Internet Computer (IC) に 10 分以内でデプロイするためのクイックチュートリアルです。アプリのデプロイに必要な知識はターミナルの使い方のみです。
始める前に、この Dapp がオンチェーンで動作しているのを見てみましょう:https://6lqbm-ryaaa-aaaai-qibsa-cai.ic0.app/
このチュートリアルでは、次のことを学びます:
- Canister SDK をインストールする
- ローカルで Dapp をビルドしてデプロイする
- Dapp の動力(ガス)となる無料 Cycle を受け取る
- Cycle ウォレットを作成し、そこから他の Dapp に Cycle を転送する
- Dapp をオンチェーンにデプロイする
このシンプルな Hello
Dapp は、2つの Canister スマートコントラクト(バックエンド用とフロントエンド用)で構成されています。このアプリはテキストを入力として受け取り、挨拶( greeting )を返します。例えば、Canister SDK(Canisterのインストール方法は後述)を使ってコマンドラインで greet
メソッドに Everyone
というテキスト引数を与えて呼び出すと、ターミナルに Hello, Everyone!
と返されます:
$ dfx canister call hello_backend greet Everyone
$ "Hello, Everyone"
またはブラウザで Dapp を経由すると、メッセージとともにポップアップウィンドウが表示されます。 Hello, Everyone!
"Hello World" Dapp は、IC とのやりとりに特化したプログラミング言語である Motoko で書かれたバックエンドコードと、webpack ベースのシンプルなフロントエンドから構成されていることに注意してください。
このチュートリアルは、Linux、macOS 12.* Monterey 以降、または Windows Subsystem for Linux (WSL) がインストールされた Windows で実施します。
このチュートリアルで扱うトピック
Canister は、IC にインストールされたスマートコントラクトです。実行されるコードと、その結果生成されるステートが格納されます。"Hello World” アプリのように、複数の Canister で構成されることが一般的です。
Cycle は、リソースの消費量を表す単位で、通常は IC 上で消費される処理(メモリ、ストレージ、ネットワーク帯域幅)を指します。このチュートリアルでは、Cycle はイーサリアムのガスに似ています。Cycle は Dapps を実行するために必要ですが、ガスと違って安定しており、価格も安くなります。各 Canister には Cycle アカウントがあり、そこから Canister で消費されたリソースがチャージされます。IC のユーティリティ・トークン(ICP)は、Cycle に変換して Canister に転送することができます。ICP は常に SDR (通貨バスケット)で測定された ICP の現在価格を使って Cycle に変換することができ、1兆サイクルが 1SDR に対応するという慣例があります。Cycle faucet(無料)
Cycle ウォレットは Cycle を入れて、Dapps をパワーアップする Canister です。
1. ツールをインストールする
Hello
Dapp をビルドしてデプロイするには、以下のツールをインストールする必要があります。
DFX
このチュートリアルでは、DFINITY 財団が管理しているデフォルトのSDKである dfx
という Canister SDK を使用します。
dfx
をインストールするには、以下を実行します:
sh -ci "$(curl -fsSL https://internetcomputer.org/install.sh)"
dfx
が正しくインストールされたか確認するには以下を実行します:
dfx --version
ターミナルには最新版(参照: SDK リリースノート)が表示されるはずです。
その他のインストールオプションや dfx
のアンインストール方法については、SDKのインストールで説明されています。
Node.js
Node.js はフロントエンドのアセットをレンダリングするために必要なので、このチュートリアルを完了させるために必要です。しかし、一般的な Canister の開発には Node.js は必要ありません。
Node.js は12から始まるすべての安定したバージョンをサポートしています。12、14、16 のいずれかをインストールすることができます。Node 17は Webpack の API プロキシツールをサポートしていないため、npm start
が正しく動作しない可能性があることに注意してください。
node.js をインストールする方法はたくさんあります。Linux では、お使いのシステムのパッケージマネージャを使用することをお勧めします。macOS では、Homebrew をお勧めします。また、nodejs.org website に説明があります。
このチュートリアルは 16.*.*
よりも高いバージョンの node.js で最適に動作します。
2. プロジェクトを生成する(1分)
dfx
プロジェクトは、ソースコードや設定ファイルを含むアーティファクトのセットであり、Canister にコンパイルすることができます。以下を実行します:
dfx new hello
dfx
は hello
という名前の新しいプロジェクトディレクトリを作成します。ターミナルの出力は以下のようになるはずです:
"hello world” Canister と新しい hello
Git リポジトリに必要なアーティファクトは、hello
プロジェクトディレクトリにあります。ディレクトリはこのようになっているはずです:
hello
プロジェクトは、2つの Canister で構成されています:
hello_backend
Canister、 テンプレートバックエンドロジックを含みますhello_frontend
Canister、 Dapp アセット(画像や html ファイルなど)を含みます
「なぜ Canister が2つあるのか」と思われるかもしれません。2つの Canister は、プロジェクトを整理するために作成されます。アセットとバックエンドのロジックを1つの Canister に収めることもできますが、IC 開発者は2つの Canister(バックエンド用とフロントエンド用)を作成することが有用であると理解しています。
3. Dapp をローカル環境で実行する(3分)
これで hello
プロジェクトが作成されましたので、次のステップではそれをローカルにデプロイします。ローカルにデプロイするために dfx
は実行環境のローカルインスタンスを開始することができます。この環境は完全な IC レプリカではなく、IC レプリカのステートをダウンロードすることもありません。Dapps のデプロイ専用に設計された軽量な環境です。
このため、ターミナルを2つ使用することを推奨します:
ターミナル A には、実行環境の出力が表示されます。これは、node.js の Express、python の Django、Ruby の Rails など、web2 プロジェクトでローカルサーバを起動するのと似ています。
ターミナル B は、実行環境で動作している Canister と対話するために使用されます。これは、ローカルで動作しているサーバ、例えば Postman や Panic に HTTP API メッセージを送信することに類似しています。
このチュートリアルでは、2つのターミナルを区別するために、ターミナル A の背景を紺色にしています...
... ターミナル B の背景は黒色です。
実行環境の起動する
ターミナル A で、プロジェクトのルートディレクトリ hello
に移動し、次のように実行します:
dfx start
- お使いのプラットフォームやローカルのセキュリティ設定によっては、警告が表示されることがあります。着信ネットワーク接続の許可または拒否を求めるメッセージが表示された場合は、「許可 」をクリックしてください。
- 8000番台のポートの競合を引き起こすような他のネットワークプロセスが実行されていないことを確認します。
おめでとうございます! これであなたのマシン上でICの実行環境のローカルインスタンスが動作しています! このウィンドウ/タブを開いたままにしておいてください。 ウィンドウ/タブを閉じると、IC の実行環境のローカルインスタンスが動作しなくなり、このチュートリアルの続きができなくなります。
Dappをローカルにデプロイする
これは Canister 実行環境のみなので、このデプロイはメインネットへのデプロイよりも手順が少ないですが、Cycle が必要です。
ターミナル B で、プロジェクトのルートディレクトリ hello
に移動します。必要なすべての node モジュールをインストールするには、以下のコマンドを実行します:
npm install
hello
Canister を登録、ビルドし、ローカルの実行環境にデプロイします。以下のコマンドを実行します:
dfx deploy
Dapp は2つの Canister で構成されています。(ターミナル B から)以下のコピーで確認できます:
Installing code for canister hello_backend, with canister_id rrkah-fqaaa-aaaaa-aaaaq-cai
Installing code for canister hello_frontend, with canister_id ryjl3-tyaaa-aaaaa-aaaba-cai
hello_backend
Canisterrrkah-fqaaa-aaaaa-aaaaq-cai
バックエンドロジックを含みます。hello_frontend
Canisteryjl3-tyaaa-aaaaa-aaaba-cai
フロントエンドのアセット(HTML、JS、CSSなど)を含みます。
コマンドラインからローカルの Dapp をテストする
これで、Canister がローカルの実行環境にデプロイされたので、メッセージを送受信して Canister と対話できるようになります。Canister には greet
というメソッド (パラメータとして文字列を受け取ります)があるので、メッセージを送信してみましょう。ターミナル B で、以下を実行します。
dfx canister call hello_backend greet everyone
dfx canister call
コマンドでは、Canister 名と呼び出す関数を指定する必要があります。hello_backend
は呼び出す Canister の名前を指定します。greet
は関数名を指定します。everyone
はgreet
関数に渡す引数です。
ブラウザでローカルの Dapp をテストする
Dapp がデプロイされ、コマンドラインで動作確認ができたので、Web ブラウザでフロントエンドにアクセスできることを確認しましょう。
ターミナル B で、開発用サーバーを起動します:
npm start
ブラウザを開き、http://localhost:8080/ に移動してください。
シンプルな HTML ページが表示され、サンプルアセット、画像ファイル、入力欄、ボタンを確認できます。
greeting に入力し、Click Me をクリックすると、greeting が返されます。
ローカル Canister の実行環境を停止する
ブラウザでアプリケーションをテストした後、ローカル Canister の実行環境を停止して、バックグラウンドで実行し続けないようにします。オンチェーン・デプロイには、この実行環境は必要ありません。
ローカル・デプロイメントを停止するには、以下の手順に従います:
ターミナル A で、Control-C を押して、ローカルネットワークの処理を中断します。
ターミナル B で、Control-C を押して、開発サーバーのプロセスを中断します。
ローカル・コンピュータ上で動作しているローカル Canister 実行環境を停止します。
dfx stop
トラブルシューティング
Node.js が正しくインストールされない
ブラウザでアプリが表示されない場合、Node.js がインストールされていない可能性があります。インストールされているかどうか、実行して確認してください。
node --version
以前の dfx インストール
2022年2月以前に IC Dapp を作成したことがある場合、クリーンインストールが必要な場合があります。SDK と関連するプロファイルを削除して、再インストールすることができます。こちらの手順に従ってください。SDK のインストール に従ってください。
4. オンチェーン・デプロイのための Cycle 取得(5分)
IC Dapps がオンチェーンで動作するためには、計算と保存のための費用として Cycle が必要です。つまり、開発者は Cycle を獲得し、Canister に充填する必要があります。Cycle は ICP トークンから生成されます。
このフローは、ホスティングプロバイダーにクレジットカードを追加してアプリをデプロイし、後で課金される Web2 ソフトウェアに慣れている人にとっては驚くべきことかもしれません。Web3 では、ブロックチェーンはスマートコントラクトが何かを消費することを要求します(それがイーサリアムのガスであろうとICの Cycle であろうとです)。次のステップは、クリプトやブロックチェーンの関係者には馴染み深いもので、アプリをデプロイする最初のステップは「トークンを取りに行く」というものです。
さらに、なぜ ICP トークンではなく Cycle で Dapp が動くのか不思議に思うかもしれません。ICP トークンのコストは暗号市場によって変動しますが、Cycle は予測可能で比較的安定したトークンであり、SDR にペグされるからです。1兆 Cycle は、ICP の価格に関係なく、常に 1SDR のコストになります。
Cycle に関する実用的な注意点:
- 新しい開発者は20 兆 Cycle を与えられます。 Cycle フォーセット
- Canister をデプロイするには1000億 Cycle が必要ですが、十分な Cycle で Canister をロードするために、
dfx
は Canister を作成すると3兆 Cycle を注入します(これは変更可能なパラメータです)。 - 計算と保存のコストの表はこちらで見ることができます。計算とストレージのコスト
- ICP の取得と管理については、Acquiring and managing ICP tokensで詳しく説明しています。
このチュートリアルでは、Cycle を取得する2つの方法を紹介します:
- オプション1: 無料 Cycle フォーセットから Cycle を取得するは、Cycle フォーセットから Cycle を取得する方法です(新しい開発者に最も一般的です)。
- オプション2: ICP トークンを Cycle に変換するは ICP トークンで Cycle を取得する方法です(多くの Cycle を求める開発者に最も一般的です)。
このセクションが終わるころには、Canister が3つになっていることでしょう:
hello_backend
Canister(IC に未デプロイ)hello_frontend
プロジェクトの Canister(IC に未デプロイ)- Cycle を収納するウォレット Canister(ICにデプロイ済み)
サニティチェックとして、Internet Computer のブロックチェーンの現状と接続の可否を確認することで、IC への接続が安定しているかどうかを確認するとよいでしょう:
dfx ping ic
成功すると、次のような出力が表示されます:
$ {
"ic_api_version": "0.18.0" "impl_hash": "d639545e0f38e075ad240fd4ec45d4eeeb11e1f67a52cdd449cd664d825e7fec" "impl_version": "8dc1a28b4fb9605558c03121811c9af9701a6142" "replica_health_status": "healthy" "root_key": [48, 129, 130, 48, 29, 6, 13, 43, 6, 1, 4, 1, 130, 220, 124, 5, 3, 1, 2, 1, 6, 12, 43, 6, 1, 4, 1, 130, 220, 124, 5, 3, 2, 1, 3, 97, 0, 129, 76, 14, 110, 199, 31, 171, 88, 59, 8, 189, 129, 55, 60, 37, 92, 60, 55, 27, 46, 132, 134, 60, 152, 164, 241, 224, 139, 116, 35, 93, 20, 251, 93, 156, 12, 213, 70, 217, 104, 95, 145, 58, 12, 11, 44, 197, 52, 21, 131, 191, 75, 67, 146, 228, 103, 219, 150, 214, 91, 155, 180, 203, 113, 113, 18, 248, 71, 46, 13, 90, 77, 20, 80, 95, 253, 116, 132, 176, 18, 145, 9, 28, 95, 135, 185, 136, 131, 70, 63, 152, 9, 26, 11, 170, 174]
}
オプション1: 無料の Cycle フォーセットによる Cycle の取得(2分)
このオプションは、最小限の時間しか投資したくない人、Cycle フォーセットを使ったことがない人に最適です(フォーセットは1度だけ使用できます)。
このチュートリアルでは、Cycle フォーセットから Hello
Dapp 用の無料 Cycle を取得します。こちらの手順に従ってください。Cycle フォーセット
Cycle 残高をチェックする
Cycle フォーセットを使用した後は、ターミナル B で Cycle 残高を確認することができます:
dfx wallet --network ic balance
Cycle ウォレットを使用した後にこれを実行すると、20兆 Cycle が表示されるはずです。その場合は、5.オンチェーンデプロイ(1分) のセクションにスキップしてください。
Cycle が表示されない場合、このチュートリアルの残りの部分でオンチェーンをデプロイしてもうまくいきません。オプション2: ICP トークンを Cycle に変換する(5分) を試す必要があります。
オプション2: ICP トークンを Cycle に変換する(5分)
このオプションは、すでに Cycle ウォレットを使い果たしてしまった人や、将来的に Cycle を追加するために環境を整えたい人に最適です。
ICP トークンを Cycle に変換するには、まず ICP をいくつか入手し、適切なアカウントに転送する必要があります。ICP トークンは取引所で入手するか、知り合いに頼んで送ってもらうことができます。ICP トークンをどのアカウントに転送するかは、以下を実行してください。
dfx ledger account-id
これにより、ICP 台帳にアカウント番号が表示されます。これと似た文字列です:
e213184a548871a47fb526f3cba24e2ee2fbbc8129c4ab497ef2ce535130a0a4
このアカウントに ICP トークンを送金したら(5~10ドル分あれば十分)、このコマンドで残高を確認することができます:
dfx ledger --network ic balance
すると、このような出力が得られます:
12.49840000 ICP
ICP トークンの準備ができたら、Cycle ウォレットの作成に取りかかりましょう。まず、ウォレットとなる Cycle を作成する必要があります。そのための基本コマンドは以下の通りです:
dfx ledger --network ic create-canister <your-principal-identifier> --amount <icp-tokens>
代入する値は、自分の Principal と、変換したいトークン数の2つです。自分の Principal を知るには、dfx identity get-principal
の出力を使用します。私の Principal が tsqwz-udeik-5migd-ehrev-pvoqv-szx2g-akh5s-fkyqc-zy6q7-snav6-uqe
で、 2.3 ICPを Cycle に変換したい場合、コマンドは以下のようになります:
dfx ledger --network ic create-canister tsqwz-udeik-5migd-ehrev-pvoqv-szx2g-akh5s-fkyqc-zy6q7-snav6-uqe --amount 2.3
このコマンドは少し時間がかかり、次のようなものが出力されます:
Transfer sent at BlockHeight: 351220
Canister created with id: "gastn-uqaaa-aaaae-aaafq-cai"
この出力にある ID は、あなたのウォレットの Canister アドレスです。この例では、gastn-uqaaa-aaaae-aaafq-cai
となります。
これで Canister が作成されたので、このコマンドを使用してウォレットコードをインストールすることができます:
dfx identity --network ic deploy-wallet <canister-identifer>
ここでは、前のコマンドの出力で受け取った ID を使用して、Canister の識別子を代入する必要があります。つまり、この例では次のようになります:
dfx identity --network ic deploy-wallet gastn-uqaaa-aaaae-aaafq-cai
そして、このような出力になるはずです:
Creating a wallet canister on the IC network.
The wallet canister on the "ic" network for user "default" is "gastn-uqaaa-aaaae-aaafq-cai"
これで、ウォレットの設定が完了し、使用できるようになりました。すべてがうまくいったかどうかを確認するには、以下を実行して、設定したウォレットの識別子を確認します:
dfx identity --network ic get-wallet
これで、先ほどのコマンドで使用した Canister ID が表示されるはずです。
また、新しい Cycle ウォレットの残高を確認することもできます:
dfx wallet --network ic balance
これで、次のようなものが表示されるはずです:
6.951 TC (trillion cycles).
5. オンチェーン・デプロイ(1分)
Cycle と dfx
が Cycle を転送するように設定されたので、hello
Dapp をオンチェーンにデプロイする準備ができています。ターミナル B で、以下を実行します:
npm install
dfx deploy --network ic --with-cycles 1000000000000
—network
オプションは、Dapp をデプロイするためのネットワークエイリアスまたは URL を指定します。このオプションは、Internet Computer のブロックチェーンメインネットにインストールするために必要です。—with-cycles
は dfx
に使用する Cycle 数を明示的に指定します。そうでなければ、デフォルトの3兆 Cycle が使用されます。
成功すると、ターミナルはこのようになります:
Deploying all canisters.
Creating canisters...
Creating canister "hello_backend"...
"hello_backend" canister created on network "ic" with canister id: "5o6tz-saaaa-aaaaa-qaacq-cai"
Creating canister "hello_frontend"...
"hello_frontend" canister created on network "ic" with canister id: "5h5yf-eiaaa-aaaaa-qaada-cai"
Building canisters...
Building frontend...
Installing canisters...
Installing code for canister hello_backend, with canister_id 5o6tz-saaaa-aaaaa-qaacq-cai
Installing code for canister hello_frontend, with canister_id 5h5yf-eiaaa-aaaaa-qaada-cai
Authorizing our identity (default) to the asset canister...
Uploading assets to asset canister...
/index.html 1/1 (472 bytes)
/index.html (gzip) 1/1 (314 bytes)
/index.js 1/1 (260215 bytes)
/index.js (gzip) 1/1 (87776 bytes)
/main.css 1/1 (484 bytes)
/main.css (gzip) 1/1 (263 bytes)
/sample-asset.txt 1/1 (24 bytes)
/logo.png 1/1 (25397 bytes)
/index.js.map 1/1 (842511 bytes)
/index.js.map (gzip) 1/1 (228404 bytes)
/index.js.LICENSE.txt 1/1 (499 bytes)
/index.js.LICENSE.txt (gzip) 1/1 (285 bytes)
Deployed canisters.
URLs:
Frontend:
hello_frontend: https://5h5yf-eiaaa-aaaaa-qaada-cai.ic0.app/
Candid:
hello_backend: https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.ic0.app/?id=5o6tz-saaaa-aaaaa-qaacq-cai
メッセージの一番下に、Canister のフロントエンドがオンチェーンにデプロイされているのを見ることができる URL が返されることに注意してください:https://5h5yf-eiaaa-aaaaa-qaada-cai.ic0.app/
上記の例では、hello
という Dapp を作成し、以下を構成しています:
hello_backend
Canister、5o6tz-saaaa-aaaaa-qaacq-cai
バックエンドロジックを含みます。hello_frontend
Canister、5h5yf-eiaaa-aaaaa-qaada-cai
フロントエンドのアセット(HTML、JS、CSSなど)を含みます。
ブラウザで デプロイされた Dapp オンチェーンを確認する
こちらに移動し、名前を入力します:https://5h5yf-eiaaa-aaaaa-qaada-cai.ic0.app/
Dapp がロードされる前に、ブラウザにはすぐに次のようなメッセージが表示されます。Installing "Internet Computer Validating Service Worker “ この service worker は IC から来るもので、ユーザーが見る Web アプリが改ざんされていない正しいフロントエンドであることを確認するために使用されます。一度読み込まれると、ブラウザはサービスワーカーをキャッシュし、Web アプリはより速く読み込まれるようになります。
サービスワーカーをロードした後、Dapp がロードされます:
コマンドラインからオンチェーン Dapp をテストする
Canister には greet
というメソッド(パラメータとして文字列を受け取ります)があるので、dfx
を介してメッセージを送ることができます:
dfx canister --network ic call hello_backend greet '("everyone": text)'
メッセージの構成に注目してください:
dfx canister --network ic call
は IC 上の Canister を呼び出すためのセットアップです。hello_backend greet
は、hello
という名前の Canister にメッセージを送信し、そのgreet
メソッドを呼び出すことを意味します。これは、hello
とCanister ID のマッピングがローカルの.dfx/local/canister_ids.json
に保存されているためです。'("everyone": text)'
はgreet
に送るパラメータです (このパラメータはText
を唯一の入力として受け取ります)。
トラブルシューティング
403 Error
403 Error が表示される場合、使用している ID に十分な Cycle がない可能性があります。デバッグのために以下を試してみてください:
1. あなたが想定している ID を使用していることを確認する
dfx identity whoami
2. 使用する ID がオンチェーンに十分な Cycle を有していることを確認する
dfx wallet --network ic balance
3. ウォレット経由のプロキシを試す
時々(特に0.9.0より前のバージョンの dfx
で Canister を作成した場合)あなたのウォレットが Canister のコントローラとして設定されていることがあります。あなたのウォレットをデプロイ命令のソースにするには、デプロイコマンドまたはコールコマンドに --wallet <insert-your-wallet-id-here>
というフラグを追加してください。
これがうまくいって、自分の Principal を Canister のコントローラとして追加したい場合(そうすれば、もう --wallet
オプションを使う必要はありません)、次のように実行できます:
dfx canister --wallet "$(dfx identity get-wallet)" update-settings --all --add-controller "$(dfx identity get-principal)"
完成
おめでとうございます。あなたは10分以内に完全にオンチェーン(バックエンドとフロントエンドの両方)の Dapp を構築しました。
チュートリアルの要約
- Dapps は複数の Canister で構成することができます。
- Dapps はローカルにもオンチェーンにもデプロイできます。
- Dapps を動かすには Cycle が必要です。
- Cycle ウォレットから無料 Cycle を取得します。
- 無料 Cycle を使って Dapps を追加することができます。
原点に立ち返る
ゼロから始める場合は、SDK と関連するプロファイルを削除して、再インストールしてください。こちらの手順に従ってください。SDK のインストール
Dapps や ICP に紐づく ID は必ず保存してください。
困ったときは?
もし、問題が発生した場合は、開発者フォーラムや Discord で解決策を探したり、質問を投稿してください。
次の挑戦の準備はできていますか?
DAO や NFT などの構築などさらに進むには こちら。
もっと詳しく知りたい方は?
始める前にもっと情報を知りたい、自分で試す前にデプロイ方法のデモを見たい、という方は、以下の関連リソースをご覧ください: