♾️

【Internet Computer】メインネットにアプリをデプロイする方法

2025/02/24に公開

本記事では、Internet Computer(ICP)のメインネットにアプリをデプロイする手順を紹介します。
今回題材にするアプリはdfx newで生成されるhelloアプリです。そもそもアプリの作り方を知りたいという方はまずはこちらの記事からご覧ください。
https://zenn.dev/taka101/articles/d1f413a48a2e1f

事前準備1: ウォレットの設定

ICPを初めて扱う場合は、まずICPに対応したウォレットを設定する必要があります。こちらのページから利用可能なウォレットを確認することができます。
https://internetcomputer.org/docs/current/developer-docs/defi/wallets/overview#third-party-custody
私はPlugを利用しました。ブラウザに拡張機能をインストールしてすぐに利用開始することができます。

事前準備2: cycleの入手

cycleとは各種処理で消費されるリソースの単位です。EthereumのGasのようなものです。メインネットへのデプロイ時にもcycleを消費するためアカウントに準備する必要があります。

ここでは公式ドキュメントのOption Bの方法に従って用意します。

ICPトークンの入手

まずは準備1で作成したPlugのアカウントにICPトークンを用意します。方法はさまざまありますが、Polygonチェーンに少量のPOLと数千円程度のUSDC.eが残っていたため、SimpleSwapを利用してUSDC.eをICPトークンに変換しました。19ドル分の変換に1ドル程度の手数料がかかりました。(変換の最低量が18ドル少々だったため19ドルとしました。)

開発アカウントへのICPトークンの送金

次にデプロイなどを行うアカウントにICPトークンを送ります。helloアプリのフォルダのルート階層で次のコマンドを実行すると開発アカウントのIDが表示されます。

dfx ledger account-id

Plugを開き、上記のコマンド実行結果として表示されたアカウントIDにICPトークンを送金します。私は合計1.3ICPを送りました。

送金完了後、次のコマンドを実行するとICPが増えていることが確認できます。

❯ dfx ledger --network ic balance
0.30000000 ICP

ICPトークンをcycleに変換

次のコマンドを実行してICPトークンをcycleに変換します。以下の例は0.1ICPを変換する場合のコマンドです。

❯ dfx cycles convert --amount 0.1 --network ic
Transfer sent at block height 20698244
Using transfer at block height 20698244
Account was topped up with 542_900_000_000 cycles! New balance is 542_800_000_000 cycles.

これで準備完了です。

メインネットへデプロイ

メインネットへのデプロイは前回の記事で紹介したローカル環境へのデプロイと同様にdfx deploy --network icを実行するだけですが、案の定(?)失敗してしまいました。

❯ dfx deploy --network ic
Deploying all canisters.
Creating canisters...
Creating canister hello_backend...
created-at-time for canister hello_backend is 1740286230054562000.
Error: Failed while trying to deploy canisters.
Caused by: Failed while trying to register all canisters.
Caused by: Failed to create canister 'hello_backend'.
Caused by: Failed to create canister via cycles ledger.
Caused by: Insufficient funds. Current balance: 542800000000

cycleが足りていないと言われていそうですが、勉強も兼ねてdfx deployで行われる処理を1つずつ行っていきます。
dfx deployの処理内容は前回の記事で紹介しています。)

dfx canister create

まずはcanisterを作るところからですが、-allでまとめて作ろうとすると失敗しました。

❯ dfx canister create --all --network ic
Creating canister hello_backend...
created-at-time for canister hello_backend is 1740286283529272000.
Error: Failed to create canister 'hello_backend'.
Caused by: Failed to create canister via cycles ledger.
Caused by: Insufficient funds. Current balance: 542800000000

5000億余りのcycleを用意しているにもかかわらずcycleが足りていないと言われています。調べてみると、canister作成時にはデプロイにかかる手数料とそのcanisterが保有するcycleの初期値分が必要とのことでした。canisterが保有するcycleの初期値は--with-cyclesで指定できるそなのでひとまず10億cycleを指定してみましたが相変わらず失敗。「38,461,538,461(約400億)のcycleが必要」とのこと。

❯ dfx canister create --all --with-cycles 1_000_000_000
Creating canister hello_backend...
Error: Failed to create canister 'hello_backend'.
Caused by: The  wallet operation failed: An error happened during the call: 4: **Creating a canister requires a fee of 38_461_538_461 that is deducted from the canister's initial balance** but only 1_000_000_000 cycles were received with the create_canister request.
Try sending more cycles with the request. See documentation: http://internetcomputer.org/docs/current/references/execution-errors#create-canister-not-enough-cycles

しかし、アカウントは5000億cycleと400億以上保有しています。なぜ作成できないのか不思議に思い、一旦ローカル環境で--with-cyclesの指定が無い場合にcanisterのcycleの初期値がどの程度になっているか確認をしてみました。その結果、3兆cycle(Balance: 3_061_312_801_134 Cycles)も補充されていることがわかりました。

❯ dfx canister status hello_backend
Canister status call result for hello_backend.
Status: Running
Controllers: bnz7o-iuaaa-aaaaa-qaaaa-cai nvvvk-qgaio-3o43d-66epz-7kjue-mrijc-nohyw-e3urc-kzsba-uv3s7-6ae
Memory allocation: 0
Compute allocation: 0
Freezing threshold: 2_592_000
Idle cycles burned per day: 1_264_554
Memory Size: Nat(1608656)
Balance: 3_061_312_801_134 Cycles
Reserved: 0 Cycles
Reserved cycles limit: 5_000_000_000_000 Cycles
Wasm memory limit: 3_221_225_472 Bytes
Module hash: 0x7da3640b122e63f205df9c40d8249535ad272ce923f02fbf4c2fb1648b27b3f2
Number of queries: 0
Instructions spent in queries: 0
Total query request payload size (bytes): 0
Total query response payload size (bytes): 0
Log visibility: controllers

もう少し節約したいので適当に初期値には5000億cycleを指定してhello_frontend用のcanisterの作成を実行してみたところ、無事に作成されました。

❯ dfx canister create hello_frontend --with-cycles 500_000_000_000 --networ
k ic
Creating canister hello_frontend...
created-at-time for canister hello_frontend is 1740288092961811000.
hello_frontend canister created on network ic with canister id: xsxuh-ryaaa-aaaal-qsioq-cai

こちらはICP Dashboardの画面です。デプロイしたidのcanisterが表示されています。
https://dashboard.internetcomputer.org/canister/xsxuh-ryaaa-aaaal-qsioq-cai

同様にhello_backend用のcanisterも作成。

❯ dfx canister create hello_backend --with-cycles 500_000_000_000 --network ic
Creating canister hello_backend...
created-at-time for canister hello_backend is 1740288277293037000.
hello_backend canister created on network ic with canister id: x3u73-hqaaa-aaaal-qsipa-cai

https://dashboard.internetcomputer.org/canister/x3u73-hqaaa-aaaal-qsipa-cai

dfx build

ようやくcanisterの作成が完了したので次はbuildします。buildは問題なく成功しました。

❯ dfx build --network ic
Building canisters...
Checking for vulnerabilities in rust canisters.
    Fetching advisory database from `https://github.com/RustSec/advisory-db.git`
      Loaded 733 security advisories (from /Users/taka/.cargo/advisory-db)
    Updating crates.io index
    Scanning Cargo.lock for vulnerabilities (77 crate dependencies)
Audit found no vulnerabilities.
Executing: cargo build --target wasm32-unknown-unknown --release -p hello_backend --locked
    Finished `release` profile [optimized] target(s) in 0.37s
Building frontend...
WARN: Generating type declarations for canister hello_frontend:
  /Users/taka/icp-sandbox/hello/src/declarations/hello_frontend/hello_frontend.did.d.ts
  /Users/taka/icp-sandbox/hello/src/declarations/hello_frontend/hello_frontend.did.js
  /Users/taka/icp-sandbox/hello/src/declarations/hello_frontend/hello_frontend.did
Generating type declarations for canister hello_backend:
  /Users/taka/icp-sandbox/hello/src/declarations/hello_backend/hello_backend.did.d.ts
  /Users/taka/icp-sandbox/hello/src/declarations/hello_backend/hello_backend.did.js
  /Users/taka/icp-sandbox/hello/src/declarations/hello_backend/hello_backend.did
DEPRECATION WARNING [legacy-js-api]: The legacy JS API is deprecated and will be removed in Dart Sass 2.0.0.

More info: https://sass-lang.com/d/legacy-js-api

npm notice
npm notice New major version of npm available! 10.8.2 -> 11.1.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v11.1.0
npm notice To update run: npm install -g npm@11.1.0
npm notice

dfx canister install

作成したcanisterにインストールを行います。ひとまず -all で試してみましたがやはり失敗してしまいました。

❯ dfx canister install --all --network ic
Installing code for canister hello_backend, with canister ID x3u73-hqaaa-aaaal-qsipa-cai
Error: Failed to install wasm module to canister 'hello_backend'.
Caused by: Failed during wasm installation call
Caused by: The replica returned a rejection error: reject code SysTransient, reject message Canister x3u73-hqaaa-aaaal-qsipa-cai is out of cycles: please top up the canister with at least 989_455_530 additional cycles, error code Some("IC0207")

まずはhello_backendからインストールを行なっていきます。1つ前のコマンドの結果をみるとcycleが足りていないということだったので、10億cycle補充します。

❯ dfx cycles top-up x3u73-hqaaa-aaaal-qsipa-cai 1_000_000_000 --network ic
Transfer sent at block index 1_930_102

相変わらずcycleが足りないと言われます。

❯ dfx canister install hello_backend --network ic
Installing code for canister hello_backend, with canister ID x3u73-hqaaa-aaaal-qsipa-cai
Error: Failed to install wasm module to canister 'hello_backend'.
Caused by: Failed during wasm installation call
Caused by: The replica returned a rejection error: reject code SysTransient, reject message Canister installation failed with `Canister x3u73-hqaaa-aaaal-qsipa-cai is out of cycles: please top up the canister with at least 299_994_455_530 additional cycles`.
Top up the canister with more cycles. See documentation: https://internetcomputer.org/docs/current/references/execution-errors#install-code-not-enough-cycles, error code None

追加で1ICPをcycleに変換し、3000億cycleをhello_backend用canisterに補充。

❯ dfx cycles top-up x3u73-hqaaa-aaaal-qsipa-cai 300_000_000_000 --network i
c
Transfer sent at block index 1_930_135

ようやくインストールに成功しました。

❯ dfx canister install hello_backend --network ic
Installing code for canister hello_backend, with canister ID x3u73-hqaaa-aaaal-qsipa-cai

続いてhello_frontendのインストールです。
hello_frontendもcycleが足りないと言われるので、多めに4000億cycle補充します。

❯ dfx canister install hello_frontend --network ic
Installing code for canister hello_frontend, with canister ID xsxuh-ryaaa-aaaal-qsioq-cai
Error: Failed to install wasm module to canister 'hello_frontend'.
Caused by: Failed during wasm installation call
Caused by: The replica returned a rejection error: reject code SysTransient, reject message Canister xsxuh-ryaaa-aaaal-qsioq-cai is out of cycles: please top up the canister with at least 801_485_530 additional cycles, error code Some("IC0207")

❯ dfx cycles top-up xsxuh-ryaaa-aaaal-qsioq-cai 400_000_000_000 --network i
Transfer sent at block index 1_930_150

canisterの状態はdfx canister statusコマンドで取得できます。残高が4000億になっていることが確認できました。

❯ dfx canister status hello_frontend --network ic
Canister status call result for hello_frontend.
Status: Running
Controllers: nvvvk-qgaio-3o43d-66epz-7kjue-mrijc-nohyw-e3urc-kzsba-uv3s7-6ae
Memory allocation: 0
Compute allocation: 0
Freezing threshold: 2_592_000
Idle cycles burned per day: 1_451
Memory Size: Nat(142)
Balance: 399_998_684_000 Cycles
Reserved: 0 Cycles
Reserved cycles limit: 5_000_000_000_000 Cycles
Wasm memory limit: 3_221_225_472 Bytes
Module hash: None
Number of queries: 0
Instructions spent in queries: 0
Total query request payload size (bytes): 0
Total query response payload size (bytes): 0
Log visibility: controllers

再度インストールのコマンドを実行したところ、次は違うエラーが発生。

❯ dfx canister install hello_frontend --network ic
Installing code for canister hello_frontend, with canister ID xsxuh-ryaaa-aaaal-qsioq-cai
Uploading assets to asset canister...
WARN: This project does not define a security policy for some assets.
WARN: You should define a security policy in .ic-assets.json5. For example:
WARN: [
WARN:   {
WARN:     "match": "**/*",
WARN:     "security_policy": "standard"
WARN:   }
WARN: ]
WARN: Assets without any security policy: all
WARN: To disable the policy warning, define "disable_security_policy_warning": true in .ic-assets.json5.
Fetching properties for all assets in the canister.
Done fetching properties for all assets in the canister. Took 28.408µs
Starting batch.
Staging contents of new and changed assets in batch 1:
  /favicon.ico 1/1 (15406 bytes) sha 4e8d31b50ffb59695389d94e393d299c5693405a12f6ccd08c31bcf9b58db2d4 (with 7 headers)
  /index.html 1/1 (417 bytes) sha dbc0eae3c34b65f402b1ebadaa69174b8d1c5a3a27da448627bc897f652bcb98 (with 7 headers)
  /index.html (gzip) 1/1 (281 bytes) sha 62fa3c6e8481776cd159b35e121ed570c71f459b5b14786c7019da627f32bc77 (with 7 headers)
  /assets/index-2a8a0c6e.css 1/1 (386 bytes) sha 2a8a0c6efd388558fb59f2c3bcbf755c959b07d513139f8056b25b19a2d89de5 (with 7 headers)
  /assets/index-2a8a0c6e.css (gzip) 1/1 (264 bytes) sha 5cd712f8526579207fc695820665f333f77a1e562eae4693c282ef28d9c69b74 (with 7 headers)
  /logo2.svg 1/1 (15139 bytes) sha 037eb7ae523403daa588cf4f47a34c56a3f5de08a5a2dd2364839e45f14f4b8b (with 7 headers)
  /assets/index-7b8baca6.js 1/1 (406930 bytes) sha a2ab7352ea4234e0c2a293dc1f0c25119628a4467ee00ffd106cf440764442c6 (with 7 headers)
  /assets/index-7b8baca6.js (gzip) 1/1 (132798 bytes) sha 26c17265a82cd3a6694902a1883f32029ef9225a79699ae24685682590b61704 (with 7 headers)
Committing batch.
Committing batch with 13 operations.
Error: Failed to install wasm module to canister 'hello_frontend'.
Caused by: Failed to store assets in canister 'hello_frontend'.
Caused by: Failed asset sync with canister xsxuh-ryaaa-aaaal-qsioq-cai.
Caused by: Failed to commit batch: The replica returned a rejection error: reject code CanisterError, reject message Requested canister has no wasm module, error code Some("IC0537")

canisterがwasm moduleを持っていないというエラーが発生しているので、--mode reinstallをつけて再度実行。「データが失われるが問題ないか?」にはyesと回答し、無事にインストールが完了しました。

❯ dfx canister install hello_frontend --network ic --mode reinstall
Reinstalling code for canister hello_frontend, with canister ID xsxuh-ryaaa-aaaal-qsioq-cai
WARNING!
You are about to reinstall the hello_frontend canister
This will OVERWRITE all the data and code in the canister.

YOU WILL LOSE ALL DATA IN THE CANISTER.


Do you want to proceed? yes/No
yes
Uploading assets to asset canister...
WARN: This project does not define a security policy for some assets.
WARN: You should define a security policy in .ic-assets.json5. For example:
WARN: [
WARN:   {
WARN:     "match": "**/*",
WARN:     "security_policy": "standard"
WARN:   }
WARN: ]
WARN: Assets without any security policy: all
WARN: To disable the policy warning, define "disable_security_policy_warning": true in .ic-assets.json5.
Fetching properties for all assets in the canister.
Done fetching properties for all assets in the canister. Took 27.492µs
Starting batch.
Staging contents of new and changed assets in batch 1:
  /favicon.ico 1/1 (15406 bytes) sha 4e8d31b50ffb59695389d94e393d299c5693405a12f6ccd08c31bcf9b58db2d4 (with 7 headers)
  /index.html 1/1 (417 bytes) sha dbc0eae3c34b65f402b1ebadaa69174b8d1c5a3a27da448627bc897f652bcb98 (with 7 headers)
  /index.html (gzip) 1/1 (281 bytes) sha 62fa3c6e8481776cd159b35e121ed570c71f459b5b14786c7019da627f32bc77 (with 7 headers)
  /assets/index-7b8baca6.js 1/1 (406930 bytes) sha a2ab7352ea4234e0c2a293dc1f0c25119628a4467ee00ffd106cf440764442c6 (with 7 headers)
  /assets/index-7b8baca6.js (gzip) 1/1 (132798 bytes) sha 26c17265a82cd3a6694902a1883f32029ef9225a79699ae24685682590b61704 (with 7 headers)
  /assets/index-2a8a0c6e.css 1/1 (386 bytes) sha 2a8a0c6efd388558fb59f2c3bcbf755c959b07d513139f8056b25b19a2d89de5 (with 7 headers)
  /assets/index-2a8a0c6e.css (gzip) 1/1 (264 bytes) sha 5cd712f8526579207fc695820665f333f77a1e562eae4693c282ef28d9c69b74 (with 7 headers)
  /logo2.svg 1/1 (15139 bytes) sha 037eb7ae523403daa588cf4f47a34c56a3f5de08a5a2dd2364839e45f14f4b8b (with 7 headers)
Committing batch.
Committing batch with 13 operations.

デプロイしたアプリのURLもコマンドで確認できます。

# フロントエンド
❯ dfx canister url hello_frontend --network ic
https://xsxuh-ryaaa-aaaal-qsioq-cai.icp0.io/

# バックエンド
❯ dfx canister url hello_backend --network ic
https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=x3u73-hqaaa-aaaal-qsipa-cai

完成

というわけで、今回デプロイしたアプリのURLはこちらです。前回の記事でローカル環境で構築したサイトが確認できました。
https://xsxuh-ryaaa-aaaal-qsioq-cai.icp0.io/

また、バックエンドはCandid UIと呼ばれるインターフェース経由でアクセスすることができます。メソッドだけを試したい時などにはとても便利ですね。
https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=x3u73-hqaaa-aaaal-qsipa-cai

試行錯誤の過程も載せたため長くなりましたが、慣れればとても簡単にデプロイできると思います。皆様もぜひお試しください。

Discussion