name: midnight-dapp:transaction-flows description: 在向Midnight合约提交交易、跟踪交易状态、实现重试逻辑、在证明生成期间构建响应式UI或理解构建-证明-提交-确认流程时使用。
交易流程
通过完整的Midnight生命周期提交、跟踪和处理交易:构建、证明、提交和确认。
何时使用
- 向Midnight合约提交交易
- 跟踪交易状态和确认
- 为失败的提交实现重试逻辑
- 在证明生成期间构建响应式UI
- 理解与以太坊交易的差异
核心概念
构建-证明-提交-确认流程
Midnight交易经历四个不同的阶段:
- 构建:使用
contract.callTx.*和见证数据创建交易 - 证明:钱包通过本地证明服务器生成ZK证明(数秒)
- 提交:使用
walletAPI.submitTransaction()提交已证明的交易 - 确认:等待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- 诊断交易提交问题