アカウントタイプ

概要

プログラムアカウントは実行可能なsBPFコードを保持します。データアカウントはプログラムが所有する状態を格納します。システムアカウントはSystem Programが所有します。Sysvarsは事前定義されたアドレスでアクセス可能なクラスタ全体の状態を提供します。

executableフィールドがアカウントのカテゴリを決定します:

このコードと可変状態の分離により、プログラムは一度デプロイされ、任意の数のデータアカウントを管理できます。

プログラムアカウント

プログラムアカウントは実行可能コードを格納します。すべてのプログラムアカウントはローダープログラムによって所有されます。プログラムがデプロイされると、ランタイムはそのバイトコードを保持するためのプログラムアカウントを作成します。

プログラムアカウント、その4つのコンポーネント、およびそのローダープログラムの図。プログラムアカウント、その4つのコンポーネント、およびそのローダープログラムの図。

プログラムデータアカウント

loader-v3を使用してデプロイされたプログラム(ローダープログラムを参照)は、独自のdataフィールドに実行可能バイトコードを格納しません。代わりに、そのdataはプログラムコードを含む別のプログラムデータアカウントを指します。(下図を参照してください。)

データを持つプログラムアカウント。データは別のプログラムデータアカウントを指していますデータを持つプログラムアカウント。データは別のプログラムデータアカウントを指しています

プログラムのデプロイまたはアップグレード中、バッファアカウントはアップロードを一時的にステージングするために使用されます。

次の例では、Token Programアカウントを取得します。executableフィールドはtrueであり、これがプログラムアカウントであることを確認します。

import { Address, createSolanaRpc } from "@solana/kit";
const rpc = createSolanaRpc("https://api.mainnet.solana.com");
const programId = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" as Address;
const accountInfo = await rpc
.getAccountInfo(programId, { encoding: "base64" })
.send();
console.log(accountInfo);
Console
Click to execute the code.

データアカウント

データアカウントには実行可能なコードは含まれません。プログラムで定義された状態を保存します。

プログラム状態アカウント

プログラムはその状態をデータアカウントに保存します。プログラム状態アカウントの作成には2つのステップがあります:

  1. System Programを呼び出してアカウントを作成します。System Programは所有権を指定されたプログラムに移転します。
  2. 所有プログラムがアカウントのdataフィールドをそのinstructionsに従って初期化します。

プログラムアカウントが所有するデータアカウントの図プログラムアカウントが所有するデータアカウントの図

以下の例では、Token 2022プログラムが所有するToken Mint accountを作成し、取得します。

import {
airdropFactory,
appendTransactionMessageInstructions,
createSolanaRpc,
createSolanaRpcSubscriptions,
createTransactionMessage,
generateKeyPairSigner,
getSignatureFromTransaction,
lamports,
pipe,
sendAndConfirmTransactionFactory,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
signTransactionMessageWithSigners
} from "@solana/kit";
import { getCreateAccountInstruction } from "@solana-program/system";
import {
getInitializeMintInstruction,
getMintSize,
TOKEN_2022_PROGRAM_ADDRESS,
fetchMint
} from "@solana-program/token-2022";
// Create Connection, local validator in this example
const rpc = createSolanaRpc("http://localhost:8899");
const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");
// Generate keypairs for fee payer
const feePayer = await generateKeyPairSigner();
// Fund fee payer
await airdropFactory({ rpc, rpcSubscriptions })({
recipientAddress: feePayer.address,
lamports: lamports(1_000_000_000n),
commitment: "confirmed"
});
// Generate keypair to use as address of mint
const mint = await generateKeyPairSigner();
// Get default mint account size (in bytes), no extensions enabled
const space = BigInt(getMintSize());
// Get minimum balance for rent exemption
const rent = await rpc.getMinimumBalanceForRentExemption(space).send();
// Instruction to create new account for mint (token 2022 program)
// Invokes the system program
const createAccountInstruction = getCreateAccountInstruction({
payer: feePayer,
newAccount: mint,
lamports: rent,
space,
programAddress: TOKEN_2022_PROGRAM_ADDRESS
});
// Instruction to initialize mint account data
// Invokes the token 2022 program
const initializeMintInstruction = getInitializeMintInstruction({
mint: mint.address,
decimals: 9,
mintAuthority: feePayer.address
});
const instructions = [createAccountInstruction, initializeMintInstruction];
// Get latest blockhash to include in transaction
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
// Create transaction message
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }), // Create transaction message
(tx) => setTransactionMessageFeePayerSigner(feePayer, tx), // Set fee payer
(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), // Set transaction blockhash
(tx) => appendTransactionMessageInstructions(instructions, tx) // Append instructions
);
// Sign transaction message with required signers (fee payer and mint keypair)
const signedTransaction =
await signTransactionMessageWithSigners(transactionMessage);
// Send and confirm transaction
await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(
signedTransaction,
{ commitment: "confirmed" }
);
// Get transaction signature
const transactionSignature = getSignatureFromTransaction(signedTransaction);
console.log("Mint Address:", mint.address);
console.log("Transaction Signature:", transactionSignature);
const accountInfo = await rpc.getAccountInfo(mint.address).send();
console.log(accountInfo);
const mintAccount = await fetchMint(rpc, mint.address);
console.log(mintAccount);
Console
Click to execute the code.

システムアカウント

作成後もSystem Programが所有し続けるアカウントは、システムアカウントと呼ばれます。新しいアドレスに初めてSOLを送信すると、そのアドレスにSystem Programが所有する新しいアカウントが作成されます。

すべてのウォレットアカウントはシステムアカウントです。トランザクションの手数料支払者はシステムアカウントでなければなりません。なぜなら、System Programが所有するアカウントのみがtransaction feesを支払うことができるからです。

1,000,000 lamportsを含むSystem Programが所有するウォレット1,000,000 lamportsを含むSystem Programが所有するウォレット

以下の例では、新しいkeypairを生成し、SOLで資金を供給し、アカウントを取得します。ownerフィールドは11111111111111111111111111111111(System Program)です。

import {
airdropFactory,
createSolanaRpc,
createSolanaRpcSubscriptions,
generateKeyPairSigner,
lamports
} from "@solana/kit";
// Create a connection to Solana cluster
const rpc = createSolanaRpc("http://localhost:8899");
const rpcSubscriptions = createSolanaRpcSubscriptions("ws://localhost:8900");
// Generate a new keypair
const keypair = await generateKeyPairSigner();
console.log(`Public Key: ${keypair.address}`);
// Funding an address with SOL automatically creates an account
const signature = await airdropFactory({ rpc, rpcSubscriptions })({
recipientAddress: keypair.address,
lamports: lamports(1_000_000_000n),
commitment: "confirmed"
});
const accountInfo = await rpc.getAccountInfo(keypair.address).send();
console.log(accountInfo);
Console
Click to execute the code.

Sysvarアカウント

Sysvarアカウントは、事前定義されたアドレスに存在する特別なアカウントで、クラスター状態データへの読み取り専用アクセスを提供します。これらは各slotで動的に更新されます。

Sysvarアドレス目的
ClockSysvarC1ock11111111111111111111111111111111現在のslot、epoch、およびUnixタイムスタンプ
EpochScheduleSysvarEpochSchedu1e111111111111111111111111ジェネシスで設定されたepochスケジューリング定数
EpochRewardsSysvarEpochRewards1111111111111111111111111epoch報酬の配布状況と進捗状況
RentSysvarRent111111111111111111111111111111111rentレートと免除しきい値
SlotHashesSysvarS1otHashes111111111111111111111111111slotの親バンクの最新ハッシュ
StakeHistorySysvarStakeHistory1111111111111111111111111epoch毎のステークのアクティベーションと非アクティベーション
LastRestartSlotSysvarLastRestartS1ot1111111111111111111111最後のクラスター再起動slot
InstructionsSysvar1nstructions1111111111111111111111111現在のトランザクションのシリアライズされたinstructions
SlotHistorySysvarS1otHistory11111111111111111111111111最後のepoch中に生成されたslotの記録

次の例では、Sysvar Clockアカウントを取得してデシリアライズします。

import { createSolanaRpc } from "@solana/kit";
import { fetchSysvarClock, SYSVAR_CLOCK_ADDRESS } from "@solana/sysvars";
const rpc = createSolanaRpc("https://api.mainnet.solana.com");
const accountInfo = await rpc
.getAccountInfo(SYSVAR_CLOCK_ADDRESS, { encoding: "base64" })
.send();
console.log(accountInfo);
// Automatically fetch and deserialize the account data
const clock = await fetchSysvarClock(rpc);
console.log(clock);
Console
Click to execute the code.

Is this page helpful?

目次

ページを編集

管理運営

© 2026 Solana Foundation.
無断転載を禁じます。
つながろう