aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJeffrey Wilcke <obscuren@users.noreply.github.com>2014-11-15 00:20:05 +0800
committerJeffrey Wilcke <obscuren@users.noreply.github.com>2014-11-15 00:20:05 +0800
commit42713c6e9995a131601186363ba2c49ffd093acc (patch)
treec02fbe94c1205ce270b36b6aa65de33af6178d54 /lib
parent7ffba22f2d3e246ded4ac8f6df3d9eab5137e838 (diff)
parentea8db7a4aecb034c6a967ccd3b17c50f423cb77c (diff)
downloaddexon-42713c6e9995a131601186363ba2c49ffd093acc.tar
dexon-42713c6e9995a131601186363ba2c49ffd093acc.tar.gz
dexon-42713c6e9995a131601186363ba2c49ffd093acc.tar.bz2
dexon-42713c6e9995a131601186363ba2c49ffd093acc.tar.lz
dexon-42713c6e9995a131601186363ba2c49ffd093acc.tar.xz
dexon-42713c6e9995a131601186363ba2c49ffd093acc.tar.zst
dexon-42713c6e9995a131601186363ba2c49ffd093acc.zip
Merge pull request #12 from debris/master
simplifie contract creation && calls, improved added examples
Diffstat (limited to 'lib')
-rw-r--r--lib/abi.js200
-rw-r--r--lib/main.js48
2 files changed, 243 insertions, 5 deletions
diff --git a/lib/abi.js b/lib/abi.js
new file mode 100644
index 000000000..3df0fe684
--- /dev/null
+++ b/lib/abi.js
@@ -0,0 +1,200 @@
+/*
+ This file is part of ethereum.js.
+
+ ethereum.js is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ ethereum.js is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file abi.js
+ * @authors:
+ * Marek Kotewicz <marek@ethdev.com>
+ * @date 2014
+ */
+
+var findIndex = function (array, callback) {
+ var end = false;
+ var i = 0;
+ for (; i < array.length && !end; i++) {
+ end = callback(array[i]);
+ }
+ 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 setupInputTypes = function () {
+ var prefixedType = function (prefix) {
+ return function (type, value) {
+ var expected = prefix;
+ if (type.indexOf(expected) !== 0) {
+ return false;
+ }
+
+ var padding = parseInt(type.slice(expected.length)) / 8;
+ return padLeft(value, padding);
+ };
+ };
+
+ var namedType = function (name, padding, formatter) {
+ return function (type, value) {
+ if (type !== name) {
+ return false;
+ }
+
+ 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, formatBool),
+ ];
+};
+
+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';
+ 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);
+ }
+ if (!found) {
+ console.error('unsupported json type: ' + method.inputs[i].type);
+ }
+ bytes += found;
+ }
+ 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;
+};
+
+var inputParser = function (json) {
+ var parser = {};
+ json.forEach(function (method) {
+ parser[method.name] = function () {
+ var params = Array.prototype.slice.call(arguments);
+ return toAbiInput(json, method.name, params);
+ };
+ });
+
+ return parser;
+};
+
+var outputParser = function (json) {
+ var parser = {};
+ json.forEach(function (method) {
+ parser[method.name] = function (output) {
+ return fromAbiOutput(json, method.name, output);
+ };
+ });
+
+ return parser;
+};
+
+module.exports = {
+ inputParser: inputParser,
+ outputParser: outputParser
+};
+
diff --git a/lib/main.js b/lib/main.js
index c3ed22f8b..7990691de 100644
--- a/lib/main.js
+++ b/lib/main.js
@@ -22,6 +22,8 @@
* @date 2014
*/
+var abi = require('./abi');
+
function flattenPromise (obj) {
if (obj instanceof Promise) {
return Promise.resolve(obj);
@@ -77,6 +79,7 @@ var ethMethods = function () {
var methods = [
{ name: 'balanceAt', call: 'eth_balanceAt' },
{ name: 'stateAt', call: 'eth_stateAt' },
+ { name: 'storageAt', call: 'eth_storageAt' },
{ name: 'countAt', call: 'eth_countAt'},
{ name: 'codeAt', call: 'eth_codeAt' },
{ name: 'transact', call: 'eth_transact' },
@@ -84,8 +87,9 @@ var ethMethods = function () {
{ name: 'block', call: blockCall },
{ name: 'transaction', call: transactionCall },
{ name: 'uncle', call: uncleCall },
- { name: 'compile', call: 'eth_compile' },
- { name: 'lll', call: 'eth_lll' }
+ { name: 'compilers', call: 'eth_compilers' },
+ { name: 'lll', call: 'eth_lll' },
+ { name: 'solidity', call: 'eth_solidity' }
];
return methods;
};
@@ -290,9 +294,8 @@ var web3 = {
}
};
-var eth = web3.eth;
-setupMethods(eth, ethMethods());
-setupProperties(eth, ethProperties());
+setupMethods(web3.eth, ethMethods());
+setupProperties(web3.eth, ethProperties());
setupMethods(web3.db, dbMethods());
setupMethods(web3.shh, shhMethods());
@@ -452,5 +455,40 @@ function messageHandler(data) {
}
}
+web3.contract = function (address, desc) {
+ var inputParser = abi.inputParser(desc);
+ var outputParser = abi.outputParser(desc);
+
+ var contract = {};
+
+ desc.forEach(function (method) {
+ contract[method.name] = function () {
+ var params = Array.prototype.slice.call(arguments);
+ var parsed = inputParser[method.name].apply(null, params);
+
+ var onSuccess = function (result) {
+ return outputParser[method.name](result);
+ };
+
+ return {
+ call: function (extra) {
+ extra = extra || {};
+ extra.to = address;
+ extra.data = parsed;
+ return web3.eth.call(extra).then(onSuccess);
+ },
+ transact: function (extra) {
+ extra = extra || {};
+ extra.to = address;
+ extra.data = parsed;
+ return web3.eth.transact(extra).then(onSuccess);
+ }
+ };
+ };
+ });
+
+ return contract;
+};
+
module.exports = web3;