プログラム
Solanaでは、「スマートコントラクト」はプログラムと呼ばれています。 プログラムはオンチェーンにデプロイされ、プログラムのコンパイルされた実行可能なバイナリを含むアカウントに格納されます。ユーザーは インストラクションを含むトランザクションを送信することでプログラムと対話し、何をするべきかを指示します。
重要なポイント
- プログラムは実行可能なコードを含むアカウントであり、インストラクションと呼ばれる関数に整理されています。
- プログラム自体はステートレスですが、データを保存するための他のアカウントを作成・更新するインストラクションを含むことができます。
- アップグレード権限を持つアカウントがプログラムを更新できます。この権限が削除されると、プログラムは不変となります。
- ユーザーは検証可能なビルドを通じて、オンチェーンのプログラムアカウントのデータが公開されているソースコードと一致することを確認できます。
Solanaプログラムの作成
Solanaプログラムは主にRustプログラミング言語で書かれており、開発には一般的に2つのアプローチがあります:
-
Anchor: Solanaプログラム開発のために設計されたフレームワークです。Rustマクロを使用してボイラープレートコードを削減し、より速くシンプルにプログラムを書くことができます。初心者の方には、Anchorフレームワークから始めることをお勧めします。
-
ネイティブRust: このアプローチでは、フレームワークを使用せずにRustでSolanaプログラムを書きます。より柔軟性がありますが、複雑さも増します。
Solanaプログラムの更新
プログラムのデプロイとアップグレードについて詳しく学ぶには、 プログラムのデプロイページをご覧ください。
プログラムは「アップグレード権限」として指定されたアカウントによって
直接変更することができます。これは通常、最初にプログラムをデプロイしたアカウントです。
アップグレード権限が取り消され、null
に設定されると、プログラムは不変となり、それ以上更新することはできなくなります。
検証可能なプログラム
検証可能なビルドにより、誰でもプログラムのオンチェーンコードが公開ソースコードと一致するかどうかを確認でき、ソースとデプロイされたバージョン間の不一致を検出することが可能になります。
Solana開発者コミュニティは、検証可能なビルドをサポートするツールを導入し、開発者とユーザーの両方がオンチェーンプログラムが公開共有されたソースコードを正確に反映していることを確認できるようにしました。
-
検証済みプログラムの検索: 検証済みプログラムをすぐに確認するには、ユーザーはSolana Explorerでプログラムアドレスを検索できます。検証済みプログラムの例はこちらでご覧いただけます。
-
検証ツール: Ellipsis LabsによるSolana Verifiable Build CLIを使用すると、ユーザーは公開されたソースコードに対してオンチェーンプログラムを独自に検証できます。
-
Anchorにおける検証可能なビルドのサポート: Anchorは検証可能なビルドの組み込みサポートを提供しています。詳細はAnchorドキュメントで確認できます。
バークレーパケットフィルタ(BPF)
SolanaはLLVM(Low Level Virtual Machine)を使用してプログラムをELF(Executable and Linkable Format)ファイルにコンパイルします。これらのファイルには、「Solana Bytecode Format」(sBPF)と呼ばれるSolana独自バージョンのeBPFバイトコードが含まれています。ELFファイルにはプログラムのバイナリが含まれており、プログラムがデプロイされるとオンチェーンの実行可能アカウントに保存されます。
組み込みプログラム
ローダープログラム
すべてのプログラム自体は、そのローダーである別のプログラムによって所有されています。現在、5つのローダープログラムが存在します:
ローダー | プログラムID | 注記 | 命令リンク |
---|---|---|---|
native | NativeLoader1111111111111111111111111111111 | 他の4つのローダーを所有 | — |
v1 | BPFLoader1111111111111111111111111111111111 | 管理命令は無効化されていますが、プログラムは実行されます | — |
v2 | BPFLoader2111111111111111111111111111111111 | 管理命令は無効化されていますが、プログラムは実行されます | 命令 |
v3 | BPFLoaderUpgradeab1e11111111111111111111111 | 段階的に廃止されています | 命令 |
v4 | LoaderV411111111111111111111111111111111111 | v4は標準ローダーになる予定です | 命令 |
これらのローダーはカスタムプログラムの作成と管理に必要です:
- 新しいプログラムまたはバッファーのデプロイ
- プログラムまたはバッファーのクローズ
- 既存プログラムの再デプロイ/アップグレード
- プログラムの権限の移転
- プログラムの確定
Loader-v3とloader-v4は、初期デプロイ後のプログラム修正をサポートしています。これを行う権限は、各プログラムのアカウント所有権がローダーに属しているため、プログラムの権限によって規制されています。
プリコンパイルされたプログラム
Ed25519プログラム
プログラム | プログラムID | 説明 | 命令 |
---|---|---|---|
Ed25519プログラム | Ed25519SigVerify111111111111111111111111111 | ed25519署名を検証します。署名が失敗した場合、エラーが返されます。 | Instructions |
ed25519プログラムは命令を処理します。最初のu8
はチェックする署名の数を示し、その後に1バイトのパディングが続きます。その後、チェックする各署名について、以下の構造体がシリアライズされます。
struct Ed25519SignatureOffsets {signature_offset: u16, // offset to ed25519 signature of 64 bytessignature_instruction_index: u16, // instruction index to find signaturepublic_key_offset: u16, // offset to public key of 32 bytespublic_key_instruction_index: u16, // instruction index to find public keymessage_data_offset: u16, // offset to start of message datamessage_data_size: u16, // size of message datamessage_instruction_index: u16, // index of instruction data to get message data}
署名検証の疑似コード:
process_instruction() {for i in 0..count {// i'th index values referenced:instructions = &transaction.message().instructionsinstruction_index = ed25519_signature_instruction_index != u16::MAX ? ed25519_signature_instruction_index : current_instruction;signature = instructions[instruction_index].data[ed25519_signature_offset..ed25519_signature_offset + 64]instruction_index = ed25519_pubkey_instruction_index != u16::MAX ? ed25519_pubkey_instruction_index : current_instruction;pubkey = instructions[instruction_index].data[ed25519_pubkey_offset..ed25519_pubkey_offset + 32]instruction_index = ed25519_message_instruction_index != u16::MAX ? ed25519_message_instruction_index : current_instruction;message = instructions[instruction_index].data[ed25519_message_data_offset..ed25519_message_data_offset + ed25519_message_data_size]if pubkey.verify(signature, message) != Success {return Error}}return Success}
Secp256k1プログラム
プログラム | プログラムID | 説明 | 命令 |
---|---|---|---|
Secp256k1プログラム | KeccakSecp256k11111111111111111111111111111 | secp256k1公開鍵リカバリ操作(ecrecover)を検証します。 | Instructions |
secp256k1プログラムは、命令データ内の最初のバイトとして、以下の構造体のシリアライズされたカウントを取る命令を処理します:
struct Secp256k1SignatureOffsets {secp_signature_offset: u16, // offset to [signature,recovery_id] of 64+1 bytessecp_signature_instruction_index: u8, // instruction index to find signaturesecp_pubkey_offset: u16, // offset to ethereum_address pubkey of 20 bytessecp_pubkey_instruction_index: u8, // instruction index to find pubkeysecp_message_data_offset: u16, // offset to start of message datasecp_message_data_size: u16, // size of message datasecp_message_instruction_index: u8, // instruction index to find message data}
リカバリ検証の疑似コード:
process_instruction() {for i in 0..count {// i'th index values referenced:instructions = &transaction.message().instructionssignature = instructions[secp_signature_instruction_index].data[secp_signature_offset..secp_signature_offset + 64]recovery_id = instructions[secp_signature_instruction_index].data[secp_signature_offset + 64]ref_eth_pubkey = instructions[secp_pubkey_instruction_index].data[secp_pubkey_offset..secp_pubkey_offset + 20]message_hash = keccak256(instructions[secp_message_instruction_index].data[secp_message_data_offset..secp_message_data_offset + secp_message_data_size])pubkey = ecrecover(signature, recovery_id, message_hash)eth_pubkey = keccak256(pubkey[1..])[12..]if eth_pubkey != ref_eth_pubkey {return Error}}return Success}
これにより、ユーザーはトランザクション内の署名とメッセージデータに任意の命令データを指定できます。特別な命令sysvarを指定することで、トランザクション自体からデータを受け取ることもできます。
トランザクションのコストは、検証する署名の数に署名コスト検証乗数を掛けた値で計算されます。
Secp256r1 プログラム
プログラム | プログラム ID | 説明 | 命令 |
---|---|---|---|
Secp256r1 プログラム | Secp256r1SigVerify1111111111111111111111111 | 最大8つのsecp256r1署名を検証します。署名、公開鍵、メッセージを受け取り、いずれかが失敗した場合はエラーを返します。 | Instructions |
secp256r1プログラムは命令を処理します。最初の u8
は確認する署名の数を示し、その後に1バイトのパディングが続きます。その後、以下の構造体が、確認する署名ごとに1つずつシリアライズされます:
struct Secp256r1SignatureOffsets {signature_offset: u16, // offset to compact secp256r1 signature of 64 bytessignature_instruction_index: u16, // instruction index to find signaturepublic_key_offset: u16, // offset to compressed public key of 33 bytespublic_key_instruction_index: u16, // instruction index to find public keymessage_data_offset: u16, // offset to start of message datamessage_data_size: u16, // size of message datamessage_instruction_index: u16, // index of instruction data to get message data}
署名検証の擬似コード:
process_instruction() {if data.len() < SIGNATURE_OFFSETS_START {return Error}num_signatures = data[0] as usizeif num_signatures == 0 || num_signatures > 8 {return Error}expected_data_size = num_signatures * SIGNATURE_OFFSETS_SERIALIZED_SIZE + SIGNATURE_OFFSETS_STARTif data.len() < expected_data_size {return Error}for i in 0..num_signatures {offsets = parse_signature_offsets(data, i)signature = get_data_slice(data, instruction_datas, offsets.signature_instruction_index, offsets.signature_offset, SIGNATURE_SERIALIZED_SIZE)if s > half_curve_order {return Error}pubkey = get_data_slice(data, instruction_datas, offsets.public_key_instruction_index, offsets.public_key_offset, COMPRESSED_PUBKEY_SERIALIZED_SIZE)message = get_data_slice(data, instruction_datas, offsets.message_instruction_index, offsets.message_data_offset, offsets.message_data_size)if !verify_signature(signature, pubkey, message) {return Error}}return Success}
注意:署名の偶発的な可鍛性を避けるため、すべての署名に対して低いS値が強制されます。
コアプログラム
Solanaクラスターのジェネシスには、ネットワークの中核機能を提供する特別なプログラムのリストが含まれています。歴史的にこれらは「ネイティブ」プログラムと呼ばれ、以前はvalidatorコードと一緒に配布されていました。
プログラム | プログラム ID | 説明 | 命令 |
---|---|---|---|
System Program | 11111111111111111111111111111111 | 新しいアカウントの作成、アカウントデータの割り当て、アカウントの所有プログラムへの割り当て、System Programが所有するアカウントからのlamport転送、およびトランザクション手数料の支払いを行います。 | SystemInstruction |
Vote Program | Vote111111111111111111111111111111111111111 | validatorの投票状態と報酬を追跡するアカウントを作成および管理します。 | VoteInstruction |
Stake Program | Stake11111111111111111111111111111111111111 | validatorへの委任のためのステークと報酬を表すアカウントを作成および管理します。 | StakeInstruction |
Config Program | Config1111111111111111111111111111111111111 | 設定データをチェーンに追加し、それを変更できる公開鍵のリストを続けます。他のプログラムとは異なり、Configプログラムは個別の命令を定義していません。「store」という暗黙の命令が1つだけあります。その命令データは、アカウントへのアクセスを制御するキーのセットと、その中に格納するデータです。 | ConfigInstruction |
Compute Budget Program | ComputeBudget111111111111111111111111111111 | トランザクションのコンピュートユニットの制限と価格を設定し、ユーザーがコンピュートリソースと優先順位付け手数料を制御できるようにします。 | ComputeBudgetInstruction |
Address Lookup Table Program | AddressLookupTab1e1111111111111111111111111 | アドレス検索テーブルを管理し、トランザクションがアカウントリストに収まる数よりも多くのアカウントを参照できるようにします。 | ProgramInstruction |
ZK ElGamal Proof Program | ZkE1Gama1Proof11111111111111111111111111111 | ElGamal暗号化データのゼロ知識証明検証を提供します。 | — |
Is this page helpful?