導入
普段 Rust で作る実行ファイル(.exe など)は、自分のパソコンの OS の上でそのまま動きます。しかし Solana のプログラムは、あなたのパソコンでは実行されません。世界中に散らばる バリデータ のコンピュータ上で、同じ結果になるように実行される必要があります。そのために、普通の Rust プログラムとは違う「コンパイルのゴール」が用意されています。
説明
Solana のプログラムは、Rust のソースコードから直接ネイティブな実行ファイルを作るのではなく、SBF(Solana Bytecode Format。もとは BPF = Berkeley Packet Filter を拡張したもの) と呼ばれる中間バイトコードにコンパイルされます。これは共有ライブラリ(.so ファイル)の形をしていて、「エントリポイント(入り口の関数)を1つだけ持つ、実行ファイルではないファイル」だとイメージすると分かりやすいです。
flowchart LR
S["Rustのソースコード<br/>(lib.rs)"] -- "cargo build-sbf" --> B["SBFバイトコード<br/>(program.so)"]
B -- "solana program deploy" --> V1["バリデータ1"]
B -- 同じコードを配布 --> V2["バリデータ2"]
B -- 同じコードを配布 --> V3["バリデータ3"]
V1 & V2 & V3 --> R["全バリデータが同じ入力に<br/>同じ結果を出す"]
ビルドには専用コマンドを使います。
# 通常の cargo build ではなく、SBFターゲット向けにビルドする
cargo build-sbf
# ビルドしてできた program.so をクラスタ(devnetなど)へデプロイする
solana program deploy ./target/deploy/my_program.so
普通の Rust プロジェクトとの違いは主に2つです。
- クレートの種類が
cdylib(C言語から呼べる動的ライブラリ形式)であること。実行可能ファイル(bin)ではありません。 main関数の代わりに「エントリポイント」を持つこと。これは次のレッスンで詳しく見ます。
デプロイされたプログラム自身も、実は Solana 上では1つの「実行可能(executable)なアカウント」として扱われます。プログラムのコード(SBFバイトコード)はそのアカウントの data に、実行に必要な状態はプログラムとは別のアカウントに置く、という役割分担が、この先ずっと出てくる Solana 設計の基本パターンです。
演習
「プログラムのコード」と「プログラムが読み書きするデータ」が別々のアカウントに分かれている、という設計を思い出してください。もしこの2つが同じ場所に混ざっていたら、どんな不便が起きそうか考えてみましょう。
ヒント1を見る
同じユーザーが同じプログラムを使っても、扱うデータ(残高やカウンタなど)は人それぞれ違います。
ヒント2を見る
コード自体は全ユーザー共通で1つだけあればよい、という点に注目してみましょう。