Підсумок
Загальна комісія = базова комісія (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
у runtime обчислює:
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_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, встановлюється через SetComputeUnitPrice | 0 мікро-лампортів |
compute_unit_limit | Максимальна кількість CU, яку може спожити транзакція, встановлюється через SetComputeUnitLimit | Сума значень за замовчуванням для кожної інструкції |
1,000,000 | Коефіцієнт конвертації з мікро-лампортів у лампорти (MICRO_LAMPORTS_PER_LAMPORT) | -- |
Ліміт обчислювальних одиниць
Ліміт обчислювальних одиниць — це максимальна кількість CU, яку може спожити
транзакція. Якщо інструкція
SetComputeUnitLimit
не включена, значення за замовчуванням обчислюється на основі кількості та типу
інструкцій (200 000 CU на кожну небілтін-інструкцію, 3000 на білтін). Детальніше
про обчислення за замовчуванням див. у розділі
обчислювальний бюджет.
Пріоритетна комісія базується на запитаному ліміті CU, а не на фактичному використанні CU. Встановлення вищого ліміту, ніж потрібно, означає оплату за невикористані обчислювальні одиниці.
Ціна обчислювальної одиниці
Ціна обчислювальної одиниці — це опціональна кількість мікро-лампортів, що
сплачується за кожну запитану CU. Ціна CU безпосередньо визначає комісію за
пріоритетність. Щоб встановити ціну CU, включіть інструкцію
SetComputeUnitPrice
у вашу транзакцію.
Стандартна ціна CU дорівнює 0, що означає, що стандартна комісія за пріоритетність також дорівнює 0.
Для оцінки ціни CU в реальному часі дивіться постачальників API комісії за пріоритетність нижче.
| Постачальник | API комісії за пріоритетність |
|---|---|
| Helius | Документація |
| QuickNode | Документація |
| Triton | Документація |
Пріоритет планування транзакцій
Планувальник ранжує транзакції за допомогою функції
calculate_priority_and_cost:
Priority = reward * 1,000,000 / (cost + 1)
- reward: дохід валідатора від комісій = комісія за пріоритетність +
неспалена частина базової комісії. Обчислюється функцією
calculate_reward_for_transaction. - cost: оціночна вартість у CU планувальника (вартість підписів + вартість блокувань на запис + вартість даних інструкцій + вартість виконання програм + вартість розміру даних завантажених акаунтів). Детальніше дивіться Бюджет обчислень.
- 1,000,000: множник для збереження точності, оскільки вартість часто перевищує винагороду в сирих лампортах.
- +1: запобігає діленню на нуль.
Пріоритет визначає порядок, у якому транзакції виймаються з буфера планувальника для виконання.
Приклад: встановлення ліміту CU та ціни CU
Приклади нижче показують, як встановити ліміт CU та ціну CU для транзакції за допомогою Solana SDK.
| 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?