formatting bool tests and fixes

This commit is contained in:
Marek Kotewicz 2015-01-14 14:06:29 +01:00
parent ed1cb9edca
commit 6b2ec23132
5 changed files with 114 additions and 64 deletions

133
dist/ethereum.js vendored
View File

@ -55,56 +55,52 @@ var padLeft = function (string, chars) {
return new Array(chars - string.length + 1).join("0") + string; return new Array(chars - string.length + 1).join("0") + string;
}; };
/// Setups input formatters for solidity types
/// @returns an array of input formatters
var setupInputTypes = function () { var setupInputTypes = function () {
var prefixedType = function (prefix) { var prefixedType = function (prefix) {
return function (type, value) { return function (type, value) {
var expected = prefix; return type.indexOf(prefix) === 0;
if (type.indexOf(expected) !== 0) {
return false;
}
var padding = 32; // override as per the new ABI.
if (prefix === "string")
return web3.fromAscii(value, padding).substr(2);
if (typeof value === "number")
value = value.toString(16);
else if (typeof value === "string")
value = web3.toHex(value);
else if (value.indexOf('0x') === 0)
value = value.substr(2);
else
value = (+value).toString(16);
return padLeft(value, padding * 2);
}; };
}; };
var namedType = function (name, formatter) { var namedType = function (name, formatter) {
return function (type, value) { return function (type, value) {
if (type !== name) { return type === name;
return false;
}
var padding = 32; //override as per the new ABI.
return padLeft(formatter ? formatter(value) : value, padding * 2);
}; };
}; };
var formatInt = function (value) {
var padding = 32 * 2;
if (typeof value === 'number')
value = value.toString(16);
else if (value.indexOf('0x') === 0)
value = value.substr(2);
else if (typeof value === 'string')
value = value.toHex(value);
else
value = (+value).toString(16);
return padLeft(value, padding);
};
var formatString = function (value) {
return web3.fromAscii(value, 32).substr(2);
};
var formatBool = function (value) { var formatBool = function (value) {
return value ? '0x1' : '0x0'; return '000000000000000000000000000000000000000000000000000000000000000' + (value ? '1' : '0');
}; };
return [ return [
prefixedType('uint'), { type: prefixedType('uint'), format: formatInt },
prefixedType('int'), { type: prefixedType('int'), format: formatInt },
prefixedType('hash'), { type: prefixedType('hash'), format: formatInt },
prefixedType('string'), { type: prefixedType('string'), format: formatString },
prefixedType('real'), { type: prefixedType('real'), format: formatInt },
prefixedType('ureal'), { type: prefixedType('ureal'), format: formatInt },
namedType('address'), { type: namedType('address') },
namedType('bool', formatBool), { type: namedType('bool'), format: formatBool }
]; ];
}; };
@ -119,65 +115,73 @@ var toAbiInput = function (json, methodName, params) {
} }
var method = json[index]; var method = json[index];
var padding = 32 * 2;
for (var i = 0; i < method.inputs.length; i++) { for (var i = 0; i < method.inputs.length; i++) {
var found = false; var typeMatch = false;
for (var j = 0; j < inputTypes.length && !found; j++) { for (var j = 0; j < inputTypes.length && !typeMatch; j++) {
found = inputTypes[j](method.inputs[i].type, params[i]); typeMatch = inputTypes[j].type(method.inputs[i].type, params[i]);
} }
if (!found) { if (!typeMatch) {
console.error('unsupported json type: ' + method.inputs[i].type); console.error('input parser does not support type: ' + method.inputs[i].type);
} }
bytes += found;
var formatter = inputTypes[j - 1].format;
bytes += (formatter ? formatter(params[i]) : params[i]);
} }
return bytes; return bytes;
}; };
/// Setups output formaters for solidity types
/// @returns an array of output formatters
var setupOutputTypes = function () { var setupOutputTypes = function () {
/// @param expected type prefix (string)
/// @returns function which checks if type has matching prefix. if yes, returns true, otherwise false
var prefixedType = function (prefix) { var prefixedType = function (prefix) {
return function (type) { return function (type) {
var expected = prefix; var expected = prefix;
if (type.indexOf(expected) !== 0) { return type.indexOf(expected) === 0;
return -1;
}
var padding = 32; // override as per the new ABI.
return padding * 2;
}; };
}; };
/// @param expected type name (string)
/// @returns function which checks if type is matching expected one. if yes, returns true, otherwise false
var namedType = function (name) { var namedType = function (name) {
return function (type) { return function (type) {
var padding = 32; // override as per the new ABI. return name === type;
return name === type ? padding * 2 : -1;
}; };
}; };
/// @returns input bytes formatted to int
var formatInt = function (value) { var formatInt = function (value) {
return value.length <= 8 ? +parseInt(value, 16) : hexToDec(value); return value.length <= 8 ? +parseInt(value, 16) : hexToDec(value);
}; };
/// @returns input bytes formatted to hex
var formatHash = function (value) { var formatHash = function (value) {
return "0x" + value; return "0x" + value;
}; };
/// @returns input bytes formatted to bool
var formatBool = function (value) { var formatBool = function (value) {
return value === '1' ? true : false; return value === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false;
}; };
/// @returns input bytes formatted to ascii string
var formatString = function (value) { var formatString = function (value) {
return web3.toAscii(value); return web3.toAscii(value);
}; };
return [ return [
{ padding: prefixedType('uint'), format: formatInt }, { type: prefixedType('uint'), format: formatInt },
{ padding: prefixedType('int'), format: formatInt }, { type: prefixedType('int'), format: formatInt },
{ padding: prefixedType('hash'), format: formatHash }, { type: prefixedType('hash'), format: formatHash },
{ padding: prefixedType('string'), format: formatString }, { type: prefixedType('string'), format: formatString },
{ padding: prefixedType('real'), format: formatInt }, { type: prefixedType('real'), format: formatInt },
{ padding: prefixedType('ureal'), format: formatInt }, { type: prefixedType('ureal'), format: formatInt },
{ padding: namedType('address') }, { type: namedType('address') },
{ padding: namedType('bool'), format: formatBool } { type: namedType('bool'), format: formatBool }
]; ];
}; };
@ -194,14 +198,16 @@ var fromAbiOutput = function (json, methodName, output) {
var result = []; var result = [];
var method = json[index]; var method = json[index];
var padding = 32 * 2;
for (var i = 0; i < method.outputs.length; i++) { for (var i = 0; i < method.outputs.length; i++) {
var padding = -1; var typeMatch = false;
for (var j = 0; j < outputTypes.length && padding === -1; j++) { for (var j = 0; j < outputTypes.length && !typeMatch; j++) {
padding = outputTypes[j].padding(method.outputs[i].type); typeMatch = outputTypes[j].type(method.outputs[i].type);
} }
if (padding === -1) { if (!typeMatch) {
// not found output parsing // not found output parsing
console.error('output parser does not support type: ' + method.outputs[i].type);
continue; continue;
} }
var res = output.slice(0, padding); var res = output.slice(0, padding);
@ -213,6 +219,8 @@ var fromAbiOutput = function (json, methodName, output) {
return result; return result;
}; };
/// @param json abi for contract
/// @returns input parser object for given json abi
var inputParser = function (json) { var inputParser = function (json) {
var parser = {}; var parser = {};
json.forEach(function (method) { json.forEach(function (method) {
@ -225,6 +233,8 @@ var inputParser = function (json) {
return parser; return parser;
}; };
/// @param json abi for contract
/// @returns output parser for given json abi
var outputParser = function (json) { var outputParser = function (json) {
var parser = {}; var parser = {};
json.forEach(function (method) { json.forEach(function (method) {
@ -236,6 +246,9 @@ var outputParser = function (json) {
return parser; return parser;
}; };
/// @param json abi for contract
/// @param method name for which we want to get method signature
/// @returns (promise) contract method signature for method with given name
var methodSignature = function (json, name) { var methodSignature = function (json, name) {
var method = json[findMethodIndex(json, name)]; var method = json[findMethodIndex(json, name)];
var result = name + '('; var result = name + '(';

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -164,7 +164,7 @@ var setupOutputTypes = function () {
/// @returns input bytes formatted to bool /// @returns input bytes formatted to bool
var formatBool = function (value) { var formatBool = function (value) {
return value === '1' ? true : false; return value === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false;
}; };
/// @returns input bytes formatted to ascii string /// @returns input bytes formatted to ascii string

View File

@ -127,6 +127,24 @@ describe('abi', function() {
}); });
it('should parse input bool', function() {
// given
var d = clone(description);
d[0].inputs = [
{ type: 'bool' }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(parser.test(true), "0000000000000000000000000000000000000000000000000000000000000001");
assert.equal(parser.test(false), "0000000000000000000000000000000000000000000000000000000000000000");
});
it('should parse input hash', function() { it('should parse input hash', function() {
/* /*
// given // given
@ -253,6 +271,25 @@ describe('abi', function() {
assert.equal(parser.test("0x68656c6c6f000000000000000000000000000000000000000000000000000000")[0], 'hello'); assert.equal(parser.test("0x68656c6c6f000000000000000000000000000000000000000000000000000000")[0], 'hello');
assert.equal(parser.test("0x776f726c64000000000000000000000000000000000000000000000000000000")[0], 'world'); assert.equal(parser.test("0x776f726c64000000000000000000000000000000000000000000000000000000")[0], 'world');
});
it('should parse output bool', function() {
// given
var d = clone(description);
d[0].outputs = [
{ type: 'bool' }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(parser.test("000000000000000000000000000000000000000000000000000000000000000001")[0], true);
assert.equal(parser.test("000000000000000000000000000000000000000000000000000000000000000000")[0], false);
}); });
it('should parse multiple output strings', function() { it('should parse multiple output strings', function() {