全面解析 TON 交易:如何追踪交易结果并使用 TonClient

·

在 TON 区块链生态中,开发者常常面临一个核心问题:如何确认一笔交易是否成功执行?此外,通过 TonClient 发送交易后返回的 Boc 数据有何作用?如何从中提取关键信息?本文将从交易结构、消息构建、结果确认等角度,系统性地解答这些问题,助你深入理解 TON 的交易机制。

TON 交易的基本概念

TON 区块链采用基于消息的异步模型,每一笔交易都包含三个核心组成部分:

简单来说,发起一笔 TON 转账交易,实质是向目标钱包合约发送一条消息,合约根据消息内容执行相应操作。

构建交易消息

在使用 TonConnect 发送交易前,需先构建有效的交易消息。以下以 JavaScript 版本的 TonConnect SDK 为例,说明如何定义交易参数:

基础转账消息结构

export declare interface SendTransactionRequest {
  validUntil: number;     // 交易有效期(Unix 时间戳)
  network?: CHAIN;        // 网络类型:主网或测试网
  from?: string;          // 发送方地址(格式为 "地址")
  messages: {
    address: string;      // 接收方地址
    amount: string;       // 转账金额(单位:nanoTon)
    stateInit?: string;   // 合约初始化数据(可选)
    payload?: string;     // 交易附加数据(可选)
  }[];
}

示例:简单转账

const transaction = {
  validUntil: Math.floor(Date.now() / 1000) + 600, // 有效期 10 分钟
  messages: [
    {
      address: "0:412410771DA82CBA306A55FA9E0D43C9D245E38133CB58F1457DFB8D5CD8892F",
      amount: "20000000", // 0.02 TON
    },
  ],
};

添加交易注释

若需为转账添加注释,需构建特定负载数据(Payload),并将其编码为 Base64 格式:

import { beginCell } from "@ton/ton";

const body = beginCell()
  .storeUint(0, 32)            // 写入 32 位零值标识文本注释
  .storeStringTail("Hello, TON!") // 写入注释内容
  .endCell();

const transaction = {
  validUntil: Math.floor(Date.now() / 1000) + 600,
  messages: [
    {
      address: "0:412410771DA82CBA306A55FA9E0D43C9D245E38133CB58F1457DFB8D5CD8892F",
      amount: "20000000",
      payload: body.toBoc().toString("base64"), // 添加注释负载
    },
  ],
};

👉 查看实时消息构建工具

获取与解析交易结果

发送交易后,如何确认其已上链并获取最终结果?以下是关键步骤与代码实现。

发送交易并获取 Boc

使用 TonConnect 发送交易后,将返回一个包含 boc 字段的响应对象:

const [tonConnectUi] = useTonConnectUI();
const result = await tonConnectUi.sendTransaction(transaction);
// result.boc 为已签名的交易 Boc 数据

boc 是触发交易的初始内容,将被广播到 TON 网络进行验证与执行。

监听交易确认状态

通过 TonClient 查询交易状态,比对链上交易哈希与发送的 Boc 哈希,可确认交易是否成功:

const waitForTransaction = async (options, client) => {
  const { hash, refetchInterval = 1000, refetchLimit, address } = options;
  return new Promise((resolve) => {
    let refetches = 0;
    const walletAddress = Address.parse(address);
    const interval = setInterval(async () => {
      refetches += 1;
      console.log("等待交易确认...");
      const state = await client.getContractState(walletAddress);
      if (!state || !state.lastTransaction) {
        clearInterval(interval);
        resolve(null);
        return;
      }
      const { lt: lastLt, hash: lastHash } = state.lastTransaction;
      const lastTx = await client.getTransaction(walletAddress, lastLt, lastHash);
      if (lastTx && lastTx.inMessage) {
        const msgCell = beginCell().store(storeMessage(lastTx.inMessage)).endCell();
        const inMsgHash = msgCell.hash().toString("base64");
        if (inMsgHash === hash) {
          clearInterval(interval);
          resolve(lastTx);
        }
      }
      if (refetchLimit && refetches >= refetchLimit) {
        clearInterval(interval);
        resolve(null);
      }
    }, refetchInterval);
  });
};

该方法通过定期查询合约最新交易,比对入站消息哈希是否匹配,从而确认交易完成。此外,也可使用 getTransactions 方法监听链上交易变化。

常见问题

1. 什么是 Boc?它在 TON 交易中起什么作用?

Boc(Bag of Cells)是 TON 区块链中数据的序列化格式,用于表示消息、交易和状态等信息。发送交易后返回的 Boc 是已签名的交易内容,包含所有必要参数,用于网络验证与执行。

2. 如何判断一笔 TON 交易是否成功?

可通过比对发送交易的 Boc 哈希与链上最新交易的入站消息哈希是否一致来判断。若一致,则交易已确认;若长时间未匹配,可能因网络拥堵或手续费不足导致失败。

3. 交易注释(Payload)是否必须?如何正确添加?

注释非必填,但常用于标识转账用途。添加时需构建特定 Cell 结构,包含 32 位零值标识和文本内容,并编码为 Base64 格式作为 Payload 传入。

4. TonClient 在交易流程中扮演什么角色?

TonClient 是 TON 区块链的客户端工具,用于与网络交互,包括发送交易、查询状态、获取交易详情等。它是开发者监控和确认交易的核心接口。

5. TON 与以太坊在交易处理上有何主要区别?

TON 采用异步消息模型,交易无需等待区块确认即可继续操作;而以太坊为同步模型,需等待区块最终性。此外,TON 的消息传递机制支持更复杂的跨合约交互。

6. 交易长时间未确认可能有哪些原因?

常见原因包括网络拥堵、Gas 费用不足、交易参数错误(如地址格式无效)、或节点同步延迟。建议检查交易参数并适当提高 Gas 限额。

总结

TON 作为基于消息的异步区块链,其交易机制与以太坊等同步模型区块链有显著差异。理解消息构建、Boc 数据处理及交易状态监控方法,是构建高效 DApp 的关键。通过合理使用 TonClient 和 TonConnect,开发者可有效追踪交易结果,提升应用可靠性。

👉 探索更多高级交易策略