Solana 徹底解説 01: Solana のコアコンセプトを一度にマスター

わずか10分で、Solanaの動作メカニズム、アカウントモデル、トランザクションを理解し、その爆発的な成長の理由を解き明かしましょう。

Solana 徹底解説 01: Solana のコアコンセプトを一度にマスター

はじめに

2024年、Solanaは目覚ましい成長を遂げ、総ロックバリュー(TVL)は年初の10億ドルから約50億ドルへと急増し、4番目に大きなパブリックブロックチェーンとなりました。

イーサリアムと比較して、Solanaはより高速かつ低コストでユーザーに優れた体験を提供します。Proof of Historyベースのコンセンサスメカニズムと非同期トランザクション処理モデルは、開発者に高いトランザクションスループットと低レイテンシをもたらし、あらゆる種類の分散型アプリケーションにとって好ましいプラットフォームとなっています。

BlockSecでは、Solanaの基本概念、Solanaトランザクション分析の実践ガイド、Solanaスマートコントラクト作成チュートリアルを網羅する「Solana簡略化」シリーズを特別に企画しました。

このシリーズの最初の記事として、本稿ではSolanaネットワーク内の主要な概念、その動作メカニズム、アカウントモデル、トランザクションについて掘り下げ、Solanaで正確かつ効率的なスマートコントラクトを作成するための基盤を築きます。

eBPF:Solanaトランザクション実行の要

スマートコントラクトを作成・実行するために、ブロックチェーンは通常、プログラミング言語とチューリング完全な計算環境を必要とします。

イーサリアムのスマートコントラクトは、通常、Solidityと呼ばれる高水準言語で記述されます。コンパイラはそれをバイトコードに変換し、イーサリアム仮想マシン(EVM)で実行されます。Solanaは、完全に新しい仮想環境と言語を開発するのではなく、既存の先進技術を最大限に活用することを選択しました。Linuxカーネルの機能を拡張するために当初設計されたeBPF(extended Berkeley Packet Filter)仮想マシンは、Solanaによって基盤となる実行環境として選ばれました。

では、eBPFはEVMと比較してどのような利点があるのでしょうか?

解釈実行に限定されるEVMとは異なり、eBPFはJIT(Just-In-Time)コンパイルをサポートしており、バイトコードをプロセッサが直接実行できるマシン命令に変換できます。このような能力は、プログラムの効率を大幅に向上させます。

さらに、eBPFは効率的な命令セットと成熟したインフラストラクチャを備えています。開発者はRust言語を使用してスマートコントラクトを作成できます。LLVMコンパイラフレームワークのeBPFバックエンドを活用することで、Rustプログラムは直接eBPFバイトコードにコンパイルできます。

Solanaのアカウントモデル

Solanaアカウント構造

Solanaでは、データはアカウントの形式で保存されます。以下に示すように、Solana内のすべてのデータは、巨大なキーバリューデータベースとして概念化できます。このデータベースのキーはアカウントアドレスです。「ウォレット」アカウント(つまり、Solanaユーザーが公開鍵と秘密鍵のペアを介して直接制御するアカウント)の場合、これらのアドレスはEd25519署名システムを使用して生成された公開鍵です。データベースの値は、残高やその他の関連情報を含む、各アカウントの特定の詳細で構成されます。

Solanaは、アカウントを記述するためにAccountInfoとして知られる以下の構造を使用します。

各アカウントのAccountInfoには4つのフィールドが含まれます。それぞれの説明は以下の通りです。

  • Dataフィールド:このフィールドはアカウントに関連するデータを保存します。アカウントがプログラム(つまり、スマートコントラクト)の場合、eBPFバイトコードが保存されます。そうでない場合、データの形式は一般的にアカウント作成者によって定義されます。

  • Executableフィールド:このフィールドは、アカウントがプログラムであるかどうかを示すために使用されます。イーサリアムとは異なり、Solanaではプログラムを更新できることに注意することが重要です。

  • Lamportsフィールド:このフィールドは、アカウントのSolanaトークンの残高を記録します。Lamportsは、SOLトークンの最小単位です(1 SOL = 10億 Lamports)。

  • Ownerフィールド:このフィールドはアカウントの所有者を示します。Solanaでは、すべてのアカウントに「所有者」があります。たとえば、すべての「ウォレット」アカウントの所有者は、アカウント作成などの機能の担当であるSolanaネットワーク上の特別なアカウントであるSystem Programです。アカウントの所有者のみがアカウントデータを変更し、残高からLamportsを差し引くことができます(ただし、誰でも送金によってLamportsを増やすことができます)。

事前定義されたSolanaアカウント

Solanaには、Native Programsとして知られる事前定義された実行可能プログラムのセットがあり、固定アドレスにデプロイされています。Solanaネットワークがアップグレードされると、これらの事前定義されたプログラムも更新できます。これらはAPIおよびライブラリ関数として機能し、Solanaネットワーク内で特定の機能を提供します。

Native Programsの中で、開発者がよくやり取りするのはSystem Programです。System Programは、開発者に一連の命令を提供し、各命令は独立したタスクを実行します。たとえば、開発者はCreateAccount命令を使用して新しいアカウントを作成したり、Transfer命令を使用してLamportsを別のアカウントに転送したりできます。

もう1つの一般的なNative ProgramはBPF Loaderプログラムです。これは、他のすべてのプログラムアカウントの所有者であり、カスタムプログラムのデプロイ、更新、実行を担当します。ウォレットアカウントがデプロイしたプログラムを更新する必要がある場合、プログラムの所有者のみがデータを直接変更する権限を持っているため、実際にはBPF Loaderプログラムに委任することによって行われます。

Native Programsに加えて、SolanaはSysvarsとして知られるアカウントのセットも提供しています。これらのアカウントは、Solana上のプログラムに、現在のSolanaネットワークの状態に関連する情報およびグローバル変数(現在のクロックや最新のブロックハッシュなど)を提供します。

アカウントレント

Solanaブロックチェーンでは、各アカウントはレントとして知られる最小残高を維持する必要があります。実際のレントとは異なり、Solanaのレントは回収可能です。アカウントのデータがチェーンで利用可能であることを保証するには、アカウントは適切な量のLamportsを保持する必要があります。レントの金額は、アカウントが占めるデータサイズに関連しています。

アカウントの残高をレント額を下回るように減らそうとするトランザクションは、残高を正確にゼロにしない限り失敗します。残高をゼロにすることは、アカウントのレントが回収されたことを示し、トランザクションの終了時にSolanaはガベージコレクションプロセスで対応するアカウントのデータをクリアします。

🧐 Solana ScansでSolanaアカウントを表示する

上記概念をよりよく理解するために、Solanaの"Hello World"プロジェクトを使用してプログラムアカウントをデプロイし、SolanaのブロックチェーンエクスプローラーであるSolscanで表示しました。

上の画像に示すように、まずアカウントが「Program」とラベル付けされていることがわかります。このアカウントのレントとして送信者の残高からLamportsの一部が差し引かれたため、SOL Balanceフィールドは空ではありません。さらに、作成したアカウントはプログラムであるため、Executableフィールドは「Yes」に設定されています。 Executable DataフィールドがeBPFプログラムではなくアドレスを格納していることに混乱するかもしれません。前述のように、Solanaではプログラムの更新が可能であり、これは実際には「プロキシ」パターンを介して実装されます。プログラムアカウントへの直接変更は当初許可されていないため、SolanaはeBPFプログラムを格納するために別のデータアカウントを作成し、プログラムアカウントのDataフィールドにはこのデータアカウントのアドレスのみが格納されます。 プログラムの更新が必要な場合は、データアカウントのDataフィールドのみを変更する必要があります。Solscanを使用してデータアカウントを表示すると、「Program Executable Data Account」としてマークされており、そのDataフィールドに実際のプログラムが格納されていることがわかります。

「More Info」セクションのOwnerフィールドはBPF Loaderであり、前述した内容と一致しています。

「Overview」の最後のフィールドに、AccountInfoには存在しないUpgrade Authorityがあることに気づく人もいるかもしれません。これはどういう意味でしょうか?

前述のように、「ウォレット」アカウントはプログラムの更新をBPF Loaderに委任します。更新の前に、BPF Loaderは委任者がプログラムを最初にデプロイしたアカウントであるかどうかを確認します。プログラムアカウントのOwnerはすでにBPF Loaderに設定されているため、この情報を格納するスペースがありません。そのため、SolanaはそれをデータアカウントのDataフィールドに格納します。これが「Overview」にUpgrade Authorityフィールドがあり、実際にはプログラムをデプロイしたウォレットアドレスである理由です。 下の画像は、プログラムアカウントとデータアカウントの関係を示しています。データアカウントのDataフィールドには、ウォレットアドレスとeBPFコードの両方が含まれていることに注意してください。

Solanaのトランザクションと命令

Solanaでは、ユーザーはトランザクションを発行してプログラムを実行します。Solanaのユニークな点は、これらのトランザクションを並列実行できることであり、これが驚異的なトランザクション速度の主な理由です。それでは、トランザクションがSolanaでどのように設計されているかを詳しく見てみましょう。

Solanaトランザクションは、署名とメッセージで構成されます。トランザクションには複数の署名を含めることができます。トランザクションのメッセージは、以下の図に示すように4つの部分で構成されます。

HeaderCompact Array of Account Addressesは、トランザクションに関与するすべてのアカウントと、トランザクション中のアカウントの特性(アカウントが署名者であるかどうか、実行中に書き込み可能かどうかなど)を指定します。この情報により、Solanaは署名者アカウントから提供された署名を検証し、これらのトランザクションが同じ状態に書き込むアカウントを含まない限り、トランザクションを並列処理できます。

Recent Blockhashはトランザクションのタイムスタンプとして機能します。トランザクションのブロックハッシュが最新のブロックハッシュよりも150ブロック古い場合、それは期限切れと見なされ、実行されません。

Compact Array of Instructionsはトランザクションの最も重要な部分であり、1つ以上の命令を含んでいます。命令は、プログラムアカウントによって提供されるルーチンの実行をトリガーします。各命令は、以下の図に示すように3つのフィールドで構成されます。

最初のフィールドであるProgram ID Indexは、命令の受信者を指定します。これは、命令を処理する必要があるオンチェーンプログラムです。32バイトのアドレスを格納するのではなく、このアドレスはトランザクションメッセージのCompact Array of Account Addresses内に配置され、フィールドは配列内のアドレスを指すu8インデックスのみを格納します。

最初のフィールドと同様に、2番目のフィールドはCompact Array of Account Address Indexesとして知られるアカウントアドレスインデックスを格納します。この配列は、この命令に関与するすべてのアカウントを指定します。

最後のフィールドは、関数引数など、プログラムが命令を処理するために必要な追加データを含むバイト配列です。

Solanaは、トランザクション内のすべての命令を順番に処理し、トランザクションの原子的な実行を保証することに注意することが重要です。これは、すべての命令が正常に処理されて完全に完了するか、完全に失敗するかのどちらかであることを意味します。一部の命令が処理され、他は処理されないような状況はありません。

🧐 Solana ScansでSolanaトランザクションを表示する

別のSolanaエクスプローラーを使用して、以前にプログラムアカウントを作成したトランザクションを表示します。Overviewセクションでは、Solanaトランザクション署名、最近のブロックハッシュ、その他の情報を見ることができます。

Account Inputセクションには、現在のトランザクションに関与するすべてのアカウントと、トランザクションにおけるそれらの特性がリストされています。送信者とプログラムアカウントのアドレスに加えて、2つのNative ProgramsSysvarアカウントも含まれていることがわかります。

これは単純なプログラム作成トランザクションであるため、2つの命令しか含まれていません。最初の命令の受信者は、プログラムアカウントの作成を担当するSystem Programです。2番目の命令の受信者は、デプロイされたeBPFコードを格納するためのデータアカウントを作成し、そのアドレスをプログラムアカウントのDataフィールドに書き込むBPF Loaderです。

結論

SolanaのスマートコントラクトはRustで開発され、eBPF仮想マシン上で実行されます。Solanaはアカウントモデルに従っており、オンチェーンアカウントはデータが削除されないように十分なレントを維持する必要があります。トランザクションは、必要なすべてのアカウントを定義する1つ以上の命令で構成され、並列処理を可能にし、スループットを向上させながら応答レイテンシを削減します。これらの機能はすべて、Solanaの急速な発展に貢献し、主要なブロックチェーンの1つとなっています。

このシリーズの他の記事を読む:

Sign up for the latest updates