Refactor getOrderHash to accept order as an object

This commit is contained in:
Leonid Logvinov
2017-05-30 17:35:17 +02:00
parent 843ec2d4cf
commit be13cf127c
5 changed files with 61 additions and 78 deletions

View File

@@ -27,12 +27,11 @@
"build:umd:dev": "webpack",
"build:umd:prod": "webpack -p",
"build:commonjs:dev": "tsc; copyfiles -u 2 ./src/artifacts/*.json ../0x.js/lib/src/artifacts;",
"test:commonjs": "run-s build:commonjs:dev copy_fixtures run_mocha",
"test:commonjs": "run-s build:commonjs:dev run_mocha",
"pretest:umd": "run-s clean build:*:dev",
"substitute_umd_bundle": "npm run remove_src_files_not_used_by_tests; shx mv _bundles/* lib/src",
"remove_src_files_not_used_by_tests": "find ./lib/src \\( -path ./lib/src/utils -o -path ./lib/src/schemas -o -path \"./lib/src/types.*\" \\) -prune -o -type f -print | xargs rm",
"run_mocha": "mocha lib/test/**/*_test.js",
"copy_fixtures": "shx cp -r ./test/fixtures ./lib/test/fixtures"
"run_mocha": "mocha lib/test/**/*_test.js"
},
"config": {
"artifacts": "Proxy Exchange TokenRegistry Token Mintable EtherToken",

View File

@@ -14,6 +14,8 @@ import {ExchangeWrapper} from './contract_wrappers/exchange_wrapper';
import {TokenRegistryWrapper} from './contract_wrappers/token_registry_wrapper';
import {ecSignatureSchema} from './schemas/ec_signature_schema';
import {SolidityTypes, ECSignature, ZeroExError} from './types';
import {Order} from './types';
import {orderSchema} from "./schemas/signed_order_schema";
const MAX_DIGITS_IN_UNSIGNED_256_INT = 78;
@@ -24,38 +26,23 @@ 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);
public static getOrderHashHex(exchangeContractAddr: string, order: Order): string {
assert.doesConformToSchema('order', JSON.parse(JSON.stringify(order)), orderSchema);
const taker = _.isEmpty(order.taker) ? constants.NULL_ADDRESS : order.taker ;
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: utils.bigNumberToBN(valueM), type: SolidityTypes.uint256},
{value: utils.bigNumberToBN(valueT), type: SolidityTypes.uint256},
{value: utils.bigNumberToBN(makerFee), type: SolidityTypes.uint256},
{value: utils.bigNumberToBN(takerFee), type: SolidityTypes.uint256},
{value: utils.bigNumberToBN(expiration), type: SolidityTypes.uint256},
{value: utils.bigNumberToBN(salt), type: SolidityTypes.uint256},
{value: order.maker, type: SolidityTypes.address},
{value: order.taker, type: SolidityTypes.address},
{value: order.makerTokenAddress, type: SolidityTypes.address},
{value: order.takerTokenAddress, type: SolidityTypes.address},
{value: order.feeRecipient, type: SolidityTypes.address},
{value: utils.bigNumberToBN(order.makerTokenAmount), type: SolidityTypes.uint256},
{value: utils.bigNumberToBN(order.takerTokenAmount), type: SolidityTypes.uint256},
{value: utils.bigNumberToBN(order.makerFee), type: SolidityTypes.uint256},
{value: utils.bigNumberToBN(order.takerFee), type: SolidityTypes.uint256},
{value: utils.bigNumberToBN(order.expirationUnixTimestampSec), type: SolidityTypes.uint256},
{value: utils.bigNumberToBN(order.salt), type: SolidityTypes.uint256},
];
const types = _.map(orderParts, o => o.type);
const values = _.map(orderParts, o => o.value);

View File

@@ -7,6 +7,7 @@ import * as Sinon from 'sinon';
import {ZeroEx} from '../src/0x.js';
import {constants} from './utils/constants';
import {web3Factory} from './utils/web3_factory';
import {Order} from '../src/types';
// Use BigNumber chai add-on
chai.use(ChaiBigNumber());
@@ -43,38 +44,28 @@ describe('ZeroEx library', () => {
});
describe('#getOrderHash', () => {
const expectedOrderHash = '0x103a5e97dab5dbeb8f385636f86a7d1e458a7ccbe1bd194727f0b2f85ab116c7';
const order: Order = {
maker: constants.NULL_ADDRESS,
feeRecipient: constants.NULL_ADDRESS,
makerTokenAddress: constants.NULL_ADDRESS,
takerTokenAddress: constants.NULL_ADDRESS,
salt: new BigNumber(0),
makerFee: new BigNumber(0),
takerFee: new BigNumber(0),
makerTokenAmount: new BigNumber(0),
takerTokenAmount: new BigNumber(0),
expirationUnixTimestampSec: new BigNumber(0),
};
const exchangeAddress = constants.NULL_ADDRESS;
it('defaults takerAddress to NULL address', () => {
const orderHash = ZeroEx.getOrderHashHex(
constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
'',
constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
new BigNumber(0),
new BigNumber(0),
new BigNumber(0),
new BigNumber(0),
new BigNumber(0),
new BigNumber(0),
);
const orderHash = ZeroEx.getOrderHashHex(exchangeAddress, order);
expect(orderHash).to.be.equal(expectedOrderHash);
});
it('calculates the order hash', () => {
const orderHash = ZeroEx.getOrderHashHex(
constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
new BigNumber(0),
new BigNumber(0),
new BigNumber(0),
new BigNumber(0),
new BigNumber(0),
new BigNumber(0),
);
const orderWithZeroTaker = _.assign(order, {
taker: constants.NULL_ADDRESS,
});
const orderHash = ZeroEx.getOrderHashHex(exchangeAddress, orderWithZeroTaker);
expect(orderHash).to.be.equal(expectedOrderHash);
});
});

View File

@@ -4,9 +4,8 @@ import chaiAsPromised = require('chai-as-promised');
import {web3Factory} from './utils/web3_factory';
import {ZeroEx} from '../src/0x.js';
import {BlockchainLifecycle} from './utils/blockchain_lifecycle';
import * as OrderJSON from './fixtures/orders/5_MLN_for_42_GLM.json';
import * as BigNumber from 'bignumber.js';
import {signedOrderFromJSON} from './utils/order';
import {createSignedOrder} from './utils/order';
const expect = chai.expect;
chai.use(chaiAsPromised);
@@ -94,8 +93,8 @@ describe('ExchangeWrapper', () => {
expect(isValid).to.be.true;
});
});
describe('#fillOrderAsync', () => {
const signedOrder = signedOrderFromJSON(OrderJSON);
describe('#fillOrderAsync', async () => {
const signedOrder = await createSignedOrder(zeroEx);
it('should throw when the fill amount is zero', async () => {
const fillAmount = new BigNumber(0);
expect(zeroEx.exchange.fillOrderAsync(signedOrder, fillAmount))

View File

@@ -1,21 +1,28 @@
import {SignedOrder} from '../../src/types';
import * as BigNumber from 'bignumber.js';
import * as _ from 'lodash';
import {ZeroEx} from '../../src/0x.js';
import {constants} from './constants';
export function signedOrderFromJSON(signedOrderJSON: any): SignedOrder {
const signedOrder = {
maker: signedOrderJSON.maker.address,
taker: _.isEmpty(signedOrderJSON.taker.address) ? undefined : signedOrderJSON.taker.address,
makerTokenAddress: signedOrderJSON.maker.token.address,
takerTokenAddress: signedOrderJSON.taker.token.address,
makerTokenAmount: new BigNumber(signedOrderJSON.maker.amount),
takerTokenAmount: new BigNumber(signedOrderJSON.taker.amount),
makerFee: new BigNumber(signedOrderJSON.maker.feeAmount),
takerFee: new BigNumber(signedOrderJSON.taker.feeAmount),
expirationUnixTimestampSec: new BigNumber(signedOrderJSON.expiration),
feeRecipient: signedOrderJSON.feeRecipient,
ecSignature: signedOrderJSON.signature,
salt: new BigNumber(signedOrderJSON.salt),
export async function createSignedOrder(zeroEx: ZeroEx): Promise<SignedOrder> {
// TODO: fetch properly
const EXCHANGE_ADDRESS = '0xb69e673309512a9d726f87304c6984054f87a93b';
const INF_TIMESTAMP = 2524604400;
const order = {
maker: '0x5409ed021d9299bf6814279a6a1411a7e866a631',
taker: undefined,
makerFee: new BigNumber(0),
takerFee: new BigNumber(0),
makerTokenAmount: new BigNumber(5000000000000000000),
takerTokenAmount: new BigNumber(42000000000000000000),
makerTokenAddress: '0x07f96aa816c1f244cbc6ef114bb2b023ba54a2eb',
takerTokenAddress: '0x1e2f9e10d02a6b8f8f69fcbf515e75039d2ea30d',
salt: ZeroEx.generatePseudoRandomSalt(),
feeRecipient: constants.NULL_ADDRESS,
expirationUnixTimestampSec: new BigNumber(INF_TIMESTAMP),
};
const orderHash = ZeroEx.getOrderHashHex(EXCHANGE_ADDRESS, order);
const ecSignature = await zeroEx.signOrderHashAsync(orderHash);
const signedOrder: SignedOrder = _.assign(order, {ecSignature});
return signedOrder;
}