Appearance
版本化交易
作者 崔棉大师 X:@MasterCui Youtube: 崔棉大师
知识点
本章节通过 js 脚本构建版本化交易,在这个过程中,你将学到通过创建指令IX
,Solana 上交易内的步骤称为指令, 将指令打包成为交易,最终签署交易的整个过程
课程
0.计算账户费用
在 Solana 上保持账户活跃会产生一项存储费用,称为 租金/rent。通过存入至少两年租金的金额,你可以使账户完全免除租金收取。对于费用的计算,你需要考虑你打算在账户中存储的数据量。
js
const lamports = await connection.getMinimumBalanceForRentExemption(space);
通过命令行快速计算
sh
$solana rent 1500
Rent-exempt minimum: 0.01133088 SOL
1.创建 IX
脚本中通过SystemProgram.createAccount
函数,创建了一个指令 IX,这个指令的作用是调用系统程序创建一个账户,并且存入指定数量的 lamport 租金
js
// 创建账号IX
// 使用 web3.js 辅助函数创建这个简单的指令
const createAccountIx = SystemProgram.createAccount({
// `fromPubkey` - 该帐户需要签署交易
fromPubkey: payer.publicKey,
// `newAccountPubkey` - 在链上创建的账户地址
newAccountPubkey: Pubkey,
// 要存储在此帐户中的lamports
lamports: lamports + amount,
// 分配的总空间
space: space,
// 该帐户的owner程序id
programId: programId,
});
2.创建版本化交易
js
// 创建版本化交易
// 创建消息 (v0)
const message = new TransactionMessage({
payerKey: payerKey, // 支付账户的公钥
recentBlockhash, // 获取最后的区块hash
instructions: txs, // 交易的指令数组
}).compileToV0Message();
3.签署交易
js
// 签署交易
// 使用我们所需的签名者(例如'Payer'和'keypair')签署交易,signers可以是多个签名人的keypair
tx.sign(signers);
4.发送交易
js
// 发送交易
const sig = await connection.sendTransaction(tx);
// 输出交易签名:
console.log(`交易签名:${sig}`);
5.发送简单交易
将以上几步操作链接到一个完整的过程中,创建一个简单的交易,目的是在链上创建一个账户,并支付租金
js
// 创建账户Ix,签署交易,发送交易
// 随机计算一个地址的keypair
let to = Keypair.generate();
// 创建账户的指令IX
let createAccountIx = await CreateAccountIx(
payer,
to.publicKey,
connection,
SystemProgram.programId
);
// 创建版本化交易
const tx = await CreateVersionedTx(payer.publicKey, connection, [
createAccountIx,
]);
// 使用支付账户和to账户签名交易
const signedTx = await SignTx([payer, to], tx);
// 发送版本化交易
await SendVersionedTx(signedTx);
6.发送 SOL
通过系统程序的 transfer 函数,我们可以向指定账户发送 sol,这一小节内容将演示通过SystemProgram.transfer
函数创建发送 SOL 的指令
js
// 创建一个指令用于发送交易
const transferToTestWalletIx = SystemProgram.transfer({
// 要发送的数量,以lamports为单位,加上空间租用成本
lamports: lamports + amount,
// `fromPubkey` - 该帐户需要签署交易
fromPubkey: payer.publicKey,
// `toPubkey` - 不需要签署交易
toPubkey: toPubkey,
// 该帐户的owner程序id为系统程序id
programId: SystemProgram.programId,
});
6.发送复杂交易
前面的简单交易,在一笔交易中只有一个指令,接下来我们创建一个复杂交易,在一笔交易中同时包含 3 个指令
js
// 创建账户Ix,两个发送交易
// 随机计算一个地址的keypair
let to = Keypair.generate();
// 创建账户的指令IX
let createAccountIx = await CreateAccountIx(
payer,
to.publicKey,
connection,
SystemProgram.programIdß
);
// 创建发送SOL的指令,发送到to地址2000lamport
let transfer_1 = await Transfer(connection, payer, to.publicKey, 2_000);
// 创建发送SOL的指令,发送到STATIC_PUBLICKEY地址1000000lamport
let transfer_2 = await Transfer(connection, payer, STATIC_PUBLICKEY, 1_000_000);
// 将三个指令IX打包创建版本化交易
const tx = await CreateVersionedTx(payer.publicKey, connection, [
createAccountIx,
transfer_1,
transfer_2,
]);
// 使用支付账户和to账户签名交易
const signedTx = await SignTx([payer, to], tx);
// 发送版本化交易
await SendVersionedTx(signedTx);
7.计算交易成本
通过 message 计算
js
// 计算交易费
const fees = await connection.getFeeForMessage(tx.message);
console.log(`Estimated SOL transfer cost: ${fees.value} lamports`);