Abstractd out ZeroExTransactionDecoder
This commit is contained in:
parent
f93cd1bb48
commit
a9f8e80b1c
@ -2,10 +2,22 @@
|
|||||||
|
|
||||||
import * as ContractArtifacts from '@0x/contract-artifacts';
|
import * as ContractArtifacts from '@0x/contract-artifacts';
|
||||||
import { SimpleContractArtifact } from '@0x/types';
|
import { SimpleContractArtifact } from '@0x/types';
|
||||||
import { ContractAbi, MethodAbi } from 'ethereum-types';
|
import { AbiDefinition, ContractAbi, MethodAbi } from 'ethereum-types';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import { AbiEncoder } from '.';
|
import { AbiEncoder } from '.';
|
||||||
import { ContractAddresses, getContractAddressesForNetworkOrThrow, NetworkId } from '@0x/contract-addresses';
|
import { getContractAddressesForNetworkOrThrow, NetworkId } from '@0x/contract-addresses';
|
||||||
|
|
||||||
|
export interface FunctionInfo {
|
||||||
|
functionSignature: string;
|
||||||
|
contractName?: string;
|
||||||
|
contractAddress?: string;
|
||||||
|
networkId?: number;
|
||||||
|
abiEncoder?: AbiEncoder.Method;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FunctionInfoBySelector {
|
||||||
|
[index: string]: FunctionInfo[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface DecodedCalldata {
|
export interface DecodedCalldata {
|
||||||
functionName: string;
|
functionName: string;
|
||||||
@ -13,61 +25,110 @@ export interface DecodedCalldata {
|
|||||||
functionArguments: any;
|
functionArguments: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AbiEncoderBySelectorElement {
|
|
||||||
abiEncoder: AbiEncoder.Method;
|
|
||||||
contractName?: string;
|
|
||||||
contractAddress?: string;
|
|
||||||
networkId?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TransactionDecoderInfo {
|
|
||||||
abiEncoder: AbiEncoder.Method;
|
|
||||||
contractName?: string;
|
|
||||||
contractAddress?: string;
|
|
||||||
networkId?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TransactionProperties {
|
interface TransactionProperties {
|
||||||
contractName?: string;
|
contractName?: string;
|
||||||
contractAddress?: string;
|
contractAddress?: string;
|
||||||
networkId?: number;
|
networkId?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AbiEncoderByNeworkId {
|
|
||||||
[index: string]: AbiEncoderBySelectorElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface AbiEncoderBySelector {
|
|
||||||
[index: string]: AbiEncoderByNeworkId;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DeployedContractInfo {
|
interface DeployedContractInfo {
|
||||||
contractAddress?: string;
|
contractAddress: string;
|
||||||
networkId?: number;
|
networkId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DeployedContractInfoByName {
|
interface DeployedContractInfoByName {
|
||||||
[index: string]: DeployedContractInfo[];
|
[index: string]: DeployedContractInfo[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TransactionDecodersBySelector {
|
export class TransactionDecoder {
|
||||||
[index: string]: TransactionDecoderInfo[];
|
private _functionInfoBySelector: FunctionInfoBySelector = {};
|
||||||
|
|
||||||
|
private static getFunctionSelector(calldata: string): string {
|
||||||
|
if (!calldata.startsWith('0x') || calldata.length < 10) {
|
||||||
|
throw new Error(`Malformed calldata. Must include hex prefix '0x' and 4-byte function selector. Got '${calldata}'`);
|
||||||
|
}
|
||||||
|
const functionSelector = calldata.substr(0, 10);
|
||||||
|
return functionSelector;
|
||||||
|
}
|
||||||
|
|
||||||
|
public addABI(abiArray: AbiDefinition[], contractName: string, deploymentInfos?: DeployedContractInfo[]): void {
|
||||||
|
if (_.isEmpty(abiArray)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const functionAbis = _.filter(abiArray, abiEntry => {
|
||||||
|
return abiEntry.type === 'function';
|
||||||
|
}) as MethodAbi[];
|
||||||
|
_.each(functionAbis, functionAbi => {
|
||||||
|
const abiEncoder = new AbiEncoder.Method(functionAbi);
|
||||||
|
const functionSelector = abiEncoder.getSelector();
|
||||||
|
if (!(functionSelector in this._functionInfoBySelector)) {
|
||||||
|
this._functionInfoBySelector[functionSelector] = [];
|
||||||
|
}
|
||||||
|
// Recored deployed versions of this decoder
|
||||||
|
const functionSignature = abiEncoder.getSignature();
|
||||||
|
_.each(deploymentInfos, deploymentInfo => {
|
||||||
|
this._functionInfoBySelector[functionSelector].push({
|
||||||
|
functionSignature,
|
||||||
|
abiEncoder,
|
||||||
|
contractName,
|
||||||
|
contractAddress: deploymentInfo.contractAddress,
|
||||||
|
networkId: deploymentInfo.networkId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// If there isn't a deployed version of this contract, record it without address/network id
|
||||||
|
if (_.isEmpty(deploymentInfos)) {
|
||||||
|
this._functionInfoBySelector[functionSelector].push({
|
||||||
|
functionSignature,
|
||||||
|
abiEncoder,
|
||||||
|
contractName,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public decode(calldata: string, txProperties_?: TransactionProperties): DecodedCalldata {
|
||||||
|
const functionSelector = TransactionDecoder.getFunctionSelector(calldata);
|
||||||
|
const txProperties = _.isUndefined(txProperties_) ? {} : txProperties_;
|
||||||
|
|
||||||
|
const candidateFunctionInfos = this._functionInfoBySelector[functionSelector];
|
||||||
|
if (_.isUndefined(candidateFunctionInfos)) {
|
||||||
|
throw new Error(`No functions registered for selector '${functionSelector}'`);
|
||||||
|
}
|
||||||
|
const functionInfo = _.find(candidateFunctionInfos, (txDecoder) => {
|
||||||
|
return (_.isUndefined(txProperties.contractName) || _.toLower(txDecoder.contractName) === _.toLower(txProperties.contractName)) &&
|
||||||
|
(_.isUndefined(txProperties.contractAddress) || txDecoder.contractAddress === txProperties.contractAddress) &&
|
||||||
|
(_.isUndefined(txProperties.networkId) || txDecoder.networkId === txProperties.networkId);
|
||||||
|
});
|
||||||
|
if (_.isUndefined(functionInfo)) {
|
||||||
|
throw new Error(`No function registered with properties: ${JSON.stringify(txProperties)}.`);
|
||||||
|
} else if (_.isUndefined(functionInfo.abiEncoder)) {
|
||||||
|
throw new Error(`Function ABI Encoder is not defined, for function with properties: ${JSON.stringify(txProperties)}.`);
|
||||||
|
}
|
||||||
|
const functionName = functionInfo.abiEncoder.getDataItem().name;
|
||||||
|
const functionSignature = functionInfo.abiEncoder.getSignatureType();
|
||||||
|
const functionArguments = functionInfo.abiEncoder.decode(calldata);
|
||||||
|
const decodedCalldata = {
|
||||||
|
functionName,
|
||||||
|
functionSignature,
|
||||||
|
functionArguments
|
||||||
|
}
|
||||||
|
return decodedCalldata;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CalldataDecoder {
|
export class ZeroExTransactionDecoder extends TransactionDecoder {
|
||||||
private readonly _deployedContractInfoByName = {} as DeployedContractInfoByName;
|
private readonly _deployedContractInfoByName = {} as DeployedContractInfoByName;
|
||||||
private readonly _abiEncoderBySelector: AbiEncoderBySelector = {};
|
private static _instance: ZeroExTransactionDecoder;
|
||||||
private readonly _txDecoders: TransactionDecodersBySelector = {};
|
|
||||||
private static _instance: CalldataDecoder;
|
|
||||||
|
|
||||||
public static getInstance(): CalldataDecoder {
|
private static getInstance(): ZeroExTransactionDecoder {
|
||||||
if (!CalldataDecoder._instance) {
|
if (!ZeroExTransactionDecoder._instance) {
|
||||||
CalldataDecoder._instance = new CalldataDecoder();
|
ZeroExTransactionDecoder._instance = new ZeroExTransactionDecoder();
|
||||||
}
|
}
|
||||||
return CalldataDecoder._instance;
|
return ZeroExTransactionDecoder._instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private constructor() {
|
private constructor() {
|
||||||
|
super();
|
||||||
// Load addresses by contract name
|
// Load addresses by contract name
|
||||||
_.each(NetworkId, (networkId: any) => {
|
_.each(NetworkId, (networkId: any) => {
|
||||||
if (typeof networkId !== 'number') return;
|
if (typeof networkId !== 'number') return;
|
||||||
@ -87,66 +148,18 @@ export class CalldataDecoder {
|
|||||||
const contractName = conractArtifact.contractName;
|
const contractName = conractArtifact.contractName;
|
||||||
const contractNameLowercase = _.toLower(contractName);
|
const contractNameLowercase = _.toLower(contractName);
|
||||||
const contractAbi: ContractAbi = conractArtifact.compilerOutput.abi;
|
const contractAbi: ContractAbi = conractArtifact.compilerOutput.abi;
|
||||||
const functionAbis = _.filter(contractAbi, (abiEntry) => {return abiEntry.type === 'function'}) as MethodAbi[];
|
this.addABI(contractAbi, contractName, this._deployedContractInfoByName[contractNameLowercase]);
|
||||||
_.each(functionAbis, (functionAbi) => {
|
|
||||||
const abiEncoder = new AbiEncoder.Method(functionAbi);
|
|
||||||
const functionSelector = abiEncoder.getSelector();
|
|
||||||
if (_.has(this._abiEncoderBySelector, functionSelector)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!(functionSelector in this._txDecoders)) this._txDecoders[functionSelector] = [];
|
|
||||||
// Recored deployed versions of this decoder
|
|
||||||
_.each(this._deployedContractInfoByName[contractNameLowercase], (deployedContract) => {
|
|
||||||
this._txDecoders[functionSelector].push({
|
|
||||||
abiEncoder,
|
|
||||||
contractName,
|
|
||||||
contractAddress: deployedContract.contractAddress,
|
|
||||||
networkId: deployedContract.networkId,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
// If there isn't a deployed version of this contract, record it without address/network id
|
|
||||||
if (_.isUndefined(this._deployedContractInfoByName[contractNameLowercase])) {
|
|
||||||
this._txDecoders[functionSelector].push({
|
|
||||||
abiEncoder,
|
|
||||||
contractName,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static getFunctionSelector(calldata: string): string {
|
public static addABI(abiArray: AbiDefinition[], contractName: string, deploymentInfos?: DeployedContractInfo[]): void {
|
||||||
if (!calldata.startsWith('0x') || calldata.length < 10) {
|
const instance = ZeroExTransactionDecoder.getInstance();
|
||||||
throw new Error(`Malformed calldata. Must include hex prefix '0x' and 4-byte function selector. Got '${calldata}'`);
|
instance.addABI(abiArray, contractName, deploymentInfos);
|
||||||
}
|
|
||||||
const functionSelector = calldata.substr(0, 10);
|
|
||||||
return functionSelector;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static decode(calldata: string, txProperties_?: TransactionProperties): DecodedCalldata {
|
public static decode(calldata: string, txProperties?: TransactionProperties): DecodedCalldata {
|
||||||
const functionSelector = CalldataDecoder.getFunctionSelector(calldata);
|
const instance = ZeroExTransactionDecoder.getInstance();
|
||||||
const txProperties = _.isUndefined(txProperties_) ? {} : txProperties_;
|
const decodedCalldata = instance.decode(calldata, txProperties);
|
||||||
const instance = CalldataDecoder.getInstance();
|
|
||||||
const txDecodersByFunctionSelector = instance._txDecoders[functionSelector];
|
|
||||||
if (_.isUndefined(txDecodersByFunctionSelector)) {
|
|
||||||
throw new Error(`No decoder registered for function selector '${functionSelector}'`);
|
|
||||||
}
|
|
||||||
const txDecoderWithProperties = _.find(txDecodersByFunctionSelector, (txDecoder) => {
|
|
||||||
return (_.isUndefined(txProperties.contractName) || _.toLower(txDecoder.contractName) === _.toLower(txProperties.contractName)) &&
|
|
||||||
(_.isUndefined(txProperties.contractAddress) || txDecoder.contractAddress === txProperties.contractAddress) &&
|
|
||||||
(_.isUndefined(txProperties.networkId) || txDecoder.networkId === txProperties.networkId);
|
|
||||||
});
|
|
||||||
if (_.isUndefined(txDecoderWithProperties)) {
|
|
||||||
throw new Error(`No decoder registered with properties: ${JSON.stringify(txProperties)}.`);
|
|
||||||
}
|
|
||||||
const functionName = txDecoderWithProperties.abiEncoder.getDataItem().name;
|
|
||||||
const functionSignature = txDecoderWithProperties.abiEncoder.getSignatureType();
|
|
||||||
const functionArguments = txDecoderWithProperties.abiEncoder.decode(calldata);
|
|
||||||
const decodedCalldata = {
|
|
||||||
functionName,
|
|
||||||
functionSignature,
|
|
||||||
functionArguments
|
|
||||||
}
|
|
||||||
return decodedCalldata;
|
return decodedCalldata;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,4 +11,4 @@ export { errorUtils } from './error_utils';
|
|||||||
export { fetchAsync } from './fetch_async';
|
export { fetchAsync } from './fetch_async';
|
||||||
export { signTypedDataUtils } from './sign_typed_data_utils';
|
export { signTypedDataUtils } from './sign_typed_data_utils';
|
||||||
export import AbiEncoder = require('./abi_encoder');
|
export import AbiEncoder = require('./abi_encoder');
|
||||||
export { CalldataDecoder } from './calldata_decoder';
|
export { ZeroExTransactionDecoder } from './calldata_decoder';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
|
|
||||||
import { CalldataDecoder } from '../src';
|
import { ZeroExTransactionDecoder } from '../src';
|
||||||
import { chaiSetup } from './utils/chai_setup';
|
import { chaiSetup } from './utils/chai_setup';
|
||||||
|
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
@ -13,7 +13,7 @@ describe.only('CalldataDecoder', () => {
|
|||||||
//const cancelCalldata = '0xd46b02c3000000000000000000000000000000000000000000000000000000000000002000000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a258b39954cef5cb142fd567a46cddb31a6701240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000071d75ab9b9204fffc40000000000000000000000000000000000000000000000011c6e19c53d35b66200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c50f2ed000000000000000000000000000000000000000000000000000001689c2bc812000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000024f47261b000000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000';
|
//const cancelCalldata = '0xd46b02c3000000000000000000000000000000000000000000000000000000000000002000000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a258b39954cef5cb142fd567a46cddb31a6701240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000071d75ab9b9204fffc40000000000000000000000000000000000000000000000011c6e19c53d35b66200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c50f2ed000000000000000000000000000000000000000000000000000001689c2bc812000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000024f47261b000000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000';
|
||||||
//const marketBuycalldata = '0xe5fa431b0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000012309ce5400000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000008c26348f63f9e008f0dd09a0ce1ed7caf6c1366b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000005e150a33ffa97a8d22f59c77ae5487b089ef62e90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000001323e717ba3800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006ea9bd19a0c4b5533ac98f58db0558a96e15ec5f71d64b6070cea4b5df10b7fb35424035000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000024f47261b00000000000000000000000006cb262679c522c4f0834041a6248e8feb35f0337000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000421c750cedbf0eef0914c09b296f08462c363527f454bcf2dfaaf2f772e290d0ee5b0417d8b95837cbe501494195edc2a5a48c664d2ef74a340e40213c05db8767fa03000000000000000000000000000000000000000000000000000000000000';
|
//const marketBuycalldata = '0xe5fa431b0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000012309ce5400000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000008c26348f63f9e008f0dd09a0ce1ed7caf6c1366b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000005e150a33ffa97a8d22f59c77ae5487b089ef62e90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000001323e717ba3800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006ea9bd19a0c4b5533ac98f58db0558a96e15ec5f71d64b6070cea4b5df10b7fb35424035000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000024f47261b00000000000000000000000006cb262679c522c4f0834041a6248e8feb35f0337000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000421c750cedbf0eef0914c09b296f08462c363527f454bcf2dfaaf2f772e290d0ee5b0417d8b95837cbe501494195edc2a5a48c664d2ef74a340e40213c05db8767fa03000000000000000000000000000000000000000000000000000000000000';
|
||||||
const calldata = '0x3c28d861000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000500000000000000000000000000da912ecc847b3d98ca882e396e693e485deed5180000000000000000000000000681e844593a051e2882ec897ecd5444efe19ff20000000000000000000000008124071f810d533ff63de61d0c98db99eeb99d640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008bb6a7394e2f000000000000000000000000000000000000000000000000868cab59cce788000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c51035008197e43b4d84439ec534b62670eaaaf4a46f50ff37ff62f6d1c1fbe8b036d3c000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000503f9794d6a6bb0df8fbb19a2b3e2aeab35339ad000000000000000000000000000000000000000000000000000000000000000000000000000000003997d0f55d1daa549e95c240bc6353636f4cf9740000000000000000000000000681e844593a051e2882ec897ecd5444efe19ff20000000000000000000000008124071f810d533ff63de61d0c98db99eeb99d6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000871bcc4c32c9d66800000000000000000000000000000000000000000000000000008a70a4d2d2100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c510350c20e53540c9b2c9207ad9a04e472e2224af211f08efc2f0eec15d7e1cfbf2109000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000421c8f294b2728c269a9d01a1b58fe7cae2ef7895bd2de48cc3101eb47464d96594340924793fc8325db26a3abd5602605806a82ca77e810494c5ecab58b03449de80300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000421c372d6daa8e6ce2c696e51b6e1e33f10fd2b41b403cd88c311a617c3656ea02fe454e51cddf4682751bea9a02ce725cf364d1107f27be427d5157adbdcca2609b03000000000000000000000000000000000000000000000000000000000000';
|
const calldata = '0x3c28d861000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000500000000000000000000000000da912ecc847b3d98ca882e396e693e485deed5180000000000000000000000000681e844593a051e2882ec897ecd5444efe19ff20000000000000000000000008124071f810d533ff63de61d0c98db99eeb99d640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008bb6a7394e2f000000000000000000000000000000000000000000000000868cab59cce788000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c51035008197e43b4d84439ec534b62670eaaaf4a46f50ff37ff62f6d1c1fbe8b036d3c000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000503f9794d6a6bb0df8fbb19a2b3e2aeab35339ad000000000000000000000000000000000000000000000000000000000000000000000000000000003997d0f55d1daa549e95c240bc6353636f4cf9740000000000000000000000000681e844593a051e2882ec897ecd5444efe19ff20000000000000000000000008124071f810d533ff63de61d0c98db99eeb99d6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000871bcc4c32c9d66800000000000000000000000000000000000000000000000000008a70a4d2d2100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c510350c20e53540c9b2c9207ad9a04e472e2224af211f08efc2f0eec15d7e1cfbf2109000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000421c8f294b2728c269a9d01a1b58fe7cae2ef7895bd2de48cc3101eb47464d96594340924793fc8325db26a3abd5602605806a82ca77e810494c5ecab58b03449de80300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000421c372d6daa8e6ce2c696e51b6e1e33f10fd2b41b403cd88c311a617c3656ea02fe454e51cddf4682751bea9a02ce725cf364d1107f27be427d5157adbdcca2609b03000000000000000000000000000000000000000000000000000000000000';
|
||||||
const decodedCalldata = CalldataDecoder.decode(calldata, {networkId: 1, contractAddress: '0x4f833a24e1f95d70f028921e27040ca56e09ab0b'});
|
const decodedCalldata = ZeroExTransactionDecoder.decode(calldata, {networkId: 1, contractAddress: '0x4f833a24e1f95d70f028921e27040ca56e09ab0b'});
|
||||||
console.log(JSON.stringify(decodedCalldata, null, 4));
|
console.log(JSON.stringify(decodedCalldata, null, 4));
|
||||||
expect(5).to.be.equal(5);
|
expect(5).to.be.equal(5);
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user