プログラム

Solanaでは、スマートコントラクトはプログラムと呼ばれています。プログラムは実行可能なコードを含むステートレスな アカウントです。このコードはinstructionsと呼ばれる関数に整理されています。ユーザーは1つ以上の instructionsを含むトランザクションを送信することでプログラムと対話します。トランザクションには複数のプログラムからのinstructionsを含めることができます。

プログラムがデプロイされると、SolanaはLLVMを使用して実行可能およびリンク可能な形式 (ELF)にコンパイルします。ELFファイルにはSolana Bytecode Format(sBPF)でプログラムのバイナリが含まれ、実行可能なアカウントにオンチェーンで保存されます。

sBPFはSolanaのeBPFバイトコードのカスタムバージョンです。

プログラムを書く

プログラムの大部分はRustで書かれており、一般的な開発アプローチは2つあります:

  • Anchor: Anchorは迅速かつ簡単なSolana開発のために設計されたフレームワークです。 Rustマクロを使用してボイラープレートコードを削減し、初心者に最適です。
  • ネイティブRust: フレームワークを活用せずにRustでプログラムを書きます。このアプローチはより柔軟性を提供しますが、複雑さが増します。

プログラムの更新

既存のプログラムを 修正するには、アカウントがアップグレード権限として指定されている必要があります。(通常、元々プログラムをデプロイしたアカウントと同じです。)アップグレード権限が取り消され、nullに設定されると、プログラムは更新できなくなります。

プログラムの検証

Solanaは検証可能なビルドをサポートしており、ユーザーはプログラムのオンチェーンコードが公開ソースコードと一致するかどうかを確認できます。Anchorフレームワークは検証可能なビルドを作成するための 組み込みサポートを提供しています。

既存のプログラムが検証済みかどうかを確認するには、Solana ExplorerでそのプログラムIDを検索してください。あるいは、Ellipsis Labsの Solana Verifiable Build CLIを使用して、オンチェーンプログラムを独自に検証することもできます。

組み込みプログラム

System Program

System Programは、新しいアカウントを作成できる唯一のアカウントです。デフォルトでは、すべての新しいアカウントはSystem Programによって所有されていますが、作成時に多くのアカウントに新しい所有者が割り当てられます。System Programは以下の主要な機能を実行します:

機能説明
新規アカウント作成System Programのみが新しいアカウントを作成できます。
スペース割り当て各アカウントのデータフィールドのバイト容量を設定します。
プログラム所有権の割り当てSystem Programがアカウントを作成した後、指定されたプログラム所有者を別のプログラムアカウントに再割り当てすることができます。これにより、カスタムプログラムがSystem Programによって作成された新しいアカウントの所有権を取得します。
SOL転送システムアカウントから他のアカウントにlamports(SOL)を転送します。

System Programのアドレスは11111111111111111111111111111111です。

ローダープログラム

すべてのプログラムは別のプログラム(そのローダー)によって所有されています。ローダーはプログラムのデプロイ、再デプロイ、アップグレード、または閉鎖に使用されます。また、プログラムの確定とプログラム権限の移転にも使用されます。

ローダープログラムは「BPFローダー」と呼ばれることもあります。

現在、以下の表に示すように5つのローダープログラムがあります。

ローダープログラムID備考instructionsリンク
nativeNativeLoader1111111111111111111111111111111他の4つのローダーを所有しています
v1BPFLoader1111111111111111111111111111111111管理instructionsは無効化されていますが、プログラムは引き続き実行されます
v2BPFLoader2111111111111111111111111111111111管理instructionsは無効化されていますが、プログラムは引き続き実行されますInstructions
v3BPFLoaderUpgradeab1e11111111111111111111111プログラムはデプロイ後に更新できます。プログラム実行可能ファイルは別のプログラムデータアカウントに保存されますInstructions
v4LoaderV411111111111111111111111111111111111開発中(未リリース)Instructions

loader-v3またはloader-v4でデプロイされたプログラムは、そのアップグレード権限によって決定される通り、デプロイ後に変更可能な場合があります。

新しいプログラムがデプロイされる際、デフォルトで最新のローダーバージョンが使用されます。

プリコンパイルされたプログラム

ローダープログラムに加えて、Solanaは以下のプリコンパイルされたプログラムを提供しています。

ed25519署名の検証

ed25519プログラムは、1つまたは複数のed25519署名を検証するために使用されます。

プログラムプログラムID説明instructions
Ed25519 プログラムEd25519SigVerify111111111111111111111111111ed25519署名を検証します。いずれかの署名が失敗した場合、エラーが返されます。Instructions

ed25519プログラムはinstructionを処理します。instructionの最初のu8には、チェックする署名の数のカウントが含まれ、その後に1バイトのパディングが続きます。その後、チェックする各署名に対して以下の構造体がシリアル化されます。

Ed25519SignatureOffsets
struct Ed25519SignatureOffsets {
signature_offset: u16, // offset to ed25519 signature of 64 bytes
signature_instruction_index: u16, // instruction index to find signature
public_key_offset: u16, // offset to public key of 32 bytes
public_key_instruction_index: u16, // instruction index to find public key
message_data_offset: u16, // offset to start of message data
message_data_size: u16, // size of message data
message_instruction_index: u16, // index of instruction data to get message data
}
Signature verification pseudocode
process_instruction() {
for i in 0..count {
// i'th index values referenced:
instructions = &transaction.message().instructions
instruction_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リカバリーの検証

secp256k1プログラムは、secp256k1公開鍵のリカバリー操作を検証するために使用されます。

プログラムプログラムID説明instructions
Secp256k1 プログラムKeccakSecp256k11111111111111111111111111111secp256k1公開鍵のリカバリー操作(ecrecover)を検証します。Instructions

secp256k1プログラムはinstructionを処理します。instructionの最初のバイトには、チェックする公開鍵の数のカウントが含まれています。その後、各公開鍵に対して以下の構造体が一度作成され、シリアル化されてinstruction dataに追加されます。

Secp256k1SignatureOffsets
struct Secp256k1SignatureOffsets {
secp_signature_offset: u16, // offset to [signature,recovery_id] of 64+1 bytes
secp_signature_instruction_index: u8, // instruction index to find signature
secp_pubkey_offset: u16, // offset to ethereum_address pubkey of 20 bytes
secp_pubkey_instruction_index: u8, // instruction index to find pubkey
secp_message_data_offset: u16, // offset to start of message data
secp_message_data_size: u16, // size of message data
secp_message_instruction_index: u8, // instruction index to find message data
}
Recovery verification pseudocode
process_instruction() {
for i in 0..count {
// i'th index values referenced:
instructions = &transaction.message().instructions
signature = 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
}

これにより、ユーザーはトランザクション内の署名とメッセージデータに任意のinstruction dataを指定できます。特別なinstructions sysvarを指定することで、トランザクション自体からデータを受け取ることもできます。

トランザクションのコストは、検証する署名の数に署名コスト検証乗数を掛けた値になります。

Secp256r1プログラムは、最大8つのsecp256r1署名を検証するために使用されます。

プログラムプログラムID説明instructions
Secp256r1プログラムSecp256r1SigVerify1111111111111111111111111最大8つのsecp256r1署名を検証します。署名、公開鍵、メッセージを受け取り、いずれかが失敗した場合はエラーを返します。Instructions

Secp256r1プログラムはinstructionを処理します。instructionの最初のu8には、チェックする署名の数が含まれており、その後に1バイトのパディングが続きます。その後、以下の構造体が各署名に対して作成され、シリアル化されてinstruction dataに追加されます。

Secp256r1SignatureOffsets
struct Secp256r1SignatureOffsets {
signature_offset: u16, // offset to compact secp256r1 signature of 64 bytes
signature_instruction_index: u16, // instruction index to find signature
public_key_offset: u16, // offset to compressed public key of 33 bytes
public_key_instruction_index: u16, // instruction index to find public key
message_data_offset: u16, // offset to start of message data
message_data_size: u16, // size of message data
message_instruction_index: u16, // index of instruction data to get message data
}

署名の偶発的な可鍛性を避けるため、すべての署名に対してLow S値が強制されます。

Signature verification psuedocode
process_instruction() {
if data.len() < SIGNATURE_OFFSETS_START {
return Error
}
num_signatures = data[0] as usize
if num_signatures == 0 || num_signatures > 8 {
return Error
}
expected_data_size = num_signatures * SIGNATURE_OFFSETS_SERIALIZED_SIZE + SIGNATURE_OFFSETS_START
if 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
}

コアプログラム

以下のリストにあるプログラムは、ネットワークのコア機能を提供します。

プログラムプログラムID説明instructions
System11111111111111111111111111111111新しいアカウントの作成、アカウントデータの割り当て、アカウントを所有プログラムに割り当て、Systemプログラム所有のアカウントからlamportsの転送、トランザクション手数料の支払いSystemInstruction
VoteVote111111111111111111111111111111111111111バリデーターの投票状態と報酬を追跡するアカウントの作成と管理VoteInstruction
StakeStake11111111111111111111111111111111111111バリデーターへの委任のためのステークと報酬を表すアカウントの作成と管理StakeInstruction
ConfigConfig1111111111111111111111111111111111111設定データをチェーンに追加し、その後にそれを変更できる公開鍵のリストを追加します。他のプログラムとは異なり、Configプログラムは個別のinstructionを定義していません。「store」という暗黙的なinstructionが1つだけあります。そのinstruction dataは、アカウントへのアクセスとその中に保存されているデータを制御するキーのセットですConfigInstruction
Compute BudgetComputeBudget111111111111111111111111111111トランザクションのコンピュートユニットの制限と価格を設定し、ユーザーがコンピュートリソースと優先順位付け手数料を制御できるようにしますComputeBudgetInstruction
Address Lookup TableAddressLookupTab1e1111111111111111111111111アドレス検索テーブルを管理し、トランザクションがアカウントリストに収まる以上のアカウントを参照できるようにしますProgramInstruction
ZK ElGamal ProofZkE1Gama1Proof11111111111111111111111111111ElGamal暗号化データのゼロ知識証明検証を提供します

Is this page helpful?

管理運営

© 2025 Solana Foundation.
無断転載を禁じます。
プログラム | Solana