Підсумок
Загальна комісія = базова комісія (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. Ви можете встановити комісію за пріоритет, додавши інструкції бюджету обчислень до вашої транзакції. (Докладніше дивіться у посібнику з використання пріоритетних комісій.)
Формула комісії за пріоритет
Функція
get_prioritization_fee
обчислює:
micro_lamport_fee = compute_unit_price * compute_unit_limitprioritization_fee = ceil(micro_lamport_fee / 1,000,000)
| Змінна | Опис | За замовчуванням |
|---|---|---|
compute_unit_price | Мікро-lamports за CU, встановлюється через SetComputeUnitPrice | 0 мікро-lamports |
compute_unit_limit | Максимальна кількість CU, яку може використати транзакція, встановлюється через SetComputeUnitLimit | Сума значень за замовчуванням для кожної інструкції |
1 000 000 | Коефіцієнт перетворення мікро-lamports у lamports (MICRO_LAMPORTS_PER_LAMPORT) | -- |
Транзакції v1 встановлюють комісію безпосередньо
Ця формула ціна-помножена-на-ліміт застосовується до транзакцій legacy та v0. У форматі v1 комісія за пріоритет є абсолютною сумою в lamports, яка встановлюється безпосередньо в конфігурації повідомлення — без ціни за CU, без множення, без округлення.
Ліміт обчислювальних одиниць
Ліміт обчислювальних одиниць — це максимальна кількість CU, яку може використати транзакція.
Якщо інструкція
SetComputeUnitLimit
не включена, за замовчуванням значення розраховується виходячи з кількості та типу
інструкцій (200 000 CU для небудованих інструкцій, 3 000 для вбудованих). Докладніше про розрахунок
за замовчуванням дивіться у розділі Бюджет обчислень.
Комісія за пріоритет розраховується на основі запитаного ліміту CU, а не фактичного використання CU. Встановлення вищого ліміту, ніж необхідно, означає оплату невикористаних обчислювальних одиниць.
Ціна обчислювальної одиниці
Ціна обчислювальної одиниці — це необов'язкова сума мікро-lamports, що сплачується за кожну
запитану 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: дохід validator-а від комісій = комісія за пріоритет + незгоріла
частина базової комісії. Обчислюється функцією
calculate_reward_for_transaction. - cost: розрахункова вартість CU планувальника (вартість підписів + вартість блокування запису + вартість instruction data + вартість виконання програми + вартість розміру завантажених даних облікового запису). Докладніше дивіться у розділі Бюджет обчислень.
- 1 000 000: множник для збереження точності, оскільки вартість часто перевищує винагороду в необроблених lamports.
- +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?