요약
총 수수료 = 기본 수수료 (서명당 5,000 lamports, 50% 소각) + 우선순위 수수료 (CU_price * CU_limit / 1M lamports, 100% validator에게 지급). 트랜잭션 성공 여부에 관계없이 수수료가 부과됩니다.
수수료 계산 알고리즘
트랜잭션의 총 수수료는
calculate_fee_details에 의해 계산됩니다:
total_fee = base_fee + prioritization_fee
입력값은 트랜잭션 메시지, 현재 lamports_per_signature
(현재 5,000), 그리고 컴퓨트 버짓 명령어에서 도출된 우선순위 수수료입니다. 총 수수료는
실행 시작 전에 수수료 납부자로부터 차감됩니다. 트랜잭션이 실패하더라도 수수료는 부과됩니다.
기본 수수료
기본 수수료는 Ed25519 서명 검증 비용과 프리컴파일 서명 검증 비용을 포함합니다. 트랜잭션의 모든 서명에 수수료가 부과되며, 여기에는 Ed25519, Secp256k1, Secp256r1 프리컴파일 프로그램에 의해 검증된 서명도 포함됩니다.
calculate_signature_fee
함수는 다음을 계산합니다:
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
함수가 다음을 계산합니다:
burn_amount = transaction_fee * 50 / 100validator_share = (transaction_fee - burn_amount) + priority_fee
- 기본 수수료 (transaction_fee): 50%는
소각되고
(유통 공급에서 제거) 나머지 50%는 블록 생성
validator에게 지급됩니다. 소각 비율은
DEFAULT_BURN_PERCENT = 50입니다. - 우선순위 수수료: SIMD-0096에 따라 100% validator에게 지급됩니다 (소각 없음).
트랜잭션에 대한 validator의 총 보상은 다음과 같습니다:
validator_reward = (base_fee / 2) + prioritization_fee
우선순위 수수료
우선순위 수수료는 트랜잭션의 스케줄링 우선순위를 높이는 선택적 수수료입니다. 컴퓨트 유닛(CU)은 트랜잭션 실행 중 런타임이 측정하는 연산 단위입니다. 모든 연산(산술, 메모리 접근, 시스콜)은 고정된 수의 CU를 소비합니다. 트랜잭션에 컴퓨트 버짓 명령어를 포함하여 우선순위 수수료를 설정할 수 있습니다. (자세한 내용은 우선순위 수수료 사용 가이드를 참조하세요.)
우선순위 수수료 공식
get_prioritization_fee
함수는 다음을 계산합니다:
micro_lamport_fee = compute_unit_price * compute_unit_limitprioritization_fee = ceil(micro_lamport_fee / 1,000,000)
| 변수 | 설명 | 기본값 |
|---|---|---|
compute_unit_price | SetComputeUnitPrice로 설정하는 CU당 마이크로-lamport | 0 마이크로-lamport |
compute_unit_limit | SetComputeUnitLimit으로 설정하는 트랜잭션이 소비할 수 있는 최대 CU | 명령어별 기본값의 합계 |
1,000,000 | 마이크로-lamport에서 lamport로의 변환 계수 (MICRO_LAMPORTS_PER_LAMPORT) | -- |
v1 트랜잭션은 수수료를 직접 설정합니다
이 가격×한도 공식은 레거시 및 v0 트랜잭션에 적용됩니다. v1 형식에서는 우선순위 수수료가 메시지 설정에서 직접 lamport 단위로 설정되는 절대 총액이며 CU당 가격, 곱셈, 반올림이 없습니다.
컴퓨트 유닛 한도
컴퓨트 유닛 한도는 트랜잭션이 소비할 수 있는 최대 CU 수입니다.
SetComputeUnitLimit
명령어가 포함되지 않은 경우, 기본값은 명령어의 수와 유형에 따라 계산됩니다
(비내장 명령어당 200,000 CU, 내장 명령어당 3,000 CU). 기본값 계산에 대한
자세한 내용은 컴퓨트 버짓을 참조하세요.
우선순위 수수료는 실제 CU 사용량이 아닌 요청된 CU 한도를 기준으로 합니다. 필요 이상으로 높은 한도를 설정하면 사용하지 않는 컴퓨트 유닛에 대한 비용을 지불하게 됩니다.
컴퓨트 유닛 가격
컴퓨트 유닛 가격은 요청된 각 CU에 대해 지불하는 선택적 마이크로-lamport 금액입니다.
CU 가격은 우선순위 수수료를 직접 결정합니다. CU 가격을 설정하려면 트랜잭션에
SetComputeUnitPrice
명령어를 포함하세요.
기본 CU 가격은 0이므로, 기본 우선순위 수수료도 0입니다.
실시간 CU 가격 추정을 위해 아래의 우선순위 수수료 API 제공업체를 참조하세요.
트랜잭션 스케줄링 우선순위
스케줄러는
calculate_priority_and_cost
함수를 사용하여 트랜잭션의 순위를 결정합니다:
Priority = reward * 1,000,000 / (cost + 1)
- reward: validator의 수수료 수입 = 우선순위 수수료 + 기본 수수료의 비소각 부분.
calculate_reward_for_transaction에 의해 계산됩니다. - cost: 스케줄러의 예상 CU 비용 (서명 비용 + 쓰기 잠금 비용 + instruction data 비용 + 프로그램 실행 비용 + 로드된 계정 데이터 크기 비용). 자세한 내용은 컴퓨트 버짓을 참조하세요.
- 1,000,000: 정밀도를 유지하기 위한 승수로, 비용이 원시 lamport 기준으로 보상을 초과하는 경우가 많기 때문입니다.
- +1: 0으로 나누는 것을 방지합니다.
우선순위는 스케줄러 버퍼에서 실행을 위해 트랜잭션이 꺼내지는 순서를 결정합니다.
예시: CU 한도 및 CU 가격 설정
아래 예시는 Solana SDK를 사용하여 트랜잭션의 CU 한도와 CU 가격을 설정하는 방법을 보여줍니다.
| 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 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?