|
|
@ -28,6 +28,10 @@ var types = require('./types'); |
|
|
|
var c = require('./const'); |
|
|
|
var c = require('./const'); |
|
|
|
var f = require('./formatters'); |
|
|
|
var f = require('./formatters'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var displayTypeError = function (type) { |
|
|
|
|
|
|
|
console.error('parser does not support type: ' + type); |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/// This method should be called if we want to check if givent type is an array type
|
|
|
|
/// This method should be called if we want to check if givent type is an array type
|
|
|
|
/// @returns true if it is, otherwise false
|
|
|
|
/// @returns true if it is, otherwise false
|
|
|
|
var arrayType = function (type) { |
|
|
|
var arrayType = function (type) { |
|
|
@ -44,31 +48,31 @@ var dynamicTypeBytes = function (type, value) { |
|
|
|
var inputTypes = types.inputTypes();
|
|
|
|
var inputTypes = types.inputTypes();
|
|
|
|
|
|
|
|
|
|
|
|
/// Formats input params to bytes
|
|
|
|
/// Formats input params to bytes
|
|
|
|
/// @param abi contract method
|
|
|
|
/// @param abi contract method inputs
|
|
|
|
/// @param array of params that will be formatted to bytes
|
|
|
|
/// @param array of params that will be formatted to bytes
|
|
|
|
/// @returns bytes representation of input params
|
|
|
|
/// @returns bytes representation of input params
|
|
|
|
var toAbiInput = function (method, params) { |
|
|
|
var formatInput = function (inputs, params) { |
|
|
|
var bytes = ""; |
|
|
|
var bytes = ""; |
|
|
|
var padding = c.ETH_PADDING * 2; |
|
|
|
var padding = c.ETH_PADDING * 2; |
|
|
|
|
|
|
|
|
|
|
|
/// first we iterate in search for dynamic
|
|
|
|
/// first we iterate in search for dynamic
|
|
|
|
method.inputs.forEach(function (input, index) { |
|
|
|
inputs.forEach(function (input, index) { |
|
|
|
bytes += dynamicTypeBytes(input.type, params[index]); |
|
|
|
bytes += dynamicTypeBytes(input.type, params[index]); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
method.inputs.forEach(function (input, i) { |
|
|
|
inputs.forEach(function (input, i) { |
|
|
|
var typeMatch = false; |
|
|
|
var typeMatch = false; |
|
|
|
for (var j = 0; j < inputTypes.length && !typeMatch; j++) { |
|
|
|
for (var j = 0; j < inputTypes.length && !typeMatch; j++) { |
|
|
|
typeMatch = inputTypes[j].type(method.inputs[i].type, params[i]); |
|
|
|
typeMatch = inputTypes[j].type(inputs[i].type, params[i]); |
|
|
|
} |
|
|
|
} |
|
|
|
if (!typeMatch) { |
|
|
|
if (!typeMatch) { |
|
|
|
console.error('input parser does not support type: ' + method.inputs[i].type); |
|
|
|
displayTypeError(inputs[i].type); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var formatter = inputTypes[j - 1].format; |
|
|
|
var formatter = inputTypes[j - 1].format; |
|
|
|
var toAppend = ""; |
|
|
|
var toAppend = ""; |
|
|
|
|
|
|
|
|
|
|
|
if (arrayType(method.inputs[i].type)) |
|
|
|
if (arrayType(inputs[i].type)) |
|
|
|
toAppend = params[i].reduce(function (acc, curr) { |
|
|
|
toAppend = params[i].reduce(function (acc, curr) { |
|
|
|
return acc + formatter(curr); |
|
|
|
return acc + formatter(curr); |
|
|
|
}, ""); |
|
|
|
}, ""); |
|
|
@ -89,34 +93,34 @@ var dynamicBytesLength = function (type) { |
|
|
|
var outputTypes = types.outputTypes();
|
|
|
|
var outputTypes = types.outputTypes();
|
|
|
|
|
|
|
|
|
|
|
|
/// Formats output bytes back to param list
|
|
|
|
/// Formats output bytes back to param list
|
|
|
|
/// @param contract abi method
|
|
|
|
/// @param contract abi method outputs
|
|
|
|
/// @param bytes representtion of output
|
|
|
|
/// @param bytes representtion of output
|
|
|
|
/// @returns array of output params
|
|
|
|
/// @returns array of output params
|
|
|
|
var fromAbiOutput = function (method, output) { |
|
|
|
var formatOutput = function (outs, output) { |
|
|
|
|
|
|
|
|
|
|
|
output = output.slice(2); |
|
|
|
output = output.slice(2); |
|
|
|
var result = []; |
|
|
|
var result = []; |
|
|
|
var padding = c.ETH_PADDING * 2; |
|
|
|
var padding = c.ETH_PADDING * 2; |
|
|
|
|
|
|
|
|
|
|
|
var dynamicPartLength = method.outputs.reduce(function (acc, curr) { |
|
|
|
var dynamicPartLength = outs.reduce(function (acc, curr) { |
|
|
|
return acc + dynamicBytesLength(curr.type); |
|
|
|
return acc + dynamicBytesLength(curr.type); |
|
|
|
}, 0); |
|
|
|
}, 0); |
|
|
|
|
|
|
|
|
|
|
|
var dynamicPart = output.slice(0, dynamicPartLength); |
|
|
|
var dynamicPart = output.slice(0, dynamicPartLength); |
|
|
|
output = output.slice(dynamicPartLength); |
|
|
|
output = output.slice(dynamicPartLength); |
|
|
|
|
|
|
|
|
|
|
|
method.outputs.forEach(function (out, i) { |
|
|
|
outs.forEach(function (out, i) { |
|
|
|
var typeMatch = false; |
|
|
|
var typeMatch = false; |
|
|
|
for (var j = 0; j < outputTypes.length && !typeMatch; j++) { |
|
|
|
for (var j = 0; j < outputTypes.length && !typeMatch; j++) { |
|
|
|
typeMatch = outputTypes[j].type(method.outputs[i].type); |
|
|
|
typeMatch = outputTypes[j].type(outs[i].type); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!typeMatch) { |
|
|
|
if (!typeMatch) { |
|
|
|
console.error('output parser does not support type: ' + method.outputs[i].type); |
|
|
|
displayTypeError(outs[i].type); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var formatter = outputTypes[j - 1].format; |
|
|
|
var formatter = outputTypes[j - 1].format; |
|
|
|
if (arrayType(method.outputs[i].type)) { |
|
|
|
if (arrayType(outs[i].type)) { |
|
|
|
var size = f.formatOutputUInt(dynamicPart.slice(0, padding)); |
|
|
|
var size = f.formatOutputUInt(dynamicPart.slice(0, padding)); |
|
|
|
dynamicPart = dynamicPart.slice(padding); |
|
|
|
dynamicPart = dynamicPart.slice(padding); |
|
|
|
var array = []; |
|
|
|
var array = []; |
|
|
@ -126,7 +130,7 @@ var fromAbiOutput = function (method, output) { |
|
|
|
} |
|
|
|
} |
|
|
|
result.push(array); |
|
|
|
result.push(array); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (types.prefixedType('string')(method.outputs[i].type)) { |
|
|
|
else if (types.prefixedType('string')(outs[i].type)) { |
|
|
|
dynamicPart = dynamicPart.slice(padding);
|
|
|
|
dynamicPart = dynamicPart.slice(padding);
|
|
|
|
result.push(formatter(output.slice(0, padding))); |
|
|
|
result.push(formatter(output.slice(0, padding))); |
|
|
|
output = output.slice(padding); |
|
|
|
output = output.slice(padding); |
|
|
@ -150,7 +154,7 @@ var inputParser = function (json) { |
|
|
|
|
|
|
|
|
|
|
|
var impl = function () { |
|
|
|
var impl = function () { |
|
|
|
var params = Array.prototype.slice.call(arguments); |
|
|
|
var params = Array.prototype.slice.call(arguments); |
|
|
|
return toAbiInput(method, params); |
|
|
|
return formatInput(method.inputs, params); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
if (parser[displayName] === undefined) { |
|
|
|
if (parser[displayName] === undefined) { |
|
|
@ -173,7 +177,7 @@ var outputParser = function (json) { |
|
|
|
var typeName = utils.extractTypeName(method.name); |
|
|
|
var typeName = utils.extractTypeName(method.name); |
|
|
|
|
|
|
|
|
|
|
|
var impl = function (output) { |
|
|
|
var impl = function (output) { |
|
|
|
return fromAbiOutput(method, output); |
|
|
|
return formatOutput(method.outputs, output); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
if (parser[displayName] === undefined) { |
|
|
|
if (parser[displayName] === undefined) { |
|
|
@ -195,6 +199,8 @@ var signatureFromAscii = function (name) { |
|
|
|
module.exports = { |
|
|
|
module.exports = { |
|
|
|
inputParser: inputParser, |
|
|
|
inputParser: inputParser, |
|
|
|
outputParser: outputParser, |
|
|
|
outputParser: outputParser, |
|
|
|
|
|
|
|
formatInput: formatInput, |
|
|
|
|
|
|
|
formatOutput: formatOutput, |
|
|
|
signatureFromAscii: signatureFromAscii |
|
|
|
signatureFromAscii: signatureFromAscii |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
@ -485,19 +491,15 @@ var inputWithName = function (inputs, name) { |
|
|
|
var indexedParamsToTopics = function (event, indexed) { |
|
|
|
var indexedParamsToTopics = function (event, indexed) { |
|
|
|
// sort keys?
|
|
|
|
// sort keys?
|
|
|
|
return Object.keys(indexed).map(function (key) { |
|
|
|
return Object.keys(indexed).map(function (key) { |
|
|
|
// TODO: simplify this!
|
|
|
|
var inputs = [inputWithName(event.inputs, key)]; |
|
|
|
var parser = abi.inputParser([{ |
|
|
|
|
|
|
|
name: 'test',
|
|
|
|
|
|
|
|
inputs: [inputWithName(event.inputs, key)]
|
|
|
|
|
|
|
|
}]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var value = indexed[key]; |
|
|
|
var value = indexed[key]; |
|
|
|
if (value instanceof Array) { |
|
|
|
if (value instanceof Array) { |
|
|
|
return value.map(function (v) { |
|
|
|
return value.map(function (v) { |
|
|
|
return parser.test(v); |
|
|
|
return abi.formatInput(inputs, [v]); |
|
|
|
});
|
|
|
|
});
|
|
|
|
} |
|
|
|
} |
|
|
|
return parser.test(value); |
|
|
|
return abi.formatInput(inputs, [value]); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|