From 42063f785ec565ae5b7f61c2c56a8eabace60d84 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 26 Feb 2018 16:33:51 -0800 Subject: Use as a backend to decode event args --- packages/utils/src/abi_decoder.ts | 27 ++++++++++++++------------- packages/utils/src/globals.d.ts | 29 +++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 15 deletions(-) (limited to 'packages/utils/src') diff --git a/packages/utils/src/abi_decoder.ts b/packages/utils/src/abi_decoder.ts index 368973b1b..024da3741 100644 --- a/packages/utils/src/abi_decoder.ts +++ b/packages/utils/src/abi_decoder.ts @@ -1,7 +1,7 @@ import { AbiType, DecodedLogArgs, LogWithDecodedArgs, RawLog, SolidityTypes } from '@0xproject/types'; +import * as ethersContracts from 'ethers-contracts'; import * as _ from 'lodash'; import * as Web3 from 'web3'; -import * as SolidityCoder from 'web3/lib/solidity/coder'; import { BigNumber } from './configured_bignumber'; @@ -27,31 +27,29 @@ export class AbiDecoder { if (_.isUndefined(event)) { return log; } + const ethersInterface = new ethersContracts.Interface([event]); const logData = log.data; const decodedParams: DecodedLogArgs = {}; - let dataIndex = 0; let topicsIndex = 1; const nonIndexedInputs = _.filter(event.inputs, input => !input.indexed); const dataTypes = _.map(nonIndexedInputs, input => input.type); - const decodedData = SolidityCoder.decodeParams(dataTypes, logData.slice('0x'.length)); + const decodedData = ethersInterface.events[event.name].parse(log.data); let failedToDecode = false; - _.forEach(event.inputs, (param: Web3.EventParameter) => { + _.forEach(event.inputs, (param: Web3.EventParameter, idx: number) => { // Indexed parameters are stored in topics. Non-indexed ones in decodedData - let value: BigNumber | string = param.indexed ? log.topics[topicsIndex++] : decodedData[dataIndex++]; + let value: BigNumber | string | number = param.indexed ? log.topics[topicsIndex++] : decodedData[idx]; if (_.isUndefined(value)) { failedToDecode = true; return; } if (param.type === SolidityTypes.Address) { value = AbiDecoder._padZeros(new BigNumber(value).toString(16)); - } else if ( - param.type === SolidityTypes.Uint256 || - param.type === SolidityTypes.Uint8 || - param.type === SolidityTypes.Uint - ) { + } else if (param.type === SolidityTypes.Uint256 || param.type === SolidityTypes.Uint) { value = new BigNumber(value); + } else if (param.type === SolidityTypes.Uint8) { + value = new BigNumber(value).toNumber(); } decodedParams[param.name] = value; }); @@ -67,11 +65,14 @@ export class AbiDecoder { } } private _addABI(abiArray: Web3.AbiDefinition[]): void { + if (_.isUndefined(abiArray)) { + return; + } + const ethersInterface = new ethersContracts.Interface(abiArray); _.map(abiArray, (abi: Web3.AbiDefinition) => { if (abi.type === AbiType.Event) { - const signature = `${abi.name}(${_.map(abi.inputs, input => input.type).join(',')})`; - const signatureHash = new Web3().sha3(signature); - this._methodIds[signatureHash] = abi; + const topic = ethersInterface.events[abi.name].topic; + this._methodIds[topic] = abi; } }); this._savedABIs = this._savedABIs.concat(abiArray); diff --git a/packages/utils/src/globals.d.ts b/packages/utils/src/globals.d.ts index ade9e59db..951ef6ea2 100644 --- a/packages/utils/src/globals.d.ts +++ b/packages/utils/src/globals.d.ts @@ -1,3 +1,28 @@ -declare module 'web3/lib/solidity/coder' { - const decodeParams: (types: string[], data: string) => any[]; +declare module 'ethers-contracts' { + export interface TransactionDescription { + name: string; + signature: string; + sighash: string; + data: string; + } + export interface CallDescription extends TransactionDescription { + parse: (...args: any[]) => any; + } + export interface FunctionDescription { + (...params: any[]): TransactionDescription | CallDescription; + inputs: { names: string[]; types: string[] }; + outputs: { names: string[]; types: string[] }; + } + export interface EventDescription { + parse: (...args: any[]) => any; + inputs: { names: string[]; types: string[] }; + signature: string; + topic: string; + } + // tslint:disable-next-line:max-classes-per-file + export class Interface { + public functions: { [functionName: string]: FunctionDescription }; + public events: { [eventName: string]: EventDescription }; + constructor(abi: any); + } } -- cgit v1.2.3