Next按钮:
//MetaMask/metamask-extension/ui/ducks/send/send.js
/**
* Signs a transaction or updates a transaction in state if editing.
* This method is called when a user clicks the next button in the footer of
* the send page, signaling that a transaction should be executed. This method
* will create the transaction in state (by way of the various global provider
* constructs) which will eventually (and fairly quickly from user perspective)
* result in a confirmation window being displayed for the transaction.
* @returns {void}
*/
export function signTransaction() {
return async (dispatch, getState) => {
const state = getState();
const {
asset,
stage,
draftTransaction: { id, txParams },
recipient: { address },
amount: { value },
} = state[name];
if (stage === SEND_STAGES.EDIT) {
// When dealing with the edit flow there is already a transaction in
// state that we must update, this branch is responsible for that logic.
// We first must grab the previous transaction object from state and then
// merge in the modified txParams. Once the transaction has been modified
// we can send that to the background to update the transaction in state.
const unapprovedTxs = getUnapprovedTxs(state);
const unapprovedTx = unapprovedTxs[id];
const editingTx = {
...unapprovedTx,
txParams: Object.assign(unapprovedTx.txParams, txParams),
};
dispatch(updateTransaction(editingTx));
} else if (asset.type === ASSET_TYPES.TOKEN) {
// When sending a token transaction we have to the token.transfer method
// on the token contract to construct the transaction. This results in
// the proper transaction data and properties being set and a new
// transaction being added to background state. Once the new transaction
// is added to state a subsequent confirmation will be queued.
try {
const token = global.eth.contract(abi).at(asset.details.address);
token.transfer(address, value, {
...txParams,
to: undefined,
data: undefined,
});
dispatch(showConfTxPage());
dispatch(hideLoadingIndication());
} catch (error) {
dispatch(hideLoadingIndication());
dispatch(displayWarning(error.message));
}
} else {
// When sending a native asset we use the ethQuery.sendTransaction method
// which will result in the transaction being added to background state
// and a subsequent confirmation will be queued.
global.ethQuery.sendTransaction(txParams, (err) => {
if (err) {
dispatch(displayWarning(err.message));
}
});
dispatch(showConfTxPage());
}
};
}
Confirm按钮:
//MetaMask/metamask-extension/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js
handleSubmit() {
const {
sendTransaction,
clearConfirmTransaction,
txData,
history,
mostRecentOverviewPage,
updateCustomNonce,
} = this.props;
const { submitting } = this.state;
if (submitting) {
return;
}
this.setState(
{
submitting: true,
submitError: null,
},
() => {
this._removeBeforeUnload();
//发送交易
sendTransaction(txData)
.then(() => {
clearConfirmTransaction();
this.setState(
{
submitting: false,
},
() => {
history.push(mostRecentOverviewPage);
updateCustomNonce('');
},
);
})
.catch((error) => {
this.setState({
submitting: false,
submitError: error.message,
});
updateCustomNonce('');
});
},
);
}