Cross Program Invocation (CPI)とは、実行中に1つのプログラムが別のプログラムのinstructionを呼び出すことです。CPIは構成可能性を実現します。ネットワーク上の任意のプログラムのinstructionsは、他の任意のプログラムから呼び出すことができます。
Cross Program Invocationの例
PDA署名者なしのCPI
invoke関数の使用、Anchor CpiContext、ネイティブRustの例、SOL転送CPIの例。
PDA署名者ありのCPI
署名者シードを使用したinvoke_signedの使用、PDAを使用したAnchor CpiContext、ネイティブRust PDA署名の例。
CPIの実行と権限
11ステップのCPI実行フロー、権限拡張ルール、再入可能性、アカウント検証。
CPIコストモデルとデータ同期
CPIコスト計算式、シリアライゼーションコスト、アカウントデータ同期、PDA署名、リターンデータ。
主要な事実
- 2つの関数:
invoke(PDA署名なし)とinvoke_signed(PDA署名あり)。 - 権限拡張: アカウントの権限(署名者、書き込み可能)は呼び出し元から呼び出し先に拡張されます。呼び出し先は、呼び出し元が渡した権限を超えてエスカレートすることはできません。
- 共有計算バジェット: 呼び出し先のCU消費は、呼び出し元の残りのバジェットを減少させます。
- 再入可能性: 直接的な自己再帰は許可されています(A->A->A)。間接的な再入可能性は許可されていません(A->B->Aは*rs
ReentrancyNotAllowed*を返します)。
制限
| 制限 | 値 | ソース |
|---|---|---|
| 最大instructionスタック深度 | 5 (SIMD-0268では9) | MAX_INSTRUCTION_STACK_DEPTH, MAX_INSTRUCTION_STACK_DEPTH_SIMD_0268 |
| CPI呼び出しコスト | 1,000 CU (SIMD-0339では946) | DEFAULT_INVOCATION_COST, INVOKE_UNITS_COST_SIMD_0339 |
| CPI当たりの最大PDA署名者数 | 16 | MAX_SIGNERS |
| 最大CPIのinstruction data | 10 KiB (10,240バイト) | MAX_INSTRUCTION_DATA_LEN |
| 最大リターンデータ | 1,024バイト | MAX_RETURN_DATA |
| 最大CPIアカウント情報数 | 128 (SIMD-0339では255)* | MAX_CPI_ACCOUNT_INFOS, MAX_CPI_ACCOUNT_INFOS_SIMD_0339 |
| CPIシリアライゼーションコスト | 250バイト当たり1 CU | cpi_bytes_per_unit |
| CPI当たりの最大アカウントデータ再割り当て | 10,240バイト (10 KiB) | MAX_PERMITTED_DATA_INCREASE |
invoke vs invoke_signed
SolanaはCPIを実行するための2つの関数を提供しています:
| 関数 | 使用例 | PDA署名 |
|---|---|---|
invoke | 必要な署名者全員が元のトランザクションに既に署名している場合のCPI | なし |
invoke_signed | 呼び出し元プログラムが所有するPDAの代わりに署名する必要がある場合のCPI | あり、署名者シードを使用 |
内部的には、*rsinvokeは空の署名者シード配列を使用してrsinvoke_signedを呼び出しているだけです。PDA署名が不要な場合はrsinvokeを使用し、プログラムがPDAの代わりにアクションを承認する必要がある場合はrsinvoke_signed*を使用してください。
両方の関数は最終的に同じシステムコール(sol_invoke_signed_rust)を呼び出し、同じランタイムパス(cpi_common)を通過します。唯一の違いは、署名者シードが提供されるかどうかです。シードが提供された場合、ランタイムはPDAの公開鍵を導出し、権限チェックの前に有効な署名者のセットに追加します。
Is this page helpful?