プログラム
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です。
ローダープログラム
すべてのプログラムは別のプログラム(そのローダー)によって所有されています。ローダーはプログラムのデプロイ、再デプロイ、アップグレード、または閉鎖に使用されます。また、プログラムの確定とプログラム権限の移転にも使用されます。
現在、以下の表に示すように5つのローダープログラムがあります。
| ローダー | プログラムID | 備考 | instructionsリンク |
|---|---|---|---|
| native | NativeLoader1111111111111111111111111111111 | 他の4つのローダーを所有しています | — |
| v1 | BPFLoader1111111111111111111111111111111111 | 管理instructionsは無効化されていますが、プログラムは引き続き実行されます | — |
| v2 | BPFLoader2111111111111111111111111111111111 | 管理instructionsは無効化されていますが、プログラムは引き続き実行されます | Instructions |
| v3 | BPFLoaderUpgradeab1e11111111111111111111111 | プログラムはデプロイ後に更新できます。プログラム実行可能ファイルは別のプログラムデータアカウントに保存されます | Instructions |
| v4 | LoaderV411111111111111111111111111111111111 | 開発中(未リリース) | Instructions |
loader-v3またはloader-v4でデプロイされたプログラムは、そのアップグレード権限によって決定される通り、デプロイ後に変更可能な場合があります。
新しいプログラムがデプロイされる際、デフォルトで最新のローダーバージョンが使用されます。
プリコンパイルされたプログラム
ローダープログラムに加えて、Solanaは以下のプリコンパイルされたプログラムを提供しています。
ed25519署名の検証
ed25519プログラムは、1つまたは複数のed25519署名を検証するために使用されます。
| プログラム | プログラムID | 説明 | instructions |
|---|---|---|---|
| Ed25519 プログラム | Ed25519SigVerify111111111111111111111111111 | ed25519署名を検証します。いずれかの署名が失敗した場合、エラーが返されます。 | Instructions |
ed25519プログラムはinstructionを処理します。instructionの最初の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リカバリーの検証
secp256k1プログラムは、secp256k1公開鍵のリカバリー操作を検証するために使用されます。
| プログラム | プログラムID | 説明 | instructions |
|---|---|---|---|
| Secp256k1 プログラム | KeccakSecp256k11111111111111111111111111111 | secp256k1公開鍵のリカバリー操作(ecrecover)を検証します。 | Instructions |
secp256k1プログラムはinstructionを処理します。instructionの最初のバイトには、チェックする公開鍵の数のカウントが含まれています。その後、各公開鍵に対して以下の構造体が一度作成され、シリアル化されてinstruction dataに追加されます。
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}
これにより、ユーザーはトランザクション内の署名とメッセージデータに任意のinstruction dataを指定できます。特別なinstructions sysvarを指定することで、トランザクション自体からデータを受け取ることもできます。
トランザクションのコストは、検証する署名の数に署名コスト検証乗数を掛けた値になります。
Secp256r1プログラムは、最大8つのsecp256r1署名を検証するために使用されます。
| プログラム | プログラムID | 説明 | instructions |
|---|---|---|---|
| Secp256r1プログラム | Secp256r1SigVerify1111111111111111111111111 | 最大8つのsecp256r1署名を検証します。署名、公開鍵、メッセージを受け取り、いずれかが失敗した場合はエラーを返します。 | Instructions |
Secp256r1プログラムはinstructionを処理します。instructionの最初のu8には、チェックする署名の数が含まれており、その後に1バイトのパディングが続きます。その後、以下の構造体が各署名に対して作成され、シリアル化されてinstruction
dataに追加されます。
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}
署名の偶発的な可鍛性を避けるため、すべての署名に対してLow S値が強制されます。
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}
コアプログラム
以下のリストにあるプログラムは、ネットワークのコア機能を提供します。
| プログラム | プログラムID | 説明 | instructions |
|---|---|---|---|
| System | 11111111111111111111111111111111 | 新しいアカウントの作成、アカウントデータの割り当て、アカウントを所有プログラムに割り当て、Systemプログラム所有のアカウントからlamportsの転送、トランザクション手数料の支払い | SystemInstruction |
| Vote | Vote111111111111111111111111111111111111111 | バリデーターの投票状態と報酬を追跡するアカウントの作成と管理 | VoteInstruction |
| Stake | Stake11111111111111111111111111111111111111 | バリデーターへの委任のためのステークと報酬を表すアカウントの作成と管理 | StakeInstruction |
| Config | Config1111111111111111111111111111111111111 | 設定データをチェーンに追加し、その後にそれを変更できる公開鍵のリストを追加します。他のプログラムとは異なり、Configプログラムは個別のinstructionを定義していません。「store」という暗黙的なinstructionが1つだけあります。そのinstruction dataは、アカウントへのアクセスとその中に保存されているデータを制御するキーのセットです | ConfigInstruction |
| Compute Budget | ComputeBudget111111111111111111111111111111 | トランザクションのコンピュートユニットの制限と価格を設定し、ユーザーがコンピュートリソースと優先順位付け手数料を制御できるようにします | ComputeBudgetInstruction |
| Address Lookup Table | AddressLookupTab1e1111111111111111111111111 | アドレス検索テーブルを管理し、トランザクションがアカウントリストに収まる以上のアカウントを参照できるようにします | ProgramInstruction |
| ZK ElGamal Proof | ZkE1Gama1Proof11111111111111111111111111111 | ElGamal暗号化データのゼロ知識証明検証を提供します | — |
Is this page helpful?