アカウント

Solanaネットワーク上のすべてのデータはアカウントに保存されています。Solanaネットワークを単一のアカウントテーブルを持つ公開データベースと考えることができます。アカウントとそのアドレスの関係は、キーがアドレスで値がアカウントであるキーと値のペアに似ています。

各アカウントは同じ基本的な構造を持ち、そのアドレスを使用して見つけることができます。

3つのアカウントとそのアドレスの図。アカウント構造の定義を含む。3つのアカウントとそのアドレスの図。アカウント構造の定義を含む。

アカウントアドレス

アカウントのアドレスは、Solanaブロックチェーン上でアカウントを特定するための32バイトの一意のIDです。アカウントアドレスはよくbase58でエンコードされた文字列として表示されます。ほとんどのアカウントはアドレスとしてEd25519公開鍵を使用していますが、SolanaはProgram Derived Addressもサポートしているため、これは必須ではありません。

base58でエンコードされた公開鍵アドレスを持つアカウントbase58でエンコードされた公開鍵アドレスを持つアカウント

公開鍵

以下の例は、Solana SDKを使用してkeypairを作成する方法を示しています。

import { generateKeyPairSigner } from "@solana/kit";
// Kit does not enable extractable private keys
const keypairSigner = await generateKeyPairSigner();
console.log(keypairSigner);
Console
Click to execute the code.

Program Derived Address

Program Derived Address(PDA)は、プログラムIDと1つ以上のオプション入力(シード)を使用して決定論的に導出されるアドレスです。以下の例は、Solana SDKを使用してProgram Derived Addressを作成する方法を示しています。

import { Address, getProgramDerivedAddress } from "@solana/kit";
const programAddress = "11111111111111111111111111111111" as Address;
const seeds = ["helloWorld"];
const [pda, bump] = await getProgramDerivedAddress({
programAddress,
seeds
});
console.log(`PDA: ${pda}`);
console.log(`Bump: ${bump}`);
Console
Click to execute the code.

アカウント構造

すべてのAccountは最大サイズが10MiBで、以下の情報を含んでいます:

  • lamports: アカウント内のlamportsの数
  • data: アカウントのデータ
  • owner: アカウントを所有するプログラムのID
  • executable: アカウントが実行可能なバイナリを含むかどうかを示す
  • rent_epoch: 非推奨のrent epochフィールド
Account
pub struct Account {
/// lamports in the account
pub lamports: u64,
/// data held in this account
#[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
pub data: Vec<u8>,
/// the program that owns this account. If executable, the program that loads this account.
pub owner: Pubkey,
/// this account's data contains a loaded program (and is now read-only)
pub executable: bool,
/// the epoch at which this account will next owe rent
pub rent_epoch: Epoch,
}

Lamports

アカウントの残高(lamport単位)。

すべてのアカウントは、rentと呼ばれる最低限のlamport残高を持つ必要があります。これによりデータをチェーン上に保存することができます。rentはアカウントのサイズに比例します。

この残高は「rent」と呼ばれていますが、実際には預け金のように機能します。アカウントが閉鎖されると全額が回収できるためです。(「rent」という名前は、現在は非推奨となっているrent epochフィールドに由来しています。)

最低残高の計算式と適用される定数を参照してください。)

データ

このフィールドは一般的に「アカウントデータ」と呼ばれています。このフィールドのdataは任意のバイト列を含むことができるため、任意と見なされます。各プログラムがこのフィールドに格納されるデータの構造を定義します。

  • Program accounts: このフィールドには、実行可能なプログラムコードか、実行可能なプログラムコードを格納するプログラムデータアカウントのアドレスが含まれています。
  • データアカウント: このフィールドには一般的に、読み取り用の状態データが格納されています。

Solanaアカウントからデータを読み取るには、次の2つのステップが必要です:

  1. アドレスを使用してアカウントを取得する
  2. プログラムが定義したデータ構造に従って、アカウントのdataフィールドを生のバイトから適切なデータ構造にデシリアライズする

オーナー

このフィールドには、アカウントのオーナーのプログラムIDが含まれています。

すべてのSolanaアカウントには、オーナーとして指定されたプログラムがあります。アカウントのオーナーは、プログラムのinstructionsで指示された通りに、アカウントのdataを変更したりlamportsを差し引いたりできる唯一のプログラムです。

(program accountの場合、オーナーはローダープログラムです。)

実行可能フラグ

このフィールドは、アカウントがprogram accountデータアカウントかを示します

  • trueの場合:アカウントはprogram accountです
  • falseの場合:アカウントはデータアカウントです

Rent epoch

rent_epochフィールドは非推奨です。

過去には、このフィールドはアカウントがrentを支払う必要がある時期を追跡していました。しかし、このrent徴収メカニズムはその後非推奨となりました。

Lamports

アカウントの残高(lamport単位)。

すべてのアカウントは、rentと呼ばれる最低限のlamport残高を持つ必要があります。これによりデータをチェーン上に保存することができます。rentはアカウントのサイズに比例します。

この残高は「rent」と呼ばれていますが、実際には預け金のように機能します。アカウントが閉鎖されると全額が回収できるためです。(「rent」という名前は、現在は非推奨となっているrent epochフィールドに由来しています。)

最低残高の計算式と適用される定数を参照してください。)

データ

このフィールドは一般的に「アカウントデータ」と呼ばれています。このフィールドのdataは任意のバイト列を含むことができるため、任意と見なされます。各プログラムがこのフィールドに格納されるデータの構造を定義します。

  • Program accounts: このフィールドには、実行可能なプログラムコードか、実行可能なプログラムコードを格納するプログラムデータアカウントのアドレスが含まれています。
  • データアカウント: このフィールドには一般的に、読み取り用の状態データが格納されています。

Solanaアカウントからデータを読み取るには、次の2つのステップが必要です:

  1. アドレスを使用してアカウントを取得する
  2. プログラムが定義したデータ構造に従って、アカウントのdataフィールドを生のバイトから適切なデータ構造にデシリアライズする

オーナー

このフィールドには、アカウントのオーナーのプログラムIDが含まれています。

すべてのSolanaアカウントには、オーナーとして指定されたプログラムがあります。アカウントのオーナーは、プログラムのinstructionsで指示された通りに、アカウントのdataを変更したりlamportsを差し引いたりできる唯一のプログラムです。

(program accountの場合、オーナーはローダープログラムです。)

実行可能フラグ

このフィールドは、アカウントがprogram accountデータアカウントかを示します

  • trueの場合:アカウントはprogram accountです
  • falseの場合:アカウントはデータアカウントです

Rent epoch

rent_epochフィールドは非推奨です。

過去には、このフィールドはアカウントがrentを支払う必要がある時期を追跡していました。しかし、このrent徴収メカニズムはその後非推奨となりました。

Account Examples
// Example Token Mint Account
Account {
lamports: 1461600,
data.len: 82,
owner: TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb,
executable: false,
rent_epoch: 0,
data: 010000001e213c90625a7e643d9555bb01b6c3fe6416d7afd523ce8c7ddd9b923ceafb9d00000000000000000901010000001e213c90625a7e643d9555bb01b6,
}
// Example Token Program Account
Account {
lamports: 4513200894,
data.len: 134080,
owner: BPFLoader2111111111111111111111111111111111,
executable: true,
rent_epoch: 18446744073709551615,
data: 7f454c460201010000000000000000000300f70001000000d8f90000000000004000000000000000800902000000000000000000400038000400400009000800,
}

アカウントの種類

アカウントは基本的に2つのカテゴリに分類されます:

この分離により、プログラムの実行可能コードとその状態は別々のアカウントに格納されます。(オペレーティングシステムが通常、プログラムとそのデータを別々のファイルに持つのと同様です。)

Program accounts

すべてのプログラムはローダープログラムによって所有されており、このローダープログラムはアカウントのデプロイと管理に使用されます。新しいプログラムがデプロイされると、その実行可能コードを格納するためのアカウントが作成されます。これをprogram accountと呼びます。(簡単に言えば、program accountをプログラム自体と考えることができます。)

下の図では、ローダープログラムがprogram accountをデプロイするために使用されているのがわかります。program accountのdataには実行可能なプログラムコードが含まれています。

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

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

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

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

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

以下の例ではToken Programアカウントを取得しています。executableフィールドがtrueに設定されていることに注目してください。これはアカウントがプログラムであることを示しています。

import { Address, createSolanaRpc } from "@solana/kit";
const rpc = createSolanaRpc("https://api.mainnet-beta.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.

データアカウント

データアカウントは実行可能なコードを含みません。代わりに、情報を保存します。

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

プログラムはデータアカウントを使用して状態を維持します。そのためには、まず新しいデータアカウントを作成する必要があります。プログラム状態アカウントの作成プロセスはしばしば抽象化されていますが、基本的なプロセスを理解することは役立ちます。

状態を管理するために、新しいプログラムは以下を行う必要があります:

  1. System Programを呼び出してアカウントを作成します。(System Programはその後、所有権を新しいプログラムに転送します。)
  2. instructionsで定義されているように、アカウントデータを初期化します。

プログラムアカウントによって所有されるデータアカウントの図プログラムアカウントによって所有されるデータアカウントの図

以下の例では、Token 2022プログラムによって所有されるトークンミントアカウントを作成して取得しています。

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によって作成されたすべてのアカウントが新しい所有者に割り当てられるわけではありません。System Programが所有するアカウントはシステムアカウントと呼ばれます。すべてのウォレットアカウントはシステムアカウントであり、これにより取引手数料を支払うことができます。

System Programが所有する1,000,000ラムポートを含むウォレットSystem Programが所有する1,000,000ラムポートを含むウォレット

SOLが初めて新しいアドレスに送信されると、そのアドレスにSystem Programが所有するアカウントが作成されます。

以下の例では、新しいkeypairが生成され、SOLで資金提供されています。コードを実行した後、アカウントのownerのアドレスが11111111111111111111111111111111System 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アカウントは事前に定義されたアドレスに存在し、クラスターの状態データへのアクセスを提供します。これらはネットワーククラスターに関するデータで動的に更新されます。Sysvarアカウントの完全なリストをご覧ください。

以下の例では、Sysvar Clockアカウントからデータを取得し、デシリアライズしています。

import { createSolanaRpc } from "@solana/kit";
import { fetchSysvarClock, SYSVAR_CLOCK_ADDRESS } from "@solana/sysvars";
const rpc = createSolanaRpc("https://api.mainnet-beta.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?

管理運営

© 2025 Solana Foundation.
無断転載を禁じます。
アカウント | Solana