交易 (TX) 优先级是通过在基本费用之外支付优先费用来实现的。默认情况下,计算预算是 200,000 个计算单元 (CU) * 指令数量的乘积,最高为 1.4M CU。基本费用为每个签名 5,000 个 Lamport。一个 microLamport 等于 0.000001 个 Lamport。
您可以在此处找到有关如何使用优先费用的详细指南 。
可以通过添加来自 ComputeBudgetProgram 的指令来更改单个 TX 的总计算预算或优先级费用。
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: number })将在基本费用(5,000 Lamport)之上添加优先费用。microLamports 中提供的值将乘以 CU 预算,以确定 Lamports 中的优先费用。例如,如果您的 CU 预算为 1M CU,并且您添加 1 microLamport/CU,则优先费用将为 1 Lamport(1M * 0.000001)。总费用将为 5001 Lamports。
用于ComputeBudgetProgram.setComputeUnitLimit({ units: number })设置新的计算预算。提供的值将取代默认值。交易应请求执行所需的最小 CU 量,以最大化吞吐量或最小化费用。
web3.js v1
import { BN } from "@coral-xyz/anchor";
import {
Keypair,
Connection,
LAMPORTS_PER_SOL,
sendAndConfirmTransaction,
ComputeBudgetProgram,
SystemProgram,
Transaction,
} from "@solana/web3.js";
(async () => {
const payer = Keypair.generate();
const toAccount = Keypair.generate().publicKey;
const connection = new Connection("http://127.0.0.1:8899", "confirmed");
const airdropSignature = await connection.requestAirdrop(
payer.publicKey,
LAMPORTS_PER_SOL,
);
await connection.confirmTransaction(airdropSignature);
// request a specific compute unit budget
const modifyComputeUnits = ComputeBudgetProgram.setComputeUnitLimit({
units: 1000000,
});
// set the desired priority fee
const addPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({
microLamports: 1,
});
// Total fee will be 5,001 Lamports for 1M CU
const transaction = new Transaction()
.add(modifyComputeUnits)
.add(addPriorityFee)
.add(
SystemProgram.transfer({
fromPubkey: payer.publicKey,
toPubkey: toAccount,
lamports: 10000000,
}),
);
const signature = await sendAndConfirmTransaction(connection, transaction, [
payer,
]);
console.log(signature);
const result = await connection.getParsedTransaction(signature);
console.log(result);
})();
web3.js v2
import {
airdropFactory,
appendTransactionMessageInstructions,
createSolanaRpc,
createSolanaRpcSubscriptions,
createTransactionMessage,
devnet,
generateKeyPairSigner,
getComputeUnitEstimateForTransactionMessageFactory,
getSignatureFromTransaction,
lamports,
pipe,
prependTransactionMessageInstructions,
sendAndConfirmTransactionFactory,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
signTransactionMessageWithSigners,
} from "@solana/web3.js";
import {
getSetComputeUnitLimitInstruction,
getSetComputeUnitPriceInstruction,
} from "@solana-program/compute-budget";
import { getAddMemoInstruction } from "@solana-program/memo";
async function writeMemoWithPriorityFees(message: string) {
// Create an RPC.
const CLUSTER = "devnet";
const rpc = createSolanaRpc(devnet(`https://api.${CLUSTER}.solana.com`));
const rpcSubscriptions = createSolanaRpcSubscriptions(
devnet(`wss://api.${CLUSTER}.solana.com`),
);
// Create an airdrop function.
const airdrop = airdropFactory({ rpc, rpcSubscriptions });
// Create a utility that estimates a transaction message's compute consumption.
const getComputeUnitEstimate =
getComputeUnitEstimateForTransactionMessageFactory({ rpc });
// Create a transaction sending function.
const sendAndConfirmTransaction = sendAndConfirmTransactionFactory({
rpc,
rpcSubscriptions,
});
// Create and fund an account.
const keypairSigner = await generateKeyPairSigner();
console.log("Created an account with address", keypairSigner.address);
console.log("Requesting airdrop");
await airdrop({
commitment: "confirmed",
lamports: lamports(1000_000n),
recipientAddress: keypairSigner.address,
});
console.log("Airdrop confirmed");
// Create a memo transaction.
console.log("Creating a memo transaction");
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
const transactionMessage = pipe(
createTransactionMessage({ version: "legacy" }),
m => setTransactionMessageFeePayerSigner(keypairSigner, m),
m => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),
m =>
appendTransactionMessageInstructions(
[
getSetComputeUnitPriceInstruction({ microLamports: 5000n }),
getAddMemoInstruction({ memo: message }),
],
m,
),
);
// Figure out how many compute units to budget for this transaction
// so that you can right-size the compute budget to maximize the
// chance that it will be selected for inclusion into a block.
console.log("Estimating the compute consumption of the transaction");
var estimatedComputeUnits = await getComputeUnitEstimate(transactionMessage);
// While these estimates are quite accurate they are not perfect. So you may want to add a
// buffer if you expect that the transaction may consume more compute units than estimated.
// Its not possible to exactly know what the transaction will consume when
// you send it in the future. The state may change. You can add a buffer to the estimate to account for this.
// estimatedComputeUnits += 1000;
// estimatedComputeUnits *= 1.1;
// You can read more about the issue here: https://github.com/solana-labs/solana-web3.js/tree/master/packages/library#getcomputeunitestimatefortransactionmessagefactoryrpc
console.log(
`Transaction is estimated to consume ${estimatedComputeUnits} compute units`,
);
const budgetedTransactionMessage = prependTransactionMessageInstructions(
[getSetComputeUnitLimitInstruction({ units: estimatedComputeUnits })],
transactionMessage,
);
// Sign and send the transaction.
console.log("Signing and sending the transaction");
const signedTx = await signTransactionMessageWithSigners(
budgetedTransactionMessage,
);
const signature = getSignatureFromTransaction(signedTx);
console.log(
"Sending transaction https://explorer.solana.com/tx/" +
signature +
"/?cluster=" +
CLUSTER,
);
await sendAndConfirmTransaction(signedTx, { commitment: "confirmed" });
console.log("Transaction confirmed");
}
writeMemoWithPriorityFees("Hello, priority fees!");
https://solana.com/zh/developers/cookbook/transactions/add-priority-fees