forked from matter-labs/zksync
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrevert-reason.ts
104 lines (93 loc) · 3.67 KB
/
revert-reason.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import { ethers } from 'ethers';
import { readContractCode, readProductionContracts } from '../src.ts/deploy';
import { Interface } from 'ethers/lib/utils';
import * as chalk from 'chalk';
import { web3Url } from './utils';
const contracts = readProductionContracts();
const franklinInterface = new Interface(contracts.zkSync.abi);
const governanceInterface = new Interface(contracts.governance.abi);
const verifierInterface = new Interface(contracts.governance.abi);
const deployFactoryInterface = new Interface(readContractCode('DeployFactory').abi);
function hex_to_ascii(str1) {
const hex = str1.toString();
let str = '';
for (let n = 0; n < hex.length; n += 2) {
str += String.fromCharCode(parseInt(hex.substr(n, 2), 16));
}
return str;
}
async function reason() {
const args = process.argv.slice(2);
const hash = args[0];
const web3 = args[1] == null ? web3Url() : args[1];
console.log('tx hash:', hash);
console.log('provider:', web3);
const provider = new ethers.providers.JsonRpcProvider(web3);
const tx = await provider.getTransaction(hash);
if (!tx) {
console.log('tx not found');
} else {
try {
const parsedTransaction = franklinInterface.parseTransaction({ data: tx.data });
if (parsedTransaction) {
console.log('parsed tx: ', parsedTransaction.name, parsedTransaction);
console.log('tx args: ', parsedTransaction.name, JSON.stringify(parsedTransaction.args, null, 2));
} else {
console.log('tx:', tx);
}
} catch (e) {
console.log('zkSync transaction is not parsed');
}
const transaction = await provider.getTransaction(hash);
const receipt = await provider.getTransactionReceipt(hash);
console.log('receipt:', receipt);
console.log('\n \n ');
if (receipt.gasUsed) {
const gasLimit = transaction.gasLimit;
const gasUsed = receipt.gasUsed;
console.log('Gas limit: ', transaction.gasLimit.toString());
console.log('Gas used: ', receipt.gasUsed.toString());
// If more than 90% of gas was used, report it as an error.
const threshold = gasLimit.mul(90).div(100);
if (gasUsed.gte(threshold)) {
const error = chalk.bold.red;
console.log(error('More than 90% of gas limit was used!'));
console.log(error('It may be the reason of the transaction failure'));
}
}
if (receipt.status) {
console.log('tx success');
} else {
const code = await provider.call(tx, tx.blockNumber);
const reason = hex_to_ascii(code.substr(138));
console.log('revert reason:', reason);
console.log('revert code', code);
}
for (const log of receipt.logs) {
console.log(log);
try {
let parsedLog = franklinInterface.parseLog(log);
if (!parsedLog) {
parsedLog = governanceInterface.parseLog(log);
}
if (!parsedLog) {
parsedLog = verifierInterface.parseLog(log);
}
if (!parsedLog) {
parsedLog = deployFactoryInterface.parseLog(log);
}
if (parsedLog) {
console.log(parsedLog);
} else {
console.log(log);
}
} catch {}
}
}
}
reason()
.then(() => process.exit(0))
.catch((err) => {
console.error('Error:', err.message || err);
process.exit(1);
});