instructions
InstructionsはSolanaブロックチェーンとやり取りするための基本的な構成要素です。instructionは本質的に、Solanaネットワークを使用する誰もが呼び出せる公開関数です。各instructionは特定のアクションを実行するために使用されます。instructionsの実行ロジックはプログラムに格納され、各プログラムは独自のinstructionsセットを定義します。Solanaネットワークとやり取りするには、1つ以上のinstructionsをトランザクションに追加し、処理のためにネットワークに送信します。
SOL送金の例
以下の図は、トランザクションとinstructionsがどのように連携してユーザーがネットワークとやり取りできるようにするかを示しています。この例では、SOLがあるアカウントから別のアカウントに送金されます。
送信者アカウントのメタデータは、トランザクションに署名する必要があることを示しています。(これによりSystem Programがlamportを差し引くことができます。)送信者と受信者の両方のアカウントは、lamportの残高を変更するために書き込み可能である必要があります。このinstructionを実行するために、送信者のウォレットは署名とSOL送金instructionを含むメッセージを含むトランザクションを送信します。
SOL送金図
トランザクションが送信された後、System Programは送金instructionを処理し、両方のアカウントのlamport残高を更新します。
SOL送金処理図
以下の例は、上記の図に関連するコードを示しています。(System Programの送金instructionを参照してください。)
import {airdropFactory,appendTransactionMessageInstructions,createSolanaRpc,createSolanaRpcSubscriptions,createTransactionMessage,generateKeyPairSigner,getSignatureFromTransaction,lamports,pipe,sendAndConfirmTransactionFactory,setTransactionMessageFeePayerSigner,setTransactionMessageLifetimeUsingBlockhash,signTransactionMessageWithSigners} from "@solana/kit";import { getTransferSolInstruction } from "@solana-program/system";// Create a connection to clusterconst rpc = createSolanaRpc("http://localhost:8899");const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");// Generate sender and recipient keypairsconst sender = await generateKeyPairSigner();const recipient = await generateKeyPairSigner();const LAMPORTS_PER_SOL = 1_000_000_000n;const transferAmount = lamports(LAMPORTS_PER_SOL / 100n); // 0.01 SOL// Fund sender with airdropawait airdropFactory({ rpc, rpcSubscriptions })({recipientAddress: sender.address,lamports: lamports(LAMPORTS_PER_SOL), // 1 SOLcommitment: "confirmed"});// Check balance before transferconst { value: preBalance1 } = await rpc.getBalance(sender.address).send();const { value: preBalance2 } = await rpc.getBalance(recipient.address).send();// Create a transfer instruction for transferring SOL from sender to recipientconst transferInstruction = getTransferSolInstruction({source: sender,destination: recipient.address,amount: transferAmount // 0.01 SOL in lamports});// Add the transfer instruction to a new transactionconst { value: latestBlockhash } = await rpc.getLatestBlockhash().send();const transactionMessage = pipe(createTransactionMessage({ version: 0 }),(tx) => setTransactionMessageFeePayerSigner(sender, tx),(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),(tx) => appendTransactionMessageInstructions([transferInstruction], tx));// Send the transaction to the networkconst signedTransaction =await signTransactionMessageWithSigners(transactionMessage);await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedTransaction,{ commitment: "confirmed" });const transactionSignature = getSignatureFromTransaction(signedTransaction);// Check balance after transferconst { value: postBalance1 } = await rpc.getBalance(sender.address).send();const { value: postBalance2 } = await rpc.getBalance(recipient.address).send();console.log("Sender prebalance:",Number(preBalance1) / Number(LAMPORTS_PER_SOL));console.log("Recipient prebalance:",Number(preBalance2) / Number(LAMPORTS_PER_SOL));console.log("Sender postbalance:",Number(postBalance1) / Number(LAMPORTS_PER_SOL));console.log("Recipient postbalance:",Number(postBalance2) / Number(LAMPORTS_PER_SOL));console.log("Transaction Signature:", transactionSignature);
Console
Click to execute the code.
Instructions
3つのコンポーネントに分解されたinstructionを含むトランザクションを描いた図
Instruction
は以下の情報で構成されています:
program_id
: 呼び出されるプログラムのID。accounts
: アカウントメタデータの配列data
: instructionで使用される追加[データ]を含むバイト配列。
Instruction struct
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>,}
プログラムID
instructionのprogram_id
は、instructionのビジネスロジックを含むプログラムの公開鍵アドレスです。
アカウントメタデータ
instructionのaccounts
配列はAccountMeta
構造体の配列です。instructionが相互作用する各アカウントにはメタデータを提供する必要があります。(これにより、同じアカウントを変更しない限り、トランザクションは複数のinstructionsを並行して実行できます。)
以下の図は、単一のinstructionを含むトランザクションを示しています。instructionのaccounts
配列には2つのアカウントのメタデータが含まれています。
1つのinstructionを持つトランザクション。instructionにはaccounts配列内に2つのAccountMeta構造体が含まれています。
アカウントメタデータには以下の情報が含まれます:
- pubkey: アカウントの公開鍵アドレス
- is_signer: アカウントがトランザクションに署名する必要がある場合は
true
に設定 - is_writable:
instructionがアカウントのデータを変更する場合は
true
に設定
instructionがどのアカウントを必要とするか、どれが書き込み可能、読み取り専用、またはトランザクションに署名する必要があるかを知るには、プログラムによって定義されたinstructionの実装を参照する必要があります。
AccountMeta
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
は、プログラムのどのinstructionを呼び出すかを指定するバイト配列です。また、instructionが必要とする引数も含まれています。
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));
Console
Click to execute the code.
以下のコードは、前のコードスニペットからの出力を示しています。フォーマットはSDKによって異なりますが、各instructionsには同じ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}}
以下の例は、転送instructionsを手動で構築する方法を示しています。(Expanded Instruction
タブは機能的にInstruction
タブと同等です。)
実際には、通常Instruction
を手動で構築する必要はありません。
ほとんどのプログラムはinstructionsを作成するためのヘルパー関数を持つクライアントライブラリを提供しています。ライブラリが利用できない場合は、手動でinstructionsを構築することができます。
const transferAmount = 0.01; // 0.01 SOLconst transferInstruction = getTransferSolInstruction({source: sender,destination: recipient.address,amount: transferAmount * LAMPORTS_PER_SOL});
Is this page helpful?