MidnightDApp交易流程Skill midnight-dapp:transaction-flows

Midnight DApp交易流程技能专注于在Midnight区块链上实现完整的交易生命周期管理,包括构建交易、生成零知识证明、提交交易和跟踪确认状态。该技能涵盖ZK证明生成期间的UI响应式设计、交易重试逻辑实现、状态机管理以及性能优化策略,特别适用于需要隐私保护的DApp开发。关键词:Midnight区块链、ZK证明、DApp开发、交易流程、状态跟踪、重试逻辑、零知识证明、隐私交易、Web3开发、智能合约交互。

DApp开发 0 次安装 0 次浏览 更新于 2/26/2026

name: midnight-dapp:transaction-flows description: 在向Midnight合约提交交易、跟踪交易状态、实现重试逻辑、在证明生成期间构建响应式UI或理解构建-证明-提交-确认流程时使用。

交易流程

通过完整的Midnight生命周期提交、跟踪和处理交易:构建、证明、提交和确认。

何时使用

  • 向Midnight合约提交交易
  • 跟踪交易状态和确认
  • 为失败的提交实现重试逻辑
  • 在证明生成期间构建响应式UI
  • 理解与以太坊交易的差异

核心概念

构建-证明-提交-确认流程

Midnight交易经历四个不同的阶段:

  1. 构建:使用contract.callTx.*和见证数据创建交易
  2. 证明:钱包通过本地证明服务器生成ZK证明(数秒)
  3. 提交:使用walletAPI.submitTransaction()提交已证明的交易
  4. 确认:等待Midnight网络上的最终性
// 完整的交易流程
const tx = await contract.callTx.transfer(recipient, amount, witnesses);
const provenTx = await walletAPI.balanceAndProveTransaction(tx, newCoins);
const txHash = await walletAPI.submitTransaction(provenTx);
// 等待确认...

用户体验影响

与以太坊的即时签名不同,Midnight证明生成需要数秒时间。您的UI必须:

  • 在证明生成期间显示加载状态
  • 尽可能提供进度指示器
  • 优雅地处理超时
  • 支持取消操作
  • 允许失败时重试

参考文档

文档 描述
transaction-lifecycle.md 包含状态转换的完整交易流程
signing-flow.md 钱包签名和证明生成详情
confirmation-patterns.md 轮询、最终性和UI更新策略
web3-comparison.md 以太坊交易模式与Midnight对比

示例

示例 描述
submit-transaction/ 完整的交易提交流程
tx-status-tracker/ 交易状态跟踪UI
retry-patterns/ 指数退避和重试UI

快速开始

1. 构建交易

import type { WitnessContext } from "@midnight-ntwrk/midnight-js-types";

// 为私有数据定义见证
const witnesses = {
  get_secret: ({ privateState }: WitnessContext<PrivateState>): bigint => {
    return privateState.secret;
  },
};

// 构建交易
const tx = await contract.callTx.transfer(recipient, amount, witnesses);

2. 证明并提交

// 显示加载状态 - 这需要数秒时间
setStatus("正在生成证明...");

// 证明交易(调用本地证明服务器)
const provenTx = await walletAPI.balanceAndProveTransaction(tx, newCoins);

// 提交到网络
setStatus("正在提交...");
const txHash = await walletAPI.submitTransaction(provenTx);

setStatus("已提交!");
console.log("交易哈希:", txHash);

3. 跟踪状态

function useTxStatus(txHash: string | null) {
  const [status, setStatus] = useState<TxStatus>("pending");

  useEffect(() => {
    if (!txHash) return;

    const checkStatus = async () => {
      // 轮询交易确认状态
      const result = await checkTransaction(txHash);
      setStatus(result.status);
    };

    const interval = setInterval(checkStatus, 3000);
    return () => clearInterval(interval);
  }, [txHash]);

  return status;
}

4. 使用重试处理错误

async function submitWithRetry(
  buildTx: () => Promise<Transaction>,
  maxRetries = 3
): Promise<string> {
  let lastError: Error | null = null;

  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const tx = await buildTx();
      const provenTx = await walletAPI.balanceAndProveTransaction(tx, newCoins);
      return await walletAPI.submitTransaction(provenTx);
    } catch (error) {
      lastError = error as Error;

      // 不重试用户拒绝
      if (error.message.includes("rejected")) {
        throw error;
      }

      // 指数退避
      if (attempt < maxRetries) {
        await new Promise((r) => setTimeout(r, 1000 * Math.pow(2, attempt)));
      }
    }
  }

  throw lastError ?? new Error("交易失败");
}

常见模式

交易状态机

type TxState =
  | { status: "idle" }
  | { status: "building" }
  | { status: "proving" }
  | { status: "submitting" }
  | { status: "pending"; txHash: string }
  | { status: "confirmed"; txHash: string }
  | { status: "failed"; error: Error };

function txReducer(state: TxState, action: TxAction): TxState {
  switch (action.type) {
    case "START":
      return { status: "building" };
    case "PROVING":
      return { status: "proving" };
    case "SUBMITTING":
      return { status: "submitting" };
    case "SUBMITTED":
      return { status: "pending", txHash: action.txHash };
    case "CONFIRMED":
      return { status: "confirmed", txHash: action.txHash };
    case "FAILED":
      return { status: "failed", error: action.error };
    case "RESET":
      return { status: "idle" };
    default:
      return state;
  }
}

乐观UI更新

async function transferWithOptimisticUpdate(
  recipient: Uint8Array,
  amount: bigint
) {
  // 乐观更新UI
  const previousBalance = balance;
  setBalance((prev) => prev - amount);

  try {
    const tx = await contract.callTx.transfer(recipient, amount, witnesses);
    const provenTx = await walletAPI.balanceAndProveTransaction(tx, newCoins);
    await walletAPI.submitTransaction(provenTx);
    // 成功 - 乐观更新正确
  } catch (error) {
    // 回滚乐观更新
    setBalance(previousBalance);
    throw error;
  }
}

性能考虑

关注点 缓解措施
证明生成(5-30秒) 显示进度UI,允许取消
网络延迟 实现指数退避重试
证明期间超时 设置适当超时(60秒+),超时重试
用户等待确认 显示待处理状态,允许后台监控

相关技能

  • wallet-integration - 交易前的钱包连接
  • proof-handling - 见证构造和证明生成
  • state-management - 交易前后的状态读取
  • error-handling - 交易错误消息和恢复

相关命令

  • /dapp-check - 验证交易提供者配置
  • /dapp-debug transactions - 诊断交易提交问题