diff options
author | Greg Hysen <greg.hysen@gmail.com> | 2018-11-15 07:27:07 +0800 |
---|---|---|
committer | Greg Hysen <greg.hysen@gmail.com> | 2018-11-29 08:38:10 +0800 |
commit | 5b0d554f7baec54837d795b6568ae5ba8d8a0908 (patch) | |
tree | b3ed8128c0c6006633790e2af70931d23ded7198 /packages/order-utils | |
parent | 71c050375b23336e7bc2700b595032eefe0ca4c1 (diff) | |
download | dexon-sol-tools-5b0d554f7baec54837d795b6568ae5ba8d8a0908.tar dexon-sol-tools-5b0d554f7baec54837d795b6568ae5ba8d8a0908.tar.gz dexon-sol-tools-5b0d554f7baec54837d795b6568ae5ba8d8a0908.tar.bz2 dexon-sol-tools-5b0d554f7baec54837d795b6568ae5ba8d8a0908.tar.lz dexon-sol-tools-5b0d554f7baec54837d795b6568ae5ba8d8a0908.tar.xz dexon-sol-tools-5b0d554f7baec54837d795b6568ae5ba8d8a0908.tar.zst dexon-sol-tools-5b0d554f7baec54837d795b6568ae5ba8d8a0908.zip |
Moved Abi Encoder into utils package
Diffstat (limited to 'packages/order-utils')
-rw-r--r-- | packages/order-utils/test/abi_encoder/calldata.ts | 520 | ||||
-rw-r--r-- | packages/order-utils/test/abi_encoder/data_type.ts | 322 | ||||
-rw-r--r-- | packages/order-utils/test/abi_encoder/evm_data_types.ts | 550 | ||||
-rw-r--r-- | packages/order-utils/test/abi_encoder/index.ts | 2 | ||||
-rw-r--r-- | packages/order-utils/test/abi_encoder_test.ts | 943 | ||||
-rw-r--r-- | packages/order-utils/test/abi_samples.ts | 814 |
6 files changed, 0 insertions, 3151 deletions
diff --git a/packages/order-utils/test/abi_encoder/calldata.ts b/packages/order-utils/test/abi_encoder/calldata.ts deleted file mode 100644 index 32278e5c5..000000000 --- a/packages/order-utils/test/abi_encoder/calldata.ts +++ /dev/null @@ -1,520 +0,0 @@ -import ethUtil = require('ethereumjs-util'); -import CommunicationChatBubbleOutline from 'material-ui/SvgIcon'; -var _ = require('lodash'); - -export interface DecodingRules { - structsAsObjects: boolean; -} - -export interface EncodingRules { - optimize?: boolean; - annotate?: boolean; -} - -export abstract class CalldataBlock { - private name: string; - private signature: string; - private offsetInBytes: number; - private headerSizeInBytes: number; - private bodySizeInBytes: number; - private relocatable: boolean; - private parentName: string; - - constructor(name: string, signature: string, parentName: string, /*offsetInBytes: number,*/ headerSizeInBytes: number, bodySizeInBytes: number, relocatable: boolean) { - this.name = name; - this.signature = signature; - this.parentName = parentName; - this.offsetInBytes = 0; - this.headerSizeInBytes = headerSizeInBytes; - this.bodySizeInBytes = bodySizeInBytes; - this.relocatable = relocatable; - } - - protected setHeaderSize(headerSizeInBytes: number) { - this.headerSizeInBytes = headerSizeInBytes; - } - - protected setBodySize(bodySizeInBytes: number) { - this.bodySizeInBytes = bodySizeInBytes; - } - - protected setName(name: string) { - this.name = name; - } - - public getName(): string { - return this.name; - } - - public getParentName(): string { - return this.parentName; - } - - public getSignature(): string { - return this.signature; - } - - public isRelocatable(): boolean { - return this.relocatable; - } - - public getHeaderSizeInBytes(): number { - return this.headerSizeInBytes; - } - - public getBodySizeInBytes(): number { - return this.bodySizeInBytes; - } - - public getSizeInBytes(): number { - return this.headerSizeInBytes + this.bodySizeInBytes; - } - - public getOffsetInBytes(): number { - return this.offsetInBytes; - } - - public setOffset(offsetInBytes: number) { - this.offsetInBytes = offsetInBytes; - } - - public computeHash(): Buffer { - const rawData = this.getRawData(); - const hash = ethUtil.sha3(rawData); - return hash; - } - - public abstract toBuffer(): Buffer; - public abstract getRawData(): Buffer; -} - -export class PayloadCalldataBlock extends CalldataBlock { - private payload: Buffer; - - constructor(name: string, signature: string, parentName: string, /*offsetInBytes: number,*/ relocatable: boolean, payload: Buffer) { - const headerSizeInBytes = 0; - const bodySizeInBytes = payload.byteLength; - super(name, signature, parentName, headerSizeInBytes, bodySizeInBytes, relocatable); - this.payload = payload; - } - - public toBuffer(): Buffer { - return this.payload; - } - - public getRawData(): Buffer { - return this.payload; - } -} - -export class DependentCalldataBlock extends CalldataBlock { - public static DEPENDENT_PAYLOAD_SIZE_IN_BYTES = 32; - public static RAW_DATA_START = new Buffer('<'); - public static RAW_DATA_END = new Buffer('>'); - private parent: CalldataBlock; - private dependency: CalldataBlock; - private aliasFor: CalldataBlock | undefined; - - constructor(name: string, signature: string, parentName: string, relocatable: boolean, dependency: CalldataBlock, parent: CalldataBlock) { - const headerSizeInBytes = 0; - const bodySizeInBytes = DependentCalldataBlock.DEPENDENT_PAYLOAD_SIZE_IN_BYTES; - super(name, signature, parentName, headerSizeInBytes, bodySizeInBytes, relocatable); - this.parent = parent; - this.dependency = dependency; - this.aliasFor = undefined; - } - - public toBuffer(): Buffer { - const destinationOffset = (this.aliasFor !== undefined) ? this.aliasFor.getOffsetInBytes() : this.dependency.getOffsetInBytes(); - const parentOffset = this.parent.getOffsetInBytes(); - const parentHeaderSize = this.parent.getHeaderSizeInBytes(); - const pointer: number = destinationOffset - (parentOffset + parentHeaderSize); - const pointerBuf = ethUtil.toBuffer(`0x${pointer.toString(16)}`); - const evmWordWidthInBytes = 32; - const pointerBufPadded = ethUtil.setLengthLeft(pointerBuf, evmWordWidthInBytes); - return pointerBufPadded; - } - - public getDependency(): CalldataBlock { - return this.dependency; - } - - public setAlias(block: CalldataBlock) { - this.aliasFor = block; - this.setName(`${this.getName()} (alias for ${block.getName()})`); - } - - public getAlias(): CalldataBlock | undefined { - return this.aliasFor; - } - - public getRawData(): Buffer { - const dependencyRawData = this.dependency.getRawData(); - const rawDataComponents: Buffer[] = []; - rawDataComponents.push(DependentCalldataBlock.RAW_DATA_START); - rawDataComponents.push(dependencyRawData); - rawDataComponents.push(DependentCalldataBlock.RAW_DATA_END); - const rawData = Buffer.concat(rawDataComponents); - return rawData; - } -} - -export class MemberCalldataBlock extends CalldataBlock { - private static DEPENDENT_PAYLOAD_SIZE_IN_BYTES = 32; - private header: Buffer | undefined; - private members: CalldataBlock[]; - private contiguous: boolean; - - constructor(name: string, signature: string, parentName: string, relocatable: boolean, contiguous: boolean) { - super(name, signature, parentName, 0, 0, relocatable); - this.members = []; - this.header = undefined; - this.contiguous = contiguous; - } - - public getRawData(): Buffer { - const rawDataComponents: Buffer[] = []; - if (this.header !== undefined) { - rawDataComponents.push(this.header); - } - _.each(this.members, (member: CalldataBlock) => { - const memberBuffer = member.getRawData(); - rawDataComponents.push(memberBuffer); - }); - - const rawData = Buffer.concat(rawDataComponents); - return rawData; - } - - public setMembers(members: CalldataBlock[]) { - let bodySizeInBytes = 0; - _.each(members, (member: CalldataBlock) => { - bodySizeInBytes += member.getSizeInBytes(); - }); - this.members = members; - this.setBodySize(0); - } - - public isContiguous(): boolean { - return true; - } - - public setHeader(header: Buffer) { - this.setHeaderSize(header.byteLength); - this.header = header; - } - - public toBuffer(): Buffer { - if (this.header !== undefined) return this.header; - return new Buffer(''); - } - - public getMembers(): CalldataBlock[] { - return this.members; - } -} - -class Queue<T> { - private store: T[] = []; - push(val: T) { - this.store.push(val); - } - pushFront(val: T) { - this.store.unshift(val); - } - pop(): T | undefined { - return this.store.shift(); - } - popBack(): T | undefined { - if (this.store.length === 0) return undefined; - const backElement = this.store.splice(-1, 1)[0]; - return backElement; - } - merge(q: Queue<T>) { - this.store = this.store.concat(q.store); - } - mergeFront(q: Queue<T>) { - this.store = q.store.concat(this.store); - } - getStore(): T[] { - return this.store; - } - peek(): T | undefined { - return this.store.length >= 0 ? this.store[0] : undefined; - } -} - -export class Calldata { - private selector: string; - private rules: EncodingRules; - private sizeInBytes: number; - private root: MemberCalldataBlock | undefined; - - constructor(rules: EncodingRules) { - this.selector = ''; - this.rules = rules; - this.sizeInBytes = 0; - this.root = undefined; - } - - private createQueue(memberBlock: MemberCalldataBlock): Queue<CalldataBlock> { - const blockQueue = new Queue<CalldataBlock>(); - _.eachRight(memberBlock.getMembers(), (member: CalldataBlock) => { - if (member instanceof MemberCalldataBlock) { - blockQueue.mergeFront(this.createQueue(member)); - } else { - blockQueue.pushFront(member); - } - }); - - // Children - _.each(memberBlock.getMembers(), (member: CalldataBlock) => { - if (member instanceof DependentCalldataBlock && member.getAlias() === undefined) { - let dependency = member.getDependency(); - if (dependency instanceof MemberCalldataBlock) { - blockQueue.merge(this.createQueue(dependency)); - } else { - blockQueue.push(dependency); - } - } - }); - - blockQueue.pushFront(memberBlock); - return blockQueue; - } - - private generateAnnotatedHexString(): string { - let hexValue = `${this.selector}`; - if (this.root === undefined) { - throw new Error('expected root'); - } - - const valueQueue = this.createQueue(this.root); - - let block: CalldataBlock | undefined; - let offset = 0; - const functionBlock = valueQueue.peek(); - let functionName: string = functionBlock === undefined ? '' : functionBlock.getName(); - while ((block = valueQueue.pop()) !== undefined) { - // Set f - - // Process each block 1 word at a time - const size = block.getSizeInBytes(); - const name = block.getName(); - const parentName = block.getParentName(); - - //const ancestrialNamesOffset = name.startsWith('ptr<') ? 4 : 0; - //const parentOffset = name.lastIndexOf(parentName); - const prettyName = name.replace(`${parentName}.`, '').replace(`${functionName}.`, '');//.replace(`${parentName}[`, '['); - const signature = block.getSignature(); - - // Current offset - let offsetStr = ''; - - // If this block is empty then it's a newline - let value = ''; - let nameStr = ''; - let line = ''; - if (size === 0) { - offsetStr = ' '.repeat(10); - value = ' '.repeat(74); - nameStr = `### ${prettyName.padEnd(80)}`; - line = `\n${offsetStr}${value}${nameStr}`; - } else { - offsetStr = `0x${offset.toString(16)}`.padEnd(10, ' '); - value = ethUtil.stripHexPrefix(ethUtil.bufferToHex(block.toBuffer().slice(0, 32))).padEnd(74); - if (block instanceof MemberCalldataBlock) { - nameStr = `### ${prettyName.padEnd(80)}`; - line = `\n${offsetStr}${value}${nameStr}`; - } else { - nameStr = ` ${prettyName.padEnd(80)}`; - line = `${offsetStr}${value}${nameStr}`; - } - } - - for (let j = 32; j < size; j += 32) { - offsetStr = `0x${(offset + j).toString(16)}`.padEnd(10, ' '); - value = ethUtil.stripHexPrefix(ethUtil.bufferToHex(block.toBuffer().slice(j, j + 32))).padEnd(74); - nameStr = ' '.repeat(40); - - line = `${line}\n${offsetStr}${value}${nameStr}`; - } - - // Append to hex value - hexValue = `${hexValue}\n${line}`; - offset += size; - } - - return hexValue; - } - - private generateCondensedHexString(): string { - let selectorBuffer = ethUtil.toBuffer(this.selector); - if (this.root === undefined) { - throw new Error('expected root'); - } - - const valueQueue = this.createQueue(this.root); - const valueBufs: Buffer[] = [selectorBuffer]; - let block: CalldataBlock | undefined; - while ((block = valueQueue.pop()) !== undefined) { - valueBufs.push(block.toBuffer()); - } - - const combinedBuffers = Buffer.concat(valueBufs); - const hexValue = ethUtil.bufferToHex(combinedBuffers); - return hexValue; - } - - public optimize() { - if (this.root === undefined) { - throw new Error('expected root'); - } - - const blocksByHash: { [key: string]: CalldataBlock } = {}; - - // 1. Create a queue of subtrees by hash - // Note that they are ordered the same as - const subtreeQueue = this.createQueue(this.root); - let block: CalldataBlock | undefined; - while ((block = subtreeQueue.popBack()) !== undefined) { - if (block instanceof DependentCalldataBlock) { - const blockHashBuf = block.getDependency().computeHash(); - const blockHash = ethUtil.bufferToHex(blockHashBuf); - if (blockHash in blocksByHash) { - const blockWithSameHash = blocksByHash[blockHash]; - if (blockWithSameHash !== block.getDependency()) { - block.setAlias(blockWithSameHash); - } - } - continue; - } - - const blockHashBuf = block.computeHash(); - const blockHash = ethUtil.bufferToHex(blockHashBuf); - if (blockHash in blocksByHash === false) { - blocksByHash[blockHash] = block; - } - } - } - - public toHexString(): string { - if (this.root === undefined) { - throw new Error('expected root'); - } - - if (this.rules.optimize) this.optimize(); - - const offsetQueue = this.createQueue(this.root); - let block: CalldataBlock | undefined; - let offset = 0; - while ((block = offsetQueue.pop()) !== undefined) { - block.setOffset(offset); - offset += block.getSizeInBytes(); - } - - const hexValue = this.rules.annotate ? this.generateAnnotatedHexString() : this.generateCondensedHexString(); - return hexValue; - } - - public getSelectorHex(): string { - return this.selector; - } - - public getSizeInBytes(): number { - return this.sizeInBytes; - } - - public toAnnotatedString(): string { - return ""; - } - - public setRoot(block: MemberCalldataBlock) { - this.root = block; - this.sizeInBytes += block.getSizeInBytes(); - } - - public setSelector(selector: string) { - // Ensure we have a 0x prefix - if (selector.startsWith('0x')) { - this.selector = selector; - } else { - this.selector = `$0x${selector}`; - } - - // The selector must be 10 characters: '0x' followed by 4 bytes (two hex chars per byte) - if (this.selector.length !== 10) { - throw new Error(`Invalid selector '${this.selector}'`); - } - this.sizeInBytes += 8; - } -} - -export class RawCalldata { - private value: Buffer; - private offset: number; // tracks current offset into raw calldata; used for parsing - private selector: string; - private scopes: Queue<number>; - - constructor(value: string | Buffer) { - 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 - this.offset = 0; - this.scopes = new Queue<number>(); - this.scopes.push(0); - } - - public popBytes(lengthInBytes: number): Buffer { - const value = this.value.slice(this.offset, this.offset + lengthInBytes); - this.setOffset(this.offset + lengthInBytes); - return value; - } - - public popWord(): Buffer { - const wordInBytes = 32; - return this.popBytes(wordInBytes); - } - - public popWords(length: number): Buffer { - const wordInBytes = 32; - return this.popBytes(length * wordInBytes); - } - - public readBytes(from: number, to: number): Buffer { - const value = this.value.slice(from, to); - return value; - } - - public setOffset(offsetInBytes: number) { - this.offset = offsetInBytes; - } - - public startScope() { - this.scopes.pushFront(this.offset); - } - - public endScope() { - this.scopes.pop(); - } - - public getOffset(): number { - return this.offset; - } - - public toAbsoluteOffset(relativeOffset: number) { - const scopeOffset = this.scopes.peek(); - if (scopeOffset === undefined) { - throw new Error(`Tried to access undefined scope.`); - } - const absoluteOffset = relativeOffset + scopeOffset; - return absoluteOffset; - } - - public getSelector(): string { - return this.selector; - } -}
\ No newline at end of file diff --git a/packages/order-utils/test/abi_encoder/data_type.ts b/packages/order-utils/test/abi_encoder/data_type.ts deleted file mode 100644 index 4c4537a69..000000000 --- a/packages/order-utils/test/abi_encoder/data_type.ts +++ /dev/null @@ -1,322 +0,0 @@ -import { RawCalldata, Calldata, CalldataBlock, PayloadCalldataBlock, DependentCalldataBlock, MemberCalldataBlock } from "./calldata"; -import { MethodAbi, DataItem } from 'ethereum-types'; -import { DecodingRules, EncodingRules } from './calldata'; -import { BigNumber } from '@0x/utils'; -import ethUtil = require('ethereumjs-util'); -var _ = require('lodash'); - -export interface DataTypeFactory { - create: (dataItem: DataItem, parentDataType: DataType) => DataType; - mapDataItemToDataType: (dataItem: DataItem) => DataType; -} - -export abstract class DataType { - private static DEFAULT_ENCODING_RULES = { optimize: false, annotate: false } as EncodingRules; - private static DEFAULT_DECODING_RULES = { structsAsObjects: false } as DecodingRules; - - private dataItem: DataItem; - private factory: DataTypeFactory; - - constructor(dataItem: DataItem, factory: DataTypeFactory) { - this.dataItem = dataItem; - this.factory = factory; - } - - public getDataItem(): DataItem { - return this.dataItem; - } - - public getFactory(): DataTypeFactory { - return this.factory; - } - - public encode(value: any, rules?: EncodingRules, selector?: string): string { - const rules_ = rules ? rules : DataType.DEFAULT_ENCODING_RULES; - const calldata = new Calldata(rules_); - if (selector) calldata.setSelector(selector); - const block = this.generateCalldataBlock(value); - calldata.setRoot(block as MemberCalldataBlock); // @TODO CHANGE - const calldataHex = calldata.toHexString(); - return calldataHex; - } - - public decode(calldata: string, rules?: DecodingRules): any { - const rawCalldata = new RawCalldata(calldata); - const rules_ = rules ? rules : DataType.DEFAULT_DECODING_RULES; - const value = this.generateValue(rawCalldata, rules_); - return value; - } - - public abstract generateCalldataBlock(value: any, parentBlock?: CalldataBlock): CalldataBlock; - public abstract generateValue(calldata: RawCalldata, rules: DecodingRules): any; - public abstract getSignature(): string; - public abstract isStatic(): boolean; -} - -export abstract class PayloadDataType extends DataType { - protected hasConstantSize: boolean; - - public constructor(dataItem: DataItem, factory: DataTypeFactory, hasConstantSize: boolean) { - super(dataItem, factory); - this.hasConstantSize = hasConstantSize; - } - - public generateCalldataBlock(value: any, parentBlock?: CalldataBlock): PayloadCalldataBlock { - const encodedValue = this.encodeValue(value); - const name = this.getDataItem().name; - const signature = this.getSignature(); - const parentName = parentBlock === undefined ? '' : parentBlock.getName(); - const relocatable = false; - const block = new PayloadCalldataBlock(name, signature, parentName, /*offsetInBytes,*/ relocatable, encodedValue); - return block; - } - - public generateValue(calldata: RawCalldata, rules: DecodingRules): any { - const value = this.decodeValue(calldata); - return value; - } - - public isStatic(): boolean { - // If a payload has a constant size then it's static - return this.hasConstantSize; - } - - public abstract encodeValue(value: any): Buffer; - public abstract decodeValue(calldata: RawCalldata): any; -} - -export abstract class DependentDataType extends DataType { - protected dependency: DataType; - protected parent: DataType; - - public constructor(dataItem: DataItem, factory: DataTypeFactory, dependency: DataType, parent: DataType) { - super(dataItem, factory); - this.dependency = dependency; - this.parent = parent; - } - - public generateCalldataBlock(value: any, parentBlock?: CalldataBlock): DependentCalldataBlock { - if (parentBlock === undefined) { - throw new Error(`DependentDataType requires a parent block to generate its block`); - } - const dependencyBlock = this.dependency.generateCalldataBlock(value, parentBlock); - const name = this.getDataItem().name; - const signature = this.getSignature(); - const parentName = parentBlock === undefined ? '' : parentBlock.getName(); - const relocatable = false; - const block = new DependentCalldataBlock(name, signature, parentName, relocatable, dependencyBlock, parentBlock); - return block; - } - - public generateValue(calldata: RawCalldata, rules: DecodingRules): any { - const destinationOffsetBuf = calldata.popWord(); - const currentOffset = calldata.getOffset(); - const destinationOffsetRelative = parseInt(ethUtil.bufferToHex(destinationOffsetBuf), 16); - const destinationOffsetAbsolute = calldata.toAbsoluteOffset(destinationOffsetRelative); - calldata.setOffset(destinationOffsetAbsolute); - const value = this.dependency.generateValue(calldata, rules); - calldata.setOffset(currentOffset); - return value; - } - - public isStatic(): boolean { - return true; - } -} - -export interface MemberMap { - [key: string]: number; -} - -export abstract class MemberDataType extends DataType { - private memberMap: MemberMap; - private members: DataType[]; - private isArray: boolean; - protected arrayLength: number | undefined; - protected arrayElementType: string | undefined; - - - public constructor(dataItem: DataItem, factory: DataTypeFactory, isArray: boolean = false, arrayLength?: number, arrayElementType?: string) { - super(dataItem, factory); - this.memberMap = {}; - this.members = []; - this.isArray = isArray; - this.arrayLength = arrayLength; - this.arrayElementType = arrayElementType; - if (isArray && arrayLength !== undefined) { - [this.members, this.memberMap] = this.createMembersWithLength(dataItem, arrayLength); - } else if (!isArray) { - [this.members, this.memberMap] = this.createMembersWithKeys(dataItem); - } - } - - private createMembersWithKeys(dataItem: DataItem): [DataType[], MemberMap] { - // Sanity check - if (dataItem.components === undefined) { - throw new Error(`Expected components`); - } - - let members: DataType[] = []; - let memberMap: MemberMap = {}; - _.each(dataItem.components, (memberItem: DataItem) => { - const childDataItem = { - type: memberItem.type, - name: `${dataItem.name}.${memberItem.name}`, - } as DataItem; - const components = memberItem.components; - if (components !== undefined) { - childDataItem.components = components; - } - const child = this.getFactory().create(childDataItem, this); - memberMap[memberItem.name] = members.length; - members.push(child); - }); - - return [members, memberMap]; - } - - private createMembersWithLength(dataItem: DataItem, length: number): [DataType[], MemberMap] { - let members: DataType[] = []; - let memberMap: MemberMap = {}; - const range = _.range(length); - _.each(range, (idx: number) => { - const childDataItem = { - type: this.arrayElementType, - name: `${dataItem.name}[${idx.toString(10)}]`, - } as DataItem; - const components = dataItem.components; - if (components !== undefined) { - childDataItem.components = components; - } - const child = this.getFactory().create(childDataItem, this); - memberMap[idx.toString(10)] = members.length; - members.push(child); - }); - - return [members, memberMap]; - } - - protected generateCalldataBlockFromArray(value: any[], parentBlock?: CalldataBlock): MemberCalldataBlock { - // Sanity check length - if (this.arrayLength !== undefined && value.length !== this.arrayLength) { - throw new Error( - `Expected array of ${JSON.stringify( - this.arrayLength, - )} elements, but got array of length ${JSON.stringify(value.length)}`, - ); - } - - const parentName = parentBlock === undefined ? '' : parentBlock.getName(); - const methodBlock: MemberCalldataBlock = new MemberCalldataBlock(this.getDataItem().name, this.getSignature(), parentName, this.isStatic(), false); - - let members = this.members; - if (this.isArray && this.arrayLength === undefined) { - [members,] = this.createMembersWithLength(this.getDataItem(), value.length); - - const lenBuf = ethUtil.setLengthLeft(ethUtil.toBuffer(`0x${value.length.toString(16)}`), 32); - methodBlock.setHeader(lenBuf); - } - - const memberBlocks: CalldataBlock[] = []; - _.each(members, (member: DataType, idx: number) => { - const block = member.generateCalldataBlock(value[idx], methodBlock); - memberBlocks.push(block); - }); - methodBlock.setMembers(memberBlocks); - return methodBlock; - } - - protected generateCalldataBlockFromObject(obj: object, parentBlock?: CalldataBlock): MemberCalldataBlock { - const parentName = parentBlock === undefined ? '' : parentBlock.getName(); - const methodBlock: MemberCalldataBlock = new MemberCalldataBlock(this.getDataItem().name, this.getSignature(), parentName, this.isStatic(), false); - const memberBlocks: CalldataBlock[] = []; - let childMap = _.cloneDeep(this.memberMap); - _.forOwn(obj, (value: any, key: string) => { - if (key in childMap === false) { - throw new Error(`Could not assign tuple to object: unrecognized key '${key}' in object ${this.getDataItem().name}`); - } - const block = this.members[this.memberMap[key]].generateCalldataBlock(value, methodBlock); - memberBlocks.push(block); - delete childMap[key]; - }); - - if (Object.keys(childMap).length !== 0) { - throw new Error(`Could not assign tuple to object: missing keys ${Object.keys(childMap)}`); - } - - methodBlock.setMembers(memberBlocks); - return methodBlock; - } - - public generateCalldataBlock(value: any[] | object, parentBlock?: CalldataBlock): MemberCalldataBlock { - const block = (value instanceof Array) ? this.generateCalldataBlockFromArray(value, parentBlock) : this.generateCalldataBlockFromObject(value, parentBlock); - return block; - } - - public generateValue(calldata: RawCalldata, rules: DecodingRules): any[] | object { - let members = this.members; - if (this.isArray && this.arrayLength === undefined) { - const arrayLengthBuf = calldata.popWord(); - const arrayLengthHex = ethUtil.bufferToHex(arrayLengthBuf); - const hexBase = 16; - const arrayLength = new BigNumber(arrayLengthHex, hexBase); - - [members,] = this.createMembersWithLength(this.getDataItem(), arrayLength.toNumber()); - } - - calldata.startScope(); - let value: any[] | object; - if (rules.structsAsObjects && !this.isArray) { - value = {}; - _.each(this.memberMap, (idx: number, key: string) => { - const member = this.members[idx]; - let memberValue = member.generateValue(calldata, rules); - (value as { [key: string]: any })[key] = memberValue; - }); - } else { - value = []; - _.each(members, (member: DataType, idx: number) => { - let memberValue = member.generateValue(calldata, rules); - (value as any[]).push(memberValue); - }); - } - calldata.endScope(); - return value; - } - - protected computeSignatureOfMembers(): string { - // Compute signature of members - let signature = `(`; - _.each(this.members, (member: DataType, i: number) => { - signature += member.getSignature(); - if (i < this.members.length - 1) { - signature += ','; - } - }); - signature += ')'; - return signature; - } - - public isStatic(): boolean { - /* For Tuple: - const isStaticTuple = this.children.length === 0; - return isStaticTuple; // @TODO: True in every case or only when dynamic data? - - For Array: - if isLengthDefined = false then this is false - - Otherwise if the first element is a Pointer then false - */ - - if (this.isArray && this.arrayLength === undefined) { - return false; - } - - // Search for dependent members - const dependentMember = _.find(this.members, (member: DataType) => { - return (member instanceof DependentDataType); - }); - const isStatic = (dependentMember === undefined); // static if we couldn't find a dependent member - return isStatic; - } -} diff --git a/packages/order-utils/test/abi_encoder/evm_data_types.ts b/packages/order-utils/test/abi_encoder/evm_data_types.ts deleted file mode 100644 index bb7c1d81d..000000000 --- a/packages/order-utils/test/abi_encoder/evm_data_types.ts +++ /dev/null @@ -1,550 +0,0 @@ -import { DataType, DataTypeFactory, PayloadDataType, DependentDataType, MemberDataType } from './data_type'; - -import { DecodingRules, EncodingRules } from './calldata'; - -import { MethodAbi, DataItem } from 'ethereum-types'; - -import ethUtil = require('ethereumjs-util'); - -import { Calldata, RawCalldata } from './calldata'; - -import { BigNumber } from '@0x/utils'; - -var _ = require('lodash'); - -export interface DataTypeStaticInterface { - matchGrammar: (type: string) => boolean; - encodeValue: (value: any) => Buffer; - decodeValue: (rawCalldata: RawCalldata) => any; -} - -export class Address extends PayloadDataType { - private static SIZE_KNOWN_AT_COMPILE_TIME: boolean = true; - - constructor(dataItem: DataItem) { - super(dataItem, EvmDataTypeFactory.getInstance(), Address.SIZE_KNOWN_AT_COMPILE_TIME); - if (!Address.matchGrammar(dataItem.type)) { - throw new Error(`Tried to instantiate Address with bad input: ${dataItem}`); - } - } - - public getSignature(): string { - return 'address'; - } - - public static matchGrammar(type: string): boolean { - return type === 'address'; - } - - public encodeValue(value: boolean): Buffer { - const evmWordWidth = 32; - const encodedValueBuf = ethUtil.setLengthLeft(ethUtil.toBuffer(value), evmWordWidth); - return encodedValueBuf; - } - - public decodeValue(calldata: RawCalldata): string { - const paddedValueBuf = calldata.popWord(); - const valueBuf = paddedValueBuf.slice(12); - const value = ethUtil.bufferToHex(valueBuf); - return value; - } -} - -export class Bool extends PayloadDataType { - private static SIZE_KNOWN_AT_COMPILE_TIME: boolean = true; - - constructor(dataItem: DataItem) { - super(dataItem, EvmDataTypeFactory.getInstance(), Bool.SIZE_KNOWN_AT_COMPILE_TIME); - if (!Bool.matchGrammar(dataItem.type)) { - throw new Error(`Tried to instantiate Bool with bad input: ${dataItem}`); - } - } - - public getSignature(): string { - return 'bool'; - } - - public static matchGrammar(type: string): boolean { - return type === 'bool'; - } - - public encodeValue(value: boolean): Buffer { - const evmWordWidth = 32; - const encodedValue = value === true ? '0x1' : '0x0'; - const encodedValueBuf = ethUtil.setLengthLeft(ethUtil.toBuffer(encodedValue), evmWordWidth); - return encodedValueBuf; - } - - public decodeValue(calldata: RawCalldata): boolean { - const valueBuf = calldata.popWord(); - const valueHex = ethUtil.bufferToHex(valueBuf); - const valueNumber = new BigNumber(valueHex, 16); - let value: boolean = (valueNumber.equals(0)) ? false : true; - if (!(valueNumber.equals(0) || valueNumber.equals(1))) { - throw new Error(`Failed to decode boolean. Expected 0x0 or 0x1, got ${valueHex}`); - } - return value; - } -} - -abstract class Number extends PayloadDataType { - private static SIZE_KNOWN_AT_COMPILE_TIME: boolean = true; - static MAX_WIDTH: number = 256; - static DEFAULT_WIDTH: number = Number.MAX_WIDTH; - width: number = Number.DEFAULT_WIDTH; - - constructor(dataItem: DataItem, matcher: RegExp) { - super(dataItem, EvmDataTypeFactory.getInstance(), Number.SIZE_KNOWN_AT_COMPILE_TIME); - const matches = matcher.exec(dataItem.type); - if (matches === null) { - throw new Error(`Tried to instantiate Number with bad input: ${dataItem}`); - } - if (matches !== null && matches.length === 2 && matches[1] !== undefined) { - this.width = parseInt(matches[1]); - } else { - this.width = 256; - } - } - - public encodeValue(value: BigNumber): Buffer { - 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())) { - throw `tried to assign value of ${value}, which exceeds min value of ${this.getMinValue()}`; - } - - const hexBase = 16; - const evmWordWidth = 32; - let valueBuf: Buffer; - if (value.greaterThanOrEqualTo(0)) { - valueBuf = ethUtil.setLengthLeft(ethUtil.toBuffer(`0x${value.toString(hexBase)}`), evmWordWidth); - } else { - // BigNumber can't write a negative hex value, so we use twos-complement conversion to do it ourselves. - // Step 1/3: Convert value to positive binary string - const binBase = 2; - const valueBin = value.times(-1).toString(binBase); - - // Step 2/3: Invert binary value - const bitsInEvmWord = 256; - let invertedValueBin = '1'.repeat(bitsInEvmWord - valueBin.length); - _.each(valueBin, (bit: string) => { - invertedValueBin += bit === '1' ? '0' : '1'; - }); - const invertedValue = new BigNumber(invertedValueBin, binBase); - - // Step 3/3: Add 1 to inverted value - // The result is the two's-complement represent of the input value. - const negativeValue = invertedValue.plus(1); - - // Convert the negated value to a hex string - valueBuf = ethUtil.setLengthLeft( - ethUtil.toBuffer(`0x${negativeValue.toString(hexBase)}`), - evmWordWidth, - ); - } - - return valueBuf; - } - - public decodeValue(calldata: RawCalldata): BigNumber { - const paddedValueBuf = calldata.popWord(); - const paddedValueHex = ethUtil.bufferToHex(paddedValueBuf); - let value = new BigNumber(paddedValueHex, 16); - if (this instanceof Int) { - // Check if we're negative - const binBase = 2; - const paddedValueBin = value.toString(binBase); - const valueBin = paddedValueBin.slice(paddedValueBin.length - this.width); - if (valueBin[0].startsWith('1')) { - // Negative - // Step 1/3: Invert binary value - let invertedValueBin = ''; - _.each(valueBin, (bit: string) => { - invertedValueBin += bit === '1' ? '0' : '1'; - }); - const invertedValue = new BigNumber(invertedValueBin, binBase); - - // Step 2/3: Add 1 to inverted value - // The result is the two's-complement represent of the input value. - const positiveValue = invertedValue.plus(1); - - // Step 3/3: Invert positive value - const negativeValue = positiveValue.times(-1); - value = negativeValue; - } - } - - return value; - } - - public abstract getMaxValue(): BigNumber; - public abstract getMinValue(): BigNumber; -} - -export class Int extends Number { - static matcher = RegExp( - '^int(8|16|24|32|40|48|56|64|72|88|96|104|112|120|128|136|144|152|160|168|176|184|192|200|208|216|224|232|240|248|256){0,1}$', - ); - - constructor(dataItem: DataItem) { - super(dataItem, Int.matcher); - } - - public getMaxValue(): BigNumber { - return new BigNumber(2).toPower(this.width - 1).sub(1); - } - - public getMinValue(): BigNumber { - return new BigNumber(2).toPower(this.width - 1).times(-1); - } - - public getSignature(): string { - return `int${this.width}`; - } - - public static matchGrammar(type: string): boolean { - return this.matcher.test(type); - } -} - -export class UInt extends Number { - static matcher = RegExp( - '^uint(8|16|24|32|40|48|56|64|72|88|96|104|112|120|128|136|144|152|160|168|176|184|192|200|208|216|224|232|240|248|256){0,1}$', - ); - - constructor(dataItem: DataItem) { - super(dataItem, UInt.matcher); - } - - public getMaxValue(): BigNumber { - return new BigNumber(2).toPower(this.width).sub(1); - } - - public getMinValue(): BigNumber { - return new BigNumber(0); - } - - public getSignature(): string { - return `uint${this.width}`; - } - - public static matchGrammar(type: string): boolean { - return this.matcher.test(type); - } -} - -export class Byte extends PayloadDataType { - private static SIZE_KNOWN_AT_COMPILE_TIME: boolean = true; - static matcher = RegExp( - '^(byte|bytes(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32))$', - ); - - static DEFAULT_WIDTH = 1; - width: number = Byte.DEFAULT_WIDTH; - - constructor(dataItem: DataItem) { - super(dataItem, EvmDataTypeFactory.getInstance(), Byte.SIZE_KNOWN_AT_COMPILE_TIME); - const matches = Byte.matcher.exec(dataItem.type); - if (!Byte.matchGrammar(dataItem.type)) { - throw new Error(`Tried to instantiate Byte with bad input: ${dataItem}`); - } - if (matches !== null && matches.length === 3 && matches[2] !== undefined) { - this.width = parseInt(matches[2]); - } else { - this.width = Byte.DEFAULT_WIDTH; - } - } - - public getSignature(): string { - // Note that `byte` reduces to `bytes1` - return `bytes${this.width}`; - } - - public encodeValue(value: string | Buffer): Buffer { - // Convert value into a buffer and do bounds checking - const valueBuf = ethUtil.toBuffer(value); - if (valueBuf.byteLength > this.width) { - throw new Error( - `Tried to assign ${value} (${ - valueBuf.byteLength - } bytes), which exceeds max bytes that can be stored in a ${this.getSignature()}`, - ); - } else if (value.length % 2 !== 0) { - throw new Error(`Tried to assign ${value}, which is contains a half-byte. Use full bytes only.`); - } - - // Store value as hex - const evmWordWidth = 32; - const paddedValue = ethUtil.setLengthRight(valueBuf, evmWordWidth); - return paddedValue; - } - - public decodeValue(calldata: RawCalldata): string { - const paddedValueBuf = calldata.popWord(); - const valueBuf = paddedValueBuf.slice(0, this.width); - const value = ethUtil.bufferToHex(valueBuf); - return value; - } - - public static matchGrammar(type: string): boolean { - return this.matcher.test(type); - } -} - -export class Bytes extends PayloadDataType { - private static SIZE_KNOWN_AT_COMPILE_TIME: boolean = false; - static UNDEFINED_LENGTH = new BigNumber(-1); - length: BigNumber = Bytes.UNDEFINED_LENGTH; - - constructor(dataItem: DataItem) { - super(dataItem, EvmDataTypeFactory.getInstance(), Bytes.SIZE_KNOWN_AT_COMPILE_TIME); - if (!Bytes.matchGrammar(dataItem.type)) { - throw new Error(`Tried to instantiate Bytes with bad input: ${dataItem}`); - } - } - - public encodeValue(value: string | Buffer): Buffer { - if (typeof value === 'string' && !value.startsWith('0x')) { - throw new Error(`Input value must be hex (prefixed with 0x). Actual value is '${value}'`); - } - const valueBuf = ethUtil.toBuffer(value); - if (value.length % 2 !== 0) { - throw new Error(`Tried to assign ${value}, which is contains a half-byte. Use full bytes only.`); - } - - const wordsForValue = Math.ceil(valueBuf.byteLength / 32); - const paddedBytesForValue = wordsForValue * 32; - const paddedValueBuf = ethUtil.setLengthRight(valueBuf, paddedBytesForValue); - const paddedLengthBuf = ethUtil.setLengthLeft(ethUtil.toBuffer(valueBuf.byteLength), 32); - const encodedValueBuf = Buffer.concat([paddedLengthBuf, paddedValueBuf]); - return encodedValueBuf; - } - - public decodeValue(calldata: RawCalldata): string { - const lengthBuf = calldata.popWord(); - const lengthHex = ethUtil.bufferToHex(lengthBuf); - const length = parseInt(lengthHex, 16); - const wordsForValue = Math.ceil(length / 32); - const paddedValueBuf = calldata.popWords(wordsForValue); - const valueBuf = paddedValueBuf.slice(0, length); - const decodedValue = ethUtil.bufferToHex(valueBuf); - return decodedValue; - } - - public getSignature(): string { - return 'bytes'; - } - - public static matchGrammar(type: string): boolean { - return type === 'bytes'; - } -} - -export class SolString extends PayloadDataType { - private static SIZE_KNOWN_AT_COMPILE_TIME: boolean = false; - constructor(dataItem: DataItem) { - super(dataItem, EvmDataTypeFactory.getInstance(), SolString.SIZE_KNOWN_AT_COMPILE_TIME); - if (!SolString.matchGrammar(dataItem.type)) { - throw new Error(`Tried to instantiate String with bad input: ${dataItem}`); - } - } - - public encodeValue(value: string): Buffer { - const wordsForValue = Math.ceil(value.length / 32); - const paddedBytesForValue = wordsForValue * 32; - const valueBuf = ethUtil.setLengthRight(ethUtil.toBuffer(value), paddedBytesForValue); - const lengthBuf = ethUtil.setLengthLeft(ethUtil.toBuffer(value.length), 32); - const encodedValueBuf = Buffer.concat([lengthBuf, valueBuf]); - return encodedValueBuf; - } - - public decodeValue(calldata: RawCalldata): string { - const lengthBuf = calldata.popWord(); - const lengthHex = ethUtil.bufferToHex(lengthBuf); - const length = parseInt(lengthHex, 16); - const wordsForValue = Math.ceil(length / 32); - const paddedValueBuf = calldata.popWords(wordsForValue); - const valueBuf = paddedValueBuf.slice(0, length); - const value = valueBuf.toString('ascii'); - return value; - } - - public getSignature(): string { - return 'string'; - } - - public static matchGrammar(type: string): boolean { - return type === 'string'; - } -} - -export class Pointer extends DependentDataType { - - constructor(destDataType: DataType, parentDataType: DataType) { - const destDataItem = destDataType.getDataItem(); - const dataItem = { name: `ptr<${destDataItem.name}>`, type: `ptr<${destDataItem.type}>` } as DataItem; - super(dataItem, EvmDataTypeFactory.getInstance(), destDataType, parentDataType); - } - - public getSignature(): string { - return this.dependency.getSignature(); - } -} - -export class Tuple extends MemberDataType { - private tupleSignature: string; - - constructor(dataItem: DataItem) { - super(dataItem, EvmDataTypeFactory.getInstance()); - if (!Tuple.matchGrammar(dataItem.type)) { - throw new Error(`Tried to instantiate Tuple with bad input: ${dataItem}`); - } - this.tupleSignature = this.computeSignatureOfMembers(); - } - - public getSignature(): string { - return this.tupleSignature; - } - - public static matchGrammar(type: string): boolean { - return type === 'tuple'; - } -} - -export class SolArray extends MemberDataType { - static matcher = RegExp('^(.+)\\[([0-9]*)\\]$'); - private arraySignature: string; - private elementType: string; - - constructor(dataItem: DataItem) { - // Sanity check - const matches = SolArray.matcher.exec(dataItem.type); - if (matches === null || matches.length !== 3) { - throw new Error(`Could not parse array: ${dataItem.type}`); - } else if (matches[1] === undefined) { - throw new Error(`Could not parse array type: ${dataItem.type}`); - } else if (matches[2] === undefined) { - throw new Error(`Could not parse array length: ${dataItem.type}`); - } - - const isArray = true; - const arrayElementType = matches[1]; - const arrayLength = (matches[2] === '') ? undefined : parseInt(matches[2], 10); - super(dataItem, EvmDataTypeFactory.getInstance(), isArray, arrayLength, arrayElementType); - this.elementType = arrayElementType; - this.arraySignature = this.computeSignature(); - } - - private computeSignature(): string { - let dataItem = { - type: this.elementType, - name: 'N/A', - } as DataItem; - const components = this.getDataItem().components; - if (components !== undefined) { - dataItem.components = components; - } - const elementDataType = this.getFactory().mapDataItemToDataType(dataItem); - const type = elementDataType.getSignature(); - if (this.arrayLength === undefined) { - return `${type}[]`; - } else { - return `${type}[${this.arrayLength}]`; - } - } - - public getSignature(): string { - return this.arraySignature; - } - - public static matchGrammar(type: string): boolean { - return this.matcher.test(type); - } -} - -export class Method extends MemberDataType { - private methodSignature: string; - private methodSelector: string; - - // TMP - public selector: string; - - constructor(abi: MethodAbi) { - super({ type: 'method', name: abi.name, components: abi.inputs }, EvmDataTypeFactory.getInstance()); - this.methodSignature = this.computeSignature(); - this.selector = this.methodSelector = this.computeSelector(); - - } - - 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(0, 4))); - return selector; - } - - 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 value = super.decode(calldata, rules); - return value; - } - - public getSignature(): string { - return this.methodSignature; - } - - public getSelector(): string { - return this.methodSelector; - } -} - -export class EvmDataTypeFactory implements DataTypeFactory { - private static instance: DataTypeFactory; - - private constructor() { } - - public static getInstance(): DataTypeFactory { - if (!EvmDataTypeFactory.instance) { - EvmDataTypeFactory.instance = new EvmDataTypeFactory(); - } - return EvmDataTypeFactory.instance; - } - - public mapDataItemToDataType(dataItem: DataItem): DataType { - if (SolArray.matchGrammar(dataItem.type)) return new SolArray(dataItem); - if (Address.matchGrammar(dataItem.type)) return new Address(dataItem); - if (Bool.matchGrammar(dataItem.type)) return new Bool(dataItem); - if (Int.matchGrammar(dataItem.type)) return new Int(dataItem); - if (UInt.matchGrammar(dataItem.type)) return new UInt(dataItem); - if (Byte.matchGrammar(dataItem.type)) return new Byte(dataItem); - if (Tuple.matchGrammar(dataItem.type)) return new Tuple(dataItem); - if (Bytes.matchGrammar(dataItem.type)) return new Bytes(dataItem); - if (SolString.matchGrammar(dataItem.type)) return new SolString(dataItem); - //if (Fixed.matchGrammar(dataItem.type)) return Fixed(dataItem); - //if (UFixed.matchGrammar(dataItem.type)) return UFixed(dataItem); - - throw new Error(`Unrecognized data type: '${dataItem.type}'`); - } - - public create(dataItem: DataItem, parentDataType: DataType): DataType { - const dataType = this.mapDataItemToDataType(dataItem); - if (dataType.isStatic()) { - return dataType; - } - - const pointer = new Pointer(dataType, parentDataType); - return pointer; - } -}
\ No newline at end of file diff --git a/packages/order-utils/test/abi_encoder/index.ts b/packages/order-utils/test/abi_encoder/index.ts deleted file mode 100644 index 991edb8c5..000000000 --- a/packages/order-utils/test/abi_encoder/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { EncodingRules, DecodingRules } from './calldata'; -export * from './evm_data_types';
\ No newline at end of file diff --git a/packages/order-utils/test/abi_encoder_test.ts b/packages/order-utils/test/abi_encoder_test.ts deleted file mode 100644 index f1e562bc6..000000000 --- a/packages/order-utils/test/abi_encoder_test.ts +++ /dev/null @@ -1,943 +0,0 @@ -import * as chai from 'chai'; -import 'mocha'; -import ethUtil = require('ethereumjs-util'); - -var _ = require('lodash'); - -// import { assert } from '@0x/order-utils/src/assert'; - -import { chaiSetup } from './utils/chai_setup'; - -import { MethodAbi, DataItem } from 'ethereum-types'; - -import { BigNumber } from '@0x/utils'; -import { assert } from '@0x/order-utils/src/assert'; -//import * as AbiEncoder from './abi_encoder'; - -import * as AbiEncoder from './abi_encoder'; - -import * as AbiSamples from './abi_samples'; - -chaiSetup.configure(); -const expect = chai.expect; - -describe.only('ABI Encoder', () => { - describe.only('Optimizer', () => { - - }); - - describe.only('ABI Tests at Method Level', () => { - - it('Should reuse duplicated strings in string array', async () => { - const method = new AbiEncoder.Method(AbiSamples.stringAbi); - const strings = [ - "Test String", - "Test String 2", - "Test String", - "Test String 2", - ]; - const args = [strings]; - - // Verify optimized calldata is expected - const optimizedCalldata = method.encode(args, { optimize: true }); - const expectedOptimizedCalldata = '0x13e751a900000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000b5465737420537472696e67000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d5465737420537472696e67203200000000000000000000000000000000000000'; - //expect(optimizedCalldata).to.be.equal(expectedOptimizedCalldata); - - // Verify args decode properly - const decodedArgs = method.decode(optimizedCalldata); - const decodedArgsJson = JSON.stringify(decodedArgs); - const argsJson = JSON.stringify(args); - expect(decodedArgsJson).to.be.equal(argsJson); - - console.log('*'.repeat(100), '\n', method.encode(args, { optimize: true, annotate: true }), '\n', '*'.repeat(100)); - console.log('*'.repeat(100), '\n', method.encode(args, { optimize: true }), '\n', '*'.repeat(100)); - }); - - it('Should point array elements to a duplicated value from another parameter', async () => { - const method = new AbiEncoder.Method(AbiSamples.optimizerAbi2); - const stringArray = [ - "Test String", - "Test String", - "Test String", - "Test String 2", - ]; - const string = 'Test String'; - const args = [stringArray, string]; - - // Verify optimized calldata is expected - const optimizedCalldata = method.encode(args, { optimize: true }); - const expectedOptimizedCalldata = '0xe0e0d34900000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000d5465737420537472696e67203200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b5465737420537472696e67000000000000000000000000000000000000000000'; - expect(optimizedCalldata).to.be.equal(expectedOptimizedCalldata); - - // Verify args decode properly - const decodedArgs = method.decode(optimizedCalldata); - const decodedArgsJson = JSON.stringify(decodedArgs); - const argsJson = JSON.stringify(args); - expect(decodedArgsJson).to.be.equal(argsJson); - - console.log('*'.repeat(100), '\n', method.encode(args, { optimize: true, annotate: true }), '\n', '*'.repeat(100)); - console.log('*'.repeat(100), '\n', method.encode(args, { optimize: true }), '\n', '*'.repeat(100)); - }); - - - it('Optimizer #3 (tuple should point to array)', async () => { - const method = new AbiEncoder.Method(AbiSamples.optimizerAbi3); - const uint8Array = [ - new BigNumber(100), - new BigNumber(150), - new BigNumber(200), - new BigNumber(225), - ]; - const uintTupleArray = [[uint8Array[0]], [uint8Array[1]], [uint8Array[2]], [uint8Array[3]]]; - const args = [uint8Array, uintTupleArray]; - - - const TEST = method.encode(args, { optimize: true, annotate: true }); - console.log('*'.repeat(50), ' ENCODED DATA ', TEST); - - const optimizedCalldata = method.encode(args, { optimize: true }); - - console.log(`OPTIMIZED CALLDATA == '${optimizedCalldata}'`); - const decodedArgs = method.decode(optimizedCalldata); - const decodedArgsJson = JSON.stringify(decodedArgs); - const argsJson = JSON.stringify(args); - console.log(JSON.stringify(decodedArgs)); - expect(decodedArgsJson).to.be.equal(argsJson); - }); - - it('Optimizer #4 (Expect no optimization)', async () => { - const method = new AbiEncoder.Method(AbiSamples.optimizerAbi4); - const uint8Array = [ - new BigNumber(100), - new BigNumber(150), - new BigNumber(200), - new BigNumber(225), - ]; - const uintTupleArray = [[uint8Array[0]], [uint8Array[1]], [uint8Array[2]], [uint8Array[3]]]; - const args = [uint8Array, uintTupleArray]; - - - const TEST = method.encode(args, { optimize: true, annotate: true }); - console.log('*'.repeat(50), ' ENCODED DATA ', TEST); - - const optimizedCalldata = method.encode(args, { optimize: true }); - - console.log(`OPTIMIZED CALLDATA == '${optimizedCalldata}'`); - const decodedArgs = method.decode(optimizedCalldata); - const decodedArgsJson = JSON.stringify(decodedArgs); - const argsJson = JSON.stringify(args); - console.log(JSON.stringify(decodedArgs)); - expect(decodedArgsJson).to.be.equal(argsJson); - }); - - it('Crazy ABI', async () => { - const method = new AbiEncoder.Method(AbiSamples.crazyAbi); - console.log(method.getSignature()); - - const someStaticArray = [new BigNumber(127), new BigNumber(14), new BigNumber(54)]; - const someStaticArrayWithDynamicMembers = [ - 'the little piping piper piped a piping pipper papper', - 'the kid knows how to write poems, what can I say -- I guess theres a lot I could say to try to fill this line with a lot of text.', - ]; - const someDynamicArrayWithDynamicMembers = [ - '0x38745637834987324827439287423897238947239847', - '0x7283472398237423984723984729847248927498748974284728947239487498749847874329423743492347329847239842374892374892374892347238947289478947489374289472894738942749823743298742389472389473289472389437249823749823742893472398', - '0x283473298473248923749238742398742398472894729843278942374982374892374892743982', - ]; - const some2DArray = [ - [ - 'some string', - 'some another string', - 'there are just too many stringsup in', - 'here', - 'yall ghonna make me lose my mind', - ], - [ - 'the little piping piper piped a piping pipper papper', - 'the kid knows how to write poems, what can I say -- I guess theres a lot I could say to try to fill this line with a lot of text.', - ], - [], - ]; - const someTuple = { - someUint32: new BigNumber(4037824789), - someStr: 'the kid knows how to write poems, what can I say -- I guess theres a lot I could say to try to fill this line with a lot of text.' - }; - const someTupleWithDynamicTypes = { - someUint: new BigNumber(4024789), - someStr: 'akdhjasjkdhasjkldshdjahdkjsahdajksdhsajkdhsajkdhadjkashdjksadhajkdhsajkdhsadjk', - someBytes: '0x29384723894723843743289742389472398473289472348927489274894738427428947389facdea', - someAddress: '0xe41d2489571d322189246dafa5ebde1f4699f498', - }; - const someTupleWithDynamicTypes2 = { - someUint: new BigNumber(9024789), - someStr: 'ksdhsajkdhsajkdhadjkashdjksadhajkdhsajkdhsadjkakdhjasjkdhasjkldshdjahdkjsahdaj', - someBytes: '0x29384723894398473289472348927489272384374328974238947274894738427428947389facde1', - someAddress: '0x746dafa5ebde1f4699f4981d3221892e41d24895', - }; - const someTupleWithDynamicTypes3 = { - someUint: new BigNumber(1024789), - someStr: 'sdhsajkdhsajkdhadjkashdjakdhjasjkdhasjkldshdjahdkjsahdajkksadhajkdhsajkdhsadjk', - someBytes: '0x38947238437432829384729742389472398473289472348927489274894738427428947389facdef', - someAddress: '0x89571d322189e415ebde1f4699f498d24246dafa', - }; - const someArrayOfTuplesWithDynamicTypes = [someTupleWithDynamicTypes2, someTupleWithDynamicTypes3]; - - const args = { - someStaticArray: someStaticArray, - someStaticArrayWithDynamicMembers: someStaticArrayWithDynamicMembers, - someDynamicArrayWithDynamicMembers: someDynamicArrayWithDynamicMembers, - some2DArray: some2DArray, - someTuple: someTuple, - someTupleWithDynamicTypes: someTupleWithDynamicTypes, - someArrayOfTuplesWithDynamicTypes: someArrayOfTuplesWithDynamicTypes - }; - - const calldata = method.encode(args); - console.log(calldata); - - console.log('*'.repeat(40)); - console.log(JSON.stringify(args)); - console.log(method.getSignature()); - - const expectedCalldata = '0x4b49031c000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000000000000000000000000000000000000088000000000000000000000000000000000000000000000000000000000000009800000000000000000000000000000000000000000000000000000000000000ae0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000034746865206c6974746c6520706970696e67207069706572207069706564206120706970696e6720706970706572207061707065720000000000000000000000000000000000000000000000000000000000000000000000000000000000000081746865206b6964206b6e6f777320686f7720746f20777269746520706f656d732c20776861742063616e204920736179202d2d2049206775657373207468657265732061206c6f74204920636f756c642073617920746f2074727920746f2066696c6c2074686973206c696e6520776974682061206c6f74206f6620746578742e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000163874563783498732482743928742389723894723984700000000000000000000000000000000000000000000000000000000000000000000000000000000006e72834723982374239847239847298472489274987489742847289472394874987498478743294237434923473298472398423748923748923748923472389472894789474893742894728947389427498237432987423894723894732894723894372498237498237428934723980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027283473298473248923749238742398742398472894729843278942374982374892374892743982000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000b736f6d6520737472696e670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013736f6d6520616e6f7468657220737472696e67000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024746865726520617265206a75737420746f6f206d616e7920737472696e6773757020696e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046865726500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002079616c6c2067686f6e6e61206d616b65206d65206c6f7365206d79206d696e640000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000034746865206c6974746c6520706970696e67207069706572207069706564206120706970696e6720706970706572207061707065720000000000000000000000000000000000000000000000000000000000000000000000000000000000000081746865206b6964206b6e6f777320686f7720746f20777269746520706f656d732c20776861742063616e204920736179202d2d2049206775657373207468657265732061206c6f74204920636f756c642073617920746f2074727920746f2066696c6c2074686973206c696e6520776974682061206c6f74206f6620746578742e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f0ac511500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000081746865206b6964206b6e6f777320686f7720746f20777269746520706f656d732c20776861742063616e204920736179202d2d2049206775657373207468657265732061206c6f74204920636f756c642073617920746f2074727920746f2066696c6c2074686973206c696e6520776974682061206c6f74206f6620746578742e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d69d500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f498000000000000000000000000000000000000000000000000000000000000004e616b64686a61736a6b646861736a6b6c647368646a6168646b6a73616864616a6b73646873616a6b646873616a6b646861646a6b617368646a6b73616468616a6b646873616a6b64687361646a6b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002829384723894723843743289742389472398473289472348927489274894738427428947389facdea0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000089b51500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000746dafa5ebde1f4699f4981d3221892e41d24895000000000000000000000000000000000000000000000000000000000000004e6b73646873616a6b646873616a6b646861646a6b617368646a6b73616468616a6b646873616a6b64687361646a6b616b64686a61736a6b646861736a6b6c647368646a6168646b6a73616864616a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002829384723894398473289472348927489272384374328974238947274894738427428947389facde100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fa3150000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000089571d322189e415ebde1f4699f498d24246dafa000000000000000000000000000000000000000000000000000000000000004e73646873616a6b646873616a6b646861646a6b617368646a616b64686a61736a6b646861736a6b6c647368646a6168646b6a73616864616a6b6b73616468616a6b646873616a6b64687361646a6b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002838947238437432829384729742389472398473289472348927489274894738427428947389facdef000000000000000000000000000000000000000000000000'; - //const expectedCalldata = '0x30e1f844000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000960000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000034746865206c6974746c6520706970696e67207069706572207069706564206120706970696e6720706970706572207061707065720000000000000000000000000000000000000000000000000000000000000000000000000000000000000081746865206b6964206b6e6f777320686f7720746f20777269746520706f656d732c20776861742063616e204920736179202d2d2049206775657373207468657265732061206c6f74204920636f756c642073617920746f2074727920746f2066696c6c2074686973206c696e6520776974682061206c6f74206f6620746578742e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000163874563783498732482743928742389723894723984700000000000000000000000000000000000000000000000000000000000000000000000000000000006e72834723982374239847239847298472489274987489742847289472394874987498478743294237434923473298472398423748923748923748923472389472894789474893742894728947389427498237432987423894723894732894723894372498237498237428934723980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027283473298473248923749238742398742398472894729843278942374982374892374892743982000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000b736f6d6520737472696e670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013736f6d6520616e6f7468657220737472696e67000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024746865726520617265206a75737420746f6f206d616e7920737472696e6773757020696e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046865726500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002079616c6c2067686f6e6e61206d616b65206d65206c6f7365206d79206d696e640000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000034746865206c6974746c6520706970696e67207069706572207069706564206120706970696e6720706970706572207061707065720000000000000000000000000000000000000000000000000000000000000000000000000000000000000081746865206b6964206b6e6f777320686f7720746f20777269746520706f656d732c20776861742063616e204920736179202d2d2049206775657373207468657265732061206c6f74204920636f756c642073617920746f2074727920746f2066696c6c2074686973206c696e6520776974682061206c6f74206f6620746578742e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f0ac511500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000081746865206b6964206b6e6f777320686f7720746f20777269746520706f656d732c20776861742063616e204920736179202d2d2049206775657373207468657265732061206c6f74204920636f756c642073617920746f2074727920746f2066696c6c2074686973206c696e6520776974682061206c6f74206f6620746578742e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cf5763d5ec63d500600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f498000000000000000000000000000000000000000000000000000000000000004e616b64686a61736a6b646861736a6b6c647368646a6168646b6a73616864616a6b73646873616a6b646873616a6b646861646a6b617368646a6b73616468616a6b646873616a6b64687361646a6b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f7484848484848484848484848484848484848384757687980943399445858584893209100000000000000000000000000000000000000000000000000000000'; - expect(calldata).to.be.equal(expectedCalldata); - - // Test decoding - const expectedDecodedValueJson = JSON.stringify(args); - const decodedValue = method.decode(calldata, { structsAsObjects: true }); - const decodedValueJson = JSON.stringify(decodedValue); - console.log(`DECODED`, '*'.repeat(200), '\n', decodedValueJson); - expect(decodedValueJson).to.be.equal(expectedDecodedValueJson); - }); - - it('Crazy ABI #1', async () => { - const method = new AbiEncoder.Method(AbiSamples.crazyAbi1); - - const args = [ - new BigNumber(256745454), - new BigNumber(-256745454), - new BigNumber(434244), - '0x43', - '0x0001020304050607080911121314151617181920212223242526272829303132', - '0x0001020304050607080911121314151617181920212223242526272829303132080911121314151617181920212223242526272829303132', - 'Little peter piper piped a piping pepper pot', - '0xe41d2489571d322189246dafa5ebde1f4699f498', - true - ]; - - const calldata = method.encode(args); - console.log(calldata); - console.log('*'.repeat(40)); - console.log(method.getSignature()); - console.log(JSON.stringify(args)); - const expectedCalldata = '0x312d4d42000000000000000000000000000000000000000000000000000000000f4d9feefffffffffffffffffffffffffffffffffffffffffffffffffffffffff0b26012000000000000000000000000000000000000000000000000000000000006a0444300000000000000000000000000000000000000000000000000000000000000000102030405060708091112131415161718192021222324252627282930313200000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000180000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f4980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003800010203040506070809111213141516171819202122232425262728293031320809111213141516171819202122232425262728293031320000000000000000000000000000000000000000000000000000000000000000000000000000002c4c6974746c65207065746572207069706572207069706564206120706970696e672070657070657220706f740000000000000000000000000000000000000000'; - expect(calldata).to.be.equal(expectedCalldata); - - // Test decoding - const expectedDecodedValueJson = JSON.stringify(args); - const decodedValue = method.decode(calldata); - const decodedValueJson = JSON.stringify(decodedValue); - expect(decodedValueJson).to.be.equal(expectedDecodedValueJson); - }); - - - it('Types with default widths', async () => { - const method = new AbiEncoder.Method(AbiSamples.typesWithDefaultWidthsAbi); - console.log(method); - const args = [new BigNumber(1), new BigNumber(-1), '0x56', [new BigNumber(1)], [new BigNumber(-1)], ['0x56']]; - const calldata = method.encode(args); - console.log(calldata); - console.log('*'.repeat(40)); - console.log(method.getSignature()); - console.log(JSON.stringify(args)); - const expectedCalldata = '0x09f2b0c30000000000000000000000000000000000000000000000000000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff560000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000015600000000000000000000000000000000000000000000000000000000000000'; - expect(calldata).to.be.equal(expectedCalldata); - - // Test decoding - const expectedDecodedValueJson = JSON.stringify(args); - const decodedValue = method.decode(calldata); - const decodedValueJson = JSON.stringify(decodedValue); - expect(decodedValueJson).to.be.equal(expectedDecodedValueJson); - }); - - it('Array of Static Tuples (Array has defined length)', async () => { - const method = new AbiEncoder.Method(AbiSamples.arrayOfStaticTuplesWithDefinedLengthAbi); - - let value = 0; - const arrayOfTuples = []; - for (let i = 0; i < 8; ++i) { - arrayOfTuples.push([new BigNumber(++value), new BigNumber(++value)]); - } - const args = [arrayOfTuples]; - const calldata = method.encode(args); - console.log(calldata); - console.log('*'.repeat(40)); - console.log(method.getSignature()); - console.log(JSON.stringify(args)); - const expectedCalldata = '0x9eb20969000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000010'; - expect(calldata).to.be.equal(expectedCalldata); - - // Test decoding - const expectedDecodedValueJson = JSON.stringify(args); - const decodedValue = method.decode(calldata); - const decodedValueJson = JSON.stringify(decodedValue); - expect(decodedValueJson).to.be.equal(expectedDecodedValueJson); - }); - - it('Array of Static Tuples (Array has dynamic length)', async () => { - const method = new AbiEncoder.Method(AbiSamples.arrayOfStaticTuplesWithDynamicLengthAbi); - - let value = 0; - const arrayOfTuples = []; - for (let i = 0; i < 8; ++i) { - arrayOfTuples.push([new BigNumber(++value), new BigNumber(++value)]); - } - const args = [arrayOfTuples]; - const calldata = method.encode(args); - console.log(calldata); - console.log('*'.repeat(40)); - console.log(method.getSignature()); - console.log(JSON.stringify(args)); - const expectedCalldata = '0x63275d6e00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000010'; - expect(calldata).to.be.equal(expectedCalldata); - - // Test decoding - const expectedDecodedValueJson = JSON.stringify(args); - const decodedValue = method.decode(calldata); - const decodedValueJson = JSON.stringify(decodedValue); - expect(decodedValueJson).to.be.equal(expectedDecodedValueJson); - }); - - it('Array of Dynamic Tuples (Array has defined length)', async () => { - const method = new AbiEncoder.Method(AbiSamples.arrayOfDynamicTuplesWithDefinedLengthAbi); - - let value = 0; - const arrayOfTuples = []; - for (let i = 0; i < 8; ++i) { - arrayOfTuples.push([new BigNumber(++value), (new BigNumber(++value)).toString()]); - } - const args = [arrayOfTuples]; - const calldata = method.encode(args); - console.log(calldata); - console.log('*'.repeat(40)); - console.log(method.getSignature()); - console.log(JSON.stringify(args)); - const expectedCalldata = '0xdeedb00f00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000132000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000013400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000138000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000023130000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000023132000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000023134000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000023136000000000000000000000000000000000000000000000000000000000000'; - expect(calldata).to.be.equal(expectedCalldata); - - // Test decoding - const expectedDecodedValueJson = JSON.stringify(args); - const decodedValue = method.decode(calldata); - const decodedValueJson = JSON.stringify(decodedValue); - expect(decodedValueJson).to.be.equal(expectedDecodedValueJson); - }); - - it('Array of Dynamic Tuples (Array has dynamic length)', async () => { - const method = new AbiEncoder.Method(AbiSamples.arrayOfDynamicTuplesWithUndefinedLengthAbi); - - let value = 0; - const arrayOfTuples = []; - for (let i = 0; i < 8; ++i) { - arrayOfTuples.push([new BigNumber(++value), (new BigNumber(++value)).toString()]); - } - const args = [arrayOfTuples]; - const calldata = method.encode(args); - console.log(calldata); - console.log('*'.repeat(40)); - console.log(method.getSignature()); - console.log(JSON.stringify(args)); - const expectedCalldata = '0x60c847fb000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000132000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000013400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000138000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000023130000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000023132000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000023134000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000023136000000000000000000000000000000000000000000000000000000000000'; - expect(calldata).to.be.equal(expectedCalldata); - - // Test decoding - const expectedDecodedValueJson = JSON.stringify(args); - const decodedValue = method.decode(calldata); - const decodedValueJson = JSON.stringify(decodedValue); - expect(decodedValueJson).to.be.equal(expectedDecodedValueJson); - }); - - it('Multidimensional Arrays / Static Members', async () => { - const method = new AbiEncoder.Method(AbiSamples.multiDimensionalArraysStaticTypeAbi); - - // Eight 3-dimensional arrays of uint8[2][2][2] - let value = 0; - const args = []; - for (let i = 0; i < 8; ++i) { - args.push( - [ - [ - [new BigNumber(++value), new BigNumber(++value)], - [new BigNumber(++value), new BigNumber(++value)], - ], - [ - [new BigNumber(++value), new BigNumber(++value)], - [new BigNumber(++value), new BigNumber(++value)], - ] - ] - ); - } - const calldata = method.encode(args); - console.log(calldata); - console.log('*'.repeat(40)); - console.log(method.getSignature()); - console.log(JSON.stringify(args)); - const expectedCalldata = '0xc2f47d6f00000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000e600000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000003f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000130000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001500000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001b000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001d000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000210000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000230000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000025000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000027000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000029000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000002b000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000002d000000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000002f0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000038'; expect(calldata).to.be.equal(expectedCalldata); - expect(calldata).to.be.equal(expectedCalldata); - - // Test decoding - const expectedDecodedValueJson = JSON.stringify(args); - const decodedValue = method.decode(calldata); - const decodedValueJson = JSON.stringify(decodedValue); - expect(decodedValueJson).to.be.equal(expectedDecodedValueJson); - }); - - it('Multidimensional Arrays / Dynamic Members', async () => { - const method = new AbiEncoder.Method(AbiSamples.multiDimensionalArraysDynamicTypeAbi); - - // Eight 3-dimensional arrays of string[2][2][2] - let value = 0; - const args = []; - for (let i = 0; i < 4; ++i) { - args.push( - [ - [ - [new BigNumber(++value).toString(), new BigNumber(++value).toString()], - [new BigNumber(++value).toString(), new BigNumber(++value).toString()], - ], - [ - [new BigNumber(++value).toString(), new BigNumber(++value).toString()], - [new BigNumber(++value).toString(), new BigNumber(++value).toString()], - ] - ] - ); - } - const calldata = method.encode(args); - console.log(calldata); - console.log('*'.repeat(40)); - console.log(method.getSignature()); - console.log(JSON.stringify(args)); - const expectedCalldata = '0x81534ebd0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000009a00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000131000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000013300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000134000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000137000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000139000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002313000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000023131000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000231320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000002313300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023134000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000231350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002313600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000231370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002313800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000023139000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000232300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000023231000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000232320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000002323300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023234000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000232350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002323600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000232370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002323800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000002323900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000002333100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023332000000000000000000000000000000000000000000000000000000000000'; - expect(calldata).to.be.equal(expectedCalldata); - - // Test decoding - const expectedDecodedValueJson = JSON.stringify(args); - const decodedValue = method.decode(calldata); - const decodedValueJson = JSON.stringify(decodedValue); - expect(decodedValueJson).to.be.equal(expectedDecodedValueJson); - }); - - it('Fixed Lenfgth Array / Dynamic Members', async () => { - const method = new AbiEncoder.Method(AbiSamples.staticArrayDynamicMembersAbi); - const args = [["Brave", "New", "World"]]; - const calldata = method.encode(args); - console.log(calldata); - console.log('*'.repeat(40)); - console.log(JSON.stringify(args)); - const expectedCalldata = - '0x243a6e6e0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000005427261766500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034e657700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005576f726c64000000000000000000000000000000000000000000000000000000'; - expect(calldata).to.be.equal(expectedCalldata); - - // Test decoding - const expectedDecodedValueJson = JSON.stringify(args); - const decodedValue = method.decode(calldata); - const decodedValueJson = JSON.stringify(decodedValue); - expect(decodedValueJson).to.be.equal(expectedDecodedValueJson); - }); - - it('Fixed Lenfgth Array / Dynamic Members', async () => { - const method = new AbiEncoder.Method(AbiSamples.staticArrayDynamicMembersAbi); - const args = [["Brave", "New", "World"]]; - const calldata = method.encode(args); - console.log(calldata); - console.log('*'.repeat(40)); - console.log(JSON.stringify(args)); - const expectedCalldata = - '0x243a6e6e0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000005427261766500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034e657700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005576f726c64000000000000000000000000000000000000000000000000000000'; - expect(calldata).to.be.equal(expectedCalldata); - - // Test decoding - const expectedDecodedValueJson = JSON.stringify(args); - const decodedValue = method.decode(calldata); - const decodedValueJson = JSON.stringify(decodedValue); - expect(decodedValueJson).to.be.equal(expectedDecodedValueJson); - }); - - it('Unfixed Length Array / Dynamic Members ABI', async () => { - const method = new AbiEncoder.Method(AbiSamples.dynamicArrayDynamicMembersAbi); - const args = [["Brave", "New", "World"]]; - const calldata = method.encode(args); - console.log(calldata); - console.log('*'.repeat(40)); - console.log(JSON.stringify(args)); - const expectedCalldata = '0x13e751a900000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000005427261766500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034e657700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005576f726c64000000000000000000000000000000000000000000000000000000'; - expect(calldata).to.be.equal(expectedCalldata); - - // Test decoding - const expectedDecodedValueJson = JSON.stringify(args); - const decodedValue = method.decode(calldata); - const decodedValueJson = JSON.stringify(decodedValue); - expect(decodedValueJson).to.be.equal(expectedDecodedValueJson); - }); - - it('Unfixed Length Array / Static Members ABI', async () => { - const method = new AbiEncoder.Method(AbiSamples.dynamicArrayStaticMembersAbi); - const args = [[new BigNumber(127), new BigNumber(14), new BigNumber(54)]]; - const calldata = method.encode(args); - const expectedCalldata = '0x4fc8a83300000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000036'; - expect(calldata).to.be.equal(expectedCalldata); - - // Test decoding - const expectedDecodedValueJson = JSON.stringify(args); - const decodedValue = method.decode(calldata); - const decodedValueJson = JSON.stringify(decodedValue); - expect(decodedValueJson).to.be.equal(expectedDecodedValueJson); - }); - - - it('Fixed Length Array / Static Members ABI', async () => { - const method = new AbiEncoder.Method(AbiSamples.staticArrayAbi); - const args = [[new BigNumber(127), new BigNumber(14), new BigNumber(54)]]; - const calldata = method.encode(args); - const expectedCalldata = - '0xf68ade72000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000036'; - expect(calldata).to.be.equal(expectedCalldata); - - // Test decoding - const expectedDecodedValueJson = JSON.stringify(args); - const decodedValue = method.decode(calldata); - const decodedValueJson = JSON.stringify(decodedValue); - expect(decodedValueJson).to.be.equal(expectedDecodedValueJson); - }); - - - it('Simple ABI 2', async () => { - const method = new AbiEncoder.Method(AbiSamples.simpleAbi2); - - const args = [ - '0xaf', // e (bytes1) - '0x0001020304050607080911121314151617181920212223242526272829303132', // f (bytes32) - '0x616161616161616161616161616161616161616161616161616161616161616161616161616161611114f324567838475647382938475677448899338457668899002020202020', // g - 'My first name is Greg and my last name is Hysen, what do ya know!', // h - ]; - - const calldata = method.encode(args); - const expectedCalldata = - '0x7ac2bd96af000000000000000000000000000000000000000000000000000000000000000001020304050607080911121314151617181920212223242526272829303132000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000047616161616161616161616161616161616161616161616161616161616161616161616161616161611114f3245678384756473829384756774488993384576688990020202020200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000414d79206669727374206e616d65206973204772656720616e64206d79206c617374206e616d6520697320487973656e2c207768617420646f207961206b6e6f772100000000000000000000000000000000000000000000000000000000000000'; - expect(calldata).to.be.equal(expectedCalldata); - - // Test decoding - const expectedDecodedValueJson = JSON.stringify(args); - const decodedValue = method.decode(calldata); - const decodedValueJson = JSON.stringify(decodedValue); - expect(decodedValueJson).to.be.equal(expectedDecodedValueJson); - }); - - it('Array ABI', async () => { - const method = new AbiEncoder.Method(AbiSamples.stringAbi); - console.log(method); - const args = [['five', 'six', 'seven']]; - const calldata = method.encode(args); - console.log(method.getSignature()); - console.log(method.selector); - - console.log(calldata); - const expectedCalldata = - '0x13e751a900000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000046669766500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000373697800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005736576656e000000000000000000000000000000000000000000000000000000'; - expect(calldata).to.be.equal(expectedCalldata); - - // Test decoding - const expectedDecodedValueJson = JSON.stringify(args); - const decodedValue = method.decode(calldata); - const decodedValueJson = JSON.stringify(decodedValue); - expect(decodedValueJson).to.be.equal(expectedDecodedValueJson); - }); - - it('Static Tuple', async () => { - // This is dynamic because it has dynamic members - const method = new AbiEncoder.Method(AbiSamples.staticTupleAbi); - const args = [[new BigNumber(5), new BigNumber(10), new BigNumber(15), false]]; - const calldata = method.encode(args); - console.log(method.getSignature()); - console.log(method.selector); - - console.log(calldata); - const expectedCalldata = '0xa9125e150000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000000'; - expect(calldata).to.be.equal(expectedCalldata); - - // Test decoding - const expectedDecodedValueJson = JSON.stringify(args); - const decodedValue = method.decode(calldata); - const decodedValueJson = JSON.stringify(decodedValue); - expect(decodedValueJson).to.be.equal(expectedDecodedValueJson); - }); - - it('Dynamic Tuple (Array input)', async () => { - // This is dynamic because it has dynamic members - const method = new AbiEncoder.Method(AbiSamples.dynamicTupleAbi); - const args = [[new BigNumber(5), 'five']]; - const calldata = method.encode(args); - console.log(method.getSignature()); - console.log(method.selector); - - console.log(calldata); - const expectedCalldata = - '0x5b998f3500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000046669766500000000000000000000000000000000000000000000000000000000'; - expect(calldata).to.be.equal(expectedCalldata); - - // Test decoding - const expectedDecodedValueJson = JSON.stringify(args); - const decodedValue = method.decode(calldata); - const decodedValueJson = JSON.stringify(decodedValue); - expect(decodedValueJson).to.be.equal(expectedDecodedValueJson); - }); - - it('Dynamic Tuple (Object input)', async () => { - // This is dynamic because it has dynamic members - const method = new AbiEncoder.Method(AbiSamples.dynamicTupleAbi); - const calldata = method.encode([{ someUint: new BigNumber(5), someStr: 'five' }]); - console.log(method.getSignature()); - console.log(method.selector); - - console.log(calldata); - const expectedCalldata = - '0x5b998f3500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000046669766500000000000000000000000000000000000000000000000000000000'; - expect(calldata).to.be.equal(expectedCalldata); - }); - - it.skip('Nested Tuples', async () => { - // Couldn't get nested tuples to work with Remix - // This is dynamic because it has dynamic members - const method = new AbiEncoder.Method(AbiSamples.nestedTuples); - const firstTuple = { - someUint32: new BigNumber(30472), - nestedTuple: { - someUint: new BigNumber('48384725243211555532'), - someAddress: '0xe41d2489571d322189246dafa5ebde1f4699f498' - } - }; - const secondTuple = { - someUint: new BigNumber(2984237422), - someStr: 'This string will exceed 256 bits, so it will spill into the next word of memory.', - nestedTuple: { - someUint32: new BigNumber(23), - secondNestedTuple: { - someUint: new BigNumber(234324), - someStr: 'Im also a short string -- oops I just got loooooooooooooooooonger!', - someBytes: '0x23847287fff3472984723498ff23487324987aaa237438911873429472ba', - someAddress: '0xe41d2489571d322189246dafa5ebde1f4699f498' - } - }, - someBytes: '0x2834y3947289423u489aaaff4783924739847489', - someAddress: '0xe41d2489571d322189246dafa5ebde1f4699afaf', - }; - const thirdTuple = { - 'someUint': new BigNumber(37422), - 'someStr': 'This into the next word of memory. string will exceed 256 bits, so it will spill.', - 'nestedTuple': { - someUint32: new BigNumber(23999222), - 'secondNestedTuple': { - 'someUint': new BigNumber(324), - 'someStr': 'Im also a short st', - 'someBytes': '0x723498ff2348732498723847287fff3472984aaa237438911873429472ba', - 'someAddress': '0x46dafa5ebde1f4699f498e41d2489571d3221892' - } - }, - 'someBytes': '0x947289423u489aaaff472834y383924739847489', - 'someAddress': '0x46dafa5ebde1f46e41d2489571d322189299afaf', - }; - const fourthTuple = { - 'someUint': new BigNumber(222283488822), - 'someStr': 'exceed 256 bits, so it will spill into the. This string will next word of memory.', - 'nestedTuple': { - someUint32: new BigNumber(2300), - 'secondNestedTuple': { - 'someUint': new BigNumber(343224), - 'someStr': 'The alphabet backwards is arguably easier to say if thats the way you learned the first time.', - 'someBytes': '0x87324987aaa23743891187323847287fff3472984723498ff234429472ba', - 'someAddress': '0x71d322189246dafa5ebe41d24895de1f4699f498' - } - }, - 'someBytes': '0x2783924739847488343947289423u489aaaff490', - 'someAddress': '0xebde1d322189246dafa1f4699afafe41d2489575', - }; - const args = [ - [firstTuple], - [secondTuple, thirdTuple, fourthTuple] - ]; - - console.log('*'.repeat(250), method, '*'.repeat(250)); - - - const calldata = method.encode(args); - console.log(method.getSignature()); - console.log(method.selector); - console.log(JSON.stringify(args)); - - console.log(calldata); - const expectedCalldata = '0x'; - expect(calldata).to.be.equal(expectedCalldata); - }); - - it.skip('Object ABI (Object input - Missing Key)', async () => { - const method = new AbiEncoder.Method(AbiSamples.dynamicTupleAbi); - const calldata = method.encode([{ someUint: new BigNumber(5) }]); - console.log(method.getSignature()); - console.log(method.selector); - - console.log(calldata); - const expectedCalldata = - '0x5b998f3500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000046669766500000000000000000000000000000000000000000000000000000000'; - - // @TODO: Figure out how to catch throw - expect(calldata).to.be.equal(expectedCalldata); - }); - - it.skip('Object ABI (Object input - Too Many Keys)', async () => { - const method = new AbiEncoder.Method(AbiSamples.dynamicTupleAbi); - const calldata = method.encode([{ someUint: new BigNumber(5), someStr: 'five', unwantedKey: 14 }]); - console.log(method.getSignature()); - console.log(method.selector); - - console.log(calldata); - const expectedCalldata = - '0x5b998f3500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000046669766500000000000000000000000000000000000000000000000000000000'; - - // @TODO: Figure out how to catch throw - expect(calldata).to.be.equal(expectedCalldata); - }); - }); - /* - describe('Array', () => { - it('sample', async () => { - const testDataItem = { name: 'testArray', type: 'int[2]' }; - const dataType = new AbiEncoder.SolArray(testDataItem); - console.log(JSON.stringify(dataType, null, 4)); - console.log('*'.repeat(60)); - dataType.assignValue([new BigNumber(5), new BigNumber(6)]); - console.log(JSON.stringify(dataType, null, 4)); - const hexValue = dataType.getHexValue(); - console.log('*'.repeat(60)); - console.log(hexValue); - }); - - it('sample undefined size', async () => { - const testDataItem = { name: 'testArray', type: 'int[]' }; - const dataType = new AbiEncoder.SolArray(testDataItem); - console.log(JSON.stringify(dataType, null, 4)); - console.log('*'.repeat(60)); - dataType.assignValue([new BigNumber(5), new BigNumber(6)]); - console.log(JSON.stringify(dataType, null, 4)); - const hexValue = dataType.getHexValue(); - console.log('*'.repeat(60)); - console.log(hexValue); - }); - - it('sample dynamic types', async () => { - const testDataItem = { name: 'testArray', type: 'string[]' }; - const dataType = new AbiEncoder.SolArray(testDataItem); - console.log(JSON.stringify(dataType, null, 4)); - console.log('*'.repeat(60)); - dataType.assignValue(['five', 'six', 'seven']); - console.log(JSON.stringify(dataType, null, 4)); - const hexValue = dataType.getHexValue(); - console.log('*'.repeat(60)); - console.log(hexValue); - const calldata = new AbiEncoder.Calldata('0x01020304', 1); - dataType.bind(calldata, AbiEncoder.CalldataSection.PARAMS); - console.log('*'.repeat(60)); - console.log(calldata.getHexValue()); - }); - }); - - describe('Address', () => { - const testAddressDataItem = { name: 'testAddress', type: 'address' }; - it('Valid Address', async () => { - const addressDataType = new AbiEncoder.Address(testAddressDataItem); - addressDataType.assignValue('0xe41d2489571d322189246dafa5ebde1f4699f498'); - const expectedAbiEncodedAddress = '0x000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f498'; - - console.log(addressDataType.getHexValue()); - console.log(expectedAbiEncodedAddress); - expect(addressDataType.getHexValue()).to.be.equal(expectedAbiEncodedAddress); - }); - }); - - describe('Bool', () => { - const testBoolDataItem = { name: 'testBool', type: 'bool' }; - it('True', async () => { - const boolDataType = new AbiEncoder.Bool(testBoolDataItem); - boolDataType.assignValue(true); - const expectedAbiEncodedBool = '0x0000000000000000000000000000000000000000000000000000000000000001'; - expect(boolDataType.getHexValue()).to.be.equal(expectedAbiEncodedBool); - }); - - it('False', async () => { - const boolDataType = new AbiEncoder.Bool(testBoolDataItem); - boolDataType.assignValue(false); - const expectedAbiEncodedBool = '0x0000000000000000000000000000000000000000000000000000000000000000'; - expect(boolDataType.getHexValue()).to.be.equal(expectedAbiEncodedBool); - }); - }); - - describe('Integer', () => { - const testIntDataItem = { name: 'testInt', type: 'int' }; - it('Positive - Base case', async () => { - const intDataType = new AbiEncoder.Int(testIntDataItem); - intDataType.assignValue(new BigNumber(1)); - const expectedAbiEncodedInt = '0x0000000000000000000000000000000000000000000000000000000000000001'; - expect(intDataType.getHexValue()).to.be.equal(expectedAbiEncodedInt); - }); - - it('Positive', async () => { - const intDataType = new AbiEncoder.Int(testIntDataItem); - intDataType.assignValue(new BigNumber(437829473)); - const expectedAbiEncodedInt = '0x000000000000000000000000000000000000000000000000000000001a18bf61'; - expect(intDataType.getHexValue()).to.be.equal(expectedAbiEncodedInt); - }); - - it('Negative - Base case', async () => { - const intDataType = new AbiEncoder.Int(testIntDataItem); - intDataType.assignValue(new BigNumber(-1)); - const expectedAbiEncodedInt = '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'; - expect(intDataType.getHexValue()).to.be.equal(expectedAbiEncodedInt); - }); - - it('Negative', async () => { - const intDataType = new AbiEncoder.Int(testIntDataItem); - intDataType.assignValue(new BigNumber(-437829473)); - const expectedAbiEncodedInt = '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffe5e7409f'; - expect(intDataType.getHexValue()).to.be.equal(expectedAbiEncodedInt); - }); - - // TODO: Add bounds tests + tests for different widths - }); - - describe('Unsigned Integer', () => { - const testIntDataItem = { name: 'testUInt', type: 'uint' }; - it('Lower Bound', async () => { - const uintDataType = new AbiEncoder.UInt(testIntDataItem); - uintDataType.assignValue(new BigNumber(0)); - const expectedAbiEncodedUInt = '0x0000000000000000000000000000000000000000000000000000000000000000'; - expect(uintDataType.getHexValue()).to.be.equal(expectedAbiEncodedUInt); - }); - - it('Base Case', async () => { - const uintDataType = new AbiEncoder.UInt(testIntDataItem); - uintDataType.assignValue(new BigNumber(1)); - const expectedAbiEncodedUInt = '0x0000000000000000000000000000000000000000000000000000000000000001'; - expect(uintDataType.getHexValue()).to.be.equal(expectedAbiEncodedUInt); - }); - - it('Random value', async () => { - const uintDataType = new AbiEncoder.UInt(testIntDataItem); - uintDataType.assignValue(new BigNumber(437829473)); - const expectedAbiEncodedUInt = '0x000000000000000000000000000000000000000000000000000000001a18bf61'; - expect(uintDataType.getHexValue()).to.be.equal(expectedAbiEncodedUInt); - }); - - // TODO: Add bounds tests + tests for different widths - }); - - describe('Static Bytes', () => { - it('Byte (padded)', async () => { - const testByteDataItem = { name: 'testStaticBytes', type: 'byte' }; - const byteDataType = new AbiEncoder.Byte(testByteDataItem); - byteDataType.assignValue('0x05'); - const expectedAbiEncodedByte = '0x0500000000000000000000000000000000000000000000000000000000000000'; - expect(byteDataType.getHexValue()).to.be.equal(expectedAbiEncodedByte); - }); - - it.skip('Byte (no padding)', async () => { - const testByteDataItem = { name: 'testStaticBytes', type: 'byte' }; - const byteDataType = new AbiEncoder.Byte(testByteDataItem); - - // @TODO: This does not catch the Error - expect(byteDataType.assignValue('0x5')).to.throw(); - }); - - it('Bytes1', async () => { - const testByteDataItem = { name: 'testStaticBytes', type: 'bytes1' }; - const byteDataType = new AbiEncoder.Byte(testByteDataItem); - byteDataType.assignValue('0x05'); - const expectedAbiEncodedByte = '0x0500000000000000000000000000000000000000000000000000000000000000'; - expect(byteDataType.getHexValue()).to.be.equal(expectedAbiEncodedByte); - }); - - it('Bytes32 (padded)', async () => { - const testByteDataItem = { name: 'testStaticBytes', type: 'bytes32' }; - const byteDataType = new AbiEncoder.Byte(testByteDataItem); - byteDataType.assignValue('0x0001020304050607080911121314151617181920212223242526272829303132'); - const expectedAbiEncodedByte = '0x0001020304050607080911121314151617181920212223242526272829303132'; - expect(byteDataType.getHexValue()).to.be.equal(expectedAbiEncodedByte); - }); - - it('Bytes32 (unpadded)', async () => { - const testByteDataItem = { name: 'testStaticBytes', type: 'bytes32' }; - const byteDataType = new AbiEncoder.Byte(testByteDataItem); - byteDataType.assignValue('0x1a18bf61'); - const expectedAbiEncodedByte = '0x1a18bf6100000000000000000000000000000000000000000000000000000000'; - expect(byteDataType.getHexValue()).to.be.equal(expectedAbiEncodedByte); - }); - - it.skip('Bytes32 - Too long', async () => { - const testByteDataItem = { name: 'testStaticBytes', type: 'bytes32' }; - const byteDataType = new AbiEncoder.Byte(testByteDataItem); - - // @TODO: This does not catch the Error - expect( - byteDataType.assignValue('0x000102030405060708091112131415161718192021222324252627282930313233'), - ).to.throw( - `Tried to assign 0x000102030405060708091112131415161718192021222324252627282930313233 (33 bytes), which exceeds max bytes that can be stored in a bytes32`, - ); - }); - }); - - describe('Bytes (Dynamic)', () => { - const testBytesDataItem = { name: 'testBytes', type: 'bytes' }; - it('Less than 32 bytes', async () => { - const bytesDataType = new AbiEncoder.Bytes(testBytesDataItem); - bytesDataType.assignValue('0x010203'); - const expectedAbiEncodedBytes = - '0x00000000000000000000000000000000000000000000000000000000000000030102030000000000000000000000000000000000000000000000000000000000'; - - expect(bytesDataType.getHexValue()).to.be.equal(expectedAbiEncodedBytes); - }); - - it('Greater than 32 bytes', async () => { - const bytesDataType = new AbiEncoder.Bytes(testBytesDataItem); - const testValue = '0x' + '61'.repeat(40); - bytesDataType.assignValue(testValue); - const expectedAbiEncodedBytes = - '0x000000000000000000000000000000000000000000000000000000000000002861616161616161616161616161616161616161616161616161616161616161616161616161616161000000000000000000000000000000000000000000000000'; - expect(bytesDataType.getHexValue()).to.be.equal(expectedAbiEncodedBytes); - }); - - // @TODO: Add test for throw on half-byte - // @TODO: Test with no 0x prefix - // @TODO: Test with Buffer as input - }); - - describe('String', () => { - const testStringDataItem = { name: 'testString', type: 'string' }; - it('Less than 32 bytes', async () => { - const stringDataType = new AbiEncoder.SolString(testStringDataItem); - stringDataType.assignValue('five'); - const expectedAbiEncodedString = - '0x00000000000000000000000000000000000000000000000000000000000000046669766500000000000000000000000000000000000000000000000000000000'; - - console.log(stringDataType.getHexValue()); - console.log(expectedAbiEncodedString); - expect(stringDataType.getHexValue()).to.be.equal(expectedAbiEncodedString); - }); - - it('Greater than 32 bytes', async () => { - const stringDataType = new AbiEncoder.SolString(testStringDataItem); - const testValue = 'a'.repeat(40); - stringDataType.assignValue(testValue); - const expectedAbiEncodedString = - '0x000000000000000000000000000000000000000000000000000000000000002861616161616161616161616161616161616161616161616161616161616161616161616161616161000000000000000000000000000000000000000000000000'; - expect(stringDataType.getHexValue()).to.be.equal(expectedAbiEncodedString); - }); - });*/ -}); diff --git a/packages/order-utils/test/abi_samples.ts b/packages/order-utils/test/abi_samples.ts deleted file mode 100644 index 5e8268f1a..000000000 --- a/packages/order-utils/test/abi_samples.ts +++ /dev/null @@ -1,814 +0,0 @@ -import { MethodAbi } from 'ethereum-types'; - -export const simpleAbi = { - constant: false, - inputs: [ - { - name: 'greg', - type: 'uint256', - }, - { - name: 'gregStr', - type: 'string', - }, - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const stringAbi = { - constant: false, - inputs: [ - { - name: 'greg', - type: 'string[]', - }, - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const optimizerAbi2 = { - constant: false, - inputs: [ - { - name: 'stringArray', - type: 'string[]', - }, - { - name: 'string', - type: 'string', - }, - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const optimizerAbi3 = { - constant: false, - inputs: [ - { - name: 'uint8Array', - type: 'uint8[]', - }, - { - components: [ - { - name: 'uint', - type: 'uint', - }, - ], - name: 'uintTuple', - type: 'tuple[]', - }, - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const optimizerAbi4 = { - constant: false, - inputs: [ - { - name: 'uint8Array', - type: 'uint8[4]', - }, - { - components: [ - { - name: 'uint', - type: 'uint', - }, - ], - name: 'uintTuple', - type: 'tuple[]', - }, - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const typesWithDefaultWidthsAbi = { - constant: false, - inputs: [ - { - name: 'someUint', - type: 'uint', - }, - { - name: 'someInt', - type: 'int', - }, - { - name: 'someByte', - type: 'byte', - }, - { - name: 'someUint', - type: 'uint[]', - }, - { - name: 'someInt', - type: 'int[]', - }, - { - name: 'someByte', - type: 'byte[]', - }, - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const multiDimensionalArraysStaticTypeAbi = { - constant: false, - inputs: [ - { - name: 'a', - type: 'uint8[][][]', - }, - { - name: 'b', - type: 'uint8[][][2]', - }, - { - name: 'c', - type: 'uint8[][2][]', - }, - { - name: 'd', - type: 'uint8[2][][]', - }, - { - name: 'e', - type: 'uint8[][2][2]', - }, - { - name: 'f', - type: 'uint8[2][2][]', - }, - { - name: 'g', - type: 'uint8[2][][2]', - }, - { - name: 'h', - type: 'uint8[2][2][2]', - }, - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const multiDimensionalArraysDynamicTypeAbi = { - constant: false, - inputs: [ - { - name: 'a', - type: 'string[][][]', - }, - { - name: 'b', - type: 'string[][][2]', - }, - { - name: 'c', - type: 'string[][2][]', - }, - { - name: 'h', - type: 'string[2][2][2]', - }, - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const dynamicTupleAbi = { - constant: false, - inputs: [ - { - components: [ - { - name: 'someUint', - type: 'uint256', - }, - { - name: 'someStr', - type: 'string', - }, - ], - name: 'order', - type: 'tuple', - }, - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const arrayOfStaticTuplesWithDefinedLengthAbi = { - constant: false, - inputs: [ - { - components: [ - { - name: 'someUint', - type: 'uint256', - }, - { - name: 'someUint2', - type: 'uint256', - }, - ], - name: 'order', - type: 'tuple[8]', - }, - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const arrayOfStaticTuplesWithDynamicLengthAbi = { - constant: false, - inputs: [ - { - components: [ - { - name: 'someUint', - type: 'uint256', - }, - { - name: 'someUint2', - type: 'uint256', - }, - ], - name: 'order', - type: 'tuple[]', - }, - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const arrayOfDynamicTuplesWithDefinedLengthAbi = { - constant: false, - inputs: [ - { - components: [ - { - name: 'someUint', - type: 'uint256', - }, - { - name: 'someString', - type: 'string', - }, - ], - name: 'order', - type: 'tuple[8]', - }, - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const arrayOfDynamicTuplesWithUndefinedLengthAbi = { - constant: false, - inputs: [ - { - components: [ - { - name: 'someUint', - type: 'uint256', - }, - { - name: 'someString', - type: 'string', - }, - ], - name: 'order', - type: 'tuple[]', - }, - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const arrayOfDynamicTuplesAbi = { - constant: false, - inputs: [ - { - components: [ - { - name: 'someUint', - type: 'uint256', - }, - { - name: 'someString', - type: 'string', - }, - ], - name: 'order', - type: 'tuple[]', - }, - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const multidimensionalArrayOfDynamicTuplesAbi = { - constant: false, - inputs: [ - { - components: [ - { - name: 'someUint', - type: 'uint256', - }, - { - name: 'someString', - type: 'string', - }, - ], - name: 'order', - type: 'tuple[][2][]', - }, - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const staticTupleAbi = { - constant: false, - inputs: [ - { - components: [ - { - name: 'someUint1', - type: 'uint256', - }, - { - name: 'someUint2', - type: 'uint256', - }, - { - name: 'someUint3', - type: 'uint256', - }, - { - name: 'someBool', - type: 'bool', - }, - ], - name: 'order', - type: 'tuple', - }, - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const staticArrayAbi = { - constant: false, - inputs: [ - { - name: 'someStaticArray', - type: 'uint8[3]', - } - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const staticArrayDynamicMembersAbi = { - constant: false, - inputs: [ - { - name: 'someStaticArray', - type: 'string[3]', - } - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const dynamicArrayDynamicMembersAbi = { - constant: false, - inputs: [ - { - name: 'someStaticArray', - type: 'string[]', - } - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const dynamicArrayStaticMembersAbi = { - constant: false, - inputs: [ - { - name: 'someStaticArray', - type: 'uint8[]', - } - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const crazyAbi1 = { - constant: false, - inputs: [ - { - name: 'someUInt256', - type: 'uint256', - }, - { - name: 'someInt256', - type: 'int256', - }, - { - name: 'someInt32', - type: 'int32', - }, - { - name: 'someByte', - type: 'byte', - }, - { - name: 'someBytes32', - type: 'bytes32', - }, - { - name: 'someBytes', - type: 'bytes', - }, - { - name: 'someString', - type: 'string', - }, - { - name: 'someAddress', - type: 'address', - }, - { - name: 'someBool', - type: 'bool', - }, - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const crazyAbi = { - constant: false, - inputs: [ - { - name: 'someStaticArray', - type: 'uint8[3]', - }, - { - name: 'someStaticArrayWithDynamicMembers', - type: 'string[2]', - }, - { - name: 'someDynamicArrayWithDynamicMembers', - type: 'bytes[]', - }, - { - name: 'some2DArray', - type: 'string[][]', - }, - { - name: 'someTuple', - type: 'tuple', - components: [ - { - name: 'someUint32', - type: 'uint32', - }, - { - name: 'someStr', - type: 'string', - }, - ], - }, - { - name: 'someTupleWithDynamicTypes', - type: 'tuple', - components: [ - { - name: 'someUint', - type: 'uint256', - }, - { - name: 'someStr', - type: 'string', - }, - /*{ - name: 'someStrArray', - type: 'string[]', - },*/ - { - name: 'someBytes', - type: 'bytes', - }, - { - name: 'someAddress', - type: 'address', - }, - ], - }, - { - name: 'someArrayOfTuplesWithDynamicTypes', - type: 'tuple[]', - components: [ - { - name: 'someUint', - type: 'uint256', - }, - { - name: 'someStr', - type: 'string', - }, - /*{ - name: 'someStrArray', - type: 'string[]', - },*/ - { - name: 'someBytes', - type: 'bytes', - }, - { - name: 'someAddress', - type: 'address', - }, - ], - } - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const nestedTuples = { - constant: false, - inputs: [ - { - name: 'firstTuple', - type: 'tuple[1]', - components: [ - { - name: 'someUint32', - type: 'uint32', - }, - { - name: 'nestedTuple', - type: 'tuple', - components: [ - { - name: 'someUint', - type: 'uint256', - }, - { - name: 'someAddress', - type: 'address', - }, - ], - }, - ], - }, - { - name: 'secondTuple', - type: 'tuple[]', - components: [ - { - name: 'someUint', - type: 'uint256', - }, - { - name: 'someStr', - type: 'string', - }, - { - name: 'nestedTuple', - type: 'tuple', - components: [ - { - name: 'someUint32', - type: 'uint32', - }, - { - name: 'secondNestedTuple', - type: 'tuple', - components: [ - { - name: 'someUint', - type: 'uint256', - }, - { - name: 'someStr', - type: 'string', - }, - { - name: 'someBytes', - type: 'bytes', - }, - { - name: 'someAddress', - type: 'address', - }, - ], - }, - ], - }, - { - name: 'someBytes', - type: 'bytes', - }, - { - name: 'someAddress', - type: 'address', - }, - ], - } - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const simpleAbi2 = { - constant: false, - inputs: [ - { - name: 'someByte', - type: 'byte', - }, - { - name: 'someBytes32', - type: 'bytes32', - }, - { - name: 'someBytes', - type: 'bytes', - }, - { - name: 'someString', - type: 'string', - }, - ], - name: 'simpleFunction', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; - -export const fillOrderAbi = { - constant: false, - inputs: [ - { - components: [ - { - name: 'makerAddress', - type: 'address', - }, - { - name: 'takerAddress', - type: 'address', - }, - { - name: 'feeRecipientAddress', - type: 'address', - }, - { - name: 'senderAddress', - type: 'address', - }, - { - name: 'makerAssetAmount', - type: 'uint256', - }, - { - name: 'takerAssetAmount', - type: 'uint256', - }, - { - name: 'makerFee', - type: 'uint256', - }, - { - name: 'takerFee', - type: 'uint256', - }, - { - name: 'expirationTimeSeconds', - type: 'uint256', - }, - { - name: 'salt', - type: 'uint256', - }, - { - name: 'makerAssetData', - type: 'bytes', - }, - { - name: 'takerAssetData', - type: 'bytes', - }, - ], - name: 'order', - type: 'tuple', - }, - { - name: 'takerAssetFillAmount', - type: 'uint256', - }, - { - name: 'salt', - type: 'uint256', - }, - { - name: 'orderSignature', - type: 'bytes', - }, - { - name: 'takerSignature', - type: 'bytes', - }, - ], - name: 'fillOrder', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', -} as MethodAbi; |