From 8a8b904a292063d1adb3df0a84023610a3985f7f Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Thu, 15 Nov 2018 14:33:40 -0800 Subject: Use new ABI Encoder for contracts --- packages/utils/src/abi_encoder/calldata.ts | 12 ++++++--- packages/utils/src/abi_encoder/data_type.ts | 2 +- packages/utils/src/abi_encoder/evm_data_types.ts | 32 +++++++++++++++++++++--- 3 files changed, 39 insertions(+), 7 deletions(-) (limited to 'packages/utils/src/abi_encoder') diff --git a/packages/utils/src/abi_encoder/calldata.ts b/packages/utils/src/abi_encoder/calldata.ts index 32278e5c5..078767c22 100644 --- a/packages/utils/src/abi_encoder/calldata.ts +++ b/packages/utils/src/abi_encoder/calldata.ts @@ -456,13 +456,19 @@ export class RawCalldata { private selector: string; private scopes: Queue; - constructor(value: string | Buffer) { + constructor(value: string | Buffer, hasSelectorPrefix: boolean = true) { if (typeof value === 'string' && !value.startsWith('0x')) { throw new Error(`Expected raw calldata to start with '0x'`); } const valueBuf = ethUtil.toBuffer(value); - this.selector = ethUtil.bufferToHex(valueBuf.slice(0, 4)); - this.value = valueBuf.slice(4); // disregard selector + if (hasSelectorPrefix) { + this.selector = ethUtil.bufferToHex(valueBuf.slice(0, 4)); + this.value = valueBuf.slice(4); // disregard selector + } else { + this.selector = '0x'; + this.value = valueBuf; + } + this.offset = 0; this.scopes = new Queue(); this.scopes.push(0); diff --git a/packages/utils/src/abi_encoder/data_type.ts b/packages/utils/src/abi_encoder/data_type.ts index 3b4028abd..f5a8087ea 100644 --- a/packages/utils/src/abi_encoder/data_type.ts +++ b/packages/utils/src/abi_encoder/data_type.ts @@ -6,7 +6,7 @@ import ethUtil = require('ethereumjs-util'); var _ = require('lodash'); export interface DataTypeFactory { - create: (dataItem: DataItem, parentDataType: DataType) => DataType; + create: (dataItem: DataItem, parentDataType?: DataType) => DataType; mapDataItemToDataType: (dataItem: DataItem) => DataType; } diff --git a/packages/utils/src/abi_encoder/evm_data_types.ts b/packages/utils/src/abi_encoder/evm_data_types.ts index 2973596fe..d024a9bfa 100644 --- a/packages/utils/src/abi_encoder/evm_data_types.ts +++ b/packages/utils/src/abi_encoder/evm_data_types.ts @@ -106,7 +106,8 @@ abstract class Number extends PayloadDataType { } } - public encodeValue(value: BigNumber): Buffer { + public encodeValue(value_: BigNumber | string | number): Buffer { + const value = new BigNumber(value_, 10); if (value.greaterThan(this.getMaxValue())) { throw `tried to assign value of ${value}, which exceeds max value of ${this.getMaxValue()}`; } else if (value.lessThan(this.getMinValue())) { @@ -465,6 +466,7 @@ export class SolArray extends MemberDataType { export class Method extends MemberDataType { private methodSignature: string; private methodSelector: string; + private returnDataTypes: DataType[]; // TMP public selector: string; @@ -473,7 +475,11 @@ export class Method extends MemberDataType { super({ type: 'method', name: abi.name, components: abi.inputs }, EvmDataTypeFactory.getInstance()); this.methodSignature = this.computeSignature(); this.selector = this.methodSelector = this.computeSelector(); - + this.returnDataTypes = []; + const dummy = new Byte({ type: 'byte', name: 'DUMMY' }); // @TODO TMP + _.each(abi.outputs, (dataItem: DataItem) => { + this.returnDataTypes.push(this.getFactory().create(dataItem, dummy)); + }); } private computeSignature(): string { @@ -501,6 +507,23 @@ export class Method extends MemberDataType { return value; } + public decodeReturnValues(returndata: string, rules?: DecodingRules): any { + //console.log('O'.repeat(100), '\n', returndata, '\n', this.returnDataTypes, 'P'.repeat(100)); + + const returnValues: any[] = []; + const rules_ = rules ? rules : { structsAsObjects: false } as DecodingRules; + const rawReturnData = new RawCalldata(returndata, false); + _.each(this.returnDataTypes, (dataType: DataType) => { + returnValues.push(dataType.generateValue(rawReturnData, rules_)); + }); + + //console.log('*'.repeat(40), '\n', JSON.stringify(returnValues), '\n', '*'.repeat(100)); + /*if (returnValues.length === 1) { + return returnValues[0]; + }*/ + return returnValues; + } + public getSignature(): string { return this.methodSignature; } @@ -538,12 +561,15 @@ export class EvmDataTypeFactory implements DataTypeFactory { throw new Error(`Unrecognized data type: '${dataItem.type}'`); } - public create(dataItem: DataItem, parentDataType: DataType): DataType { + public create(dataItem: DataItem, parentDataType?: DataType): DataType { const dataType = this.mapDataItemToDataType(dataItem); if (dataType.isStatic()) { return dataType; } + if (parentDataType === undefined) { // @Todo -- will this work for return values? + throw new Error(`Trying to create a pointer`); + } const pointer = new Pointer(dataType, parentDataType); return pointer; } -- cgit v1.2.3