Struktura opłat

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 formula
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:

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: 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:

Fee distribution
burn_amount = transaction_fee * 50 / 100
validator_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:

Prioritization fee formula
micro_lamport_fee = compute_unit_price * compute_unit_limit
prioritization_fee = ceil(micro_lamport_fee / 1,000,000)
ZmiennaOpisDomyślna
compute_unit_priceMikro-lamports za CU, ustawiane przez SetComputeUnitPrice0 mikro-lamports
compute_unit_limitMaksymalna liczba CU, którą transakcja może zużyć, ustawiana przez SetComputeUnitLimitSuma wartości domyślnych dla poszczególnych instrukcji
1 000 000Współ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.

Priorytet planowania transakcji

Harmonogram szereguje transakcje przy użyciu funkcji calculate_priority_and_cost:

Transaction priority formula
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.

SDKOdniesienie 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 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?

Spis treści

Edytuj stronę