From 7b27c47d6956e038f28154f43354baa3a9d8e05e Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 28 Jul 2015 03:44:19 +0200 Subject: [PATCH] solidity refactor in progres --- lib/solidity/address.js | 63 +++++++++++++++++ lib/solidity/coder.js | 153 +--------------------------------------- lib/solidity/type.js | 98 +++++++++++++++++++++++++ 3 files changed, 164 insertions(+), 150 deletions(-) create mode 100644 lib/solidity/address.js create mode 100644 lib/solidity/type.js diff --git a/lib/solidity/address.js b/lib/solidity/address.js new file mode 100644 index 0000000..fbcd8b6 --- /dev/null +++ b/lib/solidity/address.js @@ -0,0 +1,63 @@ +var f = require('./formatters'); +var SolidityType = require('./type'); + +var SolidityTypeAddress = function () { + this._inputFormatter = f.formatInputInt; + this._outputFormatter = f.formatOutputAddress; +}; + +SolidityTypeAddress.prototype = new SolidityType({}); +SolidityTypeAddress.prototype.constructor = SolidityTypeAddress; + +SolidityTypeAddress.prototype.isType = function (name) { + return !!name.match(/address(\[([0-9]*)\])?/); +}; + +SolidityTypeAddress.prototype.staticPartLength = function (name) { + return 32 * this.staticArrayLength(name); +}; + +SolidityTypeAddress.prototype.isDynamicArray = function (name) { + var matches = name.match(/address(\[([0-9]*)\])?/); + // is array && doesn't have length specified + return !!matches[1] && !matches[2]; +}; + +SolidityTypeAddress.prototype.isStaticArray = function (name) { + var matches = name.match(/address(\[([0-9]*)\])?/); + // is array && have length specified + return !!matches[1] && !!matches[2]; +}; + +SolidityTypeAddress.prototype.staticArrayLength = function (name) { + return name.match(/address(\[([0-9]*)\])?/)[2] || 1; +}; + +SolidityTypeAddress.prototype.nestedName = function (name) { + // removes first [] in name + return name.replace(/\[([0-9])*\]/, ''); +}; + +SolidityTypeAddress.prototype.formatOutput = function (param, unused, name) { + if (this.isStaticArray(name)) { + var staticPart = param.staticPart(); + var result = []; + for (var i = 0; i < staticPart.length; i += 64) { + result.push(this._outputFormatter(new SolidityParam(staticPart.substr(0, i + 64)))); + } + return result; + } else if (this.isDynamicArray(name)) { + var dynamicPart = param.dynamicPart(); + var result = []; + // first position of dynamic part is the length of the array + var length = new BigNumber(param.dynamicPart().slice(0, 64), 16); + for (var i = 0; i < length * 64; i += 64) { + result.push(this._outputFormatter(new SolidityParam(dynamicPart.substr(i + 64, 64)))); + } + return result; + } + + return this._outputFormatter(param); +}; + +module.exports = SolidityTypeAddress; diff --git a/lib/solidity/coder.js b/lib/solidity/coder.js index 4c8335a..05a4461 100644 --- a/lib/solidity/coder.js +++ b/lib/solidity/coder.js @@ -22,99 +22,11 @@ var BigNumber = require('bignumber.js'); var utils = require('../utils/utils'); -var f = require('./formatters'); var SolidityParam = require('./param'); +var f = require('./formatters'); -/** - * SolidityType prototype is used to encode/decode solidity params of certain type - */ -var SolidityType = function (config) { - this._inputFormatter = config.inputFormatter; - this._outputFormatter = config.outputFormatter; -}; - -/** - * Should be used to determine if this SolidityType do match given type - * - * @method isType - * @param {String} name - * @return {Bool} true if type match this SolidityType, otherwise false - */ -SolidityType.prototype.isType = function (name) { - throw "this method should be overrwritten!"; -}; - -SolidityType.prototype.encode = function (value, name) { - if (this.isDynamicArray(name)) { - var length = value.length; // in int - var nestedName = this.nestedName(name); - - var result = []; - result.push(f.formatInputInt(length).encode()); - - var self = this; - value.forEach(function (v) { - result.push(self.encode(v, nestedName)); - }); - - return result; - } else if (this.isStaticArray(name)) { - var length = this.staticArrayLength(name); // in int - var nestedName = this.nestedName(name); - - var result = []; - for (var i = 0; i < length; i++) { - result.push(this.encode(value[i], nestedName)); - } - - return result; - } - - return this._inputFormatter(value, name).encode(); -}; - -/** - * Should be used to decode params from bytes - * - * @method decode - * @param {String} bytes - * @param {Number} offset in bytes - * @param {String} name type name - * @returns {SolidityParam} param - */ -SolidityType.prototype.decode = function (bytes, offset, name) { - if (this.isDynamicArray(name)) { - var arrayOffset = parseInt('0x' + bytes.substr(offset * 2, 64)); // in bytes - var length = parseInt('0x' + bytes.substr(arrayOffset * 2, 64)); // in int - var arrayStart = arrayOffset + 32; // array starts after length; // in bytes - - var nestedName = this.nestedName(name); - var nestedStaticPartLength = this.staticPartLength(nestedName); // in bytes - var result = []; - - for (var i = 0; i < length * nestedStaticPartLength; i += nestedStaticPartLength) { - result.push(this.decode(bytes, arrayStart + i, nestedName)); - } - - return result; - } else if (this.isStaticArray(name)) { - var length = this.staticArrayLength(name); // in int - var arrayStart = offset; // in bytes - - var nestedName = this.nestedName(name); - var nestedStaticPartLength = this.staticPartLength(nestedName); // in bytes - var result = []; - - for (var i = 0; i < length * nestedStaticPartLength; i += nestedStaticPartLength) { - result.push(this.decode(bytes, arrayStart + i, nestedName)); - } - - return result; - } - - var length = this.staticPartLength(name); - return this._outputFormatter(new SolidityParam(bytes.substr(offset * 2, length * 2))); -}; +var SolidityType = require('./type'); +var SolidityTypeAddress = require('./address'); /** * SolidityCoder prototype should be used to encode/decode solidity params of any type @@ -307,65 +219,6 @@ SolidityCoder.prototype.getSolidityTypes = function (types) { }); }; -var SolidityTypeAddress = function () { - this._inputFormatter = f.formatInputInt; - this._outputFormatter = f.formatOutputAddress; -}; - -SolidityTypeAddress.prototype = new SolidityType({}); -SolidityTypeAddress.prototype.constructor = SolidityTypeAddress; - -SolidityTypeAddress.prototype.isType = function (name) { - return !!name.match(/address(\[([0-9]*)\])?/); -}; - -SolidityTypeAddress.prototype.staticPartLength = function (name) { - return 32 * this.staticArrayLength(name); -}; - -SolidityTypeAddress.prototype.isDynamicArray = function (name) { - var matches = name.match(/address(\[([0-9]*)\])?/); - // is array && doesn't have length specified - return !!matches[1] && !matches[2]; -}; - -SolidityTypeAddress.prototype.isStaticArray = function (name) { - var matches = name.match(/address(\[([0-9]*)\])?/); - // is array && have length specified - return !!matches[1] && !!matches[2]; -}; - -SolidityTypeAddress.prototype.staticArrayLength = function (name) { - return name.match(/address(\[([0-9]*)\])?/)[2] || 1; -}; - -SolidityTypeAddress.prototype.nestedName = function (name) { - // removes first [] in name - return name.replace(/\[([0-9])*\]/, ''); -}; - -SolidityTypeAddress.prototype.formatOutput = function (param, unused, name) { - if (this.isStaticArray(name)) { - var staticPart = param.staticPart(); - var result = []; - for (var i = 0; i < staticPart.length; i += 64) { - result.push(this._outputFormatter(new SolidityParam(staticPart.substr(0, i + 64)))); - } - return result; - } else if (this.isDynamicArray(name)) { - var dynamicPart = param.dynamicPart(); - var result = []; - // first position of dynamic part is the length of the array - var length = new BigNumber(param.dynamicPart().slice(0, 64), 16); - for (var i = 0; i < length * 64; i += 64) { - result.push(this._outputFormatter(new SolidityParam(dynamicPart.substr(i + 64, 64)))); - } - return result; - } - - return this._outputFormatter(param); -}; - var SolidityTypeBool = function () { this._inputFormatter = f.formatInputBool; this._outputFormatter = f.formatOutputBool; diff --git a/lib/solidity/type.js b/lib/solidity/type.js new file mode 100644 index 0000000..901b1dd --- /dev/null +++ b/lib/solidity/type.js @@ -0,0 +1,98 @@ + + +var f = require('./formatters'); +var SolidityParam = require('./param'); + +/** + * SolidityType prototype is used to encode/decode solidity params of certain type + */ +var SolidityType = function (config) { + this._inputFormatter = config.inputFormatter; + this._outputFormatter = config.outputFormatter; +}; + +/** + * Should be used to determine if this SolidityType do match given type + * + * @method isType + * @param {String} name + * @return {Bool} true if type match this SolidityType, otherwise false + */ +SolidityType.prototype.isType = function (name) { + throw "this method should be overrwritten!"; +}; + +SolidityType.prototype.encode = function (value, name) { + if (this.isDynamicArray(name)) { + var length = value.length; // in int + var nestedName = this.nestedName(name); + + var result = []; + result.push(f.formatInputInt(length).encode()); + + var self = this; + value.forEach(function (v) { + result.push(self.encode(v, nestedName)); + }); + + return result; + } else if (this.isStaticArray(name)) { + var length = this.staticArrayLength(name); // in int + var nestedName = this.nestedName(name); + + var result = []; + for (var i = 0; i < length; i++) { + result.push(this.encode(value[i], nestedName)); + } + + return result; + } + + return this._inputFormatter(value, name).encode(); +}; + +/** + * Should be used to decode params from bytes + * + * @method decode + * @param {String} bytes + * @param {Number} offset in bytes + * @param {String} name type name + * @returns {SolidityParam} param + */ +SolidityType.prototype.decode = function (bytes, offset, name) { + if (this.isDynamicArray(name)) { + var arrayOffset = parseInt('0x' + bytes.substr(offset * 2, 64)); // in bytes + var length = parseInt('0x' + bytes.substr(arrayOffset * 2, 64)); // in int + var arrayStart = arrayOffset + 32; // array starts after length; // in bytes + + var nestedName = this.nestedName(name); + var nestedStaticPartLength = this.staticPartLength(nestedName); // in bytes + var result = []; + + for (var i = 0; i < length * nestedStaticPartLength; i += nestedStaticPartLength) { + result.push(this.decode(bytes, arrayStart + i, nestedName)); + } + + return result; + } else if (this.isStaticArray(name)) { + var length = this.staticArrayLength(name); // in int + var arrayStart = offset; // in bytes + + var nestedName = this.nestedName(name); + var nestedStaticPartLength = this.staticPartLength(nestedName); // in bytes + var result = []; + + for (var i = 0; i < length * nestedStaticPartLength; i += nestedStaticPartLength) { + result.push(this.decode(bytes, arrayStart + i, nestedName)); + } + + return result; + } + + var length = this.staticPartLength(name); + return this._outputFormatter(new SolidityParam(bytes.substr(offset * 2, length * 2))); +}; + +module.exports = SolidityType; +