Podsumowanie
Całkowita opłata = opłata podstawowa (5 000 lamports/podpis, 50% spalane) + opłata priorytetowa (CU_price * CU_limit / 1M lamports, 100% dla validatora). Pobierana niezależnie od tego, czy transakcja zakończy się powodzeniem, czy niepowodzeniem.
Algorytm obliczania opłat
Całkowita opłata za transakcję jest obliczana przez
calculate_fee_details:
total_fee = base_fee + prioritization_fee
Dane wejściowe to komunikat transakcji, bieżąca wartość lamports_per_signature
(aktualnie 5 000) oraz opłata priorytetowa wynikająca z instrukcji budżetu obliczeniowego. Całkowita opłata jest pobierana od płatnika opłaty przed rozpoczęciem wykonania.
Jeśli transakcja nie powiedzie się, opłata i tak zostaje pobrana.
Opłata podstawowa
Opłata podstawowa pokrywa koszt weryfikacji podpisu Ed25519 oraz wszelkich weryfikacji podpisów przez programy precompile. Każdy podpis w transakcji jest obciążany opłatą, w tym podpisy weryfikowane przez programy precompile Ed25519, Secp256k1 i Secp256r1.
Funkcja
calculate_signature_fee
oblicza:
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: liczba podpisów Ed25519 w transakcji (zazwyczaj jeden na podpisującego).num_ed25519_signatures,num_secp256k1_signatures,num_secp256r1_signatures: podpisy weryfikowane przez odpowiednie programy precompile.lamports_per_signature: aktualnie 5 000 lamports.
Dystrybucja opłat
Opłata podstawowa i opłata priorytetowa są dystrybuowane w różny sposób. Funkcja
calculate_reward_and_burn_fee_details
w środowisku uruchomieniowym oblicza:
burn_amount = transaction_fee * 50 / 100validator_share = (transaction_fee - burn_amount) + priority_fee
- Opłata podstawowa (transaction_fee): 50% jest
spalane
(usuwane z obiegu) i 50% trafia do validatora produkującego blok. Procent spalania wynosi
DEFAULT_BURN_PERCENT = 50. - Opłata priorytetowa: 100% trafia do validatora (nic nie jest spalane), zgodnie z SIMD-0096.
Łączna nagroda validatora za transakcję wynosi:
validator_reward = (base_fee / 2) + prioritization_fee
Opłata priorytetowa
Opłata priorytetowa to opcjonalna opłata zwiększająca priorytet planowania transakcji. Jednostka obliczeniowa (CU) to jednostka obliczeń mierzona przez środowisko uruchomieniowe podczas wykonywania transakcji. Każda operacja (arytmetyczna, dostęp do pamięci, syscall) kosztuje określoną liczbę CU. Opłatę priorytetową można ustawić, dołączając instrukcje budżetu obliczeniowego do transakcji. (Szczegóły znajdziesz w przewodniku Jak używać opłat priorytetowych.)
Wzór na opłatę priorytetową
Funkcja
get_prioritization_fee
oblicza:
micro_lamport_fee = compute_unit_price * compute_unit_limitprioritization_fee = ceil(micro_lamport_fee / 1,000,000)
| Zmienna | Opis | Domyślna |
|---|---|---|
compute_unit_price | Mikro-lamports za CU, ustawiane przez SetComputeUnitPrice | 0 mikro-lamports |
compute_unit_limit | Maksymalna liczba CU, którą transakcja może zużyć, ustawiana przez SetComputeUnitLimit | Suma wartości domyślnych dla poszczególnych instrukcji |
1 000 000 | Współczynnik konwersji z mikro-lamports na lamports (MICRO_LAMPORTS_PER_LAMPORT) | -- |
Transakcje v1 ustawiają opłatę bezpośrednio
Ten wzór cena-razy-limit dotyczy transakcji legacy i v0. W formacie v1 opłata priorytetowa jest bezwzględną sumą w lamports ustawianą bezpośrednio w konfiguracji komunikatu — bez ceny za CU, bez mnożenia, bez zaokrąglania.
Limit jednostek obliczeniowych
Limit jednostek obliczeniowych to maksymalna liczba CU, którą transakcja może zużyć.
Jeśli nie zostanie dołączona instrukcja
SetComputeUnitLimit,
wartość domyślna jest obliczana na podstawie liczby i typu instrukcji (200 000 CU dla instrukcji niebędących wbudowanymi, 3 000 dla wbudowanych). Szczegóły dotyczące domyślnego obliczenia znajdziesz w
Budżecie obliczeniowym.
Opłata priorytetowa opiera się na żądanym limicie CU, a nie na rzeczywistym zużyciu CU. Ustawienie wyższego limitu niż potrzeba oznacza płacenie za niewykorzystane jednostki obliczeniowe.
Cena jednostki obliczeniowej
Cena jednostki obliczeniowej to opcjonalna kwota w mikro-lamports płacona za każdą
żądaną CU. Cena CU bezpośrednio determinuje opłatę priorytetową. Aby ustawić
cenę CU, dołącz do transakcji instrukcję
SetComputeUnitPrice.
Domyślna cena CU wynosi 0, co oznacza, że domyślna opłata priorytetowa również wynosi 0.
Aby uzyskać szacunki ceny CU w czasie rzeczywistym, zapoznaj się z dostawcami API opłat priorytetowych poniżej.
| Dostawca | API opłat priorytetowych |
|---|---|
| Helius | Dokumentacja |
| QuickNode | Dokumentacja |
| Triton | Dokumentacja |
Priorytet planowania transakcji
Harmonogram szereguje transakcje przy użyciu funkcji
calculate_priority_and_cost:
Priority = reward * 1,000,000 / (cost + 1)
- reward: dochód validatora z opłat = opłata priorytetowa + niespaloona
część opłaty podstawowej. Obliczana przez
calculate_reward_for_transaction. - cost: szacowany przez harmonogram koszt CU (koszty podpisów + koszty blokad zapisu + koszty instruction data + koszty wykonania programu + koszt rozmiaru danych załadowanych kont). Szczegóły znajdziesz w Budżecie obliczeniowym.
- 1 000 000: mnożnik służący zachowaniu precyzji, ponieważ koszt często przewyższa nagrodę w surowych lamports.
- +1: zapobiega dzieleniu przez zero.
Priorytet decyduje o kolejności, w jakiej transakcje są usuwane z bufora harmonogramu do wykonania.
Przykład: Ustawianie limitu CU i ceny CU
Poniższe przykłady pokazują, jak ustawić limit CU i cenę CU dla transakcji przy użyciu Solana SDK.
| SDK | Odniesienie do kodu źródłowego |
|---|---|
@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?