|
|
|
@ -8,11 +8,17 @@ var findIndex = function (array, callback) { |
|
|
|
|
return end ? i - 1 : -1; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
var findMethodIndex = function (json, methodName) { |
|
|
|
|
return findIndex(json, function (method) { |
|
|
|
|
return method.name === methodName; |
|
|
|
|
}); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
var padLeft = function (number, n) { |
|
|
|
|
return (new Array(n * 2 - number.toString().length + 1)).join("0") + number; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
var setupTypes = function () { |
|
|
|
|
var setupInputTypes = function () { |
|
|
|
|
var prefixedType = function (prefix) { |
|
|
|
|
return function (type, value) { |
|
|
|
|
var expected = prefix; |
|
|
|
@ -25,31 +31,33 @@ var setupTypes = function () { |
|
|
|
|
}; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
var namedType = function (name, padding) { |
|
|
|
|
var namedType = function (name, padding, formatter) { |
|
|
|
|
return function (type, value) { |
|
|
|
|
if (type !== name) { |
|
|
|
|
return false;
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return padLeft(value, padding); |
|
|
|
|
return padLeft(formatter ? value : formatter(value), padding); |
|
|
|
|
}; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
var formatBool = function (value) { |
|
|
|
|
return value ? '1' : '0'; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
return [ |
|
|
|
|
prefixedType('uint'), |
|
|
|
|
prefixedType('int'), |
|
|
|
|
namedType('address', 20), |
|
|
|
|
namedType('bool', 1), |
|
|
|
|
namedType('bool', 1, formatBool), |
|
|
|
|
]; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
var types = setupTypes(); |
|
|
|
|
var inputTypes = setupInputTypes(); |
|
|
|
|
|
|
|
|
|
var toBytes = function (json, methodName, params) { |
|
|
|
|
var toAbiInput = function (json, methodName, params) { |
|
|
|
|
var bytes = ""; |
|
|
|
|
var index = findIndex(json, function (method) { |
|
|
|
|
return method.name === methodName; |
|
|
|
|
}); |
|
|
|
|
var index = findMethodIndex(json, methodName); |
|
|
|
|
|
|
|
|
|
if (index === -1) { |
|
|
|
|
return; |
|
|
|
@ -62,8 +70,8 @@ var toBytes = function (json, methodName, params) { |
|
|
|
|
|
|
|
|
|
for (var i = 0; i < method.inputs.length; i++) { |
|
|
|
|
var found = false; |
|
|
|
|
for (var j = 0; j < types.length && !found; j++) { |
|
|
|
|
found = types[j](method.inputs[i].type, params[i]); |
|
|
|
|
for (var j = 0; j < inputTypes.length && !found; j++) { |
|
|
|
|
found = inputTypes[j](method.inputs[i].type, params[i]); |
|
|
|
|
} |
|
|
|
|
if (!found) { |
|
|
|
|
console.error('unsupported json type: ' + method.inputs[i].type); |
|
|
|
@ -73,7 +81,75 @@ var toBytes = function (json, methodName, params) { |
|
|
|
|
return bytes; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
var setupOutputTypes = function () { |
|
|
|
|
var prefixedType = function (prefix) { |
|
|
|
|
return function (type) { |
|
|
|
|
var expected = prefix; |
|
|
|
|
if (type.indexOf(expected) !== 0) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var padding = parseInt(type.slice(expected.length)) / 8; |
|
|
|
|
return padding * 2; |
|
|
|
|
}; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
var namedType = function (name, padding) { |
|
|
|
|
return function (type) { |
|
|
|
|
return name === type ? padding * 2: -1; |
|
|
|
|
}; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
var formatInt = function (value) { |
|
|
|
|
return parseInt(value, 16); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
var formatBool = function (value) { |
|
|
|
|
return value === '1' ? true : false; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
return [ |
|
|
|
|
{ padding: prefixedType('uint'), format: formatInt }, |
|
|
|
|
{ padding: prefixedType('int'), format: formatInt }, |
|
|
|
|
{ padding: namedType('address', 20) }, |
|
|
|
|
{ padding: namedType('bool', 1), format: formatBool } |
|
|
|
|
]; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
var outputTypes = setupOutputTypes(); |
|
|
|
|
|
|
|
|
|
var fromAbiOutput = function (json, methodName, output) { |
|
|
|
|
var index = findMethodIndex(json, methodName); |
|
|
|
|
|
|
|
|
|
if (index === -1) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
output = output.slice(2); |
|
|
|
|
|
|
|
|
|
var result = []; |
|
|
|
|
var method = json[index]; |
|
|
|
|
for (var i = 0; i < method.outputs.length; i++) { |
|
|
|
|
var padding = -1; |
|
|
|
|
for (var j = 0; j < outputTypes.length && padding === -1; j++) { |
|
|
|
|
padding = outputTypes[j].padding(method.outputs[i].type); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (padding === -1) { |
|
|
|
|
// not found output parsing
|
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
var res = output.slice(0, padding); |
|
|
|
|
var formatter = outputTypes[j - 1].format; |
|
|
|
|
result.push(formatter ? formatter(res): res); |
|
|
|
|
output = output.slice(padding); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
module.exports = { |
|
|
|
|
toBytes: toBytes |
|
|
|
|
toAbiInput: toAbiInput, |
|
|
|
|
fromAbiOutput: fromAbiOutput |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|