Tóm tắt
Tổng phí = phí cơ bản (5.000 lamports/chữ ký, 50% bị đốt) + phí ưu tiên (giá_CU * giới_hạn_CU / 1M lamports, 100% cho validator). Phí được tính dù giao dịch thành công hay thất bại.
Thuật toán tính phí
Tổng phí cho một giao dịch được tính bởi
calculate_fee_details:
total_fee = base_fee + prioritization_fee
Các đầu vào là thông điệp giao dịch, lamports_per_signature hiện tại (hiện là
5.000), và phí ưu tiên được tính từ các lệnh ngân sách tính toán. Tổng phí được
khấu trừ từ người trả phí trước khi bắt đầu thực thi. Nếu giao dịch thất bại,
phí vẫn được tính.
Phí cơ bản
Phí cơ bản bao gồm chi phí xác minh chữ ký Ed25519 cộng với bất kỳ xác minh chữ ký precompile nào. Mọi chữ ký trong giao dịch đều được tính phí, bao gồm các chữ ký được xác minh bởi các chương trình precompile Ed25519, Secp256k1 và Secp256r1.
Hàm
calculate_signature_fee
tính toán:
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: số lượng chữ ký Ed25519 trên giao dịch (thường là một chữ ký cho mỗi người ký).num_ed25519_signatures,num_secp256k1_signatures,num_secp256r1_signatures: các chữ ký được xác minh bởi các chương trình precompile tương ứng.lamports_per_signature: hiện tại là 5.000 lamports.
Phân phối phí
Phí cơ bản và phí ưu tiên được phân phối khác nhau. Hàm
calculate_reward_and_burn_fee_details
trong runtime tính toán:
burn_amount = transaction_fee * 50 / 100validator_share = (transaction_fee - burn_amount) + priority_fee
- Phí cơ bản (transaction_fee): 50% bị
đốt
(loại bỏ khỏi nguồn cung lưu thông) và 50% được chuyển cho validator sản xuất
block. Tỷ lệ đốt là
DEFAULT_BURN_PERCENT = 50. - Phí ưu tiên: 100% được chuyển cho validator (không bị đốt), theo SIMD-0096.
Tổng phần thưởng của validator cho một giao dịch là:
validator_reward = (base_fee / 2) + prioritization_fee
Phí ưu tiên
Phí ưu tiên là khoản phí tùy chọn giúp tăng mức độ ưu tiên lập lịch cho một giao dịch. Đơn vị tính toán (CU) là đơn vị tính toán mà runtime đo lường trong quá trình thực thi giao dịch. Mỗi thao tác (số học, truy cập bộ nhớ, syscall) tiêu tốn một số lượng CU cố định. Bạn có thể thiết lập phí ưu tiên bằng cách bao gồm các lệnh compute budget trong giao dịch của mình. (Xem Hướng dẫn cách sử dụng phí ưu tiên để biết chi tiết.)
Công thức phí ưu tiên
Hàm
get_prioritization_fee
tính toán:
micro_lamport_fee = compute_unit_price * compute_unit_limitprioritization_fee = ceil(micro_lamport_fee / 1,000,000)
| Biến | Mô tả | Mặc định |
|---|---|---|
compute_unit_price | Micro-lamport trên mỗi CU, được thiết lập qua SetComputeUnitPrice | 0 micro-lamport |
compute_unit_limit | Số CU tối đa mà giao dịch có thể tiêu thụ, được thiết lập qua SetComputeUnitLimit | Tổng các giá trị mặc định theo từng lệnh |
1,000,000 | Hệ số chuyển đổi từ micro-lamport sang lamport (MICRO_LAMPORTS_PER_LAMPORT) | -- |
Giới hạn đơn vị tính toán
Giới hạn đơn vị tính toán là số lượng CU tối đa mà một giao dịch có thể tiêu
thụ. Nếu không có lệnh
SetComputeUnitLimit
được bao gồm, giá trị mặc định được tính toán dựa trên số lượng và loại lệnh
(200.000 CU cho mỗi lệnh không phải builtin, 3.000 cho builtin). Xem
Compute Budget để biết chi tiết về cách tính
toán mặc định.
Phí ưu tiên dựa trên giới hạn CU được yêu cầu, không phải mức sử dụng CU thực tế. Thiết lập giới hạn cao hơn mức cần thiết có nghĩa là bạn phải trả cho các đơn vị tính toán không sử dụng.
Giá đơn vị tính toán
Giá đơn vị tính toán là số lượng micro-lamport tùy chọn được trả cho mỗi CU được
yêu cầu. Giá CU trực tiếp xác định phí ưu tiên. Để thiết lập giá CU, hãy bao gồm
lệnh
SetComputeUnitPrice
trong giao dịch của bạn.
Giá CU mặc định là 0, nghĩa là phí ưu tiên mặc định cũng là 0.
Để biết ước tính giá CU theo thời gian thực, xem các nhà cung cấp API phí ưu tiên bên dưới.
Mức độ ưu tiên lập lịch giao dịch
Bộ lập lịch xếp hạng các giao dịch bằng cách sử dụng hàm
calculate_priority_and_cost:
Priority = reward * 1,000,000 / (cost + 1)
- reward: thu nhập phí của validator = phí ưu tiên + phần không bị đốt của
phí cơ bản. Được tính bởi
calculate_reward_for_transaction. - cost: chi phí CU ước tính của bộ lập lịch (chi phí chữ ký + chi phí khóa ghi + chi phí dữ liệu lệnh + chi phí thực thi chương trình + chi phí kích thước dữ liệu tài khoản được tải). Xem Compute Budget để biết chi tiết.
- 1,000,000: hệ số nhân để bảo toàn độ chính xác, vì chi phí thường vượt quá phần thưởng tính bằng lamport thô.
- +1: ngăn chặn chia cho không.
Mức độ ưu tiên xác định thứ tự các giao dịch được lấy ra khỏi bộ đệm của bộ lập lịch để thực thi.
Ví dụ: Thiết lập giới hạn CU và giá CU
Các ví dụ dưới đây cho thấy cách thiết lập giới hạn CU và giá CU trên một giao dịch bằng cách sử dụng Solana SDK.
| SDK | Tham chiếu mã nguồn |
|---|---|
@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?