Sui.

帖子

分享您的知识。

article banner.
Sergey Ilin.
Jun 04, 2025
文章

如何转移特定数量的 SUI 代币:处理硬币对象

如何转移特定数量的 SUI 代币:处理硬币对象

挑战

与代币余额为简单数字的传统区块链不同,SUI将代币存储为单独的硬币对象. 这意味着,如果您有 3 个 SUI 代币,它们将作为三个独立的对象存在(例如,1 个 SUI + 1 个 SUI + 1 个 SUI = 总计 3 个),而不是 “3 个 SUI” 的单一余额.

当你想转账特定金额(比如 2.5 SUI)时,你需要:

  1. 如果需要,合并多个硬币对象
  2. 拆分硬币以获得确切金额 3.转移生成的硬币对象

代码示例:传输 2.5 SUI

以下是一个完整的 TypeScript 示例,展示了如何处理这个问题:

import { SuiClient, getFullnodeUrl } from '@mysten/sui.js/client';
import { TransactionBlock } from '@mysten/sui.js/transactions';
import { Ed25519Keypair } from '@mysten/sui.js/keypairs/ed25519';

// Initialize client and keypair
const client = new SuiClient({ url: getFullnodeUrl('testnet') });
const keypair = Ed25519Keypair.fromSecretKey(YOUR_SECRET_KEY);
const senderAddress = keypair.getPublicKey().toSuiAddress();

async function transferSUI(recipientAddress: string, amountInSUI: number) {
  try {
    // Convert SUI to MIST (1 SUI = 1,000,000,000 MIST)
    const amountInMist = Math.floor(amountInSUI * 1_000_000_000);
    
    // Step 1: Get all SUI coin objects owned by sender
    const coinObjects = await client.getCoins({
      owner: senderAddress,
      coinType: '0x2::sui::SUI'
    });
    
    if (coinObjects.data.length === 0) {
      throw new Error('No SUI coins found');
    }
    
    console.log(`Found ${coinObjects.data.length} SUI coin objects`);
    coinObjects.data.forEach((coin, index) => {
      console.log(`Coin ${index + 1}: ${coin.balance} MIST`);
    });
    
    // Step 2: Create transaction block
    const txb = new TransactionBlock();
    
    // Step 3: Handle coin merging and splitting
    let primaryCoin;
    
    if (coinObjects.data.length === 1) {
      // Single coin - just split it
      primaryCoin = coinObjects.data[0].coinObjectId;
    } else {
      // Multiple coins - merge them first
      primaryCoin = coinObjects.data[0].coinObjectId;
      const coinsToMerge = coinObjects.data.slice(1).map(coin => coin.coinObjectId);
      
      if (coinsToMerge.length > 0) {
        txb.mergeCoins(primaryCoin, coinsToMerge);
        console.log(`Merging ${coinsToMerge.length} coins into primary coin`);
      }
    }
    
    // Step 4: Split the exact amount needed
    const [transferCoin] = txb.splitCoins(primaryCoin, [amountInMist]);
    
    // Step 5: Transfer the split coin
    txb.transferObjects([transferCoin], recipientAddress);
    
    // Step 6: Set gas budget and execute
    txb.setGasBudget(10000000); // 0.01 SUI in MIST
    
    const result = await client.signAndExecuteTransactionBlock({
      signer: keypair,
      transactionBlock: txb,
      options: {
        showEffects: true,
        showObjectChanges: true,
      },
    });
    
    console.log('Transaction successful!');
    console.log('Digest:', result.digest);
    console.log('Gas used:', result.effects?.gasUsed);
    
    return result;
    
  } catch (error) {
    console.error('Transfer failed:', error);
    throw error;
  }
}

// Usage example
async function main() {
  const recipientAddress = '0x742d35cc6db7e3b6c7e4c46e7f8c7e6f1234567890abcdef';
  const amountToTransfer = 2.5; // SUI
  
  await transferSUI(recipientAddress, amountToTransfer);
}

// Run the transfer
main().catch(console.error);

分步细分

1. 获取硬币物品

const coinObjects = await client.getCoins({
  owner: senderAddress,
  coinType: '0x2::sui::SUI'
});

这将检索您的地址拥有的所有 SUI 硬币对象.

2. 合并多个硬币(如果需要)

if (coinObjects.data.length > 1) {
  const primaryCoin = coinObjects.data[0].coinObjectId;
  const coinsToMerge = coinObjects.data.slice(1).map(coin => coin.coinObjectId);
  txb.mergeCoins(primaryCoin, coinsToMerge);
}

如果你有多个硬币对象,请将它们合并成一个更大的硬币.

3. 拆分精确金额

const [transferCoin] = txb.splitCoins(primaryCoin, [amountInMist]);

从合并后的硬币中拆分您要转账的确切金额.

4. 转移分割硬币

txb.transferObjects([transferCoin], recipientAddress);

将新创建的硬币对象转移给接收者.

要记住的要点

-MIST 与 SUI:处理交易时务必将 SUI 转换为 MIST(乘以 1,000,000,000) -天然气预算:设定适当的天然气预算(通常 0.01 SUI 就足够了) -对象 ID:每枚硬币都有您在交易中引用的唯一对象 ID -原子操作:所有合并、拆分和转移操作都发生在单个交易中

错误处理技巧

// Check if you have enough balance
const totalBalance = coinObjects.data.reduce((sum, coin) => 
  sum + parseInt(coin.balance), 0
);

if (totalBalance < amountInMist) {
  throw new Error(`Insufficient balance. Have: ${totalBalance/1e9} SUI, Need: ${amountInSUI} SUI`);
}

替代方案:使用 SUI SDK 的内置方法

对于更简单的用例,你可以使用 SDK 的便捷方法:

const txb = new TransactionBlock();
const [coin] = txb.splitCoins(txb.gas, [amountInMist]);
txb.transferObjects([coin], recipientAddress);

这使用汽油币进行转账,这对于较小的金额来说效果很好. 但是,如果汽油币没有所需数量的SUI,则需要上述方法/

  • Sui
  • Transaction Processing
  • Move
1
分享
评论
.
harry phan.
Jun 5 2025, 04:31

在 SUI 中处理硬币物体就像在游戏中手工制作一样

Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.

610帖子1335答案
Sui.X.Peera.

赚取你的 1000 Sui 份额

获取声誉积分,并因帮助 Sui 社区成长而获得奖励。

奖励活动七月