improved contracts interface

This commit is contained in:
Marek Kotewicz 2014-11-14 13:11:47 +01:00
parent 8aaec1d98f
commit ea8db7a4ae
9 changed files with 166 additions and 21 deletions

10
dist/ethereum.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

75
example/contract.html Normal file

@ -0,0 +1,75 @@
<!doctype>
<html>
<head>
<script type="text/javascript" src="js/es6-promise/promise.min.js"></script>
<script type="text/javascript" src="../dist/ethereum.js"></script>
<script type="text/javascript">
var web3 = require('web3');
web3.setProvider(new web3.providers.AutoProvider());
// solidity source code
var source = "" +
"contract test {\n" +
" function multiply(uint a) returns(uint d) {\n" +
" return a * 7;\n" +
" }\n" +
"}\n";
// contract description, this will be autogenerated somehow
var desc = [{
"name": "multiply",
"inputs": [
{
"name": "a",
"type": "uint256"
}
],
"outputs": [
{
"name": "d",
"type": "uint256"
}
]
}];
var contract;
function createExampleContract() {
// hide create button
document.getElementById('create').style.visibility = 'hidden';
document.getElementById('source').innerText = source;
// create contract
web3.eth.transact({code: web3.eth.solidity(source)}).then(function (address) {
contract = web3.contract(address, desc);
document.getElementById('call').style.visibility = 'visible';
});
}
function callExampleContract() {
// this should be generated by ethereum
var param = document.getElementById('value').value;
// call the contract
contract.multiply(param).call().then(function(res) {
document.getElementById('result').innerText = res[0];
});
}
</script>
</head>
<body>
<h1>contract</h1>
<div id="source"></div>
<div id='create'>
<button type="button" onClick="createExampleContract();">create example contract</button>
</div>
<div id='call' style='visibility: hidden;'>
<input type="number" id="value" onkeyup='callExampleContract()'></input>
</div>
<div id="result"></div>
</body>
</html>

@ -30,7 +30,7 @@
</script> </script>
</head> </head>
<body> <body>
<h1>balance</h1> <h1>coinbase balance</h1>
<button type="button" onClick="watchBalance();">watch balance</button> <button type="button" onClick="watchBalance();">watch balance</button>
<div></div> <div></div>
<div id="original"></div> <div id="original"></div>

@ -3,6 +3,5 @@ web3.providers.WebSocketProvider = require('./lib/websocket');
web3.providers.HttpRpcProvider = require('./lib/httprpc'); web3.providers.HttpRpcProvider = require('./lib/httprpc');
web3.providers.QtProvider = require('./lib/qt'); web3.providers.QtProvider = require('./lib/qt');
web3.providers.AutoProvider = require('./lib/autoprovider'); web3.providers.AutoProvider = require('./lib/autoprovider');
web3.contract = require('./lib/abi');
module.exports = web3; module.exports = web3;

@ -1,5 +1,4 @@
var web3 = require('./lib/main'); var web3 = require('./lib/main');
web3.providers.QtProvider = require('./lib/qt'); web3.providers.QtProvider = require('./lib/qt');
web3.abi = require('./lib/abi');
module.exports = web3; module.exports = web3;

@ -1,3 +1,24 @@
/*
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 findIndex = function (array, callback) {
var end = false; var end = false;
@ -71,7 +92,8 @@ var toAbiInput = function (json, methodName, params) {
for (var i = 0; i < method.inputs.length; i++) { for (var i = 0; i < method.inputs.length; i++) {
var found = false; var found = false;
for (var j = 0; j < inputTypes.length && !found; j++) { for (var j = 0; j < inputTypes.length && !found; j++) {
found = inputTypes[j](method.inputs[i].type, params[i]); var val = parseInt(params[i]).toString(16);
found = inputTypes[j](method.inputs[i].type, val);
} }
if (!found) { if (!found) {
console.error('unsupported json type: ' + method.inputs[i].type); console.error('unsupported json type: ' + method.inputs[i].type);
@ -148,17 +170,31 @@ var fromAbiOutput = function (json, methodName, output) {
return result; return result;
}; };
var load = function (json) { var inputParser = function (json) {
var contract = {}; var parser = {};
json.forEach(function (method) { json.forEach(function (method) {
contract[method.name] = function () { parser[method.name] = function () {
var params = Array.prototype.slice.call(arguments); var params = Array.prototype.slice.call(arguments);
return toAbiInput(json, method.name, params); return toAbiInput(json, method.name, params);
}; };
}); });
return contract; return parser;
}; };
module.exports = load; 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
};

@ -22,6 +22,8 @@
* @date 2014 * @date 2014
*/ */
var abi = require('./abi');
function flattenPromise (obj) { function flattenPromise (obj) {
if (obj instanceof Promise) { if (obj instanceof Promise) {
return Promise.resolve(obj); return Promise.resolve(obj);
@ -292,9 +294,8 @@ var web3 = {
} }
}; };
var eth = web3.eth; setupMethods(web3.eth, ethMethods());
setupMethods(eth, ethMethods()); setupProperties(web3.eth, ethProperties());
setupProperties(eth, ethProperties());
setupMethods(web3.db, dbMethods()); setupMethods(web3.db, dbMethods());
setupMethods(web3.shh, shhMethods()); setupMethods(web3.shh, shhMethods());
@ -454,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; module.exports = web3;