diff options
author | Leonid <logvinov.leon@gmail.com> | 2017-09-06 21:26:29 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-06 21:26:29 +0800 |
commit | cb44b77d0b64bf4a0808cf1fea488ab2e1a60cf3 (patch) | |
tree | f7630683357f6a2273557d7027a1985f8a28f94b /src/utils/abi_decoder.ts | |
parent | 92eb68bf2c412d42322ab7f483af91666ccbdcb1 (diff) | |
parent | 1baf06531755597e37498005eb2c29aef5114fab (diff) | |
download | dexon-sol-tools-cb44b77d0b64bf4a0808cf1fea488ab2e1a60cf3.tar dexon-sol-tools-cb44b77d0b64bf4a0808cf1fea488ab2e1a60cf3.tar.gz dexon-sol-tools-cb44b77d0b64bf4a0808cf1fea488ab2e1a60cf3.tar.bz2 dexon-sol-tools-cb44b77d0b64bf4a0808cf1fea488ab2e1a60cf3.tar.lz dexon-sol-tools-cb44b77d0b64bf4a0808cf1fea488ab2e1a60cf3.tar.xz dexon-sol-tools-cb44b77d0b64bf4a0808cf1fea488ab2e1a60cf3.tar.zst dexon-sol-tools-cb44b77d0b64bf4a0808cf1fea488ab2e1a60cf3.zip |
Merge pull request #156 from 0xProject/feature/custom-abi-decoder
Custom abi decoder
Diffstat (limited to 'src/utils/abi_decoder.ts')
-rw-r--r-- | src/utils/abi_decoder.ts | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/utils/abi_decoder.ts b/src/utils/abi_decoder.ts new file mode 100644 index 000000000..f988a5695 --- /dev/null +++ b/src/utils/abi_decoder.ts @@ -0,0 +1,66 @@ +import * as Web3 from 'web3'; +import * as _ from 'lodash'; +import {AbiType, DecodedLogArgs, DecodedArgs} from '../types'; +import * as SolidityCoder from 'web3/lib/solidity/coder'; + +export class AbiDecoder { + private savedABIs: Web3.AbiDefinition[] = []; + private methodIds: {[signatureHash: string]: Web3.EventAbi} = {}; + constructor(abiArrays: Web3.AbiDefinition[][]) { + _.map(abiArrays, this.addABI.bind(this)); + } + public decodeLog(logItem: Web3.LogEntry): DecodedArgs|undefined { + const methodId = logItem.topics[0]; + const event = this.methodIds[methodId]; + if (!_.isUndefined(event)) { + const logData = logItem.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(2)); + _.map(event.inputs, (param: Web3.EventParameter) => { + let value; + if (param.indexed) { + value = logItem.topics[topicsIndex]; + topicsIndex++; + } else { + value = decodedData[dataIndex]; + dataIndex++; + } + if (param.type === 'address') { + value = this.padZeros(new Web3().toBigNumber(value).toString(16)); + } else if (param.type === 'uint256' || param.type === 'uint8' || param.type === 'int' ) { + value = new Web3().toBigNumber(value).toString(10); + } + decodedParams[param.name] = value; + }); + + return { + event: event.name, + args: decodedParams, + }; + } + } + private addABI(abiArray: Web3.AbiDefinition[]): void { + _.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; + } + }); + this.savedABIs = this.savedABIs.concat(abiArray); + } + private padZeros(address: string) { + let formatted = address; + if (_.startsWith(formatted, '0x')) { + formatted = formatted.slice(2); + } + + formatted = _.padStart(formatted, 40, '0'); + return `0x${formatted}`; + } +} |