solidity refactor in progres

This commit is contained in:
debris 2015-07-28 03:44:19 +02:00
parent b815c5561a
commit 7b27c47d69
3 changed files with 164 additions and 150 deletions

63
lib/solidity/address.js Normal file
View File

@ -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;

View File

@ -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;

98
lib/solidity/type.js Normal file
View File

@ -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;