|
|
@ -17,9 +17,19 @@ |
|
|
|
/** @file abi.js |
|
|
|
* @authors: |
|
|
|
* Marek Kotewicz <marek@ethdev.com> |
|
|
|
* Gav Wood <g@ethdev.com> |
|
|
|
* @date 2014 |
|
|
|
*/ |
|
|
|
|
|
|
|
// TODO: make these be actually accurate instead of falling back onto JS's doubles.
|
|
|
|
var hexToDec = function (hex) { |
|
|
|
return parseInt(hex, 16).toString(); |
|
|
|
}; |
|
|
|
|
|
|
|
var decToHex = function (dec) { |
|
|
|
return parseInt(dec).toString(16); |
|
|
|
}; |
|
|
|
|
|
|
|
var findIndex = function (array, callback) { |
|
|
|
var end = false; |
|
|
|
var i = 0; |
|
|
@ -35,8 +45,8 @@ var findMethodIndex = function (json, methodName) { |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
var padLeft = function (number, n) { |
|
|
|
return (new Array(n * 2 - number.toString().length + 1)).join("0") + number; |
|
|
|
var padLeft = function (string, chars) { |
|
|
|
return Array(chars - string.length + 1).join("0") + string; |
|
|
|
}; |
|
|
|
|
|
|
|
var setupInputTypes = function () { |
|
|
@ -48,27 +58,34 @@ var setupInputTypes = function () { |
|
|
|
} |
|
|
|
|
|
|
|
var padding = parseInt(type.slice(expected.length)) / 8; |
|
|
|
return padLeft(value, padding); |
|
|
|
if (typeof value === "number") |
|
|
|
value = value.toString(16); |
|
|
|
else if (value.indexOf('0x') === 0) |
|
|
|
value = value.substr(2); |
|
|
|
else |
|
|
|
value = (+value).toString(16); |
|
|
|
return padLeft(value, padding * 2); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
var namedType = function (name, padding, formatter) { |
|
|
|
return function (type, value) { |
|
|
|
if (type !== name) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
return padLeft(formatter ? value : formatter(value), padding); |
|
|
|
return padLeft(formatter ? formatter(value) : value, padding * 2); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
var formatBool = function (value) { |
|
|
|
return value ? '1' : '0'; |
|
|
|
return value ? '0x1' : '0x0'; |
|
|
|
}; |
|
|
|
|
|
|
|
return [ |
|
|
|
prefixedType('uint'), |
|
|
|
prefixedType('int'), |
|
|
|
prefixedType('hash'), |
|
|
|
namedType('address', 20), |
|
|
|
namedType('bool', 1, formatBool), |
|
|
|
]; |
|
|
@ -79,21 +96,18 @@ var inputTypes = setupInputTypes(); |
|
|
|
var toAbiInput = function (json, methodName, params) { |
|
|
|
var bytes = ""; |
|
|
|
var index = findMethodIndex(json, methodName); |
|
|
|
|
|
|
|
|
|
|
|
if (index === -1) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// it needs to be checked in WebThreeStubServer
|
|
|
|
// something wrong might be with this additional zero
|
|
|
|
bytes = bytes + index + 'x' + '0'; |
|
|
|
bytes = "0x" + padLeft(index.toString(16), 2); |
|
|
|
var method = json[index]; |
|
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < method.inputs.length; i++) { |
|
|
|
var found = false; |
|
|
|
for (var j = 0; j < inputTypes.length && !found; j++) { |
|
|
|
var val = parseInt(params[i]).toString(16); |
|
|
|
found = inputTypes[j](method.inputs[i].type, val); |
|
|
|
found = inputTypes[j](method.inputs[i].type, params[i]); |
|
|
|
} |
|
|
|
if (!found) { |
|
|
|
console.error('unsupported json type: ' + method.inputs[i].type); |
|
|
@ -110,7 +124,7 @@ var setupOutputTypes = function () { |
|
|
|
if (type.indexOf(expected) !== 0) { |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var padding = parseInt(type.slice(expected.length)) / 8; |
|
|
|
return padding * 2; |
|
|
|
}; |
|
|
@ -118,12 +132,16 @@ var setupOutputTypes = function () { |
|
|
|
|
|
|
|
var namedType = function (name, padding) { |
|
|
|
return function (type) { |
|
|
|
return name === type ? padding * 2: -1; |
|
|
|
return name === type ? padding * 2 : -1; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
var formatInt = function (value) { |
|
|
|
return parseInt(value, 16); |
|
|
|
return value.length <= 8 ? +parseInt(value, 16) : hexToDec(value); |
|
|
|
}; |
|
|
|
|
|
|
|
var formatHash = function (value) { |
|
|
|
return "0x" + value; |
|
|
|
}; |
|
|
|
|
|
|
|
var formatBool = function (value) { |
|
|
@ -133,6 +151,7 @@ var setupOutputTypes = function () { |
|
|
|
return [ |
|
|
|
{ padding: prefixedType('uint'), format: formatInt }, |
|
|
|
{ padding: prefixedType('int'), format: formatInt }, |
|
|
|
{ padding: prefixedType('hash'), format: formatHash }, |
|
|
|
{ padding: namedType('address', 20) }, |
|
|
|
{ padding: namedType('bool', 1), format: formatBool } |
|
|
|
]; |
|
|
@ -146,7 +165,7 @@ var fromAbiOutput = function (json, methodName, output) { |
|
|
|
if (index === -1) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
output = output.slice(2); |
|
|
|
|
|
|
|
var result = []; |
|
|
@ -163,7 +182,7 @@ var fromAbiOutput = function (json, methodName, output) { |
|
|
|
} |
|
|
|
var res = output.slice(0, padding); |
|
|
|
var formatter = outputTypes[j - 1].format; |
|
|
|
result.push(formatter ? formatter(res): res); |
|
|
|
result.push(formatter ? formatter(res) : ("0x" + res)); |
|
|
|
output = output.slice(padding); |
|
|
|
} |
|
|
|
|
|
|
@ -197,4 +216,3 @@ module.exports = { |
|
|
|
inputParser: inputParser, |
|
|
|
outputParser: outputParser |
|
|
|
}; |
|
|
|
|
|
|
|