aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Hysen <greg.hysen@gmail.com>2019-02-01 09:55:23 +0800
committerGreg Hysen <greg.hysen@gmail.com>2019-02-09 08:25:30 +0800
commit5a231fb0575a00dfcf1237ec4e733cbeb96e984d (patch)
tree5121cac79bb8deb78ac4fa60c7d1d0eac8b8e35e
parent63f41df3272060bf44924c586fd882595428eff6 (diff)
downloaddexon-0x-contracts-5a231fb0575a00dfcf1237ec4e733cbeb96e984d.tar
dexon-0x-contracts-5a231fb0575a00dfcf1237ec4e733cbeb96e984d.tar.gz
dexon-0x-contracts-5a231fb0575a00dfcf1237ec4e733cbeb96e984d.tar.bz2
dexon-0x-contracts-5a231fb0575a00dfcf1237ec4e733cbeb96e984d.tar.lz
dexon-0x-contracts-5a231fb0575a00dfcf1237ec4e733cbeb96e984d.tar.xz
dexon-0x-contracts-5a231fb0575a00dfcf1237ec4e733cbeb96e984d.tar.zst
dexon-0x-contracts-5a231fb0575a00dfcf1237ec4e733cbeb96e984d.zip
Prep for txData decoder tests
-rw-r--r--packages/contract-wrappers/src/utils/transaction_encoder.ts17
-rw-r--r--packages/contract-wrappers/test/zeroex_transaction_decoder_test.ts88
-rw-r--r--packages/utils/src/address_utils.ts25
-rw-r--r--packages/utils/src/index.ts1
-rw-r--r--packages/utils/src/transaction_decoder.ts6
-rw-r--r--packages/utils/test/transaction_decoder_test.ts13
6 files changed, 130 insertions, 20 deletions
diff --git a/packages/contract-wrappers/src/utils/transaction_encoder.ts b/packages/contract-wrappers/src/utils/transaction_encoder.ts
index 307487a9b..5faa593a5 100644
--- a/packages/contract-wrappers/src/utils/transaction_encoder.ts
+++ b/packages/contract-wrappers/src/utils/transaction_encoder.ts
@@ -242,6 +242,23 @@ export class TransactionEncoder {
return abiEncodedData;
}
/**
+ * Encodes a matchOrders transaction.
+ * @param leftOrder
+ * @param rightOrder
+ * @return Hex encoded abi of the function call.
+ */
+ public matchOrdersTx(leftOrder: SignedOrder, rightOrder: SignedOrder): string {
+ assert.doesConformToSchema('order', leftOrder, schemas.orderSchema);
+ assert.doesConformToSchema('order', rightOrder, schemas.orderSchema);
+ const abiEncodedData = this._getExchangeContract().matchOrders.getABIEncodedTransactionData(
+ leftOrder,
+ rightOrder,
+ leftOrder.signature,
+ rightOrder.signature,
+ );
+ return abiEncodedData;
+ }
+ /**
* Encodes a preSign transaction.
* @param hash Hash to pre-sign
* @param signerAddress Address that should have signed the given hash.
diff --git a/packages/contract-wrappers/test/zeroex_transaction_decoder_test.ts b/packages/contract-wrappers/test/zeroex_transaction_decoder_test.ts
index 7ac507076..e4fbb8b99 100644
--- a/packages/contract-wrappers/test/zeroex_transaction_decoder_test.ts
+++ b/packages/contract-wrappers/test/zeroex_transaction_decoder_test.ts
@@ -1,20 +1,100 @@
+import { assetDataUtils } from '@0x/order-utils';
import * as chai from 'chai';
import 'mocha';
+import * as _ from 'lodash';
+import { addressUtils, BigNumber } from '@0x/utils';
+import { Web3Wrapper } from '@0x/web3-wrapper';
-import { ZeroExTransactionDecoder } from '../src';
+import {
+ constants,
+ OrderFactory,
+ web3Wrapper,
+} from '@0x/contracts-test-utils';
+import { SignedOrder } from '@0x/types';
+
+import { TransactionEncoder, ZeroExTransactionDecoder } from '../src';
import { chaiSetup } from './utils/chai_setup';
chaiSetup.configure();
const expect = chai.expect;
describe.only('ZeroExTransactionDecoder', () => {
+ let orderFactory: OrderFactory;
+ let defaultERC20MakerAssetAddress = addressUtils.generatePseudoRandomAddress();
+ let defaultERC20TakerAssetAddress = addressUtils.generatePseudoRandomAddress();
+ let signedOrderLeft: SignedOrder;
+ let signedOrderRifght: SignedOrder;
+ let matchOrdersTxData: string;
const sampleMatchOrdersTxData = '0x3c28d861000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000500000000000000000000000000da912ecc847b3d98ca882e396e693e485deed5180000000000000000000000000681e844593a051e2882ec897ecd5444efe19ff20000000000000000000000008124071f810d533ff63de61d0c98db99eeb99d640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008bb6a7394e2f000000000000000000000000000000000000000000000000868cab59cce788000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c51035008197e43b4d84439ec534b62670eaaaf4a46f50ff37ff62f6d1c1fbe8b036d3c000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000503f9794d6a6bb0df8fbb19a2b3e2aeab35339ad000000000000000000000000000000000000000000000000000000000000000000000000000000003997d0f55d1daa549e95c240bc6353636f4cf9740000000000000000000000000681e844593a051e2882ec897ecd5444efe19ff20000000000000000000000008124071f810d533ff63de61d0c98db99eeb99d6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000871bcc4c32c9d66800000000000000000000000000000000000000000000000000008a70a4d2d2100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c510350c20e53540c9b2c9207ad9a04e472e2224af211f08efc2f0eec15d7e1cfbf2109000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000421c8f294b2728c269a9d01a1b58fe7cae2ef7895bd2de48cc3101eb47464d96594340924793fc8325db26a3abd5602605806a82ca77e810494c5ecab58b03449de80300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000421c372d6daa8e6ce2c696e51b6e1e33f10fd2b41b403cd88c311a617c3656ea02fe454e51cddf4682751bea9a02ce725cf364d1107f27be427d5157adbdcca2609b03000000000000000000000000000000000000000000000000000000000000';
+ before(async () => {
+ // Create accounts
+ const accounts = await web3Wrapper.getAvailableAddressesAsync();
+
+ let makerAddressLeft = addressUtils.generatePseudoRandomAddress();
+ let makerAddressRight = addressUtils.generatePseudoRandomAddress();
+ const exchangeAddress = addressUtils.generatePseudoRandomAddress();
+ const feeRecipientAddress = addressUtils.generatePseudoRandomAddress();;
+ // Create orders to match
+ const defaultOrderParamsLeft = {
+ makerAddress: makerAddressLeft,
+ exchangeAddress,
+ makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
+ takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
+ feeRecipientAddress,
+ };
+ const defaultOrderParamsRight = {
+ makerAddress: makerAddressRight,
+ exchangeAddress,
+ makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
+ takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
+ feeRecipientAddress,
+ };
+
+ const privateKeyLeft = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddressLeft)];
+ const orderFactoryLeft = new OrderFactory(privateKeyLeft, defaultOrderParamsLeft);
+ const privateKeyRight = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddressRight)];
+ const orderFactoryRight = new OrderFactory(privateKeyRight, defaultOrderParamsRight);
+
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
+ takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
+ makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
+ takerAssetAmount: new BigNumber(1),
+ });
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
+ makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
+ makerAssetAmount: new BigNumber(1),
+ takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(8), 18),
+ });
+
+
+ //matchOrdersTxData = TransactionEncoder.matchOrdersTx(signedOrderLeft, signedOrderRight);
+ });
+
describe('decode', () => {
- it('should successfully decode matchOrders txData', async () => {
- const expected
- const decodedTxData = ZeroExTransactionDecoder.decode(calldata, { contractName: 'Dutchauction' }); //{networkId: 1, contractAddress: '0x4f833a24e1f95d70f028921e27040ca56e09ab0b'});
+ /*
+ it('should successfully decode DutchAuction.matchOrders txData', async () => {
+ const decodedTxData = ZeroExTransactionDecoder.decode(matchOrdersTxData, { contractName: 'DutchAuction' }); //{networkId: 1, contractAddress: '0x4f833a24e1f95d70f028921e27040ca56e09ab0b'});
console.log(decodedTxData);
});
+ it('should successfully decode Exchange.matchOrders txData', async () => {
+ const decodedTxData = ZeroExTransactionDecoder.decode(matchOrdersTxData, { contractName: 'Exchange' }); //{networkId: 1, contractAddress: '0x4f833a24e1f95d70f028921e27040ca56e09ab0b'});
+ console.log(decodedTxData);
+ });
+ it('should successfully decode Exchange.matchOrders, using exchange address to identify the exchange contract', async () => {
+ const decodedTxData = ZeroExTransactionDecoder.decode(matchOrdersTxData, {networkId: 1, contractAddress: '0x4f833a24e1f95d70f028921e27040ca56e09ab0b'});
+ console.log(decodedTxData);
+ });
+ it('should throw if cannot decode txData', async () => {
+ const decodedTxData = ZeroExTransactionDecoder.decode(matchOrdersTxData, {networkId: 1, contractAddress: '0x4f833a24e1f95d70f028921e27040ca56e09ab0b'});
+ console.log(decodedTxData);
+ });*/
+ });
+
+ describe('addABI', () => {
+ /*it('should successfully add a new ABI', async () => {
+ const decodedTxData = ZeroExTransactionDecoder.decode(matchOrdersTxData, { contractName: 'DutchAuction' }); //{networkId: 1, contractAddress: '0x4f833a24e1f95d70f028921e27040ca56e09ab0b'});
+ console.log(decodedTxData);
+ });*/
});
});
diff --git a/packages/utils/src/address_utils.ts b/packages/utils/src/address_utils.ts
index 1fc960408..318504c37 100644
--- a/packages/utils/src/address_utils.ts
+++ b/packages/utils/src/address_utils.ts
@@ -1,10 +1,13 @@
-import { addHexPrefix, stripHexPrefix } from 'ethereumjs-util';
+import { addHexPrefix, stripHexPrefix, sha3 } from 'ethereumjs-util';
import * as jsSHA3 from 'js-sha3';
import * as _ from 'lodash';
+import { BigNumber } from './configured_bignumber';
+
const BASIC_ADDRESS_REGEX = /^(0x)?[0-9a-f]{40}$/i;
const SAME_CASE_ADDRESS_REGEX = /^(0x)?([0-9a-f]{40}|[0-9A-F]{40})$/;
const ADDRESS_LENGTH = 40;
+const MAX_DIGITS_IN_UNSIGNED_256_INT = 78;
export const addressUtils = {
isChecksumAddress(address: string): boolean {
@@ -43,4 +46,24 @@ export const addressUtils = {
padZeros(address: string): string {
return addHexPrefix(_.padStart(stripHexPrefix(address), ADDRESS_LENGTH, '0'));
},
+ /**
+ * Generates a pseudo-random 256-bit salt.
+ * The salt can be included in a 0x order, ensuring that the order generates a unique orderHash
+ * and will not collide with other outstanding orders that are identical in all other parameters.
+ * @return A pseudo-random 256-bit number that can be used as a salt.
+ */
+ generatePseudoRandomSalt(): BigNumber {
+ // BigNumber.random returns a pseudo-random number between 0 & 1 with a passed in number of decimal places.
+ // Source: https://mikemcl.github.io/bignumber.js/#random
+ const randomNumber = BigNumber.random(MAX_DIGITS_IN_UNSIGNED_256_INT);
+ const factor = new BigNumber(10).pow(MAX_DIGITS_IN_UNSIGNED_256_INT - 1);
+ const salt = randomNumber.times(factor);
+ return salt;
+ },
+ generatePseudoRandomAddress(): string {
+ const randomBigNum = addressUtils.generatePseudoRandomSalt();
+ const randomBuff = sha3(randomBigNum.toString());
+ const randomAddress = `0x${randomBuff.slice(0, 20).toString('hex')}`;
+ return randomAddress;
+ }
};
diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts
index c0f15f2ab..6f1c14c83 100644
--- a/packages/utils/src/index.ts
+++ b/packages/utils/src/index.ts
@@ -13,4 +13,3 @@ export { signTypedDataUtils } from './sign_typed_data_utils';
export import AbiEncoder = require('./abi_encoder');
export * from './types';
export { TransactionDecoder } from './transaction_decoder';
-export { ZeroExTransactionDecoder } from './zeroex_transaction_decoder';
diff --git a/packages/utils/src/transaction_decoder.ts b/packages/utils/src/transaction_decoder.ts
index 1ce2ea3b0..2c3b96c72 100644
--- a/packages/utils/src/transaction_decoder.ts
+++ b/packages/utils/src/transaction_decoder.ts
@@ -18,7 +18,7 @@ export class TransactionDecoder {
`Malformed transaction data. Must include a hex prefix '0x' and 4-byte function selector. Got '${txData}'`,
);
}
- const functionSelector = calldata.substr(0, functionSelectorLength);
+ const functionSelector = txData.substr(0, functionSelectorLength);
return functionSelector;
}
/**
@@ -32,9 +32,9 @@ export class TransactionDecoder {
*/
public addABI(abiDefinitions: AbiDefinition[], contractName?: string, deploymentInfos?: DeployedContractInfo[]): void {
// Disregard definitions that are not functions
- const functionAbis: MethodAbi[] = _.filter(abiDefinitions, abiEntry => {
+ const functionAbis = _.filter(abiDefinitions, abiEntry => {
return abiEntry.type === 'function';
- });
+ }) as MethodAbi[];
// Record function ABI's
_.each(functionAbis, functionAbi => {
const abiEncoder = new AbiEncoder.Method(functionAbi);
diff --git a/packages/utils/test/transaction_decoder_test.ts b/packages/utils/test/transaction_decoder_test.ts
index eee712e98..f214b1733 100644
--- a/packages/utils/test/transaction_decoder_test.ts
+++ b/packages/utils/test/transaction_decoder_test.ts
@@ -1,21 +1,12 @@
import * as chai from 'chai';
import 'mocha';
-import { ZeroExTransactionDecoder } from '../src';
+
import { chaiSetup } from './utils/chai_setup';
chaiSetup.configure();
const expect = chai.expect;
describe.only('TransactionDecoder', () => {
- describe('decode', () => {
- it('should successfull decode fillOrder calldata', async () => {
- //const cancelCalldata = '0xd46b02c3000000000000000000000000000000000000000000000000000000000000002000000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a258b39954cef5cb142fd567a46cddb31a6701240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000071d75ab9b9204fffc40000000000000000000000000000000000000000000000011c6e19c53d35b66200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c50f2ed000000000000000000000000000000000000000000000000000001689c2bc812000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000024f47261b000000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000';
- //const marketBuycalldata = '0xe5fa431b0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000012309ce5400000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000008c26348f63f9e008f0dd09a0ce1ed7caf6c1366b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000005e150a33ffa97a8d22f59c77ae5487b089ef62e90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000001323e717ba3800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006ea9bd19a0c4b5533ac98f58db0558a96e15ec5f71d64b6070cea4b5df10b7fb35424035000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000024f47261b00000000000000000000000006cb262679c522c4f0834041a6248e8feb35f0337000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000421c750cedbf0eef0914c09b296f08462c363527f454bcf2dfaaf2f772e290d0ee5b0417d8b95837cbe501494195edc2a5a48c664d2ef74a340e40213c05db8767fa03000000000000000000000000000000000000000000000000000000000000';
- const calldata =
- '0x3c28d861000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000500000000000000000000000000da912ecc847b3d98ca882e396e693e485deed5180000000000000000000000000681e844593a051e2882ec897ecd5444efe19ff20000000000000000000000008124071f810d533ff63de61d0c98db99eeb99d640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008bb6a7394e2f000000000000000000000000000000000000000000000000868cab59cce788000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c51035008197e43b4d84439ec534b62670eaaaf4a46f50ff37ff62f6d1c1fbe8b036d3c000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000503f9794d6a6bb0df8fbb19a2b3e2aeab35339ad000000000000000000000000000000000000000000000000000000000000000000000000000000003997d0f55d1daa549e95c240bc6353636f4cf9740000000000000000000000000681e844593a051e2882ec897ecd5444efe19ff20000000000000000000000008124071f810d533ff63de61d0c98db99eeb99d6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000871bcc4c32c9d66800000000000000000000000000000000000000000000000000008a70a4d2d2100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c510350c20e53540c9b2c9207ad9a04e472e2224af211f08efc2f0eec15d7e1cfbf2109000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000421c8f294b2728c269a9d01a1b58fe7cae2ef7895bd2de48cc3101eb47464d96594340924793fc8325db26a3abd5602605806a82ca77e810494c5ecab58b03449de80300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000421c372d6daa8e6ce2c696e51b6e1e33f10fd2b41b403cd88c311a617c3656ea02fe454e51cddf4682751bea9a02ce725cf364d1107f27be427d5157adbdcca2609b03000000000000000000000000000000000000000000000000000000000000';
- const decodedTxData = ZeroExTransactionDecoder.decode(calldata, { contractName: 'Dutchauction' }); //{networkId: 1, contractAddress: '0x4f833a24e1f95d70f028921e27040ca56e09ab0b'});
- console.log(decodedTxData);
- });
- });
+
});