Solana入門01:Solanaコアコンセプトを1冊でマスター

10分でSolanaの仕組み、アカウントモデル、トランザクションを理解し、急成長の理由を解明します。

Solana入門01:Solanaコアコンセプトを1冊でマスター

はじめに

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

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

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

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

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

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

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

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

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

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

Solanaのアカウントモデル

Solanaアカウント構造

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

Solanaは、アカウントを説明するために AccountInfo という構造体を使用します。

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

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

  • Executable フィールド:このフィールドは、アカウントがプログラムであるかどうかを示すために使用されます。Ethereumとは異なり、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を転送したりできます。

もう一つの一般的な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トランザクションは、署名とメッセージで構成されます。1つのトランザクションには複数の署名を含めることができます。トランザクションのメッセージは、以下の図に示すように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エクスプローラーを使用しました(https://explorer.solana.com/tx/3uKQ85Lpsnwb5D6CgUntoMyJX3tSaeGb4pjUoMaMyNVqQNPp5PRG1kJEEEk3YNdWLYEMZGmoJ5Rowgon8hZzwL9D?cluster=testnet)。Overviewセクションでは、Solanaトランザクション署名、最近のブロックハッシュ、その他の情報が表示されます。

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

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

結論

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

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

Sign up for the latest updates