前言
Metamask中控制器众多(50个左右),我们不可能一一介绍,从本章开始我们会选择性的讲解几个最核心的控制器实现,这一章我们讲交易控制器TransactionController,也是最核心的控制器。
1. 交易控制器概述
TransactionController是MetaMask的核心控制器,负责管理所有交易相关的操作,包括:
- 交易的创建、签名、发布
- 交易状态的跟踪和更新
- 交易历史的维护
- 多链交易的支持
- 交易模拟和安全检查
2. 核心架构组件
2.1 主要组件
- TransactionController: 主控制器,协调所有交易操作
- PendingTransactionTracker: 跟踪待处理交易状态
- MultichainTrackingHelper: 多链交易跟踪助手
- TransactionPoller: 交易轮询器
- IncomingTransactionHelper: 入账交易助手
2.2 状态管理
typescript
interface TransactionControllerState {
transactions: TransactionMeta[]; // 所有交易列表
transactionBatches: TransactionBatchMeta[]; // 批量交易
methodData: Record<string, MethodData>; // 方法数据缓存
lastFetchedBlockNumbers: { [key: string]: number | string }; // 最后获取的区块号
submitHistory: SubmitHistoryEntry[]; // 提交历史
}
3. 交易流程详解
当用户发起转账交易,会调用交易的入口函数addTransaction
:
js
// 伪代码
async addTransaction(txParams: TransactionParams, options) {
// ===== 第一阶段:交易创建 =====
// 1. 创建交易元数据
const transactionMeta = {
actionId: options.actionId, // 操作唯一标识,防止重复请求,确保幂等性
status: TransactionStatus.unapproved,
txParams: txParams,
chainId: options.networkClientId,
networkClientId: options.networkClientId,
origin: options.origin,
time: Date.now(),
};
// 2. 添加到状态
this.update((state) => {
state.transactions.push(transactionMeta);
});
// 3. 发布未批准交易事件
this.messagingSystem.publish('unapprovedTransactionAdded', transactionMeta);
// ===== 第二阶段:模拟交易 =====
// 4. 执行交易模拟,调用模拟API,获取余额变化、gas费用等信息
await this.#updateSimulationData(transactionMeta);
// ===== 第三阶段:用户批准 =====
// 5. 等待用户批准
if (options.requireApproval !== false) {
await this.#requestApproval(transactionMeta);
}
// ===== 第四阶段:交易发布 =====
// 6. 签名交易
const signedTx = await this.#signTransaction(transactionMeta);
// 7. 发布到区块链
const hash = await this.#publishTransaction(signedTx);
// 8. 更新状态为已提交
this.#updateTransaction(transactionMeta.id, {
status: TransactionStatus.submitted,
hash: hash,
submittedTime: Date.now()
});
// ===== 第五阶段:交易跟踪 =====
// 9. 创建待处理交易跟踪器
const pendingTracker = new PendingTransactionTracker({
provider: this.#getProvider(),
transactionMeta: transactionMeta,
onTransactionConfirmed: (txMeta) => {
// 伪代码:交易确认回调
this.#updateTransaction(txMeta.id, {
status: TransactionStatus.confirmed,
txReceipt: txMeta.txReceipt
});
this.messagingSystem.publish('transactionConfirmed', txMeta);
}
});
// 10. 开始跟踪交易状态
pendingTracker.startTracking();
return {
result: Promise.resolve(hash),
transactionMeta: transactionMeta
};
}
4. 关键概念解析
4.1 交易状态流转
typescript
enum TransactionStatus {
unapproved = 'unapproved', // 未批准
approved = 'approved', // 已批准
signed = 'signed', // 已签名
submitted = 'submitted', // 已提交
confirmed = 'confirmed', // 已确认
failed = 'failed', // 失败
dropped = 'dropped', // 已丢弃
rejected = 'rejected' // 已拒绝
}
4.2 交易模拟机制
MetaMask使用专用的模拟API进行交易模拟:
typescript
// 模拟API调用
const simulationResult = await fetch('https://tx-sentinel-{0}.api.cx.metamask.io/', {
method: 'POST',
body: JSON.stringify({
method: 'infura_simulateTransactions',
params: [txParams]
})
});
相比标准的eth_call
和eth_estimateGas
,MetaMask的模拟API提供:
- 更详细的余额变化信息
- 安全风险检测
- 更丰富的交易分析数据
5. 多链支持架构
5.1 MultichainTrackingHelper
负责管理多链交易的跟踪:
typescript
class MultichainTrackingHelper {
#trackingMap: Map<NetworkClientId, {
nonceTracker: NonceTracker;
pendingTransactionTracker: PendingTransactionTracker;
}> = new Map();
// 为每个网络客户端创建独立的跟踪器
#startTrackingByNetworkClientId(networkClientId: NetworkClientId) {
const trackers = this.#trackingMap.get(networkClientId);
if (trackers) {
return;
}
// 创建该链的跟踪器
const pendingTransactionTracker = this.#createPendingTransactionTracker({
provider,
blockTracker,
chainId,
networkClientId,
});
this.#trackingMap.set(networkClientId, {
nonceTracker,
pendingTransactionTracker,
});
}
}
5.2 网络状态监听
typescript
// 监听网络状态变化,自动管理跟踪器
this.messagingSystem.subscribe('NetworkController:stateChange', () => {
this.#refreshTrackingMap(networkClients);
});
6. 交易跟踪机制
6.1 PendingTransactionTracker
负责跟踪待处理交易的状态变化:
typescript
class PendingTransactionTracker {
// 启动跟踪
startIfPendingTransactions = () => {
const pendingTransactions = this.#getPendingTransactions();
if (pendingTransactions.length) {
this.#start(pendingTransactions);
} else {
this.stop();
}
};
// 轮询检查交易状态
async #checkTransactions() {
const pendingTransactions = this.#getPendingTransactions();
for (const txMeta of pendingTransactions) {
await this.#checkTransaction(txMeta);
}
}
}
6.2 事件驱动架构
typescript
// 监听交易状态变化事件
pendingTransactionTracker.hub.on('transaction-confirmed', (txMeta) => {
this.#onConfirmedTransaction(txMeta);
});
pendingTransactionTracker.hub.on('transaction-failed', (txMeta, error) => {
this.#failTransaction(txMeta, error);
});
7. 安全机制
- 交易参数验证
- Gas费用合理性检查
- 合约交互风险检测(通过PPOM)
- 钓鱼网站防护(通过电鱼网站控制器)
8. 高级功能
8.1 交易加速和取消
typescript
// 交易加速
async speedUpTransaction(transactionId: string, gasValues) {
return this.#retryTransaction({
transactionId,
gasValues,
label: 'speedup',
rate: SPEEDUP_RATE,
transactionType: TransactionType.retry,
});
}
// 交易取消
async stopTransaction(transactionId: string, gasValues) {
return this.#retryTransaction({
transactionId,
gasValues,
label: 'cancel',
rate: CANCEL_RATE,
transactionType: TransactionType.cancel,
prepareTransactionParams: (txParams) => {
delete txParams.data;
txParams.to = txParams.from;
txParams.value = '0x0';
},
});
}
8.2 批量交易支持
typescript
// 批量交易处理
async addTransactionBatch(request: TransactionBatchRequest) {
const { transactions, options } = request;
const batchId = generateBatchId();
const batchMeta = {
id: batchId,
transactions: [],
status: TransactionStatus.unapproved,
};
// 处理批量交易
for (const txParams of transactions) {
const result = await this.addTransaction(txParams, {
...options,
batchId,
});
batchMeta.transactions.push(result.transactionMeta);
}
return { batchId, transactions: batchMeta.transactions };
}
9. 性能优化
9.1 交易历史管理
typescript
// 限制交易历史数量
const transactionHistoryLimit = 1000;
if (state.transactions.length > transactionHistoryLimit) {
state.transactions = state.transactions.slice(-transactionHistoryLimit);
}
9.2 缓存机制
- 方法数据缓存
- 区块号缓存
- Gas费用缓存
10. 总结
TransactionController是MetaMask的核心组件,通过模块化设计实现了:
- 多链支持: 通过MultichainTrackingHelper管理多链交易
- 状态管理: 完整的状态流转和事件通知机制
- 安全防护: 多层次的安全检查和风险防护
- 性能优化: 智能缓存和历史管理
- 扩展性: 钩子机制支持自定义逻辑
这个架构设计使得MetaMask能够安全、高效地处理各种复杂的交易场景,为用户提供可靠的区块链交互体验。
sequenceDiagram
participant UI as 用户界面
participant TC as TransactionController
participant PTT as PendingTransactionTracker
participant BC as 区块链
UI->>TC: addTransaction
TC->>TC: 创建交易元数据
TC->>UI: unapprovedTransactionAdded
UI->>TC: 用户批准
TC->>TC: #processApproval
TC->>BC: 发布交易
TC->>UI: transactionSubmitted
PTT->>BC: 轮询交易收据
BC->>PTT: 返回收据
PTT->>TC: transaction-confirmed
TC->>TC: #onConfirmedTransaction
TC->>UI: transactionConfirmed
TC->>UI: transactionStatusUpdated
学习交流请添加vx: gh313061
下期预告: 构建网络控制器(NetworkController)