refactored extensions

This commit is contained in:
debris 2015-10-08 04:09:51 +02:00
parent 98f4318015
commit 7dff0a461a
23 changed files with 460 additions and 463 deletions

View File

@ -36,17 +36,21 @@ var version = require('./version.json');
var utils = require('./utils/utils');
var sha3 = require('./utils/sha3');
var extend = require('./web3/extend');
var Batch = require('./web3/batch');
var Contract = require('./web3/contract');
function Web3 (provider) {
this._requestManager = new RequestManager(provider);
this.eth = new Eth(this);
this.db = new DB(this);
this.shh = new Shh(this);
this.net = new Net(this);
this.settings = new Settings();
this.providers = {};
this.version = {
version: version.version
};
this._extend = extend(this);
}
Web3.prototype.setProvider = function (provider) {
@ -58,6 +62,8 @@ Web3.prototype.reset = function () {
this.settings = new Settings();
};
Web3.prototype.toHex = utils.toHex;
Web3.prototype.toAscii = utils.toAscii;
Web3.prototype.toUtf8 = utils.toUtf8;
@ -71,7 +77,6 @@ Web3.prototype.fromWei = utils.fromWei;
Web3.prototype.isAddress = utils.isAddress;
Web3.prototype.isIBAN = utils.isIBAN;
Web3.prototype.sha3 = sha3;
Web3.prototype._extend = extend;
/**
* Transforms direct icap to address
@ -109,9 +114,9 @@ Web3.prototype.fromICAP = function (icap) {
//return (this.currentProvider && this.currentProvider.isConnected());
//};
//Web3.prototype.createBatch = function () {
//return new Batch();
//};
Web3.prototype.createBatch = function () {
return new Batch();
};
module.exports = Web3;

View File

@ -20,7 +20,6 @@
* @date 2014
*/
var web3 = require('../web3');
var utils = require('../utils/utils');
var coder = require('../solidity/coder');
var SolidityEvent = require('./event');
@ -85,16 +84,6 @@ var addEventsToContract = function (contract, abi) {
});
};
/**
* Should be called to create new ContractFactory
*
* @method contract
* @param {Array} abi
* @returns {ContractFactory} new contract factory
*/
var contract = function (abi) {
return new ContractFactory(abi);
};
/**
* Should be called to check if the contract gets properly deployed on the blockchain.
@ -104,7 +93,7 @@ var contract = function (abi) {
* @param {Function} callback
* @returns {Undefined}
*/
var checkForContractAddress = function(contract, abi, callback){
var checkForContractAddress = function(contract, callback){
var count = 0,
callbackFired = false;
@ -113,8 +102,6 @@ var checkForContractAddress = function(contract, abi, callback){
if (!e && !callbackFired) {
count++;
// console.log('Checking for contract address', count);
// stop watching after 50 blocks (timeout)
if (count > 50) {
@ -147,10 +134,6 @@ var checkForContractAddress = function(contract, abi, callback){
contract.address = receipt.contractAddress;
// attach events and methods
addFunctionsToContract(contract, abi);
addEventsToContract(contract, abi);
// call callback for the second time
if(callback)
callback(null, contract);
@ -175,10 +158,22 @@ var checkForContractAddress = function(contract, abi, callback){
* @method ContractFactory
* @param {Array} abi
*/
var ContractFactory = function (abi) {
var ContractFactory = function (web3, abi) {
this.web3 = web3;
this.abi = abi;
};
/**
* Should be called to create new ContractFactory
*
* @method contract
* @param {Array} abi
* @returns {ContractFactory} new contract factory
*/
//var contract = function (abi) {
//return new ContractFactory(abi);
//};
/**
* Should be called to create new contract on a blockchain
*
@ -190,7 +185,6 @@ var ContractFactory = function (abi) {
* @returns {Contract} returns contract instance
*/
ContractFactory.prototype.new = function () {
var _this = this;
var contract = new Contract(this.abi);
// parse arguments
@ -207,33 +201,30 @@ ContractFactory.prototype.new = function () {
options = args.pop();
}
// throw an error if there are no options
var bytes = encodeConstructorParams(this.abi, args);
options.data += bytes;
if (callback) {
// wait for the contract address adn check if the code was deployed
web3.eth.sendTransaction(options, function (err, hash) {
this.web3.eth.sendTransaction(options, function (err, hash) {
if (err) {
callback(err);
} else {
// add the transaction hash
contract.transactionHash = hash;
contract._transactionHash = hash;
// call callback for the first time
callback(null, contract);
checkForContractAddress(contract, _this.abi, callback);
checkForContractAddress(contract, callback);
}
});
} else {
var hash = web3.eth.sendTransaction(options);
var hash = this.web3.eth.sendTransaction(options);
// add the transaction hash
contract.transactionHash = hash;
checkForContractAddress(contract, _this.abi);
contract._transactionHash = hash;
checkForContractAddress(contract);
}
return contract;
@ -250,11 +241,6 @@ ContractFactory.prototype.new = function () {
*/
ContractFactory.prototype.at = function (address, callback) {
var contract = new Contract(this.abi, address);
// TODO: address is required
// attach functions
addFunctionsToContract(contract, this.abi);
addEventsToContract(contract, this.abi);
if (callback) {
callback(null, contract);
@ -270,8 +256,14 @@ ContractFactory.prototype.at = function (address, callback) {
* @param {Address} contract address
*/
var Contract = function (abi, address) {
this._transactionHash = null;
this.address = address;
// this functions are not part of prototype,
// because we dont want to spoil the interface
addFunctionsToContract(this, abi);
addEventsToContract(this, abi);
};
module.exports = contract;
module.exports = ContractFactory;

View File

@ -3,40 +3,45 @@ var utils = require('./../utils/utils');
var Method = require('./method');
var Property = require('./property');
/// creates methods in a given object based on method description on input
/// setups api calls for these methods
var setupMethods = function (obj, methods) {
methods.forEach(function (method) {
method.attachToObject(obj);
});
};
/// creates properties in a given object based on properties description on input
/// setups api calls for these properties
var setupProperties = function (obj, properties) {
properties.forEach(function (property) {
property.attachToObject(obj);
});
};
var extend = function (web3, extension) {
// TODO: refactor, so the input params are not altered.
// it's necessary to make same 'extension' work with multiple providers
var extend = function (web3) {
var ex = function (extension) {
var extendedObject;
if (extension.property && !web3[extension.property]) {
this[extension.property] = {};
extendedObject = this[extension.property];
if (extension.property) {
if (!web3[extension.property]) {
web3[extension.property] = {};
}
extendedObject = web3[extension.property];
} else {
extendedObject = this;
extendedObject = web3;
}
setupMethods(extendedObject, extension.methods || []);
setupProperties(extendedObject, extension.properties || []);
if (extension.methods) {
extension.methods.forEach(function (method) {
method.attachToObject(extendedObject);
method.setRequestManager(web3._requestManager);
});
}
if (extension.properties) {
extension.properties.forEach(function (property) {
property.attachToObject(extendedObject);
property.setRequestManager(web3._requestManager);
});
}
};
extend.formatters = formatters;
extend.utils = utils;
extend.Method = Method;
extend.Property = Property;
ex.formatters = formatters;
ex.utils = utils;
ex.Method = Method;
ex.Property = Property;
return ex;
};
module.exports = extend;

View File

@ -29,6 +29,11 @@ var Method = function (options) {
this.params = options.params || 0;
this.inputFormatter = options.inputFormatter;
this.outputFormatter = options.outputFormatter;
this.requestManager = null;
};
Method.prototype.setRequestManager = function (rm) {
this.requestManager = rm;
};
/**
@ -133,11 +138,11 @@ Method.prototype.buildCall = function() {
return function send() {
var payload = method.toPayload(Array.prototype.slice.call(arguments));
if (payload.callback) {
return this.web3._requestManager.sendAsync(payload, function (err, result) {
return method.requestManager.sendAsync(payload, function (err, result) {
payload.callback(err, method.formatOutput(result));
});
}
return method.formatOutput(this.web3._requestManager.send(payload));
return method.formatOutput(method.requestManager.send(payload));
};
};

View File

@ -23,9 +23,17 @@
var Method = require('../method');
var DB = function (web3) {
this.web3 = web3;
this._requestManager = web3._requestManager;
var self = this;
methods().forEach(function(method) {
method.attachToObject(self);
method.setRequestManager(web3._requestManager);
});
};
var methods = function () {
var putString = new Method({
name: 'putString',
call: 'db_putString',
@ -50,10 +58,9 @@ var getHex = new Method({
params: 2
});
var methods = [
return [
putString, getString, putHex, getHex
];
methods.forEach(function(method) { method.attachToObject(DB.prototype) });
};
module.exports = DB;

View File

@ -28,6 +28,7 @@ var utils = require('../../utils/utils');
var Method = require('../method');
var Property = require('../property');
var c = require('../../utils/config');
var Contract = require('../contract');
var blockCall = function (args) {
return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? "eth_getBlockByHash" : "eth_getBlockByNumber";
@ -51,6 +52,18 @@ var uncleCountCall = function (args) {
function Eth(web3) {
this.web3 = web3;
var self = this;
methods().forEach(function(method) {
method.attachToObject(self);
method.setRequestManager(web3._requestManager);
});
properties().forEach(function(p) {
p.attachToObject(self);
p.setRequestManager(web3._requestManager);
});
}
Object.defineProperty(Eth.prototype, 'defaultBlock', {
@ -73,6 +86,7 @@ Object.defineProperty(Eth.prototype, 'defaultAccount', {
}
});
var methods = function () {
var getBalance = new Method({
name: 'getBalance',
call: 'eth_getBalance',
@ -223,7 +237,7 @@ var getWork = new Method({
params: 0
});
var methods = [
return [
getBalance,
getStorageAt,
getCode,
@ -246,11 +260,11 @@ var methods = [
submitWork,
getWork
];
};
methods.forEach(function(method) { method.attachToObject(Eth.prototype) });
/// @returns an array of objects describing web3.eth api properties
var properties = [
var properties = function () {
return [
new Property({
name: 'coinbase',
getter: 'eth_coinbase'
@ -284,8 +298,12 @@ var properties = [
outputFormatter: utils.toDecimal
})
];
};
properties.forEach(function(p) { p.attachToObject(Eth.prototype) });
Eth.prototype.contract = function (abi) {
var factory = new Contract(this.web3, abi);
return factory;
};
module.exports = Eth;

View File

@ -24,11 +24,19 @@ var utils = require('../../utils/utils');
var Property = require('../property');
var Net = function (web3) {
this.web3 = web3;
this._requestManager = web3._requestManager;
var self = this;
properties().forEach(function(p) {
p.attachToObject(self);
p.setRequestManager(web3._requestManager);
});
};
/// @returns an array of objects describing web3.eth api properties
var properties = [
var properties = function () {
return [
new Property({
name: 'listening',
getter: 'net_listening'
@ -39,6 +47,6 @@ var properties = [
outputFormatter: utils.toDecimal
})
];
};
module.exports = Net;

View File

@ -24,9 +24,20 @@ var Method = require('../method');
var formatters = require('../formatters');
var Shh = function (web3) {
this.web3 = web3;
this._requestManager = web3._requestManager;
var self = this;
methods().forEach(function(method) {
method.attachToObject(self);
method.setRequestManager(web3._requestManager);
});
};
var methods = function () {
var post = new Method({
name: 'post',
call: 'shh_post',
@ -58,15 +69,14 @@ var addToGroup = new Method({
params: 0
});
var methods = [
return [
post,
newIdentity,
hasIdentity,
newGroup,
addToGroup
];
methods.forEach(function(method) { method.attachToObject(Shh.prototype) });
};
module.exports = Shh;

View File

@ -27,8 +27,8 @@ var icapRegistrarAbi= require('../contracts/ICAPRegistrar.json');
var globalNameregAddress = '0xc6d9d2cd449a754c494264e1809c50e34d64562b';
var ibanNameregAddress = '0xa1a111bc074c9cfa781f0c38e63bd51c91b8af00';
module.exports = {
namereg: contract(globalRegistrarAbi).at(globalNameregAddress),
ibanNamereg: contract(icapRegistrarAbi).at(ibanNameregAddress)
};
//module.exports = {
//namereg: contract(globalRegistrarAbi).at(globalNameregAddress),
//ibanNamereg: contract(icapRegistrarAbi).at(ibanNameregAddress)
//};

View File

@ -29,6 +29,11 @@ var Property = function (options) {
this.setter = options.setter;
this.outputFormatter = options.outputFormatter;
this.inputFormatter = options.inputFormatter;
this.requestManager = null;
};
Property.prototype.setRequestManager = function (rm) {
this.requestManager = rm;
};
/**
@ -66,6 +71,14 @@ Property.prototype.extractCallback = function (args) {
}
};
/**
* Should attach function to method
*
* @method attachToObject
* @param {Object}
* @param {Function}
*/
Property.prototype.attachToObject = function (obj) {
var proto = {
get: this.buildGet()
@ -90,7 +103,7 @@ var asyncGetterName = function (name) {
Property.prototype.buildGet = function () {
var property = this;
return function get() {
return property.formatOutput(this.web3._requestManager.send({
return property.formatOutput(property.requestManager.send({
method: property.getter
}));
};
@ -99,7 +112,7 @@ Property.prototype.buildGet = function () {
Property.prototype.buildAsyncGet = function () {
var property = this;
return function get(callback) {
this.web3._requestManager.sendAsync({
property.requestManager.sendAsync({
method: property.getter
}, function (err, result) {
callback(err, property.formatOutput(result));
@ -107,84 +120,4 @@ Property.prototype.buildAsyncGet = function () {
};
};
/**
* Should attach function to method
*
* @method attachToObject
* @param {Object}
* @param {Function}
*/
//Property.prototype.attachToObject = function (obj) {
//var proto = {
//get: this.get.bind(this),
//};
//var names = this.name.split('.');
//var name = names[0];
//if (names.length > 1) {
//obj[names[0]] = obj[names[0]] || {};
//obj = obj[names[0]];
//name = names[1];
//}
//Object.defineProperty(obj, name, proto);
//var toAsyncName = function (prefix, name) {
//return prefix + name.charAt(0).toUpperCase() + name.slice(1);
//};
//var func = this.getAsync.bind(this);
//func.request = this.request.bind(this);
//obj[toAsyncName('get', name)] = func;
//};
/**
* Should be used to get value of the property
*
* @method get
* @return {Object} value of the property
*/
//Property.prototype.get = function () {
//return this.formatOutput(RequestManager.getInstance().send({
//method: this.getter
//}));
//};
/**
* Should be used to asynchrounously get value of property
*
* @method getAsync
* @param {Function}
*/
//Property.prototype.getAsync = function (callback) {
//var self = this;
//RequestManager.getInstance().sendAsync({
//method: this.getter
//}, function (err, result) {
//if (err) {
//return callback(err);
//}
//callback(err, self.formatOutput(result));
//});
//};
/**
* Should be called to create pure JSONRPC request which can be used in batch request
*
* @method request
* @param {...} params
* @return {Object} jsonrpc request
*/
//Property.prototype.request = function () {
//var payload = {
//method: this.getter,
//params: [],
//callback: this.extractCallback(Array.prototype.slice.call(arguments))
//};
//payload.format = this.formatOutput.bind(this);
//return payload;
//};
module.exports = Property;

View File

@ -1,6 +1,7 @@
var chai = require('chai');
var assert = chai.assert;
var web3 = require('../index');
var Web3 = require('../index');
var web3 = new Web3();
var FakeHttpProvider = require('./helpers/FakeHttpProvider');
// use sendTransaction as dummy

View File

@ -1,9 +1,11 @@
var chai = require('chai');
var assert = chai.assert;
var web3 = require('../index');
var Web3 = require('../index');
var web3 = new Web3();
var FakeHttpProvider = require('./helpers/FakeHttpProvider');
var bn = require('bignumber.js');
/*
describe('lib/web3/batch', function () {
describe('execute', function () {
it('should execute batch request', function (done) {
@ -199,3 +201,4 @@ describe('lib/web3/batch', function () {
});
});
*/

View File

@ -1,12 +1,14 @@
var chai = require('chai');
var assert = chai.assert;
var web3 = require('../index');
var Web3 = require('../index');
var web3 = new Web3();
var FakeHttpProvider = require('./helpers/FakeHttpProvider');
var FakeHttpProvider2 = require('./helpers/FakeHttpProvider2');
var utils = require('../lib/utils/utils');
var BigNumber = require('bignumber.js');
var sha3 = require('../lib/utils/sha3');
/*
var desc = [{
"name": "balance(address)",
"type": "function",
@ -571,3 +573,4 @@ describe('contract', function () {
});
});
*/

View File

@ -31,7 +31,7 @@ var tests = [{
}
}];
/*
var testPolling = function (tests) {
describe('web3.eth.filter.polling', function () {
@ -118,3 +118,4 @@ var testPolling = function (tests) {
testPolling(tests);
*/

View File

@ -1,6 +1,6 @@
var chai = require('chai');
var BigNumber = require('bignumber.js');
var web3 = require('../index');
var utils = require('../lib/utils/utils.js');
var assert = chai.assert;
var tests = [
@ -14,7 +14,7 @@ describe('lib/utils/utils', function () {
describe('fromAscii', function () {
tests.forEach(function (test) {
it('should turn ' + test.value + ' to ' + test.expected, function () {
assert.strictEqual(web3.fromAscii(test.value), test.expected);
assert.strictEqual(utils.fromAscii(test.value), test.expected);
});
});
});

View File

@ -1,6 +1,6 @@
var chai = require('chai');
var BigNumber = require('bignumber.js');
var web3 = require('../index');
var utils = require('../lib/utils/utils.js');
var assert = chai.assert;
var tests = [
@ -13,7 +13,7 @@ describe('lib/utils/utils', function () {
describe('fromUtf8', function () {
tests.forEach(function (test) {
it('should turn ' + test.value + ' to ' + test.expected, function () {
assert.strictEqual(web3.fromUtf8(test.value), test.expected);
assert.strictEqual(utils.fromUtf8(test.value), test.expected);
});
});
});

View File

@ -1,6 +1,6 @@
var chai = require('chai');
var BigNumber = require('bignumber.js');
var web3 = require('../index');
var utils = require('../lib/utils/utils.js');
var assert = chai.assert;
var tests = [
@ -14,7 +14,7 @@ describe('lib/utils/utils', function () {
describe('toAscii', function () {
tests.forEach(function (test) {
it('should turn ' + test.value + ' to ' + test.expected, function () {
assert.strictEqual(web3.toAscii(test.value), test.expected);
assert.strictEqual(utils.toAscii(test.value), test.expected);
});
});
});

View File

@ -1,6 +1,6 @@
var chai = require('chai');
var BigNumber = require('bignumber.js');
var web3 = require('../index');
var utils = require('../lib/utils/utils.js');
var assert = chai.assert;
var tests = [
@ -13,7 +13,7 @@ describe('lib/utils/utils', function () {
describe('toUtf8', function () {
tests.forEach(function (test) {
it('should turn ' + test.value + ' to ' + test.expected, function () {
assert.strictEqual(web3.toUtf8(test.value), test.expected);
assert.strictEqual(utils.toUtf8(test.value), test.expected);
});
});
});

View File

@ -1,7 +1,8 @@
var chai = require('chai');
var assert = chai.assert;
var FakeHttpProvider = require('./helpers/FakeHttpProvider');
var web3 = require('../lib/web3');
var Web3 = require('../lib/web3');
var web3 = new Web3();
var tests = [{

View File

@ -1,6 +1,7 @@
var chai = require('chai');
var assert = chai.assert;
var web3 = require('../index');
var Web3 = require('../index');
var web3 = new Web3();
var FakeHttpProvider = require('./helpers/FakeHttpProvider');
var method = 'listening';

View File

@ -1,6 +1,7 @@
var chai = require('chai');
var assert = chai.assert;
var web3 = require('../index.js');
var Web3 = require('../index.js');
var web3 = new Web3();
var u = require('./helpers/test.utils.js');
describe('web3.net', function() {

View File

@ -1,6 +1,7 @@
var chai = require('chai');
var assert = chai.assert;
var web3 = require('../index');
var Web3 = require('../index');
var web3 = new Web3();
var FakeHttpProvider = require('./helpers/FakeHttpProvider');
var method = 'peerCount';

View File

@ -58,6 +58,7 @@ var tests = [{
call: 'shh_newFilter'
}];
/*
describe('shh', function () {
describe(method, function () {
tests.forEach(function (test, index) {
@ -80,5 +81,6 @@ describe('shh', function () {
});
});
});
*/