diff options
author | Leonid <logvinov.leon@gmail.com> | 2017-05-26 18:41:51 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-26 18:41:51 +0800 |
commit | f338c68f126cba0f1b49c2928f276158b64d8ee7 (patch) | |
tree | 2d90199df90974be6a596eace3503281889c29f4 /src/ts | |
parent | f7b8378a6eb4b4c6c3461ff677723869c67a4753 (diff) | |
parent | 3195741ebcfc95f4622aebcdc23fc5b8630efe39 (diff) | |
download | dexon-sol-tools-f338c68f126cba0f1b49c2928f276158b64d8ee7.tar dexon-sol-tools-f338c68f126cba0f1b49c2928f276158b64d8ee7.tar.gz dexon-sol-tools-f338c68f126cba0f1b49c2928f276158b64d8ee7.tar.bz2 dexon-sol-tools-f338c68f126cba0f1b49c2928f276158b64d8ee7.tar.lz dexon-sol-tools-f338c68f126cba0f1b49c2928f276158b64d8ee7.tar.xz dexon-sol-tools-f338c68f126cba0f1b49c2928f276158b64d8ee7.tar.zst dexon-sol-tools-f338c68f126cba0f1b49c2928f276158b64d8ee7.zip |
Merge pull request #13 from 0xProject/getOrderHash
Port getOrderHash and write tests for it
Diffstat (limited to 'src/ts')
-rw-r--r-- | src/ts/0x.js.ts | 56 | ||||
-rw-r--r-- | src/ts/globals.d.ts | 5 | ||||
-rw-r--r-- | src/ts/types.ts | 17 | ||||
-rw-r--r-- | src/ts/utils/constants.ts | 3 |
4 files changed, 81 insertions, 0 deletions
diff --git a/src/ts/0x.js.ts b/src/ts/0x.js.ts index ead1f56df..ba922d3db 100644 --- a/src/ts/0x.js.ts +++ b/src/ts/0x.js.ts @@ -1,8 +1,12 @@ import * as BigNumber from 'bignumber.js'; +import * as BN from 'bn.js'; import * as ethUtil from 'ethereumjs-util'; +import * as ethABI from 'ethereumjs-abi'; import * as _ from 'lodash'; +import {constants} from './utils/constants'; import {assert} from './utils/assert'; import {ECSignatureSchema} from './schemas/ec_signature_schema'; +import {SolidityTypes} from './types'; /** * Elliptic Curve signature @@ -17,6 +21,48 @@ const MAX_DIGITS_IN_UNSIGNED_256_INT = 78; export class ZeroEx { /** + * Computes the orderHash given the order parameters and returns it as a hex encoded string. + */ + public static getOrderHashHex(exchangeContractAddr: string, makerAddr: string, takerAddr: string, + tokenMAddress: string, tokenTAddress: string, feeRecipient: string, + valueM: BigNumber.BigNumber, valueT: BigNumber.BigNumber, + makerFee: BigNumber.BigNumber, takerFee: BigNumber.BigNumber, + expiration: BigNumber.BigNumber, salt: BigNumber.BigNumber): string { + takerAddr = _.isEmpty(takerAddr) ? constants.NULL_ADDRESS : takerAddr ; + assert.isETHAddressHex('exchangeContractAddr', exchangeContractAddr); + assert.isETHAddressHex('makerAddr', makerAddr); + assert.isETHAddressHex('takerAddr', takerAddr); + assert.isETHAddressHex('tokenMAddress', tokenMAddress); + assert.isETHAddressHex('tokenTAddress', tokenTAddress); + assert.isETHAddressHex('feeRecipient', feeRecipient); + assert.isBigNumber('valueM', valueM); + assert.isBigNumber('valueT', valueT); + assert.isBigNumber('makerFee', makerFee); + assert.isBigNumber('takerFee', takerFee); + assert.isBigNumber('expiration', expiration); + assert.isBigNumber('salt', salt); + + const orderParts = [ + {value: exchangeContractAddr, type: SolidityTypes.address}, + {value: makerAddr, type: SolidityTypes.address}, + {value: takerAddr, type: SolidityTypes.address}, + {value: tokenMAddress, type: SolidityTypes.address}, + {value: tokenTAddress, type: SolidityTypes.address}, + {value: feeRecipient, type: SolidityTypes.address}, + {value: this.bigNumberToBN(valueM), type: SolidityTypes.uint256}, + {value: this.bigNumberToBN(valueT), type: SolidityTypes.uint256}, + {value: this.bigNumberToBN(makerFee), type: SolidityTypes.uint256}, + {value: this.bigNumberToBN(takerFee), type: SolidityTypes.uint256}, + {value: this.bigNumberToBN(expiration), type: SolidityTypes.uint256}, + {value: this.bigNumberToBN(salt), type: SolidityTypes.uint256}, + ]; + const types = _.map(orderParts, o => o.type); + const values = _.map(orderParts, o => o.value); + const hashBuff = ethABI.soliditySHA3(types, values); + const hashHex = ethUtil.bufferToHex(hashBuff); + return hashHex; + } + /** * Verifies that the elliptic curve signature `signature` was generated * by signing `data` with the private key corresponding to the `signerAddressHex` address. */ @@ -83,4 +129,14 @@ export class ZeroEx { const baseUnitAmount = amount.times(unit); return baseUnitAmount; } + + /** + * Converts BigNumber instance to BN + * The only we convert to BN is to remain compatible with `ethABI. soliditySHA3 ` that + * expects values of Solidity type `uint` to be of type `BN`. + * We do not use BN anywhere else in the codebase. + */ + private static bigNumberToBN(value: BigNumber.BigNumber) { + return new BN(value.toString(), 10); + } } diff --git a/src/ts/globals.d.ts b/src/ts/globals.d.ts index 796812c87..99baf593f 100644 --- a/src/ts/globals.d.ts +++ b/src/ts/globals.d.ts @@ -1,4 +1,5 @@ declare module 'chai-bignumber'; +declare module 'bn.js'; declare interface Schema { id: string; @@ -23,3 +24,7 @@ declare module 'ethereumjs-util' { const pubToAddress: (pubKey: string) => Buffer; const isValidAddress: (address: string) => boolean; } + +declare module 'ethereumjs-abi' { + const soliditySHA3: (argTypes: string[], args: any[]) => Buffer; +} diff --git a/src/ts/types.ts b/src/ts/types.ts new file mode 100644 index 000000000..04902cca6 --- /dev/null +++ b/src/ts/types.ts @@ -0,0 +1,17 @@ +import * as _ from 'lodash'; +import * as BigNumber from 'bignumber.js'; + +// Utility function to create a K:V from a list of strings +// Adapted from: https://basarat.gitbooks.io/typescript/content/docs/types/literal-types.html +function strEnum(values: string[]): {[key: string]: string} { + return _.reduce(values, (result, key) => { + result[key] = key; + return result; + }, Object.create(null)); +} + +export const SolidityTypes = strEnum([ + 'address', + 'uint256', +]); +export type SolidityTypes = keyof typeof SolidityTypes; diff --git a/src/ts/utils/constants.ts b/src/ts/utils/constants.ts new file mode 100644 index 000000000..60af7b674 --- /dev/null +++ b/src/ts/utils/constants.ts @@ -0,0 +1,3 @@ +export const constants = { + NULL_ADDRESS: '0x0000000000000000000000000000000000000000', +} |