Skip to main content

发送交易

如何发送SOL

要发送SOL,你需要与SystemProgram 交互。

const transferTransaction = new Transaction().add(
SystemProgram.transfer({
fromPubkey: fromKeypair.publicKey,
toPubkey: toKeypair.publicKey,
lamports: lamportsToSend,
})
);

await sendAndConfirmTransaction(connection, transferTransaction, [fromKeypair]);

如何发送SPL-代币

使用 Token Program 来转移SPL代币。为了发送SPL代币,你需要知道它的SPL代币账户地址。你可以使用以下示例来获取地址并发送代币。

// Add token transfer instructions to transaction
const transaction = new web3.Transaction().add(
splToken.Token.createTransferInstruction(
splToken.TOKEN_PROGRAM_ID,
fromTokenAccount.address,
toTokenAccount.address,
fromWallet.publicKey,
[],
1
)
);

// Sign transaction, broadcast, and confirm
await web3.sendAndConfirmTransaction(connection, transaction, [fromWallet]);

如何计算交易成本

交易所需的签名数量用于计算交易成本。只要你不是创建账户,这将是最终的交易成本。如果想了解创建账户的成本,请参考 计算租金豁免

下面的两个示例展示了目前可用于计算估计交易成本的两种方法。

第一个示例使用了Transaction类上的新方法getEstimatedFee,而第二个示例使用了Connection类上的getFeeForMessage来替代getFeeCalculatorForBlockhash

getEstimatedFee

const recentBlockhash = await connection.getLatestBlockhash();

const transaction = new Transaction({
recentBlockhash: recentBlockhash.blockhash,
}).add(
SystemProgram.transfer({
fromPubkey: payer.publicKey,
toPubkey: payee.publicKey,
lamports: 10,
})
);

const fees = await transaction.getEstimatedFee(connection);
console.log(`Estimated SOL transfer cost: ${fees} lamports`);
// Estimated SOL transfer cost: 5000 lamports

getFeeForMessage

const message = new Message(messageParams);

const fees = await connection.getFeeForMessage(message);
console.log(`Estimated SOL transfer cost: ${fees.value} lamports`);
// Estimated SOL transfer cost: 5000 lamports

如何向交易添加备注

任何交易都可以利用 备注程序 (memo program). 添加消息。目前,备注程序的programID必须手动添加为MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr

const transferTransaction = new Transaction().add(
SystemProgram.transfer({
fromPubkey: fromKeypair.publicKey,
toPubkey: toKeypair.publicKey,
lamports: lamportsToSend,
})
);

await transferTransaction.add(
new TransactionInstruction({
keys: [{ pubkey: fromKeypair.publicKey, isSigner: true, isWritable: true }],
data: Buffer.from("Data to send in transaction", "utf-8"),
programId: new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"),
})
);

await sendAndConfirmTransaction(connection, transferTransaction, [fromKeypair]);

如何更改交易的计算预算、费用和优先级

交易(TX)的优先级是通过支付优先级费用(Prioritization Fee)来实现的,此外还需要支付基本费用(Base Fee)。默认情况下,计算预算是200,000个计算单元(Compute Units,CU)与指令数的乘积,最大为1.4M CU。基本费用是5,000个Lamport。一个微型Lamport等于0.000001个Lamport。

要更改单个交易的总计算预算或优先级费用,可以通过添加ComputeBudgetProgram的指令来实现。

使用ComputeBudgetProgram.setComputeUnitPrice({ microLamports: number })可以在基本费用(5,000个Lamport)之上添加优先级费用。microLamports参数提供的值将与计算预算的CU数相乘,以确定优先级费用(以Lamport为单位)。例如,如果您的计算预算为1M CU,然后添加1个microLamport/CU,优先级费用将为1个Lamport(1M * 0.000001)。总费用将为5001个Lamport。

使用ComputeBudgetProgram.setComputeUnitLimit({ units: number })来设置新的计算预算。提供的值将替换默认值。交易应该请求执行所需的最小数量的CU,以最大化吞吐量或最小化费用。

const modifyComputeUnits = ComputeBudgetProgram.setComputeUnitLimit({
units: 1000000
});

const addPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({
microLamports: 1
});

const transaction = new Transaction()
.add(modifyComputeUnits)
.add(addPriorityFee)
.add(
SystemProgram.transfer({
fromPubkey: payer.publicKey,
toPubkey: toAccount,
lamports: 10000000,
})
);

程序日志示例 ( Explorer ):

// cli
[ 1] Program ComputeBudget111111111111111111111111111111 invoke [1]
[ 2] Program ComputeBudget111111111111111111111111111111 success
[ 3]
[ 4] Program ComputeBudget111111111111111111111111111111 invoke [1]
[ 5] Program ComputeBudget111111111111111111111111111111 success