aboutsummaryrefslogtreecommitdiffstats
path: root/lib/abi.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/abi.js')
-rw-r--r--lib/abi.js102
1 files changed, 89 insertions, 13 deletions
diff --git a/lib/abi.js b/lib/abi.js
index 9102454b0..0ac27e6b8 100644
--- a/lib/abi.js
+++ b/lib/abi.js
@@ -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,32 +31,34 @@ 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
};