使用写入操作发送交易
受众: 准备好执行首次状态变更操作的开发者。
先决条件: 一个已充值的 Sui devnet 钱包和基本的 Node.js 环境。
目标: 编写一个脚本将 Sui 代币转移到另一个地址,理解 gas 和签名的作用。
简介
在前面的教程中,您通过向 SuiClient 查询数据执行了读取操作,且无需支付网络费用。
现在,您将执行一项写入操作,将 Sui 代币从您的钱包转移到另一个地址。由于这会修改链上状态,因此需要满足两个条件:
- 签名: 您必须对请求进行加密签名,以证明您拥有资金的所有权。
- Gas (邮资): 您必须以 Sui 代币支付费用,以补偿网络处理交易的开销。
先决条件
要运行本教程,您需要:
- 已充值钱包: 持有 Sui
devnet代币的钱包的 12 助记词恢复短语。您可以通过 Sui Discord faucet 或直接在兼容的 Sui 钱包内申请免费的测试代币。 - Ed25519 密钥对包:
@mysten/sui用于对交易进行签名。
安装所需的软件包(如果尚未安装):
Terminal
npm install @mysten/sui
注意
在生产应用程序中,切勿硬编码您的私钥或恢复短语。始终使用环境变量(例如 .env)。本教程使用内存变量进行演示,但切勿将私密恢复短语提交到 GitHub。
1. 导入依赖并配置客户端
创建一个名为 transfer.js 的文件。导入用于网络通信的 SuiClient 以及用于签署交易的 Ed25519Keypair。
transfer.js
import { SuiClient, getFullnodeUrl } from '@mysten/sui/client';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import { Transaction } from '@mysten/sui/transactions';
// 1. 连接到 Devnet
const client = new SuiClient({ url: getFullnodeUrl('devnet') });
// 2. 加载钱包 (发送方)
// 将此处替换为您真实的 12 助记词短语
const MNEMONIC = "word1 word2 word3 ... word12";
const keypair = Ed25519Keypair.deriveKeypair(MNEMONIC);
const senderAddress = keypair.getPublicKey().toSuiAddress();
console.log(`📦 发送方地址: ${senderAddress}`);
提示
在发送交易之前,您的发送方地址需要有测试代币来支付 gas 费。复制终端打印的 发送方地址,并通过 Sui Discord 中的 #devnet-faucet 频道申请代币。
2. 构建交易
在 Sui 中,您构建的是一个 Transaction,而不是发送原始命令。可以将其想象为在封箱前填写运送标签并将物品装箱。
使用 tx.splitCoins 命令从您的主 gas 币中拆分出特定金额:
transfer.js
// 3. 定义接收方
const RECIPIENT = '0x9999...'; // 替换为朋友的地址或销毁地址
// 4. 创建交易容器
const tx = new Transaction();
// 从 gas 币中拆分出 1000 MIST (SUI 的最小单位)
const [coinToSend] = tx.splitCoins(tx.gas, [1000]);
// 将拆分出的代币转移给接收方
tx.transferObjects([coinToSend], RECIPIENT);
3. 签署并提交交易
此步骤在链上执行交易之前计算并支付 gas。
PTB 交易生命周期
┌─────────────────────────┐ ┌─────────────────────────┐ ┌───────────────────────────┐
│ 1. 构建交易 │ ──► │ 2. 密钥对签名 │ ──► │ 3. 通过 SuiClient 提交 │
│ (splitCoins, transfer) │ │ (加密证明) │ │ (广播到 Devnet) │
└─────────────────────────┘ └─────────────────────────┘ └───────────────────────────┘
当您调用 signAndExecuteTransaction 时,SuiClient 将:
- 估算 gas: 计算计算复杂度并设置所需的 gas 预算。
- 签名: 应用您的
keypair签名以批准状态变更。 - 提交: 通过 RPC 全节点将已签名的交易传输到网络。
transfer.js
async function sendTransaction() {
try {
console.log("📝 正在签署并提交交易...");
const result = await client.signAndExecuteTransaction({
signer: keypair,
transaction: tx,
});
console.log("✅ 交易已提交!");
console.log(`Digest (跟踪 ID): ${result.digest}`);
} catch (error) {
console.error("❌ 交易失败:", error);
}
}
sendTransaction();
了解此交易中的 gas
您无需手动计算 gas 费用。
- 自动预算: 默认情况下,SDK 会为您估算 gas 费用。它会为执行设置充足的预算,避免过度超额支付。
- 支付来源: SDK 会自动从您的钱包中选择一个 SUI 代币对象来支付此费用。因此,请始终在钱包中保留少量 SUI 以支付 gas 费用。
预期输出
成功执行后,脚本将输出 交易摘要(您的交易跟踪 ID):
终端输出
📦 发送方地址: 0x123...
📝 正在签署并提交交易...
✅ 交易已提交!
Digest (跟踪 ID): 5T7x...9B2a
复制此摘要并在 Suiscan 上搜索。浏览器会显示永久的链上记录,包括 gas 消耗和执行状态。
后续步骤
现在您已经执行了第一笔链上写入交易:
- 阅读 如何获取对象数据 以检查接收方新收到的对象。
- 查阅 SuiClient 架构 了解 Sui 节点和职员的概念模型。
- 探索
getObjectAPI 参考 以查询详细的交易效果和对象架构。