跳到主要内容

TON 交易构建与签名

TON 区块链中的交易处理包括交易构建、签名和发送等核心操作。

🔄 交易基础

交易类型

TON 支持两种主要的交易类型:

  • 内部交易 (Internal): 合约之间的消息传递
  • 外部交易 (External): 从外部发起的交易

交易组件

每个交易包含以下组件:

  • 消息体 (Body): 交易的具体内容
  • 金额 (Value): 转账的 TON 数量
  • 目标地址 (To): 接收方地址
  • 序列号 (Seqno): 防止重放攻击的计数器

📝 创建交易

基本转账交易

import { internal, SendMode, toNano } from '@ton/ton';

const transfer = contract.createTransfer({
seqno,
secretKey: keyPair.secretKey,
messages: [
internal({
value: toNano('0.01'), // 转账金额
to: recipientAddress, // 接收地址
body: 'Hello TON!', // 消息内容
bounce: false, // 是否允许退回
}),
],
sendMode: SendMode.NONE,
});

批量转账

const transfer = contract.createTransfer({
seqno,
secretKey: keyPair.secretKey,
messages: [
internal({
value: toNano('0.01'),
to: address1,
body: 'First transfer',
bounce: false,
}),
internal({
value: toNano('0.02'),
to: address2,
body: 'Second transfer',
bounce: false,
}),
],
sendMode: SendMode.NONE,
});

🎯 发送模式

SendMode 选项

import { SendMode } from '@ton/ton';

// 基本发送模式
SendMode.NONE // 默认模式
SendMode.PAY_GAS_SEPARATELY // 单独支付 Gas
SendMode.IGNORE_ERRORS // 忽略错误
SendMode.DESTROY // 销毁合约
SendMode.REMAINING_GAS // 剩余 Gas 返还
SendMode.REMAINING_VALUE // 剩余价值返还
SendMode.REMAINING_GAS_VALUE // 剩余 Gas 和价值返还

组合发送模式

const sendMode = SendMode.PAY_GAS_SEPARATELY + SendMode.IGNORE_ERRORS;

const transfer = contract.createTransfer({
seqno,
secretKey: keyPair.secretKey,
messages: [/* ... */],
sendMode,
});

📤 发送交易

直接发送

// 发送交易
await contract.send(transfer);
console.log('Transaction sent successfully!');

使用 BOC 发送

// 转换为 BOC 格式
const boc = transfer.toBoc();
await contract.sendBoc(boc);

获取交易哈希

const hash = transfer.hash().toString('hex');
console.log('Transaction hash:', hash);

🔐 交易签名

自动签名

使用 createTransfer 方法时,签名会自动处理:

const transfer = contract.createTransfer({
seqno,
secretKey: keyPair.secretKey, // 私钥用于签名
messages: [/* ... */],
sendMode: SendMode.NONE,
});

手动签名

import { sign } from '@ton/crypto';

// 创建未签名的交易
const unsignedTransfer = contract.createTransfer({
seqno,
secretKey: Buffer.alloc(64), // 空私钥
messages: [/* ... */],
sendMode: SendMode.NONE,
});

// 手动签名
const signature = sign(unsignedTransfer.hash(), keyPair.secretKey);

💰 金额处理

使用 toNano 转换

import { toNano } from '@ton/ton';

// 转换不同单位的金额
const amount1 = toNano('1'); // 1 TON
const amount2 = toNano('0.5'); // 0.5 TON
const amount3 = toNano('0.001'); // 0.001 TON
const amount4 = toNano('1000000'); // 1,000,000 TON

手动计算

// 1 TON = 10^9 nano TON
const oneTon = BigInt(10 ** 9);
const halfTon = oneTon / BigInt(2);
const smallAmount = BigInt(10 ** 6); // 0.001 TON

📱 移动端交易

React Native 集成

import { TonConnect } from '@tonconnect/ui-react-native';

const connector = new TonConnect({
manifestUrl: 'https://your-app.com/tonconnect-manifest.json'
});

// 连接钱包
await connector.connect();

// 发送交易
const transaction = {
validUntil: Date.now() + 5 * 60 * 1000, // 5 分钟有效期
messages: [
{
address: recipientAddress,
amount: toNano('0.01'),
payload: 'Hello from mobile!'
}
]
};

await connector.sendTransaction(transaction);

🌐 Web 钱包集成

浏览器钱包

import { TonConnect } from '@tonconnect/ui';

const connector = new TonConnect({
manifestUrl: 'https://your-app.com/tonconnect-manifest.json'
});

// 连接钱包
await connector.connect();

// 发送交易
const transaction = {
validUntil: Date.now() + 5 * 60 * 1000,
messages: [
{
address: recipientAddress,
amount: toNano('0.01'),
payload: 'Hello from web!'
}
]
};

await connector.sendTransaction(transaction);

🔧 高级功能

自定义消息体

import { beginCell } from '@ton/core';

// 创建自定义消息体
const customBody = beginCell()
.storeUint(0x12345678, 32) // 操作码
.storeString('Custom message')
.endCell();

const transfer = contract.createTransfer({
seqno,
secretKey: keyPair.secretKey,
messages: [
internal({
value: toNano('0.01'),
to: recipientAddress,
body: customBody,
bounce: true,
}),
],
sendMode: SendMode.NONE,
});

条件交易

// 检查余额后再发送
const balance = await contract.getBalance();
const transferAmount = toNano('0.01');

if (balance >= transferAmount) {
const transfer = contract.createTransfer({
seqno,
secretKey: keyPair.secretKey,
messages: [
internal({
value: transferAmount,
to: recipientAddress,
body: 'Conditional transfer',
bounce: false,
}),
],
sendMode: SendMode.NONE,
});

await contract.send(transfer);
} else {
console.log('Insufficient balance');
}

📝 完整示例

import { mnemonicToPrivateKey } from '@ton/crypto';
import { TonClient, WalletContractV4, internal, SendMode, toNano } from '@ton/ton';

async function sendTransaction() {
// 创建客户端
const client = new TonClient({
endpoint: 'https://toncenter.com/api/v2/jsonRPC',
apiKey: 'YOUR_API_KEY'
});

// 从助记词生成密钥对
const mnemonics = process.env.TON_MNEMONIC;
const keyPair = await mnemonicToPrivateKey(mnemonics.split(' '));

// 创建钱包合约
const wallet = WalletContractV4.create({
workchain: 0,
publicKey: keyPair.publicKey
});
const contract = client.open(wallet);

// 获取当前序列号
const seqno = await contract.getSeqno();
console.log('Current sequence number:', seqno);

// 检查余额
const balance = await contract.getBalance();
console.log('Current balance:', balance.toString());

// 创建转账交易
const recipientAddress = 'UQCK8IqcjCaiKtWR4Jl0r3HmTNb2WFTMIAO7yh5cIgb8aKes';
const transferAmount = toNano('0.01');

if (balance >= transferAmount) {
const transfer = contract.createTransfer({
seqno,
secretKey: keyPair.secretKey,
messages: [
internal({
value: transferAmount,
to: recipientAddress,
body: 'Hello from TON transaction!',
bounce: false,
}),
],
sendMode: SendMode.NONE,
});

// 获取交易哈希
const hash = transfer.hash().toString('hex');
console.log('Transaction hash:', hash);

// 发送交易
await contract.send(transfer);
console.log('Transaction sent successfully!');

return { hash, seqno, amount: transferAmount };
} else {
throw new Error('Insufficient balance');
}
}

// 使用示例
sendTransaction().catch(console.error);