initia-appchain-dev について
initia-appchain-devは、コントラクト、フロントエンド連携、アプリチェーン運用を扱うInitia開発向けスキルです。VMやネットワークなどを先に確認し、環境構築から実装上の制約、検証まで案内します。
主な機能
- 01作業前にチェーンとVMを確認
- 02MOVE、EVM、WASMの環境構築を案内
- 03コントラクト、フロントエンド、運用を網羅
- 04Initiaフロントエンド連携の制約を提示
- 05ツールとVM別バイナリを検証
活用シーン
- 01VMに応じた開発環境の構築
- 02Initiaのチェーン情報を使ったフロントエンド連携
- 03既存アプリチェーンの起動やデバッグ
- 04デプロイやトランザクション実装の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ initia-labs/ agent-skills --skill initia-appchain-devインストール後、Claude Code で/initia-appchain-devを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/common-tasks.mdcontracts.mde2e-recipes.mdfrontend-evm-rpc.mdfrontend-interwovenkit.mdruntime-discovery.mdtroubleshooting.mdweave-commands.mdweave-config-schema.mdscripts/bech32_utils.pycheck-provider-setup.shconvert-address.pyfund-user.shgenerate-system-keys.pyinstall-tools.shlint-tags.shrequirements.txtscaffold-contract.shscaffold-frontend.shto_hex.pyverify-appchain.sh詳細
Initia Appchain 開発
コントラクト、フロントエンド連携、アプリチェーンの運用に関する、実践的な Initia 開発ガイダンスを提供します。
このファイルのコマンド例では、作業ディレクトリが skill/ であることを前提としています。それに応じて scripts/... のパスを使用してください。
初回確認の質問(最初に確認)
実装に着手する前に、不足している入力情報を確認します。
- 必要な VM はどれですか(
evm、move、wasm)? - 対象のネットワークはどれですか(
testnetまたはmainnet)? - 新規ロールアップの起動ですか、それとも既存ロールアップの運用/デバッグですか?
- フロントエンドの作業では、EVM JSON-RPC アプリと InterwovenKit ウォレット/ブリッジアプリのどちらを使用しますか?
- チェーン固有の値(
chain_id、RPC URL、デプロイ済みコントラクトのアドレス、denom)は分かっていますか?
重要な値が不足している場合は、最終的なコード/設定を生成する前に、簡潔な追加質問をしてください。
chain_id/エンドポイント/VM が不明な場合は、デフォルト値を仮定する前に references/runtime-discovery.md の検出フローを実行してください。
weave がインストール済みでも、シェルレベルのエラーで動作しない場合は、weave に固執せず、~/.minitia/artifacts/config.json と minitiad の直接コマンドを使って検出を続けてください。
続いて、状況に応じた確認を行います。
- フロントエンドの作業:「ローカルのロールアップ設定/ランタイムが見つかりました。このロールアップをフロントエンド連携に使用しますか?」
- フロントエンド以外の作業:「ローカルのランタイム値(VM、チェーン ID、エンドポイント)が見つかりました。今回の作業にこれらを使用しますか?」
環境セットアップのワークフロー(1 回のプロンプトでセットアップ)
ユーザーから「[Track] トラック用に環境をセットアップして」と依頼された場合(ステップ 5)は、次の手順を実行します。
1. トラックの要件と前提条件を特定する
- [MOVE] トラック:
minimoveリポジトリ →minitiad。goが必要です。 - [EVM] トラック:
minievmリポジトリ →minitiad。goとfoundryが必要です。 - [WASM] トラック:
miniwasmリポジトリ →minitiad。goとrust/cargoが必要です。
2. システムの前提条件を確認する
選択されたトラックに応じて前提条件を確認します(ツールインストーラーとの互換性を確保するため、必ず docker も確認してください)。
- [MOVE] トラック:
go、docker - [EVM] トラック:
go、docker、foundry - [WASM] トラック:
go、docker、cargo
選択されたトラックで必要な各ツールについて、次のように対応します。
- 不足している場合: ユーザーに伝え、インストールコマンドを提案します(例:「Cargo が見つかりません。
rustupを使ってインストールしますか?」)。 - インストール済みの場合: 何も伝えずに先へ進みます。
3. Initia のコアツールをインストールする
jq、weave、initiad(L1)をインストールするため、scripts/install-tools.sh を実行します。
- セキュリティ: スクリプトで
sudoが必要な場合は、実行前にユーザーに説明してください。 - 必要なツールがすでにある場合は、再インストールよりもバージョンの確認を優先してください。指定バージョンを使用するインストーラーのバージョンは、マシンにすでにインストールされているバージョンより古い場合があります。
4. VM 固有のバイナリ(minitiad)をビルドする
ソースから該当する VM をクローン、ビルドし、クリーンアップします。
ビルドはリポジトリのディレクトリ内から実行してください。実行環境によって作業ディレクトリが別々に管理される場合があるため、cd ... && make install のようにシェルコマンドを連結した例に依存しないでください。
- [MOVE]:
git clone --depth 1 https://github.com/initia-labs/minimove.git /tmp/minimove cd /tmp/minimove make install rm -rf /tmp/minimove - [EVM]:
git clone --depth 1 https://github.com/initia-labs/minievm.git /tmp/minievm cd /tmp/minievm make install rm -rf /tmp/minievm - [WASM]:
git clone --depth 1 https://github.com/initia-labs/miniwasm.git /tmp/miniwasm cd /tmp/miniwasm make install rm -rf /tmp/miniwasm
5. PATH を設定する
~/go/binがユーザーのPATHに含まれていることを確認します。- シェル設定ファイル(
.zshrc、.bashrc)を確認し、設定がない場合はexportコマンドを提案します。 - シェル設定を更新したら、現在のシェルに変更を反映するため、
source ~/.zshrcを実行する(または新しいターミナルを開く)ようユーザーに伝えてください。 - 確認のために、
zsh -lc 'source ~/.zshrc && <command>'を 1 つのコマンドとして実行できます。ただし、これは別々のアシスタントコマンド間では反映されません。
6. 最終確認
次を実行します。
weave versioninitiad versionminitiad version --long | rg '^(name|server_name|version|commit):'
必要な VM の一致:
- [EVM] トラック:
name: minievm - [MOVE] トラック:
name: minimove - [WASM] トラック: 報告された
nameがビルドした Wasm VM と一致することを確認します
minitiad version コマンドが成功しただけでは、確認として不十分です。PATH 上のバイナリが、別の VM トラックのものである可能性があります。
推奨するデフォルト設定
| 項目 | デフォルト | 備考 |
|---|---|---|
| VM | evm | 指定された場合に限り、move/wasm を使用します |
| Move のバージョン | 2.1 | minitiad move build を使用します。特定のコンパイラバージョンで必要な場合を除き、Move.toml から edition を省略することを推奨します。 |
| ネットワーク | testnet | 明示的に指定された場合に限り、mainnet を使用します |
| フロントエンド(EVM VM) | wagmi + viem JSON-RPC | 純粋な EVM アプリのデフォルトです |
| フロントエンド(Move/Wasm) | @initia/interwovenkit-react | InterwovenKit の機能が必要な場合に使用します |
| トランザクションの UX | requestTxBlock | 確認 UX を推奨します。ローカル開発での堅牢性を高めるには、requestTxSync を使用します。 |
| プロバイダーの順序 | Wagmi -> Query -> InterwovenKit | Initia SDK の安定した構成です |
| ロールアップの DA | INITIA | 明示的に必要な場合に限り、Celestia を推奨します |
| キーとキーリング | gas-station / test | ハッカソン用ツールでは、デフォルトのキーと --keyring-backend test を使用します |
| デノム | GAS(EVM)/ umin(Move) | テスト用/内部用ロールアップで一般的なデフォルトです |
厳格な制約(絶対に違反しないこと)
タグ付け規則
- VM 固有のガイダンスには、VM を先頭にしたタグを使用します:[EVM]、[MOVE]、[WASM]、[ALL-VM]。
- VM の後には、任意のコンテキストタグを追加します:[CLI]、[DEV]、[REST]、[RPC]、[FRONTEND]、[INTERWOVENKIT]、[BUILD]、[TEST]。
- 複合タグ(例:[EVM CLI])は避け、タグを連ねる形式(例:[EVM][CLI])を推奨します。
- スキルの Markdown を編集する際は、必ず次のワークフローに従ってください。変更前に
scripts/lint-tags.shを実行し、引き渡し前に再度実行します。
Initia ユーザー名(明示的な要望がある場合のみ)
- 「ユーザー名サポートを追加」のように明示的に要求されない限り、スキャフォールド、コンポーネント、コードスニペットにユーザー名サポートを実装してはなりません。
- 要求された場合、接続中のウォレット自身の表示名にのみ
useInterwovenKit().usernameを使用します。 - パターン:
{username ? username : shortenAddress(initiaAddress)} - 任意のウォレットアドレスのユーザー名(例:MemoBoard の送信者行)を解決するには、送信者のアドレスを指定して
useUsernameQuery(address?)を使用します。これには@initia/interwovenkit-react2.4.6以降が必要です。 - フィード、ボード、その他メッセージ/アカウントを表示するリストでは、子の行コンポーネント(例:
MessageRow)内で送信者のユーザー名を解決し、そこでuseUsernameQuery(address)を呼び出します。親コンポーネントの.map()コールバック内や条件付きループの本体でフックを直接呼び出してはなりません。 - フックによる解決では不十分な場合を除き、REST 経由で解決してはなりません。
useUsernameQueryの動作:- 引数なし:接続中のウォレットアドレスを解決します(
useAddress()にフォールバック)。 - 引数あり:指定されたアドレスを解決します。
- 引数なし:接続中のウォレットアドレスを解決します(
ワークスペースのクリーンアップ(重要)
- タスク完了後、プロジェクトディレクトリに一時ファイルやメタデータ JSON ファイル(例:
store_tx.json、tx.json、.bin)を残してはなりません。 - 完了前に、デプロイに使用したバイナリファイルを削除してください。
InterwovenKit ローカルアプリチェーン(重大)
- ローカルアプリチェーン用のフロントエンドを設定する場合、
InterwovenKitProviderではcustomChainとcustomChains: [customChain]の両方のプロパティを使用する必要があります。 - 使用例:
<InterwovenKitProvider {...TESTNET} customChain={customChain} customChains={[customChain]} > <App /> </InterwovenKitProvider> - ブリッジのサポート:ブリッジで
initiation-2などのパブリックチェーンを解決できるようにするには、@initia/interwovenkit-reactからインポートした{...TESTNET}プリセットを必ずInterwovenKitProviderに展開してください:<InterwovenKitProvider {...TESTNET} ... />。 - アドレスプレフィックス:
customChainにはトップレベルのbech32_prefix文字列(例:bech32_prefix: "init")を必ず含めてください。これはすべてのアプリチェーンタイプで必須です。 - メタデータの完全性:「Chain not found」エラーを避けるため、
customChainオブジェクトにはnetwork_type: 'testnet'、staking、(low/average/high_gas_price: 0を含む)fees、およびnative_assets配列を必ず含めてください。 - API の要件:キットの検出ロジックを満たすため、
apisオブジェクトにはrpc、rest、およびindexerを必ず含めてください(必要に応じてプレースホルダーを使用してください)。 - ブリッジのサポート(openBridge):
openBridgeを使用する場合は、srcChainIdとsrcDenom(例:initiation-2とuinit)のみを指定してください。ローカルチェーンがまだインデックスされていない場合に解決エラーが発生する可能性があるため、ローカルのdstChainIdは指定しないでください。 customChainの構造例:const customChain = { chain_id: '<INSERT_APPCHAIN_ID_HERE>', chain_name: '<INSERT_APP_NAME_HERE>', network_type: 'testnet', // MANDATORY bech32_prefix: 'init', apis: { rpc: [{ address: 'http://localhost:26657' }], rest: [{ address: 'http://localhost:1317' }], indexer: [{ address: 'http://localhost:8080' }], // MANDATORY 'json-rpc': [{ address: 'http://localhost:8545' }], }, fees: { fee_tokens: [{ denom: 'umin', fixed_min_gas_price: 0, low_gas_price: 0, average_gas_price: 0, high_gas_price: 0 }] }, staking: { staking_tokens: [{ denom: 'umin' }] }, native_assets: [{ denom: 'umin', name: 'Token', symbol: 'TKN', decimals: 6 }], metadata: { is_l1: false, minitia: { type: 'minimove' } } }
フロントエンドの要件(重大)
- プレースホルダーの同期:フロントエンドのスキャフォールディング直後に、
main.jsx内のすべてのプレースホルダー(<INSERT_APPCHAIN_ID_HERE>、<INSERT_NATIVE_DENOM_HERE>など)を、調査フェーズで確認した実際の値(例:bank-1、GAS、minievm)に必ず更新してください。 - ランタイム設定の同期:フロントエンドがデプロイ済みのコントラクトアドレスに依存する場合、プレースホルダーや例だけを残さず、解決済みの実アドレスをランタイム設定(例:
.env/VITE_*)に必ず反映してください。Move 固有の API とコードでは、区別が重要な場合はmodule addressという用語を維持してください。実行中の Vite アプリの.envの値を追加または変更した場合は、開発サーバーの再起動が必要であることをユーザーに伝えてください。 - フックのエクスポート:
useInterwovenKitはinitiaAddress、address、username、openConnect、openWallet、openBridge、requestTxBlock、requestTxSync、およびautoSignをエクスポートします。 - トランザクションのガード:
requestTxBlockまたはrequestTxSyncを呼び出す前に、initiaAddressが定義されていることを必ず確認してください。 - [ALL-VM] 送信元アドレス:Initia では、すべてのメッセージタイプ(
MsgCall、MsgExecute、MsgExecuteContract)のsenderフィールドに Bech32 アドレスを指定する必要があります。EVM、Move、Wasm のアプリチェーン全体で互換性を確保するため、このフィールドにはinitiaAddressを使用してください。Cosmos 形式のメッセージのsenderフィールドに、EVM チェーン上の 16 進数のaddressを使用すると、「empty address string」または「decoding bech32 failed」エラーが発生します。
セキュリティと鍵の保護(厳格に適用)
- キーリングから生の秘密鍵をエクスポートしてはなりません。
- [MOVE][DEV] 開発(公開用ビルド):公開前に、デプロイ担当者が使用する Hex アドレスを指定してモジュールを再ビルドする必要があります:
minitiad move build --named-addresses <name>=0x<hex_addr>。 - [MOVE][DEV][BUILD] 名前付きアドレスの再割り当て:
Move.tomlの[addresses].<name>がハードコードされている場合(例:0x42)、異なる--named-addresses <name>=0x...を渡すと、名前付きアドレスの再割り当てエラーが発生してコンパイルに失敗します。[addresses]では"<name>" = "_"を使い、ローカルテスト用のデフォルト値は[dev-addresses]に設定してください。 - [MOVE][DEV] 依存関係の解決:
InitiaStdlibの解決に失敗する場合は、次を使用してください:{ git = "https://github.com/initia-labs/movevm.git", subdir = "precompile/modules/initia_stdlib", rev = "main" }。 - [MOVE][DEV] パッケージのスキャフォールディング:
minitiad move new <NAME>は、兄弟ディレクトリを作成せずに、現在の作業ディレクトリにパッケージを書き込むことがあります。blockforge/のような特定のフォルダーが必要な場合は、minitiad move newを実行する前に、そのフォルダーを作成して移動してください。 - [MOVE][DEV] クリーン(非対話型シェル):
minitiad move cleanは確認を求め、TTY がないとパニックを起こす場合があります。自動化されたワークフローでクリーンビルドが必要な場合は、パッケージのbuild/ディレクトリを直接削除してください。 - [MOVE][CLI] デプロイの仕様:Move モジュールには、独立したインスタンス化トランザクションはありません。「インスタンス化」は通常、最初の状態変更を伴うエントリー呼び出し(例:初回の
mint_shardでプレイヤーごとのリソースを作成すること)を指します。 - [EVM][CLI] デプロイ:EVM のデプロイには、
--fromを指定してminitiad tx evm createを使用してください。 - [EVM][CLI] バイトコードの抽出:Foundry のアーティファクトから
jqを使ってバイトコードを抽出してください。.binファイルには0xプレフィックスを付けず、末尾の改行も含めないでください。 - [EVM][DEV][CLI]
tx evm createの入力形式:minitiad tx evm createの位置引数はバイトコードのファイルパスです。生のバイトコードを直接渡す場合は、--input 0x...を使用してください。位置引数として生の16進数を渡すと、file name too longエラーが発生する場合があります。 - [ALL-VM][SECURITY] 秘密鍵の取り扱い:ツールが秘密鍵を必要とする場合は、Initia CLI または
InterwovenKitを使う代替ワークフローを探してください。
フロントエンドの要件(追加)
- ポリフィル:
vite.config.jsでvite-plugin-node-polyfillsを使用し、globals: { Buffer: true, process: true }を指定します。また、Viteでプロバイダーのコンテキストが分割されるのを防ぐため、resolve.dedupeを['react', 'react-dom', 'wagmi', '@tanstack/react-query', 'viem']に設定します。手動でポリフィルを使用する場合は、main.jsxの先頭でBufferとprocessのグローバルポリフィルを定義します。import { Buffer } from "buffer"; window.Buffer = Buffer; window.process = { env: {} }; - スタイル:
- CSSをインポートします:
import "@initia/interwovenkit-react/styles.css". - スタイルデータをインポートします:
import InterwovenKitStyles from "@initia/interwovenkit-react/styles.js". - インジェクター関数をインポートします:
import { injectStyles } from "@initia/interwovenkit-react". - インジェクター関数を呼び出します:
injectStyles(InterwovenKitStyles). - 注:
InterwovenKitStylesはstylesサブパスからのデフォルトエクスポートで、injectStylesはメインパッケージからの名前付きエクスポートです。
- CSSをインポートします:
- プロバイダーの順序:
WagmiProvider->QueryClientProvider->InterwovenKitProvider。 - ウォレットモーダル:
- 接続モーダルを開くには、
openModalではなくopenConnectを使用します(v2.4.0以降)。 - 接続状態(重要):
initiaAddressがある場合は、必ずクリック可能なUI要素(短縮アドレスを表示するボタンなど)を用意し、openWalletを呼び出して、ユーザーが接続を管理したり切断したりできるようにします。
- 接続モーダルを開くには、
- 自動署名の実装(明示的な要求がある場合のみ):
- 「自動署名を追加」などの明示的な要求がない限り、スキャフォールド、プロバイダー、コンポーネントのいずれにも自動署名機能を実装してはいけません。
- 要求された場合:
- プロバイダー:
InterwovenKitProviderにenableAutoSign={true}を渡します。 - フック:
useInterwovenKitからautoSignの関数ではなくオブジェクトを分割代入します。 - 安全性:オプショナルチェイニング(
autoSign?.)を使用し、autoSign?.isEnabledByChain[chainId]で状態を確認します。 - 操作:
await autoSign?.enable(chainId)とawait autoSign?.disable(chainId)は非同期です。 - 権限(重要):セッションキーで特定のメッセージタイプに署名できるようにするには、必ず
autoSign.enableで権限を明示的に指定します。await autoSign.enable(chainId, { permissions: ["/initia.move.v1.MsgExecute"] }) - エラー処理:
autoSign.disableが「authorization not found」エラーで失敗した場合は、必要な権限を指定してautoSign.enableを呼び出し、セッションをリセットします。
- プロバイダー:
- RESTクライアント:
@initia/initia.jsからRESTClientを手動でインスタンス化します。これはフックからエクスポートされていません。- 重要:
useInterwovenKitからnetworksやrestを分割代入しようとしてはいけません。これらのオブジェクトはフックでは利用できません。REST/RPCエンドポイントは必ず手動で定義するか、独自の設定を通じて指定します。
- 重要:
トランザクションのメッセージフロー(重要)
- [WASM][INTERWOVENKIT] トランザクションエンベロープ:必ず
chainIdを含めてください。requestTxSyncを推奨します。- [WASM][INTERWOVENKIT] ペイロードのエンコード:
MsgExecuteContractでは、msgフィールドにバイト列(Uint8Array)を指定する必要があります。new TextEncoder().encode(JSON.stringify(msg))を使用してください。
- [WASM][INTERWOVENKIT] ペイロードのエンコード:
- [ALL-VM][INTERWOVENKIT] 自動署名(ヘッドレス):自動署名されるトランザクションを「ヘッドレス」(手数料選択のプロンプトなし)にするには、リクエストに明示的な
feeDenom(例:feeDenom: "umin")とautoSign: trueフラグを必ず含めてください。await requestTxSync({ chainId, autoSign: true, // CRITICAL: Required for silent signing flow messages: [...] }) - [EVM] 送信者(MsgCall):
MsgCallのsenderには bech32 アドレスを使用し、contractAddrには hex を使用してください。- 正規化:「decoding bech32 failed」エラーを避けるため、bech32 形式の送信者アドレスは必ず小文字にしてください。
- [EVM][INTERWOVENKIT] ペイロード:
typeUrl: "/minievm.evm.v1.MsgCall"を持つプレーンオブジェクトを使用してください。実際のメッセージフィールドは、必ずvalueキーの中に入れてください。- 誤り:
{ typeUrl: "...", sender: "...", contractAddr: "..." } - 正しい:
{ typeUrl: "...", value: { sender: "...", contractAddr: "...", ... } }
- 誤り:
- [EVM][INTERWOVENKIT]
requestTxBlockのキー:必ずmsgsではなくmessages(複数形)を使用してください。msgsを渡すと、Cannot read properties of undefined (reading 'map')が発生することがあります。 - [EVM] フィールド名:フィールドには camelCase(
contractAddr、accessList、authList)を使用し、リストには空の配列も含めてください。 - [MOVE][INTERWOVENKIT] MsgExecute のフィールド名:フィールドには camelCase を使用してください。
moduleAddressは必ず bech32 形式にしてください。- [MOVE][INTERWOVENKIT] 必須の配列:空の場合でも、必ず
typeArgs: []とargs: []を含めてください。Move 実行メッセージでこれらのフィールドを省略すると、フロントエンドでの Amino 変換処理中にTypeError(Cannot read properties of undefined reading 'length')が発生します。
- [MOVE][INTERWOVENKIT] 必須の配列:空の場合でも、必ず
Wasm REST クエリ(重要)
- [WASM][REST] クエリのエンコード:
RESTClient(例:rest.wasm.smartContractState)を使って Wasm コントラクトの状態をクエリする場合、クエリメッセージは必ず Base64 エンコードされた文字列にしてください。 - クエリ JSON と実行 JSON は、コントラクトの Rust メッセージスキーマに正確に一致させてください。
all_messagesのような名前や、text、messageなどの特定のフィールド名を想定しないでください。たとえば、MemoBoard のバリアントではpost_message: { message: ... }を指定するget_messagesがよく使われますが、他のコントラクトではフィールド名が異なることがあります。 - 実装例:
const queryData = Buffer.from(JSON.stringify({ get_messages: {} })).toString("base64"); const res = await rest.wasm.smartContractState(CONTRACT_ADDR, queryData); - [WASM][REST] レスポンスの形式:
smartContractStateは、通常、res.dataの中ではなく、デコードされたペイロードを直接返します(例:res.messages)。具体的なレスポンス形式を確認せずに、.dataでラップされていると想定しないでください。 - [WASM][REST] メソッド名:必ず
smartContractStateを使用してください。queryContractSmartなどのメソッドは、Initia のRESTClientでは利用できません。 - [WASM][CLI] 代替手段:
minitiad query wasm contract-state smart <CONTRACT_ADDRESS> ...が、アドレスが instantiate イベントまたはlist-contract-by-codeから取得されたものであるにもかかわらず Bech32 チェックサムエラーで失敗する場合は、チェーンが出力したアドレスを正しいものとして扱ってください。minitiad query wasm list-contract-by-code <CODE_ID>で確認し、CLI パーサーに固執せず、REST エンドポイントのパスまたはRESTClientを使用してください。
Wasm Rust のテスト(重要)
- [WASM][TEST] アドレスの比較:Wasm コントラクトのユニットテストを書く際、
cosmwasm_std::Addrと文字列リテラルまたはStringを比較するときは、必ず.as_str()を使用してください。AddrはPartialEq<&str>またはPartialEq<String>を直接実装していません。 - 誤り:
assert_eq!("user1", value.sender); - 正しい:
assert_eq!("user1", value.sender.as_str());
トークンの精度と資金調達(EVM 固有)
- [EVM] 精度:EVM アプリチェーン上のすべてのネイティブトークン(例:
GAS)では、標準的な EVM の精度($10^{18}$ 基本単位)を前提とします。 - [EVM] 資金調達リクエスト:ユーザーが EVM チェーンで「N トークン」を求めた場合:
- フロントエンド:$10^{18}$ を乗算します(例:
parseUnits(amount, 18))。 - CLI:値を手動でスケーリングする必要があります。「100 トークン」の場合、
bank sendコマンドでは100000000000000000000GAS(100 に 0 が 18 個続く値)を使用します。
- フロントエンド:$10^{18}$ を乗算します(例:
- [EVM][FRONTEND] 人間が読み取れる UI:EVM 残高を表示する際は、必ず
viemのformatUnits(balance, 18)を使用します。UI に基本単位の生の値を表示してはいけません。 - [EVM][FRONTEND][DEV]
parseEther/formatEtherの使用:parseEtherとformatEtherは、チェーントークンが小数点以下 18 桁を正確に使用する場合に限り、有効な省略形です。小数点以下の桁数が変わる可能性がある場合は、ランタイム設定のparseUnits(amount, decimals)とformatUnits(balance, decimals)を使用します。
EVM のクエリとトランザクション(重要)
- [EVM][FRONTEND] ABI の同期:コンパイル済みの ABI/関数名を信頼できる情報源として扱います。フロントエンドの
encodeFunctionData呼び出しを組み込む前に、生成されたアーティファクト(例:out/<Contract>.sol/<Contract>.json)で名前/シグネチャを確認し、getMyBalanceのような名前を推測してはいけません。 - [EVM][RPC] 状態クエリ:EVM の状態クエリでは、プロパティの未定義エラーを避けるため、
RESTClientより標準の JSON-RPCeth_callを優先します。 - [EVM][FRONTEND][RPC] 読み取りパスのプロバイダー:読み取り専用の EVM クエリ(
eth_call)には、注入されたウォレットプロバイダー(window.ethereum)に依存せず、設定済みの JSON-RPC エンドポイント(例:VITE_JSON_RPC_URL)を使用します。これにより、EVM 拡張機能が注入されていない場合の「EVM ウォレットプロバイダーが見つかりません」というエラーを回避できます。 - [EVM][RPC] アドレス変換:EVM の状態をクエリする場合(例:
eth_call)、必ずAccAddress.toHex(addr)を使用して bech32 アドレスを hex に変換し、hex アドレスを小文字にします。 - [EVM][CLI] 送信者の形式:
minitiad query evm callの最初の引数には、bech32 形式の送信者(init1...)を指定する必要があります。 - [EVM][CLI] クエリ出力フィールド:
minitiad query evm call -o jsonは、呼び出し結果を.response(hex 文字列)で返します。 - [EVM][CLI] Tx 検索のタイミング:ブロードキャスト直後は、
minitiad query tx <hash>が一時的にtx not foundを返すことがあります。失敗と判断する前に、少し待ってから再試行します。 - [EVM][CLI] Calldata のエンコード:
- [EVM][FRONTEND] 推奨:コントラクトの
inputhex の生成には、viem(例:encodeFunctionData)を優先して使用します。 - [EVM][CLI] 推奨:コントラクトの
inputhex の生成には、必ずcast calldata(例:$(cast calldata "func(type)" arg))を使用します。手動でのエンコード(例:printf)は壊れやすいため、必ず避けてください。 - [EVM][CLI] 手動パディング:手動でのエンコードが避けられない場合は、
BigIntの値を hex に変換し、uint256引数用に正確に 64 文字までパディングします。
- [EVM][FRONTEND] 推奨:コントラクトの
Move REST クエリ(重要)
- [MOVE][REST] モジュールアドレスの形式:
RESTClientを使用して Move コントラクトの状態をクエリする場合(例:rest.move.view)、モジュールアドレスは bech32 形式である必要があります。 - [MOVE][REST] 構造体タグアドレスの形式:
rest.move.resourceを使用して Move リソースをクエリする場合、リソース所有者は bech32 のままですが、構造体タグのモジュールアドレスは hex 形式(0x...::module::Struct)である必要があります。bech32 のモジュールアドレスを使って構造体タグを作成しないでください。 - [MOVE][REST] アドレス引数:
args内のアドレス引数は、hex に変換し、0xを取り除き、64 文字(32 バイト)になるようにパディングしてから、Base64 でエンコードする必要があります。 - 実装例:
const b64Addr = Buffer.from( AccAddress.toHex(addr).replace('0x', '').padStart(64, '0'), 'hex' ).toString('base64'); const res = await rest.move.view(mod_bech32, mod_name, func_name, [], [b64Addr]); - リソースのクエリ例:
const structTag = `${AccAddress.toHex(moduleBech32)}::items::Inventory`; const res = await rest.move.resource(walletBech32, structTag); - [MOVE][REST] レスポンスの解析:
rest.move.viewのレスポンスはViewResponseオブジェクトです。実際の値にアクセスするには、JSON.parse(res.data)を解析する必要があります。 - [MOVE][REST] リソースが存在しない場合の処理:インベントリなど、初回使用時の状態では、リソースがまだ存在しないことがあります。
rest.move.resourceから「見つかりません」というレスポンスが返された場合は、ハードエラーとして表面化させず、有効なゼロ値/デフォルト状態として扱ってください。 - [MOVE][REST] トラブルシューティング(400 Bad Request):
rest.move.viewが 400 エラーを返す場合、ほとんどの場合、原因は次のいずれかです。- モジュールアドレスが bech32 ではありません。
args内のアドレス引数が、hex にパディングして Base64 でエンコードされていません。
- [MOVE][INTERWOVENKIT] 自動署名(メッセージタイプが設定されていない):
autoSign.enableが "No message types configured" で失敗する場合は、次の点を確認してください。metadata.minitia.typeが正しく設定されている(例:minimove、minievm)。InterwovenKitProviderのdefaultChainIdがcustomChain.chain_idと一致している。customChainのトップレベルにbech32_prefixがある。
運用手順(タスクの実行方法)
- レイヤーの分類:コントラクト、フロントエンド、Appchain Ops、またはインテグレーションに分類します。
- 環境の確認:ツール(
cargo、forge、minitiad)が PATH にあることを確認します。必要に応じて絶対パスを使用します。 - ワークスペースの把握:スキャフォールディングの前に、既存の
Move.tomlまたはpackage.jsonがないか確認します。対話なしのスキャフォールディングには、提供されているスクリプトを使用します。 - デプロイ前チェックリスト(CLI):CLI でコントラクトをデプロイしたり、トークンを送信したりする前に、実際の環境を確認します(実行時の検出結果から
RPC_ENDPOINTを設定します)。- チェーン ID:
curl -s "${RPC_ENDPOINT}/status" | jq -r '.result.node_info.network' - ネイティブデノム:
minitiad q bank total --node "${RPC_ENDPOINT}" - 残高:
fromアカウントに、実際のネイティブデノムが十分にあることを確認します。
- チェーン ID:
- スキャフォールディングのクリーンアップ:スキャフォールディング後に、プレースホルダーモジュール/コントラクトを削除します。
- Appchain の健全性:RPC が停止している場合は、
weave rollup start -dを試し、scripts/verify-appchain.shで確認します。 - [MOVE][DEV] Acquires アノテーション:グローバルストレージにアクセスするすべての関数(
borrow_global、borrow_global_mut、move_fromを使用する、またはこれらを行う関数を呼び出す関数)には、そのリソース型のacquiresアノテーションを必ず含めます。 - [MOVE][DEV] 参照のルール:関数は、グローバルリソースに由来する参照(可変または不変。例:
borrow_global_mut経由)を、パラメーターとして渡されていない限り返してはいけません。必要に応じてロジックをインライン化するか、リソースをパラメーターとして渡します。 - [MOVE][DEV] 構文:ドキュメントコメント(
///)は、#[view]や#[test]などの属性の後に配置します。 - [MOVE][CLI] Publish:
minitiad tx move publishコマンドは--pathフラグを使用しません。コンパイル済み.mvファイルのパスを位置引数として渡します:minitiad tx move publish <path_to_file>.mv ...。 - [MOVE][DEV][CLI] 再公開の互換性:同じアカウントからの再公開が
BACKWARD_INCOMPATIBLE_MODULE_UPDATEで失敗する場合は、既存の公開 API を維持する(たとえば、以前の公開 entry/view 関数を互換性ラッパーとして残す)か、公開前にモジュール名を変更します。 - [ALL-VM][CLI] ブロードキャストモードの互換性:現在の Initia CLI でブロードキャストモードがサポートするのは
sync|asyncです。blockが使えるとは想定しないでください。 - [MOVE][CLI] Tx 検索のタイミング:
minitiadでブロードキャストした直後は、minitiad query tx <hash>が一時的にtx not foundを返すことがあります。失敗と判断する前に、ポーリング/再試行してください。 - [WASM][BUILD] 最適化:本番環境向けバイナリには、必ず CosmWasm オプティマイザーの Docker イメージを使用します。
- ビジュアルの仕上げ:粘着性のあるグラスモーフィズムのヘッダー、中央揃えのアプリカードレイアウト、明確な視覚的階層を優先します。
- 優れた UX:フィードの並び順(新しいものを先頭にする)、入力欄のアクセシビリティ(フィードの上に配置する)、インタラクティブなフィードバック(ホバー/フォーカス)を重視します。
- [ALL-VM][INTERWOVENKIT] ブリッジのサポート:
useInterwovenKitのopenBridgeを使用します。ローカルデモでは、srcChainIdのデフォルトとしてパブリックテストネット(例:initiation-2)を設定します。 - 検証:
scripts/verify-appchain.sh --gas-station --botsを実行し、引き渡し前にトランザクションの成功を確認します。
段階的な情報開示(必要に応じて参照)
- 一般的なタスク(資金調達、アドレス、精度):
references/common-tasks.md - コントラクト(Move/Wasm/EVM):
references/contracts.md - フロントエンド(InterwovenKit):
references/frontend-interwovenkit.md - フロントエンド(EVM JSON-RPC):
references/frontend-evm-rpc.md - エンドツーエンドのレシピ:
references/e2e-recipes.md - 実行時の検出:
references/runtime-discovery.md - Weave CLI リファレンス:
references/weave-commands.md - Rollup 設定スキーマ:
references/weave-config-schema.md - トラブルシューティングと復旧:
references/troubleshooting.md
ドキュメントの代替参照先
- コアドキュメント:
https://docs.initia.xyz - InterwovenKit ドキュメント:
https://docs.initia.xyz/interwovenkit
スクリプトの使用方法
- スキャフォールディング:
scripts/scaffold-contract.sh、scripts/scaffold-frontend.sh - ヘルスチェック:
scripts/verify-appchain.sh - ユーティリティ:
scripts/convert-address.py、scripts/to_hex.py、scripts/generate-system-keys.py - セットアップ:
scripts/install-tools.sh、scripts/fund-user.sh
期待される成果物
- 変更したファイルの正確な一覧。
- セットアップ/ビルド/テストのコマンド。
- 検証手順と出力。
- リスクに関する注意事項(セキュリティ、鍵、手数料)。