diff options
author | Greg Hysen <greg.hysen@gmail.com> | 2019-01-31 02:52:13 +0800 |
---|---|---|
committer | Greg Hysen <greg.hysen@gmail.com> | 2019-02-09 08:25:30 +0800 |
commit | 8fc3a6b828e6f3a5f1aacfc62f585834f012ce7a (patch) | |
tree | 10a9054f1c380b7c267703fa1b463cad1440086a /packages/utils | |
parent | 100840b74359e00bda90146f87ddeafd62db06e3 (diff) | |
download | dexon-0x-contracts-8fc3a6b828e6f3a5f1aacfc62f585834f012ce7a.tar.gz dexon-0x-contracts-8fc3a6b828e6f3a5f1aacfc62f585834f012ce7a.tar.zst dexon-0x-contracts-8fc3a6b828e6f3a5f1aacfc62f585834f012ce7a.zip |
Expanding search parameters for transaction decoder
Diffstat (limited to 'packages/utils')
-rw-r--r-- | packages/utils/src/calldata_decoder.ts | 93 |
1 files changed, 87 insertions, 6 deletions
diff --git a/packages/utils/src/calldata_decoder.ts b/packages/utils/src/calldata_decoder.ts index 780332514..0279aa030 100644 --- a/packages/utils/src/calldata_decoder.ts +++ b/packages/utils/src/calldata_decoder.ts @@ -5,18 +5,41 @@ import { SimpleContractArtifact } from '@0x/types'; import { ContractAbi, MethodAbi } from 'ethereum-types'; import * as _ from 'lodash'; import { AbiEncoder } from '.'; +import { ContractAddresses, getContractAddressesForNetworkOrThrow, NetworkId } from '@0x/contract-addresses'; export interface DecodedCalldata { functionName: string; functionSignature: string; functionArguments: any; + contractName: string; + deployedAddress?: string; + deployedNeworkId?: string; +} + +interface AbiEncoderBySelectorElement { + abiEncoder: AbiEncoder.Method; + contractName?: string; + contractAddress?: string; +} + +interface AbiEncoderByNeworkId { + [index: string]: AbiEncoderBySelectorElement; } interface AbiEncoderBySelector { - [index: string]: AbiEncoder.Method; + [index: string]: AbiEncoderByNeworkId; +} + +interface DeployedContractInfoByNetwork { + [index: number]: string; +} + +interface DeployedContractInfoByName { + [index: string]: DeployedContractInfoByNetwork; } export class CalldataDecoder { + private readonly _deployedContractInfoByName = {} as DeployedContractInfoByName; private readonly _abiEncoderBySelector: AbiEncoderBySelector = {}; private static _instance: CalldataDecoder; @@ -27,7 +50,15 @@ export class CalldataDecoder { return CalldataDecoder._instance; } - public constructor() { + private constructor() { + // Load addresses by contract name + _.each(NetworkId, (networkId: NetworkId) => { + const contractAddressesForNetwork = getContractAddressesForNetworkOrThrow(networkId); + _.each(contractAddressesForNetwork, (contractAddress: string, contractName: string) => { + this._deployedContractInfoByName[contractName][networkId as number] = contractAddress; + }); + }); + // Load contract artifacts _.each(ContractArtifacts, (contractArtifactAsJson: any) => { const conractArtifact = contractArtifactAsJson as SimpleContractArtifact; const contractAbi: ContractAbi = conractArtifact.compilerOutput.abi; @@ -38,21 +69,71 @@ export class CalldataDecoder { if (_.has(this._abiEncoderBySelector, functionSelector)) { return; } - this._abiEncoderBySelector[functionSelector] = abiEncoder; + this._abiEncoderBySelector[functionSelector][conractArtifact.contractName] = {abiEncoder}; }); }); } - public static decode(calldata: string, rules?: AbiEncoder.DecodingRules): DecodedCalldata { + public static registerContractAbi(contractArtifact: SimpleContractArtifact, deployedAddress?: string, deployedNeworkId?: number) { + + } + + private static getFunctionSelector(calldata: string): string { if (!calldata.startsWith('0x') || calldata.length < 10) { throw new Error(`Malformed calldata. Must include hex prefix '0x' and 4-byte function selector. Got '${calldata}'`); } const functionSelector = calldata.substr(0, 10); + return functionSelector; + } + + public static decodeWithContractAddress(calldata: string, contractAddress: string, networkId?: number): DecodedCalldata { + const functionSelector = CalldataDecoder.getFunctionSelector(calldata); const instance = CalldataDecoder.getInstance(); - const abiEncoder = instance._abiEncoderBySelector[functionSelector]; + const contractName = _.findKey(instance._deployedContractInfoByName, (info: DeployedContractInfoByNetwork) => { + return (!_.isUndefined(networkId) && info[networkId] === contractAddress) || (_.isUndefined(networkId) && contractAddress in info); + }); + if (_.isUndefined(contractName)) { + throw new Error(`Could not find contract name: ${contractName}`); + } + const abiEncoder = instance._abiEncoderBySelector[functionSelector][contractName]; if (_.isUndefined(abiEncoder)) { throw new Error(`Could not find matching abi encoder for selector '${functionSelector}'`); } + + } + + public static decodeWithContractName(calldata: string, contractName: string): DecodedCalldata { + const functionSelector = CalldataDecoder.getFunctionSelector(calldata); + const instance = CalldataDecoder.getInstance(); + const abiEncoder = instance._abiEncoderBySelector[functionSelector][contractName]; + if (_.isUndefined(abiEncoder)) { + throw new Error(`Could not find matching abi encoder for selector '${functionSelector}'`); + } + } + + public static decodeWithoutContractInfo(calldata: string): DecodedCalldata { + const functionSelector = CalldataDecoder.getFunctionSelector(calldata); + const instance = CalldataDecoder.getInstance(); + const abiEncoder = _.find(instance._abiEncoderBySelector[functionSelector], () => {return true}); + if (_.isUndefined(abiEncoder)) { + throw new Error(`Could not find matching abi encoder for selector '${functionSelector}'`); + } + return { + functionName: string; + functionSignature: string; + functionArguments: any; + contractName: string; + deployedAddress?: string; + deployedNeworkId?: string; + }; + } + + public static decode(calldata: string, contractName?: string, contractAddress?: string, networkId?: number, rules?: AbiEncoder.DecodingRules): DecodedCalldata { + + + + + /* const functionName = abiEncoder.getDataItem().name; const functionSignature = abiEncoder.getSignatureType(); const functionArguments = abiEncoder.decode(calldata, rules); @@ -61,6 +142,6 @@ export class CalldataDecoder { functionSignature, functionArguments } - return decodedCalldata; + return decodedCalldata;*/ } }
\ No newline at end of file |