摘要
总费用 = 基础费用(每个签名 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定义。 - 优先费用:根据 SIMD-0096,100% 归 validator 所有(不销毁任何部分)。
validator 对一笔交易的总奖励为:
validator_reward = (base_fee / 2) + prioritization_fee
优先费用
优先费用是一项可选费用,用于提高交易的调度优先级。计算单元(CU)是运行时在交易执行过程中计量的计算量单位。每项操作(算术运算、内存访问、系统调用)均消耗固定数量的 CU。您可以通过在交易中包含计算预算指令来设置优先费用。(详情请参阅 优先费用使用指南。)
优先费用计算公式
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) | -- |
v1 交易直接设置费用
此价格乘以上限的公式适用于传统交易和 v0 交易。在 v1 格式中, 优先费用是直接在消息配置中以 lamports 为单位设置的绝对总额——无需按 CU 单价计算,无需乘法运算,也无需取整。
计算单元上限
计算单元上限是交易可消耗的最大 CU 数量。如果未包含
SetComputeUnitLimit
指令,则默认值根据指令的数量和类型计算得出(非内置指令每条 200,000 CU,内置指令每条 3,000 CU)。有关默认计算方式的详细信息,请参阅
计算预算。
优先费用基于请求的 CU 上限计算,而非实际消耗的 CU 数量。 设置高于所需的上限意味着需要为未使用的计算单元付费。
计算单元价格
计算单元价格是每个请求 CU 所支付的可选微 lamports 金额。CU 价格直接决定优先费用的高低。若要设置 CU 价格,请在交易中包含
SetComputeUnitPrice
指令。
默认 CU 价格为 0,这意味着默认优先费用也为 0。
如需实时 CU 价格估算,请参阅下方的优先费用 API 提供商。
交易调度优先级
调度器使用
calculate_priority_and_cost
函数对交易进行排序:
Priority = reward * 1,000,000 / (cost + 1)
- reward(奖励):validator 的费用收入 = 优先费用 + 基础费用中未销毁的部分。由
calculate_reward_for_transaction计算得出。 - cost(成本):调度器的 预估 CU 成本 (签名成本 + 写锁成本 + instruction data 成本 + 程序 执行成本 + 已加载账户数据大小成本)。详情请参阅 计算预算。
- 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?