UNPKG

evm

Version:

An ethereum virtual machine (EVM) bytecode decompiler

138 lines (127 loc) 4.74 kB
import * as BigNumber from '../../node_modules/big-integer'; import * as functionHashes from '../../data/functionHashes.json'; const parseSingle = (data: any, type: any) => { if (type === 'string') { return '"' + Buffer.from(data, 'hex').toString('utf8') + '"'; } else if (type === 'address') { return '0x' + data.substring(24); } else if (type === 'uint256' || type === 'uint8') { return BigNumber(data, 16).toString(); } else if (type === 'bool') { return (!BigNumber(data, 16).isZero()).toString(); } else { return data; } }; export default class Transaction { blockHash?: string; blockNumber?: number; from?: string; gas?: number; gasPrice?: number; input?: string; to?: string; value?: number; constructor(transactionObject?: any) { if (transactionObject) { if ('blockHash' in transactionObject) { this.blockHash = transactionObject.blockHash; } if ('blockNumber' in transactionObject) { this.blockNumber = transactionObject.blockNumber; } if ('from' in transactionObject) { this.from = transactionObject.from; } if ('gas' in transactionObject) { this.gas = transactionObject.gas; } if ('gasPrice' in transactionObject) { this.gasPrice = transactionObject.gasPrice; } if ('input' in transactionObject) { this.input = transactionObject.input.replace('0x', ''); } if ('to' in transactionObject) { this.to = transactionObject.to; } if ('value' in transactionObject) { this.value = transactionObject.value; } } } setInput(input: string): void { this.input = input.replace('0x', ''); } getFunctionHash(): string | false { if (this.input && this.input.length >= 8) { return this.input.substr(0, 8); } else { return false; } } getFunction(): string | false { const functionHash = this.getFunctionHash(); if (functionHash && functionHash in functionHashes) { return (functionHashes as any)[functionHash]; } else { return false; } } getFunctionName(): string | false { const rawFunction = this.getFunction(); if (rawFunction) { return rawFunction.split('(')[0]; } else { return false; } } getRawArguments(): string[] { if (this.input && this.input.length >= 70) { return this.input.substr(8).match(/.{1,64}/g)!; } else { return []; } } getArguments(descriptive: boolean = true): string[] { const functionName = this.getFunction(); const functionArguments = this.getRawArguments(); if (functionName && this.input) { const rawFunctionArguments = functionName .split('(')[1] .slice(0, -1) .split(','); if ( rawFunctionArguments.length === 1 && rawFunctionArguments[0] === '' && functionArguments.length === 0 ) { return []; } else { const result: string[] = []; for (let i = 0; i < rawFunctionArguments.length; i++) { const functionArgumentType = rawFunctionArguments[i] || 'unknown'; const functionArgument = functionArguments[i]; if (functionArgumentType === 'string') { const location = BigNumber(functionArgument, 16) .divide(32) .toJSNumber(); const length = BigNumber(functionArguments[location], 16) .multiply(2) .toJSNumber(); const data = this.input.substring(8).substr((location + 1) * 64, length); result.push(parseSingle(data, functionArgumentType)); } else { result.push(parseSingle(functionArgument, functionArgumentType)); } } return result; } } else { return functionArguments; } } isContractCreation(): boolean { return this.to === null; } }