概要
Instructionには3つのフィールドがあります:
program_id(呼び出すプログラム)、accounts(is_signer/is_writableフラグを持つAccountMetaリスト)、data(プログラムが解釈するデータのバイト配列)。
Instructionの構造
Instructionは3つのフィールドで構成されています:
program_id: 呼び出されるプログラムのID。accounts: アカウントメタデータの配列data: Instructionで使用される追加データを含むバイト配列
pub struct Instruction {/// Pubkey of the program that executes this instruction.pub program_id: Pubkey,/// Metadata describing accounts that should be passed to the program.pub accounts: Vec<AccountMeta>,/// Opaque data passed to the program for its own interpretation.pub data: Vec<u8>,}
Program ID
Instructionのprogram_idは、Instructionの実行ロジックを含むプログラムの公開鍵アドレスです。ランタイムはこのフィールドを使用して、Instructionを処理のために正しいプログラムにルーティングします。
アカウントメタデータ
Instructionのaccounts配列は、AccountMeta構造体の順序付きリストです。Instructionが相互作用する各アカウントに対してメタデータを提供する必要があります。Validatorはこのメタデータを使用して、どのトランザクションを並列実行できるかを判断します。異なるアカウントに書き込むトランザクションは並列実行できます。
以下の図は、単一のInstructionを含むトランザクションを示しています。Instructionのaccounts配列には、2つのアカウントのメタデータが含まれています。
1つのInstructionを持つトランザクション。Instructionのaccounts配列には2つのAccountMeta構造体が含まれています。
各*rsAccountMeta*には3つのフィールドがあります:
- pubkey: アカウントの公開鍵アドレス
- is_signer: アカウントがトランザクションに署名する必要がある場合は
trueに設定 - is_writable:
Instructionがアカウントのデータを変更する場合は
trueに設定
instructionが必要とするアカウント(書き込み可能、読み取り専用、またはトランザクションへの署名が必要なアカウントを含む)を知るには、プログラムで定義されているinstructionの実装を参照する必要があります。
pub struct AccountMeta {/// An account's public key.pub pubkey: Pubkey,/// True if an `Instruction` requires a `Transaction` signature matching `pubkey`.pub is_signer: bool,/// True if the account data or metadata may be mutated during program execution.pub is_writable: bool,}
データ
instructionのdataフィールドは、プログラムにどの関数を呼び出すかを指示し、その関数の引数を提供するバイト配列です。データは通常、ターゲット関数を識別する識別子またはインデックスバイトで始まり、その後にシリアル化された引数が続きます。エンコード形式は各プログラムで定義されます(例:Borshシリアル化またはカスタムレイアウト)。
一般的なエンコード規則:
- コアプログラム(System、Stake、Vote):Bincodeでシリアル化されたenum variantインデックスの後にシリアル化された引数が続きます。
- Anchorプログラム:8バイトの識別子(
"global:<function_name>"のSHA-256ハッシュの最初の8バイト)の後にBorshでシリアル化された引数が続きます。
ランタイムはdataフィールドを解釈しません。プログラムのprocess_instructionエントリーポイントにそのまま渡されます。
コンパイル済みinstruction
instructionsがトランザクションメッセージにシリアル化されると、すべての公開鍵をメッセージのaccount_keys配列へのコンパクトな整数インデックスに置き換えるCompiledInstruction構造体になります。
例:SOL転送instruction
以下の例は、SOL転送instructionの構造を示しています。
import { generateKeyPairSigner, lamports } from "@solana/kit";import { getTransferSolInstruction } from "@solana-program/system";// Generate sender and recipient keypairsconst sender = await generateKeyPairSigner();const recipient = await generateKeyPairSigner();// Define the amount to transferconst LAMPORTS_PER_SOL = 1_000_000_000n;const transferAmount = lamports(LAMPORTS_PER_SOL / 100n); // 0.01 SOL// Create a transfer instruction for transferring SOL from sender to recipientconst transferInstruction = getTransferSolInstruction({source: sender,destination: recipient.address,amount: transferAmount});console.log(JSON.stringify(transferInstruction, null, 2));
以下のコードは、前のコードスニペットからの出力を示しています。形式はSDK間で異なりますが、各instructionには同じ3つの必須情報が含まれていることに注意してください:program_id、accounts、data。
{"accounts": [{"address": "Hu28vRMGWpQXN56eaE7jRiDDRRz3vCXEs7EKHRfL6bC","role": 3,"signer": {"address": "Hu28vRMGWpQXN56eaE7jRiDDRRz3vCXEs7EKHRfL6bC","keyPair": {"privateKey": {},"publicKey": {}}}},{"address": "2mBY6CTgeyJNJDzo6d2Umipw2aGUquUA7hLdFttNEj7p","role": 1}],"programAddress": "11111111111111111111111111111111","data": {"0": 2,"1": 0,"2": 0,"3": 0,"4": 128,"5": 150,"6": 152,"7": 0,"8": 0,"9": 0,"10": 0,"11": 0}}
以下の例は、転送instructionを手動で構築する方法を示しています。(Expanded InstructionタブはInstructionタブと機能的に同等です。)
実際には、通常_rsInstruction_を手動で構築する必要はありません。ほとんどのプログラムは、instructionsを作成するヘルパー関数を備えたクライアントライブラリを提供しています。ライブラリが利用できない場合は、instructionを手動で構築できます。
const transferAmount = 0.01; // 0.01 SOLconst transferInstruction = getTransferSolInstruction({source: sender,destination: recipient.address,amount: transferAmount * LAMPORTS_PER_SOL});
Is this page helpful?