摘要
总费用 = 基础费用(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),以及根据计算预算指令得出的优先级费用。总费用会在执行前从费用支付者账户中扣除。即使交易失败,费用也会被收取。
基础费用
基础费用覆盖 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 签名数量(通常每个签名者一个)。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。你可以通过在交易中加入 compute budget 指令来设置优先级费用。(详见如何使用优先级费用指南)
优先级费用公式
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 设置 | 各指令默认值之和 |
1,000,000 | 微 lamports 到 lamports 的换算系数(MICRO_LAMPORTS_PER_LAMPORT) | -- |
计算单元上限
计算单元上限是指一笔交易最多可消耗的 CU 数量。如果未包含
SetComputeUnitLimit
指令,则默认值根据指令数量和类型计算(每个非内置指令 200,000
CU,每个内置指令 3,000
CU)。详情请参见计算预算。
优先级费用基于请求的 CU 上限计算,而不是实际使用的 CU。设置高于实际需求的上限会导致为未使用的计算单元付费。
计算单元价格
计算单元价格是为每个请求的 CU 支付的可选微 lamports 数额。CU 价格直接决定优先级费用。要设置 CU 价格,请在交易中加入
SetComputeUnitPrice
指令。
如需实时 CU 价格估算,请参阅下方的优先级费用 API 提供商。
| Provider | Priority Fee API |
|---|---|
| Helius | Documentation |
| QuickNode | Documentation |
| Triton | Documentation |
交易调度优先级
调度器通过
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 中 cost 通常大于 reward。
- +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?