aboutsummaryrefslogtreecommitdiffstats
path: root/packages/utils/src/abi_encoder/evm_data_types/method.ts
diff options
context:
space:
mode:
authorGreg Hysen <greg.hysen@gmail.com>2018-11-21 04:58:49 +0800
committerGreg Hysen <greg.hysen@gmail.com>2018-11-29 08:38:11 +0800
commite6ab6f38bacdec90c960ff1db4781d161b1f4103 (patch)
tree7edec03e3f249edf49b9deafcc44416bf25f7dc0 /packages/utils/src/abi_encoder/evm_data_types/method.ts
parent5934e5a57b5897594e22efc9e6ff28841c6951bf (diff)
downloaddexon-sol-tools-e6ab6f38bacdec90c960ff1db4781d161b1f4103.tar
dexon-sol-tools-e6ab6f38bacdec90c960ff1db4781d161b1f4103.tar.gz
dexon-sol-tools-e6ab6f38bacdec90c960ff1db4781d161b1f4103.tar.bz2
dexon-sol-tools-e6ab6f38bacdec90c960ff1db4781d161b1f4103.tar.lz
dexon-sol-tools-e6ab6f38bacdec90c960ff1db4781d161b1f4103.tar.xz
dexon-sol-tools-e6ab6f38bacdec90c960ff1db4781d161b1f4103.tar.zst
dexon-sol-tools-e6ab6f38bacdec90c960ff1db4781d161b1f4103.zip
Split EVM data types and factory into separate files
Diffstat (limited to 'packages/utils/src/abi_encoder/evm_data_types/method.ts')
-rw-r--r--packages/utils/src/abi_encoder/evm_data_types/method.ts90
1 files changed, 90 insertions, 0 deletions
diff --git a/packages/utils/src/abi_encoder/evm_data_types/method.ts b/packages/utils/src/abi_encoder/evm_data_types/method.ts
new file mode 100644
index 000000000..e8e717bf1
--- /dev/null
+++ b/packages/utils/src/abi_encoder/evm_data_types/method.ts
@@ -0,0 +1,90 @@
+import { DataItem, MethodAbi } from 'ethereum-types';
+import * as ethUtil from 'ethereumjs-util';
+import * as _ from 'lodash';
+
+import { DecodingRules, EncodingRules, RawCalldata } from '../calldata';
+import * as Constants from '../constants';
+import { DataType, DataTypeFactory, MemberDataType } from '../data_type';
+
+import { StaticBytes } from './static_bytes';
+import { Tuple } from './tuple';
+
+export class Method extends MemberDataType {
+ // TMP
+ public selector: string;
+
+ private readonly _methodSignature: string;
+ private readonly _methodSelector: string;
+ private readonly _returnDataTypes: DataType[];
+ private readonly _returnDataItem: DataItem;
+
+ public constructor(abi: MethodAbi, dataTypeFactory: DataTypeFactory) {
+ super({ type: 'method', name: abi.name, components: abi.inputs }, dataTypeFactory);
+ 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 StaticBytes({ type: 'byte', name: 'DUMMY' }, dataTypeFactory); // @TODO TMP
+ _.each(abi.outputs, (dataItem: DataItem) => {
+ this._returnDataTypes.push(this.getFactory().create(dataItem, dummy));
+ });
+ }
+
+ public encode(value: any, rules?: EncodingRules): string {
+ const calldata = super.encode(value, rules, this.selector);
+ return calldata;
+ }
+
+ public decode(calldata: string, rules?: DecodingRules): any[] | object {
+ if (!calldata.startsWith(this.selector)) {
+ throw new Error(
+ `Tried to decode calldata, but it was missing the function selector. Expected '${this.selector}'.`,
+ );
+ }
+ const hasSelector = true;
+ const value = super.decode(calldata, rules, hasSelector);
+ return value;
+ }
+
+ public encodeReturnValues(value: any, rules?: EncodingRules): string {
+ const returnDataType = new Tuple(this._returnDataItem, this.getFactory());
+ const returndata = returnDataType.encode(value, rules);
+ return returndata;
+ }
+
+ public decodeReturnValues(returndata: string, rules?: DecodingRules): any {
+ const returnValues: any[] = [];
+ const rules_: DecodingRules = rules ? rules : { structsAsObjects: false };
+ const rawReturnData = new RawCalldata(returndata, false);
+ _.each(this._returnDataTypes, (dataType: DataType) => {
+ returnValues.push(dataType.generateValue(rawReturnData, rules_));
+ });
+ return returnValues;
+ }
+
+ public getSignature(): string {
+ return this._methodSignature;
+ }
+
+ public getSelector(): string {
+ return this._methodSelector;
+ }
+
+ private _computeSignature(): string {
+ const memberSignature = this._computeSignatureOfMembers();
+ const methodSignature = `${this.getDataItem().name}${memberSignature}`;
+ return methodSignature;
+ }
+
+ private _computeSelector(): string {
+ const signature = this._computeSignature();
+ const selector = ethUtil.bufferToHex(
+ ethUtil.toBuffer(
+ ethUtil
+ .sha3(signature)
+ .slice(Constants.HEX_SELECTOR_BYTE_OFFSET_IN_CALLDATA, Constants.HEX_SELECTOR_LENGTH_IN_BYTES),
+ ),
+ );
+ return selector;
+ }
+}