aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Hysen <greg.hysen@gmail.com>2019-02-07 09:02:47 +0800
committerGreg Hysen <greg.hysen@gmail.com>2019-02-09 08:25:30 +0800
commitd9c4c74a56c913e90f3c76566c64950fec86063b (patch)
tree95acb4a0dc54ebe4e371f4ee02d68acf6d080447
parent5a231fb0575a00dfcf1237ec4e733cbeb96e984d (diff)
downloaddexon-0x-contracts-d9c4c74a56c913e90f3c76566c64950fec86063b.tar
dexon-0x-contracts-d9c4c74a56c913e90f3c76566c64950fec86063b.tar.gz
dexon-0x-contracts-d9c4c74a56c913e90f3c76566c64950fec86063b.tar.bz2
dexon-0x-contracts-d9c4c74a56c913e90f3c76566c64950fec86063b.tar.lz
dexon-0x-contracts-d9c4c74a56c913e90f3c76566c64950fec86063b.tar.xz
dexon-0x-contracts-d9c4c74a56c913e90f3c76566c64950fec86063b.tar.zst
dexon-0x-contracts-d9c4c74a56c913e90f3c76566c64950fec86063b.zip
Added tests for ZeroExTransactionDecoder
-rw-r--r--packages/contract-wrappers/src/utils/transaction_encoder.ts4
-rw-r--r--packages/contract-wrappers/src/utils/zeroex_transaction_decoder.ts8
-rw-r--r--packages/contract-wrappers/test/zeroex_transaction_decoder_test.ts210
-rw-r--r--packages/utils/src/address_utils.ts2
-rw-r--r--packages/utils/src/transaction_decoder.ts8
-rw-r--r--packages/utils/test/transaction_decoder_test.ts5
6 files changed, 167 insertions, 70 deletions
diff --git a/packages/contract-wrappers/src/utils/transaction_encoder.ts b/packages/contract-wrappers/src/utils/transaction_encoder.ts
index 5faa593a5..8bf67ee56 100644
--- a/packages/contract-wrappers/src/utils/transaction_encoder.ts
+++ b/packages/contract-wrappers/src/utils/transaction_encoder.ts
@@ -243,8 +243,8 @@ export class TransactionEncoder {
}
/**
* Encodes a matchOrders transaction.
- * @param leftOrder
- * @param rightOrder
+ * @param leftOrder First order to match.
+ * @param rightOrder Second order to match.
* @return Hex encoded abi of the function call.
*/
public matchOrdersTx(leftOrder: SignedOrder, rightOrder: SignedOrder): string {
diff --git a/packages/contract-wrappers/src/utils/zeroex_transaction_decoder.ts b/packages/contract-wrappers/src/utils/zeroex_transaction_decoder.ts
index 4a5a5809f..17f06497c 100644
--- a/packages/contract-wrappers/src/utils/zeroex_transaction_decoder.ts
+++ b/packages/contract-wrappers/src/utils/zeroex_transaction_decoder.ts
@@ -4,7 +4,13 @@ import { SimpleContractArtifact } from '@0x/types';
import { AbiDefinition, ContractAbi } from 'ethereum-types';
import * as _ from 'lodash';
-import { DeployedContractInfo, DeployedContractInfoByName, TransactionData, TransactionDecoder, TransactionProperties } from '@0x/utils';
+import {
+ DeployedContractInfo,
+ DeployedContractInfoByName,
+ TransactionData,
+ TransactionDecoder,
+ TransactionProperties,
+} from '@0x/utils';
export class ZeroExTransactionDecoder extends TransactionDecoder {
private static _instance: ZeroExTransactionDecoder;
diff --git a/packages/contract-wrappers/test/zeroex_transaction_decoder_test.ts b/packages/contract-wrappers/test/zeroex_transaction_decoder_test.ts
index e4fbb8b99..83c810c3a 100644
--- a/packages/contract-wrappers/test/zeroex_transaction_decoder_test.ts
+++ b/packages/contract-wrappers/test/zeroex_transaction_decoder_test.ts
@@ -1,100 +1,190 @@
+import { constants, OrderFactory } from '@0x/contracts-test-utils';
+import { BlockchainLifecycle } from '@0x/dev-utils';
import { assetDataUtils } from '@0x/order-utils';
+import { SignedOrder } from '@0x/types';
+import { AbiEncoder, addressUtils, BigNumber } from '@0x/utils';
import * as chai from 'chai';
-import 'mocha';
+import { MethodAbi } from 'ethereum-types';
import * as _ from 'lodash';
-import { addressUtils, BigNumber } from '@0x/utils';
-import { Web3Wrapper } from '@0x/web3-wrapper';
+import 'mocha';
-import {
- constants,
- OrderFactory,
- web3Wrapper,
-} from '@0x/contracts-test-utils';
-import { SignedOrder } from '@0x/types';
+import { ContractAddresses, ContractWrappers } from '../src';
+import { ZeroExTransactionDecoder } from '../src/utils/zeroex_transaction_decoder';
-import { TransactionEncoder, ZeroExTransactionDecoder } from '../src';
import { chaiSetup } from './utils/chai_setup';
+import { migrateOnceAsync } from './utils/migrate';
+import { provider, web3Wrapper } from './utils/web3_wrapper';
chaiSetup.configure();
const expect = chai.expect;
+const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
+
describe.only('ZeroExTransactionDecoder', () => {
- let orderFactory: OrderFactory;
- let defaultERC20MakerAssetAddress = addressUtils.generatePseudoRandomAddress();
- let defaultERC20TakerAssetAddress = addressUtils.generatePseudoRandomAddress();
+ const defaultERC20MakerAssetAddress = addressUtils.generatePseudoRandomAddress();
+ const matchOrdersSignature =
+ 'matchOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes),(address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes,bytes)';
let signedOrderLeft: SignedOrder;
- let signedOrderRifght: SignedOrder;
+ let signedOrderRight: SignedOrder;
+ let orderLeft = {};
+ let orderRight = {};
let matchOrdersTxData: string;
- const sampleMatchOrdersTxData = '0x3c28d861000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000500000000000000000000000000da912ecc847b3d98ca882e396e693e485deed5180000000000000000000000000681e844593a051e2882ec897ecd5444efe19ff20000000000000000000000008124071f810d533ff63de61d0c98db99eeb99d640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008bb6a7394e2f000000000000000000000000000000000000000000000000868cab59cce788000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c51035008197e43b4d84439ec534b62670eaaaf4a46f50ff37ff62f6d1c1fbe8b036d3c000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000503f9794d6a6bb0df8fbb19a2b3e2aeab35339ad000000000000000000000000000000000000000000000000000000000000000000000000000000003997d0f55d1daa549e95c240bc6353636f4cf9740000000000000000000000000681e844593a051e2882ec897ecd5444efe19ff20000000000000000000000008124071f810d533ff63de61d0c98db99eeb99d6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000871bcc4c32c9d66800000000000000000000000000000000000000000000000000008a70a4d2d2100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c510350c20e53540c9b2c9207ad9a04e472e2224af211f08efc2f0eec15d7e1cfbf2109000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000421c8f294b2728c269a9d01a1b58fe7cae2ef7895bd2de48cc3101eb47464d96594340924793fc8325db26a3abd5602605806a82ca77e810494c5ecab58b03449de80300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000421c372d6daa8e6ce2c696e51b6e1e33f10fd2b41b403cd88c311a617c3656ea02fe454e51cddf4682751bea9a02ce725cf364d1107f27be427d5157adbdcca2609b03000000000000000000000000000000000000000000000000000000000000';
+ let contractAddresses: ContractAddresses;
before(async () => {
// Create accounts
const accounts = await web3Wrapper.getAvailableAddressesAsync();
-
- let makerAddressLeft = addressUtils.generatePseudoRandomAddress();
- let makerAddressRight = addressUtils.generatePseudoRandomAddress();
+ const [makerAddressLeft, makerAddressRight] = accounts.slice(0, 2);
const exchangeAddress = addressUtils.generatePseudoRandomAddress();
- const feeRecipientAddress = addressUtils.generatePseudoRandomAddress();;
- // Create orders to match
- const defaultOrderParamsLeft = {
+ const feeRecipientAddress = addressUtils.generatePseudoRandomAddress();
+ const privateKeyLeft = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddressLeft)];
+ const privateKeyRight = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddressRight)];
+ // Create orders to match
+ orderLeft = {
makerAddress: makerAddressLeft,
- exchangeAddress,
makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
- takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
+ makerAssetAmount: new BigNumber(10),
+ takerAddress: '0x0000000000000000000000000000000000000000',
+ takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
+ takerAssetAmount: new BigNumber(1),
feeRecipientAddress,
+ makerFee: new BigNumber(0),
+ takerFee: new BigNumber(0),
+ senderAddress: '0x0000000000000000000000000000000000000000',
+ expirationTimeSeconds: new BigNumber(1549498915),
+ salt: new BigNumber(217),
};
- const defaultOrderParamsRight = {
+ orderRight = {
makerAddress: makerAddressRight,
- exchangeAddress,
- makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
+ makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
+ makerAssetAmount: new BigNumber(1),
+ takerAddress: '0x0000000000000000000000000000000000000000',
takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
+ takerAssetAmount: new BigNumber(8),
feeRecipientAddress,
+ makerFee: new BigNumber(0),
+ takerFee: new BigNumber(0),
+ senderAddress: '0x0000000000000000000000000000000000000000',
+ expirationTimeSeconds: new BigNumber(1549498915),
+ salt: new BigNumber(50010),
};
-
- 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);
+ const orderFactoryLeft = new OrderFactory(privateKeyLeft, orderLeft);
+ signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({ exchangeAddress });
+ const orderFactoryRight = new OrderFactory(privateKeyRight, orderRight);
+ signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ exchangeAddress });
+ // Encode match orders transaction
+ contractAddresses = await migrateOnceAsync();
+ await blockchainLifecycle.startAsync();
+ const config = {
+ networkId: constants.TESTRPC_NETWORK_ID,
+ contractAddresses,
+ blockPollingIntervalMs: 10,
+ };
+ const contractWrappers = new ContractWrappers(provider, config);
+ const transactionEncoder = await contractWrappers.exchange.transactionEncoderAsync();
+ matchOrdersTxData = transactionEncoder.matchOrdersTx(signedOrderLeft, signedOrderRight);
});
describe('decode', () => {
- /*
it('should successfully decode DutchAuction.matchOrders txData', async () => {
- const decodedTxData = ZeroExTransactionDecoder.decode(matchOrdersTxData, { contractName: 'DutchAuction' }); //{networkId: 1, contractAddress: '0x4f833a24e1f95d70f028921e27040ca56e09ab0b'});
- console.log(decodedTxData);
+ const contractName = 'DutchAuction';
+ const decodedTxData = ZeroExTransactionDecoder.decode(matchOrdersTxData, { contractName });
+ const expectedFunctionName = 'matchOrders';
+ const expectedFunctionArguments = {
+ buyOrder: orderLeft,
+ sellOrder: orderRight,
+ buySignature: signedOrderLeft.signature,
+ sellSignature: signedOrderRight.signature,
+ };
+ expect(decodedTxData.functionName).to.be.equal(expectedFunctionName);
+ expect(decodedTxData.functionSignature).to.be.equal(matchOrdersSignature);
+ expect(decodedTxData.functionArguments).to.be.deep.equal(expectedFunctionArguments);
});
- 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 txData (and distinguish from DutchAuction.matchOrders)', async () => {
+ const contractName = 'Exchange';
+ const decodedTxData = ZeroExTransactionDecoder.decode(matchOrdersTxData, { contractName });
+ const expectedFunctionName = 'matchOrders';
+ const expectedFunctionArguments = {
+ leftOrder: orderLeft,
+ rightOrder: orderRight,
+ leftSignature: signedOrderLeft.signature,
+ rightSignature: signedOrderRight.signature,
+ };
+ expect(decodedTxData.functionName).to.be.equal(expectedFunctionName);
+ expect(decodedTxData.functionSignature).to.be.equal(matchOrdersSignature);
+ expect(decodedTxData.functionArguments).to.be.deep.equal(expectedFunctionArguments);
});
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);
+ const contractAddress = contractAddresses.exchange;
+ const decodedTxData = ZeroExTransactionDecoder.decode(matchOrdersTxData, { contractAddress });
+ const expectedFunctionName = 'matchOrders';
+ const expectedFunctionArguments = {
+ leftOrder: orderLeft,
+ rightOrder: orderRight,
+ leftSignature: signedOrderLeft.signature,
+ rightSignature: signedOrderRight.signature,
+ };
+ expect(decodedTxData.functionName).to.be.equal(expectedFunctionName);
+ expect(decodedTxData.functionSignature).to.be.equal(matchOrdersSignature);
+ expect(decodedTxData.functionArguments).to.be.deep.equal(expectedFunctionArguments);
});
it('should throw if cannot decode txData', async () => {
- const decodedTxData = ZeroExTransactionDecoder.decode(matchOrdersTxData, {networkId: 1, contractAddress: '0x4f833a24e1f95d70f028921e27040ca56e09ab0b'});
- console.log(decodedTxData);
- });*/
+ const contractAddress = contractAddresses.exchange;
+ const badTxData = '0x01020304';
+ expect(() => {
+ ZeroExTransactionDecoder.decode(badTxData, { contractAddress });
+ }).to.throw("No functions registered for selector '0x01020304'");
+ });
});
describe('addABI', () => {
- /*it('should successfully add a new ABI', async () => {
- const decodedTxData = ZeroExTransactionDecoder.decode(matchOrdersTxData, { contractName: 'DutchAuction' }); //{networkId: 1, contractAddress: '0x4f833a24e1f95d70f028921e27040ca56e09ab0b'});
- console.log(decodedTxData);
- });*/
+ it('should successfully add a new ABI', async () => {
+ // Add new ABI
+ const abi: MethodAbi = {
+ name: 'foobar',
+ type: 'function',
+ inputs: [
+ {
+ name: 'addr',
+ type: 'address',
+ },
+ ],
+ outputs: [
+ {
+ name: 'butter',
+ type: 'string',
+ },
+ ],
+ constant: false,
+ payable: false,
+ stateMutability: 'pure',
+ };
+ const contractName = 'newContract';
+ const contractAddress = addressUtils.generatePseudoRandomAddress();
+ const networkId = 1;
+ const contractInfo = [
+ {
+ contractAddress,
+ networkId,
+ },
+ ];
+ ZeroExTransactionDecoder.addABI([abi], contractName, contractInfo);
+ // Create some tx data
+ const foobarEncoder = new AbiEncoder.Method(abi);
+ const foobarSignature = foobarEncoder.getSignature();
+ const foobarTxData = foobarEncoder.encode([contractAddress]);
+ // Decode tx data using contract name
+ const decodedTxData = ZeroExTransactionDecoder.decode(foobarTxData, { contractName });
+ const expectedFunctionName = abi.name;
+ const expectedFunctionArguments = {
+ addr: contractAddress,
+ };
+ expect(decodedTxData.functionName).to.be.equal(expectedFunctionName);
+ expect(decodedTxData.functionSignature).to.be.equal(foobarSignature);
+ expect(decodedTxData.functionArguments).to.be.deep.equal(expectedFunctionArguments);
+ // Decode tx data using contract address
+ const decodedTxDataDecodedWithAddress = ZeroExTransactionDecoder.decode(foobarTxData, { contractAddress });
+ expect(decodedTxDataDecodedWithAddress).to.be.deep.equal(decodedTxData);
+ });
});
});
diff --git a/packages/utils/src/address_utils.ts b/packages/utils/src/address_utils.ts
index 318504c37..b700cd944 100644
--- a/packages/utils/src/address_utils.ts
+++ b/packages/utils/src/address_utils.ts
@@ -65,5 +65,5 @@ export const addressUtils = {
const randomBuff = sha3(randomBigNum.toString());
const randomAddress = `0x${randomBuff.slice(0, 20).toString('hex')}`;
return randomAddress;
- }
+ },
};
diff --git a/packages/utils/src/transaction_decoder.ts b/packages/utils/src/transaction_decoder.ts
index 2c3b96c72..dd1b4d19a 100644
--- a/packages/utils/src/transaction_decoder.ts
+++ b/packages/utils/src/transaction_decoder.ts
@@ -30,7 +30,11 @@ export class TransactionDecoder {
* @param contractName Name of contract that encapsulates the ABI definitions (optional).
* @param deploymentInfos A collection of network/address pairs where this contract is deployed (optional).
*/
- public addABI(abiDefinitions: AbiDefinition[], contractName?: string, deploymentInfos?: DeployedContractInfo[]): void {
+ public addABI(
+ abiDefinitions: AbiDefinition[],
+ contractName?: string,
+ deploymentInfos?: DeployedContractInfo[],
+ ): void {
// Disregard definitions that are not functions
const functionAbis = _.filter(abiDefinitions, abiEntry => {
return abiEntry.type === 'function';
@@ -70,7 +74,7 @@ export class TransactionDecoder {
* @return Decoded transaction data. Includes: function name and signature, along with the decoded arguments.
*/
public decode(txData: string, txProperties_?: TransactionProperties): TransactionData {
- // Lookup
+ // Lookup
const functionSelector = TransactionDecoder._getFunctionSelector(txData);
const txProperties = _.isUndefined(txProperties_) ? {} : txProperties_;
const candidateFunctionInfos = this._functionInfoBySelector[functionSelector];
diff --git a/packages/utils/test/transaction_decoder_test.ts b/packages/utils/test/transaction_decoder_test.ts
index f214b1733..bc40f4840 100644
--- a/packages/utils/test/transaction_decoder_test.ts
+++ b/packages/utils/test/transaction_decoder_test.ts
@@ -1,12 +1,9 @@
import * as chai from 'chai';
import 'mocha';
-
import { chaiSetup } from './utils/chai_setup';
chaiSetup.configure();
const expect = chai.expect;
-describe.only('TransactionDecoder', () => {
-
-});
+describe.only('TransactionDecoder', () => {});