概要
合計手数料 = 基本手数料(5,000 lamports/署名、50%バーン)+ 優先手数料(CU_price * CU_limit / 1M lamports、100% validatorへ)。トランザクションの成功・失敗に関わらず課金されます。
手数料計算アルゴリズム
トランザクションの合計手数料は、calculate_fee_detailsによって計算されます。
total_fee = base_fee + prioritization_fee
入力は、トランザクションメッセージ、現在のlamports_per_signature(現在5,000)、およびcompute
budget
instructionsから導出される優先手数料です。合計手数料は、実行開始前に手数料支払者から差し引かれます。トランザクションが失敗した場合でも、手数料は課金されます。
基本手数料
基本手数料は、Ed25519署名検証のコストに加えて、プリコンパイル署名検証のコストをカバーします。トランザクション内のすべての署名が課金対象となり、Ed25519、Secp256k1、およびSecp256r1プリコンパイルプログラムによって検証される署名も含まれます。
calculate_signature_fee関数は以下を計算します。
signature_count = num_transaction_signatures+ num_ed25519_signatures+ num_secp256k1_signatures+ num_secp256r1_signatures (if feature enabled)base_fee = signature_count * lamports_per_signature
num_transaction_signatures: トランザクション上のEd25519署名の数(通常は署名者ごとに1つ)。num_ed25519_signatures、num_secp256k1_signatures、num_secp256r1_signatures: 対応するプリコンパイルプログラムによって検証される署名。lamports_per_signature: 現在5,000 lamports。
手数料の配分
基本手数料と優先手数料は異なる方法で配分されます。ランタイムのcalculate_reward_and_burn_fee_details関数は以下を計算します。
burn_amount = transaction_fee * 50 / 100validator_share = (transaction_fee - burn_amount) + priority_fee
- 基本手数料(transaction_fee):
50%がバーン(流通供給量から削除)され、50%がブロック生成validatorに送られます。バーンの割合は
DEFAULT_BURN_PERCENT = 50です。 - 優先手数料: 100%がvalidatorに送られます(バーンなし)。SIMD-0096に準拠。
トランザクションに対するvalidatorの総報酬は次のとおりです:
validator_reward = (base_fee / 2) + prioritization_fee
優先手数料
優先手数料は、トランザクションのスケジューリング優先度を高めるためのオプションの手数料です。コンピュートユニット(CU)は、トランザクション実行中にランタイムが測定する計算の単位です。すべての操作(算術演算、メモリアクセス、システムコール)は固定数のCUを消費します。トランザクションにコンピュートバジェットinstructionsを含めることで、優先手数料を設定できます。(詳細については、優先手数料の使用方法ガイドを参照してください。)
優先手数料の計算式
get_prioritization_fee関数は次のように計算します:
micro_lamport_fee = compute_unit_price * compute_unit_limitprioritization_fee = ceil(micro_lamport_fee / 1,000,000)
| 変数 | 説明 | デフォルト |
|---|---|---|
compute_unit_price | CUあたりのマイクロlamports、SetComputeUnitPriceで設定 | 0マイクロlamports |
compute_unit_limit | トランザクションが消費できる最大CU、SetComputeUnitLimitで設定 | instructionsごとのデフォルトの合計 |
1,000,000 | マイクロlamportsからlamportsへの変換係数(MICRO_LAMPORTS_PER_LAMPORT) | -- |
コンピュートユニット制限
コンピュートユニット制限は、トランザクションが消費できる最大CU数です。SetComputeUnitLimit
instructionが含まれていない場合、デフォルトはinstructionsの数と種類から計算されます(非ビルトインinstructionあたり200,000
CU、ビルトインあたり3,000)。デフォルト計算の詳細については、コンピュートバジェットを参照してください。
優先手数料は、実際のCU使用量ではなく、要求されたCU制限に基づいています。必要以上に高い制限を設定すると、未使用のコンピュートユニットに対して支払うことになります。
コンピュートユニット価格
コンピュートユニット価格は、要求された各CUに対して支払われるマイクロlamportsのオプション金額です。CU価格は優先手数料を直接決定します。CU価格を設定するには、トランザクションにSetComputeUnitPrice
instructionを含めます。
リアルタイムのCU価格見積もりについては、以下の優先手数料APIプロバイダーを参照してください。
トランザクションのスケジューリング優先度
スケジューラーは、
calculate_priority_and_cost
関数を使用してトランザクションをランク付けします。
Priority = reward * 1,000,000 / (cost + 1)
- reward: validatorの手数料収入 = 優先手数料 + 基本手数料の非バーン部分。
calculate_reward_for_transactionによって計算されます。 - cost: スケジューラーの 推定CUコスト (署名コスト + 書き込みロックコスト + instruction dataコスト + プログラム実行コスト + ロードされたアカウントデータサイズコスト)。詳細はCompute Budgetを参照してください。
- 1,000,000: 精度を保持するための乗数。コストは生のlamportsで報酬を超えることが多いためです。
- +1: ゼロ除算を防ぎます。
優先度は、スケジューラーのバッファーから実行のためにトランザクションがデキューされる順序を決定します。
例: CU制限とCU価格の設定
以下の例は、Solana SDKを使用してトランザクションにCU制限とCU価格を設定する方法を示しています。
| SDK | ソースコードリファレンス |
|---|---|
@solana/web3.js (Typescript) | ComputeBudgetProgram |
solana-sdk (Rust) | ComputeBudgetInstruction |
const limitInstruction = ComputeBudgetProgram.setComputeUnitLimit({units: 300_000});const priceInstruction = ComputeBudgetProgram.setComputeUnitPrice({microLamports: 1});
import {LAMPORTS_PER_SOL,SystemProgram,Transaction,Keypair,Connection,ComputeBudgetProgram,sendAndConfirmTransaction} from "@solana/web3.js";const connection = new Connection("http://localhost:8899", "confirmed");const sender = Keypair.generate();const recipient = new Keypair();const airdropSignature = await connection.requestAirdrop(sender.publicKey,LAMPORTS_PER_SOL);await connection.confirmTransaction(airdropSignature, "confirmed");// Create compute budget instructionsconst limitInstruction = ComputeBudgetProgram.setComputeUnitLimit({units: 300_000});const priceInstruction = ComputeBudgetProgram.setComputeUnitPrice({microLamports: 1});const transferInstruction = SystemProgram.transfer({fromPubkey: sender.publicKey,toPubkey: recipient.publicKey,lamports: 0.01 * LAMPORTS_PER_SOL});// Add the compute budget and transfer instructions to a new transactionconst transaction = new Transaction().add(limitInstruction).add(priceInstruction).add(transferInstruction);const signature = await sendAndConfirmTransaction(connection, transaction, [sender]);console.log("Transaction Signature:", signature);
Is this page helpful?