Структура комісій

Підсумок

Загальна комісія = базова комісія (5 000 lamports/підпис, 50% спалюється) + комісія за пріоритет (CU_price * CU_limit / 1M lamports, 100% validator-у). Стягується незалежно від того, чи транзакція вдалась, чи ні.

Алгоритм розрахунку комісії

Загальна комісія за транзакцію обчислюється функцією calculate_fee_details:

Total fee formula
total_fee = base_fee + prioritization_fee

Вхідними даними є повідомлення транзакції, поточне значення lamports_per_signature (наразі 5 000) та комісія за пріоритет, отримана з інструкцій бюджету обчислень. Загальна комісія знімається з платника комісії до початку виконання. Якщо транзакція не вдається, комісія все одно стягується.

Базова комісія

Базова комісія покриває вартість верифікації підпису Ed25519, а також будь-яких верифікацій підписів прекомпайлів. Кожен підпис у транзакції оплачується, включаючи підписи, верифіковані програмами-прекомпайлами Ed25519, Secp256k1 та Secp256r1.

Функція calculate_signature_fee обчислює:

Base fee formula
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 у середовищі виконання обчислює:

Fee distribution
burn_amount = transaction_fee * 50 / 100
validator_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 обчислює:

Prioritization fee formula
micro_lamport_fee = compute_unit_price * compute_unit_limit
prioritization_fee = ceil(micro_lamport_fee / 1,000,000)
ЗміннаОписЗа замовчуванням
compute_unit_priceМікро-lamports за CU, встановлюється через SetComputeUnitPrice0 мікро-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:

Transaction priority formula
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 instructions
const 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 transaction
const transaction = new Transaction()
.add(limitInstruction)
.add(priceInstruction)
.add(transferInstruction);
const signature = await sendAndConfirmTransaction(connection, transaction, [
sender
]);
console.log("Transaction Signature:", signature);
Console
Click to execute the code.

Is this page helpful?