From 171618d32b649b976f8ecffa69cff3ef30fc7c7d Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Thu, 31 Jan 2019 14:07:09 -0800 Subject: Added comments for transaction decoder --- packages/contract-wrappers/src/index.ts | 1 + .../src/utils/zeroex_transaction_decoder.ts | 31 ++++++++++++--- packages/utils/src/transaction_decoder.ts | 46 ++++++++++++++++------ 3 files changed, 59 insertions(+), 19 deletions(-) diff --git a/packages/contract-wrappers/src/index.ts b/packages/contract-wrappers/src/index.ts index 69bbe3c91..269366896 100644 --- a/packages/contract-wrappers/src/index.ts +++ b/packages/contract-wrappers/src/index.ts @@ -37,6 +37,7 @@ export { OrderValidatorWrapper } from './contract_wrappers/order_validator_wrapp export { DutchAuctionWrapper } from './contract_wrappers/dutch_auction_wrapper'; export { TransactionEncoder } from './utils/transaction_encoder'; +export { ZeroExTransactionDecoder } from './utils/zeroex_transaction_decoder'; export { ContractWrappersError, diff --git a/packages/contract-wrappers/src/utils/zeroex_transaction_decoder.ts b/packages/contract-wrappers/src/utils/zeroex_transaction_decoder.ts index 441424e92..4a5a5809f 100644 --- a/packages/contract-wrappers/src/utils/zeroex_transaction_decoder.ts +++ b/packages/contract-wrappers/src/utils/zeroex_transaction_decoder.ts @@ -8,29 +8,48 @@ import { DeployedContractInfo, DeployedContractInfoByName, TransactionData, Tran export class ZeroExTransactionDecoder extends TransactionDecoder { private static _instance: ZeroExTransactionDecoder; - + /** + * Adds a set of ABI definitions, after which transaction data targeting these ABI's can be decoded. + * Additional properties can be included to disambiguate similar ABI's. For example, if two functions + * have the same signature but different parameter names, then their ABI definitions can be disambiguated + * by specifying a contract name. + * @param abiDefinitions ABI definitions for a given contract. + * @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 static addABI( - abiArray: AbiDefinition[], + abiDefinitions: AbiDefinition[], contractName: string, deploymentInfos?: DeployedContractInfo[], ): void { const instance = ZeroExTransactionDecoder._getInstance(); - instance.addABI(abiArray, contractName, deploymentInfos); + instance.addABI(abiDefinitions, contractName, deploymentInfos); } - + /** + * Decodes transaction data for a known ABI. + * @param txData hex-encoded transaction data. + * @param txProperties Properties about the transaction used to disambiguate similar ABI's (optional). + * @return Decoded transaction data. Includes: function name and signature, along with the decoded arguments. + */ public static decode(calldata: string, txProperties?: TransactionProperties): TransactionData { const instance = ZeroExTransactionDecoder._getInstance(); const decodedCalldata = instance.decode(calldata, txProperties); return decodedCalldata; } - + /** + * Gets instance for singleton. + * @return singleton instance. + */ private static _getInstance(): ZeroExTransactionDecoder { if (!ZeroExTransactionDecoder._instance) { ZeroExTransactionDecoder._instance = new ZeroExTransactionDecoder(); } return ZeroExTransactionDecoder._instance; } - + /** + * Adds all known contract ABI's defined by the @0x/Artifacts package, along with known 0x + * contract addresses. + */ private constructor() { super(); // Load addresses by contract name diff --git a/packages/utils/src/transaction_decoder.ts b/packages/utils/src/transaction_decoder.ts index 35a889a4e..1ce2ea3b0 100644 --- a/packages/utils/src/transaction_decoder.ts +++ b/packages/utils/src/transaction_decoder.ts @@ -6,29 +6,43 @@ import { DeployedContractInfo, FunctionInfoBySelector, TransactionData, Transact export class TransactionDecoder { private readonly _functionInfoBySelector: FunctionInfoBySelector = {}; - - private static _getFunctionSelector(calldata: string): string { + /** + * Retrieves the function selector from tranasction data. + * @param txData hex-encoded transaction data. + * @return hex-encoded function selector. + */ + private static _getFunctionSelector(txData: string): string { const functionSelectorLength = 10; - if (!calldata.startsWith('0x') || calldata.length < functionSelectorLength) { + if (!txData.startsWith('0x') || txData.length < functionSelectorLength) { throw new Error( - `Malformed calldata. Must include hex prefix '0x' and 4-byte function selector. Got '${calldata}'`, + `Malformed transaction data. Must include a hex prefix '0x' and 4-byte function selector. Got '${txData}'`, ); } const functionSelector = calldata.substr(0, functionSelectorLength); return functionSelector; } - - public addABI(abiArray: AbiDefinition[], contractName: string, deploymentInfos?: DeployedContractInfo[]): void { - const functionAbis: MethodAbi[] = _.filter(abiArray, abiEntry => { + /** + * Adds a set of ABI definitions, after which transaction data targeting these ABI's can be decoded. + * Additional properties can be included to disambiguate similar ABI's. For example, if two functions + * have the same signature but different parameter names, then their ABI definitions can be disambiguated + * by specifying a contract name. + * @param abiDefinitions ABI definitions for a given contract. + * @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 { + // Disregard definitions that are not functions + const functionAbis: MethodAbi[] = _.filter(abiDefinitions, abiEntry => { return abiEntry.type === 'function'; }); + // Record function ABI's _.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 + // Recored a copy of this ABI for each deployment const functionSignature = abiEncoder.getSignature(); _.each(deploymentInfos, deploymentInfo => { this._functionInfoBySelector[functionSelector].push({ @@ -39,7 +53,7 @@ export class TransactionDecoder { networkId: deploymentInfo.networkId, }); }); - // If there isn't a deployed version of this contract, record it without address/network id + // There is no deployment info for this contract; record it without an address/network id if (_.isEmpty(deploymentInfos)) { this._functionInfoBySelector[functionSelector].push({ functionSignature, @@ -49,9 +63,15 @@ export class TransactionDecoder { } }); } - - public decode(calldata: string, txProperties_?: TransactionProperties): TransactionData { - const functionSelector = TransactionDecoder._getFunctionSelector(calldata); + /** + * Decodes transaction data for a known ABI. + * @param txData hex-encoded transaction data. + * @param txProperties Properties about the transaction used to disambiguate similar ABI's (optional). + * @return Decoded transaction data. Includes: function name and signature, along with the decoded arguments. + */ + public decode(txData: string, txProperties_?: TransactionProperties): TransactionData { + // Lookup + const functionSelector = TransactionDecoder._getFunctionSelector(txData); const txProperties = _.isUndefined(txProperties_) ? {} : txProperties_; const candidateFunctionInfos = this._functionInfoBySelector[functionSelector]; if (_.isUndefined(candidateFunctionInfos)) { @@ -75,7 +95,7 @@ export class TransactionDecoder { } const functionName = functionInfo.abiEncoder.getDataItem().name; const functionSignature = functionInfo.abiEncoder.getSignatureType(); - const functionArguments = functionInfo.abiEncoder.decode(calldata); + const functionArguments = functionInfo.abiEncoder.decode(txData); const decodedCalldata = { functionName, functionSignature, -- cgit v1.2.3