aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--packages/utils/src/abi_encoder/evm_data_types.ts19
-rw-r--r--packages/utils/test/abi_encoder_test.ts69
2 files changed, 79 insertions, 9 deletions
diff --git a/packages/utils/src/abi_encoder/evm_data_types.ts b/packages/utils/src/abi_encoder/evm_data_types.ts
index 10e7b987b..b862e9396 100644
--- a/packages/utils/src/abi_encoder/evm_data_types.ts
+++ b/packages/utils/src/abi_encoder/evm_data_types.ts
@@ -276,7 +276,7 @@ export class Byte extends PayloadDataType {
if (valueBuf.byteLength > this.width) {
throw new Error(
`Tried to assign ${value} (${
- valueBuf.byteLength
+ valueBuf.byteLength
} bytes), which exceeds max bytes that can be stored in a ${this.getSignature()}`,
);
} else if (value.length % 2 !== 0) {
@@ -475,6 +475,7 @@ export class Method extends MemberDataType {
private methodSignature: string;
private methodSelector: string;
private returnDataTypes: DataType[];
+ private returnDataItem: DataItem;
// TMP
public selector: string;
@@ -484,6 +485,7 @@ export class Method extends MemberDataType {
this.methodSignature = this.computeSignature();
this.selector = this.methodSelector = this.computeSelector();
this.returnDataTypes = [];
+ this.returnDataItem = { type: 'tuple', name: abi.name, components: abi.outputs };
const dummy = new Byte({ type: 'byte', name: 'DUMMY' }); // @TODO TMP
_.each(abi.outputs, (dataItem: DataItem) => {
this.returnDataTypes.push(this.getFactory().create(dataItem, dummy));
@@ -518,20 +520,19 @@ 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));
+ public encodeReturnValues(value: any, rules?: EncodingRules): string {
+ const returnDataType = new Tuple(this.returnDataItem);
+ const returndata = returnDataType.encode(value, rules);
+ return returndata;
+ }
+ public decodeReturnValues(returndata: string, rules?: DecodingRules): any {
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;
}
@@ -547,7 +548,7 @@ export class Method extends MemberDataType {
export class EvmDataTypeFactory implements DataTypeFactory {
private static instance: DataTypeFactory;
- private constructor() {}
+ private constructor() { }
public static getInstance(): DataTypeFactory {
if (!EvmDataTypeFactory.instance) {
diff --git a/packages/utils/test/abi_encoder_test.ts b/packages/utils/test/abi_encoder_test.ts
index b672d0023..0220984b0 100644
--- a/packages/utils/test/abi_encoder_test.ts
+++ b/packages/utils/test/abi_encoder_test.ts
@@ -5,6 +5,7 @@ import { chaiSetup } from './utils/chai_setup';
import { BigNumber, AbiEncoder } from '../src/';
import * as AbiSamples from './abi_samples';
import * as OptimizedAbis from './optimizer_abis';
+import * as ReturnValueAbis from './return_value_abis';
import { DecodingRules } from '../src/abi_encoder';
import ethUtil = require('ethereumjs-util');
@@ -12,6 +13,74 @@ chaiSetup.configure();
const expect = chai.expect;
describe.only('ABI Encoder', () => {
+ describe('Decode Return Values', () => {
+ it('No Return Value', async () => {
+ // Decode return value
+ const method = new AbiEncoder.Method(ReturnValueAbis.noReturnValues);
+ const returnValue = '0x';
+ const decodedReturnValue = method.decodeReturnValues(returnValue);
+ const expectedDecodedReturnValue: any[] = [];
+ const decodedReturnValueJson = JSON.stringify(decodedReturnValue);
+ const expectedDecodedReturnValueJson = JSON.stringify(expectedDecodedReturnValue);
+ expect(decodedReturnValueJson).to.be.equal(expectedDecodedReturnValueJson);
+ });
+ it('Single static return value', async () => {
+ // Generate Return Value
+ const method = new AbiEncoder.Method(ReturnValueAbis.singleStaticReturnValue);
+ const returnValue = ['0x01020304'];
+ const encodedReturnValue = method.encodeReturnValues(returnValue);
+ const decodedReturnValue = method.decodeReturnValues(encodedReturnValue);
+ // Validate decoded return value
+ const decodedReturnValueJson = JSON.stringify(decodedReturnValue);
+ const expectedDecodedReturnValueJson = JSON.stringify(returnValue);
+ expect(decodedReturnValueJson).to.be.equal(expectedDecodedReturnValueJson);
+ });
+ it('Multiple static return values', async () => {
+ // Generate Return Value
+ const method = new AbiEncoder.Method(ReturnValueAbis.multipleStaticReturnValues);
+ const returnValue = ['0x01020304', '0x05060708'];
+ const encodedReturnValue = method.encodeReturnValues(returnValue);
+ const decodedReturnValue = method.decodeReturnValues(encodedReturnValue);
+ // Validate decoded return value
+ const decodedReturnValueJson = JSON.stringify(decodedReturnValue);
+ const expectedDecodedReturnValueJson = JSON.stringify(returnValue);
+ expect(decodedReturnValueJson).to.be.equal(expectedDecodedReturnValueJson);
+ });
+ it('Single dynamic return value', async () => {
+ // Generate Return Value
+ const method = new AbiEncoder.Method(ReturnValueAbis.singleDynamicReturnValue);
+ const returnValue = ['0x01020304'];
+ const encodedReturnValue = method.encodeReturnValues(returnValue);
+ const decodedReturnValue = method.decodeReturnValues(encodedReturnValue);
+ // Validate decoded return value
+ const decodedReturnValueJson = JSON.stringify(decodedReturnValue);
+ const expectedDecodedReturnValueJson = JSON.stringify(returnValue);
+ expect(decodedReturnValueJson).to.be.equal(expectedDecodedReturnValueJson);
+ });
+ it('Multiple dynamic return values', async () => {
+ // Generate Return Value
+ const method = new AbiEncoder.Method(ReturnValueAbis.multipleDynamicReturnValues);
+ const returnValue = ['0x01020304', '0x05060708'];
+ const encodedReturnValue = method.encodeReturnValues(returnValue);
+ const decodedReturnValue = method.decodeReturnValues(encodedReturnValue);
+ // Validate decoded return value
+ const decodedReturnValueJson = JSON.stringify(decodedReturnValue);
+ const expectedDecodedReturnValueJson = JSON.stringify(returnValue);
+ expect(decodedReturnValueJson).to.be.equal(expectedDecodedReturnValueJson);
+ });
+ it('Mixed static/dynamic return values', async () => {
+ // Generate Return Value
+ const method = new AbiEncoder.Method(ReturnValueAbis.mixedStaticAndDynamicReturnValues);
+ const returnValue = ['0x01020304', '0x05060708'];
+ const encodedReturnValue = method.encodeReturnValues(returnValue);
+ const decodedReturnValue = method.decodeReturnValues(encodedReturnValue);
+ // Validate decoded return value
+ const decodedReturnValueJson = JSON.stringify(decodedReturnValue);
+ const expectedDecodedReturnValueJson = JSON.stringify(returnValue);
+ expect(decodedReturnValueJson).to.be.equal(expectedDecodedReturnValueJson);
+ });
+ });
+
describe('Optimizer', () => {
it('Duplicate Dynamic Arrays with Static Elements', async () => {
// Generate calldata