ネットワークからの読み取り
このセクションでは、さまざまなアカウントを取得してSolanaアカウントの構造を理解するために、Solanaネットワークからデータを読み取る方法を探ります。
Solanaでは、すべてのデータは「アカウント」内に存在します。Solana上のデータは、各エントリが同じ基本的な アカウントタイプを持つアカウントである、単一の「アカウント」テーブルを持つ公開データベースと考えることができます。
#[derive(PartialEq, Eq, Clone, Default)]pub struct Account {/// lamports in the accountpub 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 rentpub rent_epoch: Epoch,}
アカウント
Solana上のアカウントは「状態」または「実行可能な」プログラムを保存できます。各アカウントには、対応するオンチェーンデータを見つけるために使用される一意のIDとして機能する「アドレス」(公開鍵)があります。
Solanaアカウントには以下のいずれかが含まれます:
- 状態:読み取りおよび永続化されることを意図したデータ。例えば、トークンに関する情報、ユーザーデータ、またはプログラム内で定義されたその他のデータなど。
- 実行可能なプログラム:Solanaプログラムの実際のコードを含むアカウント。これらのアカウントは、ユーザーが呼び出すことができるinstructionsを保存します。
プログラムコードとプログラム状態のこの分離は、Solanaのアカウントモデルの重要な特徴です。詳細については、 Solanaアカウントモデルページを参照してください。
ウォレットアカウントの取得
この例では、以下の方法を示します:
- 新しいkeypair(公開/秘密鍵のペア)を生成します。
- 新しいアドレスに資金を提供するためにSOLのエアドロップをリクエストします。
- 資金提供されたアドレスのアカウントデータを取得します。
Solanaでは、SOLで新しいアドレスに資金を提供すると、自動的にSystem Programが所有するアカウントが作成されます。すべての「ウォレット」アカウントは、単にSOLを保持し、トランザクションに署名できるSystem Program所有のアカウントです。
import { Keypair, Connection, LAMPORTS_PER_SOL } from "@solana/web3.js";const keypair = Keypair.generate();console.log(`Public Key: ${keypair.publicKey}`);const connection = new Connection("http://localhost:8899", "confirmed");// Funding an address with SOL automatically creates an accountconst signature = await connection.requestAirdrop(keypair.publicKey,LAMPORTS_PER_SOL);await connection.confirmTransaction(signature, "confirmed");const accountInfo = await connection.getAccountInfo(keypair.publicKey);console.log(JSON.stringify(accountInfo, null, 2));
Solanaにおける「ウォレット」は、Solanaの組み込みプログラムの一つであるSystem Programが所有するアカウントです。ウォレットアカウントは主にSOL(lamports
フィールドで追跡される)の保持とトランザクションの署名に使用されます。
ウォレットアカウントを取得すると、レスポンスには例の出力に示されているフィールドが含まれます。
{"data": {"type": "Buffer","data": []},"executable": false,"lamports": 1000000000,"owner": "11111111111111111111111111111111","rentEpoch": 0,"space": 0}
data
フィールドには、バイトとして保存されたアカウントのデータが含まれています。
ウォレットアカウントの場合、このフィールドは空(0バイト)です。他のアカウントはこのフィールドを使用して、プログラムの状態または実行可能なプログラムコードのいずれかを保存します。
{"data": {"type": "Buffer","data": []},"executable": false,"lamports": 1000000000,"owner": "11111111111111111111111111111111","rentEpoch": 0,"space": 0}
executable
フィールドは、アカウントのdata
フィールドに実行可能なプログラムコードが含まれているかどうかを示します。
ウォレットおよびプログラム状態を保存するアカウントの場合、このフィールドはfalse
です。
{"data": {"type": "Buffer","data": []},"executable": false,"lamports": 1000000000,"owner": "11111111111111111111111111111111","rentEpoch": 0,"space": 0}
lamports
フィールドには、lamportで表示されたアカウントのSOL残高が含まれています。
lamportはSOLの最小単位です。1 SOL = 1,000,000,000 lamportです。
{"data": {"type": "Buffer","data": []},"executable": false,"lamports": 1000000000,"owner": "11111111111111111111111111111111","rentEpoch": 0,"space": 0}
owner
フィールドは、アカウントを所有するプログラムを示します。
ウォレットの場合、所有者は常にSystem Programであり、アドレスは
11111111111111111111111111111111
です。
rentEpoch
フィールドは、アカウントがネットワーク上でデータを維持するために「rent」(lamport単位)を課金する廃止されたメカニズムからの古いフィールドです。
このフィールドは現在使用されていませんが、後方互換性のために含まれています。
space
フィールドは、data
フィールド内のバイト数を示します。これはAccount
型自体のフィールドではありませんが、レスポンスに含まれています。
この例では、data
フィールドに0バイトのデータが含まれているため、space
フィールドは0です。
Token Programの取得
この例では、ウォレットアカウントとプログラムアカウントの違いを示すためにToken Programを取得します。
プログラムアカウントには、Token Programのソースコードのコンパイルされたバイトコードが格納されています。このプログラムアカウントはSolana Explorerで確認できます。
import { Connection, PublicKey } from "@solana/web3.js";const connection = new Connection("https://api.mainnet-beta.solana.com","confirmed");const address = new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");const accountInfo = await connection.getAccountInfo(address);
Token ProgramはSolana上の実行可能なprogram accountです。ウォレットアカウントと同様に、プログラムも同じ基本的なAccountデータ構造を持っていますが、そのフィールドには重要な違いがあります。
executable
フィールドはtrue
に設定されており、このアカウントのdata
フィールドに実行可能なプログラムコードが含まれていることを示しています。
プログラムアカウントでは、data
フィールドにプログラムの実行可能コードが格納されます。対照的に、ウォレットアカウントのデータフィールドは空です。
Solanaプログラムをデプロイすると、プログラムの実行可能コードはアカウントのdata
フィールドに格納されます。
実行可能なプログラムアカウントには、アカウントのowner
として指定されたプログラムもあります。
すべてのプログラムアカウントは、Loaderプログラムによって所有されています。Loaderプログラムは、Solana上で実行可能なプログラムアカウントを所有する組み込みプログラムのカテゴリです。
Token Programの場合、owner
はBPFLoader2プログラムです。
mint accountの取得
この例では、USD Coin(USDC)のmint accountを取得して、Solana上のプログラムが別々のアカウントに状態を格納する方法を示します。
MintアカウントはToken Programによって所有されるアカウントです。特定のトークンに関する総供給量、小数点以下の桁数、トークンの発行や凍結を許可されたアカウントなどのグローバルメタデータを格納します。mint accountのアドレスは、Solanaネットワーク上のトークンを一意に識別します。
import { Connection, PublicKey } from "@solana/web3.js";const connection = new Connection("https://api.mainnet-beta.solana.com","confirmed");const address = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");const accountInfo = await connection.getAccountInfo(address);
この例で注目すべき重要なポイントは、Mint accountが実行可能なコードではなく状態を保存するということです。
Mint accountはToken Programによって所有され、Token ProgramにはMint accountの作成と更新方法を定義するinstructionsが含まれています。
{"data": {"type": "Buffer","data": [1, "...truncated, total bytes: 82...", 103]},"executable": false,"lamports": 407438077149,"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","rentEpoch": 18446744073709552000,"space": 82}
executable
フィールドはfalse
です。これはmint
accountのdata
フィールドが実行可能なコードではなく状態を保存するためです。
Token ProgramはMint
データ型を定義しており、これはmint
accountのdata
フィールドに保存されます。
{"data": {"type": "Buffer","data": [1, "...truncated, total bytes: 82...", 103]},"executable": false,"lamports": 407438077149,"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","rentEpoch": 18446744073709552000,"space": 82}
data
フィールドには、ミント権限、総供給量、小数点以下の桁数などのシリアライズされたMint
アカウント状態が含まれています。
Mint
accountから読み取るには、data
フィールドをMint
データ型にデシリアライズする必要があります。これについては次のステップで説明します。
{"data": {"type": "Buffer","data": [1, "...truncated, total bytes: 82...", 103]},"executable": false,"lamports": 407438077149,"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","rentEpoch": 18446744073709552000,"space": 82}
Token Program(TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
)がmint
accountを所有しています。
これは、mint accountのdata
フィールドがToken
Programで定義されたinstructionsによってのみ変更できることを意味します。
{"data": {"type": "Buffer","data": [1, "...truncated, total bytes: 82...", 103]},"executable": false,"lamports": 407438077149,"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","rentEpoch": 18446744073709552000,"space": 82}
Mint Accountのデシリアライズ
Solanaアカウントのdata
フィールドには生のバイトが含まれています。このデータを意味のある形で解釈するには、アカウントを所有するプログラムによって定義された適切なデータ型にデシリアライズする必要があります。
ほとんどのSolanaプログラムは、デシリアライズプロセスを抽象化するヘルパー関数を持つクライアントライブラリを提供しています。これらの関数は、生のアカウントバイトを構造化されたデータ型に変換し、アカウントデータの操作を容易にします。
例えば、*shell@solana/spl-token
*には、Mint
accountのdata
フィールドをMintデータ型にデシリアライズするのに役立つgetMint()
関数が含まれています。
import { PublicKey, Connection } from "@solana/web3.js";import { getMint } from "@solana/spl-token";const connection = new Connection("https://api.mainnet-beta.solana.com","confirmed");const address = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");const mintData = await getMint(connection, address, "confirmed");
pub struct Mint {/// Optional authority used to mint new tokens. The mint authority may only/// be provided during mint creation. If no mint authority is present/// then the mint has a fixed supply and no further tokens may be/// minted.pub mint_authority: COption<Pubkey>,/// Total supply of tokens.pub supply: u64,/// Number of base 10 digits to the right of the decimal place.pub decimals: u8,/// Is `true` if this structure has been initializedpub is_initialized: bool,/// Optional authority to freeze token accounts.pub freeze_authority: COption<Pubkey>,}
*tsgetMint()
*関数は、mint accountのdata
フィールドをToken
Programで定義されている
Mint
データ型にデシリアライズします。
{"data": {"type": "Buffer","data": [1, "...truncated, total bytes: 82...", 103]},"executable": false,"lamports": 407438077149,"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","rentEpoch": 18446744073709552000,"space": 82}
完全にデシリアライズされた Mint Account データはSolana Explorerで確認できます。
address
フィールドにはMint accountのアドレスが含まれています。
mint accountのアドレスは、Solanaネットワーク上でトークンを識別するために使用されます。
mintAuthority
フィールドは、新しいトークンをミントする権限を持つアカウントを示しています。
これは、トークンの新しい単位を作成できる唯一のアカウントです。
supply
フィールドは、ミントされたトークンの総数を示しています。
この値はトークンの最小単位で表されています。標準単位での総供給量を取得するには、supply
フィールドの値をdecimals
で調整します。
decimals
フィールドはトークンの小数点以下の桁数を示しています。
isInitialized
フィールドはmint
accountが初期化されているかどうかを示します。このフィールドはToken
Programで使用されるセキュリティチェックです。
freezeAuthority
フィールドはtoken
accountをフリーズする権限を持つ管理者を示しています。
フリーズされたtoken accountではアカウント内のトークンの転送や焼却ができなくなります。
tlvData
フィールドにはToken
Extensions用の追加データが含まれています(さらなるデシリアライズが必要)。
このフィールドはToken Extension Program (Token2022)によって作成されたアカウントにのみ関連しています。
Is this page helpful?