Tóm Tắt
Tổng phí = phí cơ bản (5.000 lamport/chữ ký, đốt 50%) + phí ưu tiên (CU_price * CU_limit / 1M lamport, 100% cho validator). Tính phí 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
Đầ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 lấy từ các lệnh ngân sách tính toán. Tổng phí sẽ được trừ từ người thanh toán phí trước khi thực thi
bắt đầu. Nếu giao dịch thất bại, phí vẫn sẽ bị 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 bị 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:
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ý 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 lamport.
Phân phối phí
Phí cơ bản và phí ưu tiên được phân phối theo cách khác nhau. Hàm
calculate_reward_and_burn_fee_details
trong runtime tính:
burn_amount = transaction_fee * 50 / 100validator_share = (transaction_fee - burn_amount) + priority_fee
- Phí cơ bản (transaction_fee): 50% bị
đốt
(xóa khỏi nguồn cung lưu thông) và 50% dành cho validator tạo block. Tỷ lệ đốt là
DEFAULT_BURN_PERCENT = 50. - Phí ưu tiên: 100% dành cho validator (không có phần 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à một khoản phí tùy chọn giúp tăng mức độ ưu tiên lên lịch của 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) đều tốn một số lượng CU cố định. Bạn có thể đặt phí ưu tiên bằng cách bao gồm các lệnh ngân sách tính toán trong giao dịch của mình. (Xem Hướng dẫn Cách Sử Dụng Phí Ưu Tiên để biết thêm chi tiết.)
Công thức phí ưu tiên
Hàm
get_prioritization_fee
tính:
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, đặt qua SetComputeUnitPrice | 0 micro-lamport |
compute_unit_limit | Số CU tối đa giao dịch có thể sử dụng, đặt qua SetComputeUnitLimit | Tổng 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) | -- |
Giao dịch v1 đặt phí trực tiếp
Công thức giá nhân giới hạn này áp dụng cho các giao dịch legacy và v0. Trong định dạng v1, phí ưu tiên là tổng tuyệt đối tính bằng lamport được đặt trực tiếp trong cấu hình thông điệp — không có giá theo CU, không nhân, không làm tròn.
Giới hạn đơn vị tính toán
Giới hạn đơn vị tính toán là số CU tối đa mà một giao dịch có thể sử dụng.
Nếu không có lệnh
SetComputeUnitLimit
nào được bao gồm, giá trị mặc định được tính từ số lượng và loại
lệnh (200.000 CU mỗi lệnh non-builtin, 3.000 mỗi builtin). Xem
Ngân sách Tính Toán để biết chi tiết về
phép tính 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ế. Đặt giới hạn cao hơn mức cần thiết có nghĩa là phải trả cho các đơn vị tính toán không dùng đến.
Giá đơn vị tính toán
Giá đơn vị tính toán là một 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. Để đặt
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.
Để xem ước tính giá CU theo thời gian thực, hãy xem các nhà cung cấp API phí ưu tiên bên dưới.
Mức độ ưu tiên lên lịch giao dịch
Bộ lập lịch xếp hạng các giao dịch bằ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í instruction data + chi phí thực thi chương trình + chi phí kích thước dữ liệu tài khoản đã tải). Xem Ngân sách Tính Toán để biết chi tiết.
- 1.000.000: hệ số nhân để giữ độ 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 chia cho số 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ụ: Đặt giới hạn CU và giá CU
Các ví dụ dưới đây cho thấy cách đặt giới hạn CU và giá CU cho 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?