mirror of
https://github.com/status-im/web3.js.git
synced 2025-02-23 19:48:13 +00:00
commit
e21ee7a474
766
dist/web3-light.js
vendored
766
dist/web3-light.js
vendored
File diff suppressed because it is too large
Load Diff
22
dist/web3-light.js.map
vendored
22
dist/web3-light.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/web3-light.min.js
vendored
4
dist/web3-light.min.js
vendored
File diff suppressed because one or more lines are too long
766
dist/web3.js
vendored
766
dist/web3.js
vendored
File diff suppressed because it is too large
Load Diff
22
dist/web3.js.map
vendored
22
dist/web3.js.map
vendored
File diff suppressed because one or more lines are too long
5
dist/web3.min.js
vendored
5
dist/web3.min.js
vendored
File diff suppressed because one or more lines are too long
@ -45,7 +45,7 @@
|
||||
var contract;
|
||||
|
||||
var update = function (err, x) {
|
||||
document.getElementById('result').innerText = JSON.stringify(x);
|
||||
document.getElementById('result').innerText = JSON.stringify(x, null, 2);
|
||||
};
|
||||
|
||||
var createContract = function () {
|
||||
|
@ -299,8 +299,8 @@ var coder = new SolidityCoder([
|
||||
name: 'bytes',
|
||||
match: 'prefix',
|
||||
mode: 'bytes',
|
||||
inputFormatter: f.formatInputString,
|
||||
outputFormatter: f.formatOutputString
|
||||
inputFormatter: f.formatInputBytes,
|
||||
outputFormatter: f.formatOutputBytes
|
||||
}),
|
||||
new SolidityType({
|
||||
name: 'real',
|
||||
|
@ -45,11 +45,11 @@ var formatInputInt = function (value) {
|
||||
/**
|
||||
* Formats input value to byte representation of string
|
||||
*
|
||||
* @method formatInputString
|
||||
* @method formatInputBytes
|
||||
* @param {String}
|
||||
* @returns {SolidityParam}
|
||||
*/
|
||||
var formatInputString = function (value) {
|
||||
var formatInputBytes = function (value) {
|
||||
var result = utils.fromAscii(value, c.ETH_PADDING).substr(2);
|
||||
return new SolidityParam('', formatInputInt(value.length).value, result);
|
||||
};
|
||||
@ -141,17 +141,6 @@ var formatOutputUReal = function (param) {
|
||||
return formatOutputUInt(param).dividedBy(new BigNumber(2).pow(128));
|
||||
};
|
||||
|
||||
/**
|
||||
* Should be used to format output hash
|
||||
*
|
||||
* @method formatOutputHash
|
||||
* @param {SolidityParam}
|
||||
* @returns {String} right-aligned output bytes formatted to hex
|
||||
*/
|
||||
var formatOutputHash = function (param) {
|
||||
return "0x" + param.value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Should be used to format output bool
|
||||
*
|
||||
@ -166,11 +155,11 @@ var formatOutputBool = function (param) {
|
||||
/**
|
||||
* Should be used to format output string
|
||||
*
|
||||
* @method formatOutputString
|
||||
* @method formatOutputBytes
|
||||
* @param {SolidityParam} left-aligned hex representation of string
|
||||
* @returns {String} ascii string
|
||||
*/
|
||||
var formatOutputString = function (param) {
|
||||
var formatOutputBytes = function (param) {
|
||||
// length might also be important!
|
||||
return utils.toAscii(param.suffix);
|
||||
};
|
||||
@ -189,16 +178,15 @@ var formatOutputAddress = function (param) {
|
||||
|
||||
module.exports = {
|
||||
formatInputInt: formatInputInt,
|
||||
formatInputString: formatInputString,
|
||||
formatInputBytes: formatInputBytes,
|
||||
formatInputBool: formatInputBool,
|
||||
formatInputReal: formatInputReal,
|
||||
formatOutputInt: formatOutputInt,
|
||||
formatOutputUInt: formatOutputUInt,
|
||||
formatOutputReal: formatOutputReal,
|
||||
formatOutputUReal: formatOutputUReal,
|
||||
formatOutputHash: formatOutputHash,
|
||||
formatOutputBool: formatOutputBool,
|
||||
formatOutputString: formatOutputString,
|
||||
formatOutputBytes: formatOutputBytes,
|
||||
formatOutputAddress: formatOutputAddress
|
||||
};
|
||||
|
||||
|
@ -101,15 +101,5 @@ SolidityParam.prototype.shiftArray = function (length) {
|
||||
return new SolidityParam('', prefix, suffix);
|
||||
};
|
||||
|
||||
/**
|
||||
* This method should be used to check if param is empty
|
||||
*
|
||||
* @method empty
|
||||
* @return {Bool} true if is empty, otherwise false
|
||||
*/
|
||||
SolidityParam.prototype.empty = function () {
|
||||
return !this.value.length && !this.prefix.length && !this.suffix.length;
|
||||
};
|
||||
|
||||
module.exports = SolidityParam;
|
||||
|
||||
|
@ -34,35 +34,7 @@ var getConstructor = function (abi, numberOfArgs) {
|
||||
})[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* Filters all functions from input abi
|
||||
*
|
||||
* @method filterFunctions
|
||||
* @param {Array} abi
|
||||
* @returns {Array} abi array with filtered objects of type 'function'
|
||||
*/
|
||||
var filterFunctions = function (json) {
|
||||
return json.filter(function (current) {
|
||||
return current.type === 'function';
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Filters all events from input abi
|
||||
*
|
||||
* @method filterEvents
|
||||
* @param {Array} abi
|
||||
* @returns {Array} abi array with filtered objects of type 'event'
|
||||
*/
|
||||
var filterEvents = function (json) {
|
||||
return json.filter(function (current) {
|
||||
return current.type === 'event';
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getConstructor: getConstructor,
|
||||
filterFunctions: filterFunctions,
|
||||
filterEvents: filterEvents
|
||||
getConstructor: getConstructor
|
||||
};
|
||||
|
||||
|
@ -14,9 +14,9 @@
|
||||
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 utils.js
|
||||
* @authors:
|
||||
* Marek Kotewicz <marek@ethdev.com>
|
||||
/**
|
||||
* @file utils.js
|
||||
* @author Marek Kotewicz <marek@ethdev.com>
|
||||
* @date 2015
|
||||
*/
|
||||
|
||||
@ -67,22 +67,6 @@ var padLeft = function (string, chars, sign) {
|
||||
return new Array(chars - string.length + 1).join(sign ? sign : "0") + string;
|
||||
};
|
||||
|
||||
/** Finds first index of array element matching pattern
|
||||
*
|
||||
* @method findIndex
|
||||
* @param {Array}
|
||||
* @param {Function} pattern
|
||||
* @returns {Number} index of element
|
||||
*/
|
||||
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;
|
||||
};
|
||||
|
||||
/**
|
||||
* Should be called to get sting from it's hex representation
|
||||
*
|
||||
@ -142,6 +126,22 @@ var fromAscii = function(str, pad) {
|
||||
return "0x" + hex;
|
||||
};
|
||||
|
||||
/**
|
||||
* Should be used to create full function/event name from json abi
|
||||
*
|
||||
* @method transformToFullName
|
||||
* @param {Object} json-abi
|
||||
* @return {String} full fnction/event name
|
||||
*/
|
||||
var transformToFullName = function (json) {
|
||||
if (json.name.indexOf('(') !== -1) {
|
||||
return json.name;
|
||||
}
|
||||
|
||||
var typeName = json.inputs.map(function(i){return i.type; }).join();
|
||||
return json.name + '(' + typeName + ')';
|
||||
};
|
||||
|
||||
/**
|
||||
* Should be called to get display name of contract function
|
||||
*
|
||||
@ -198,9 +198,6 @@ var fromDecimal = function (value) {
|
||||
var toHex = function (val) {
|
||||
/*jshint maxcomplexity:7 */
|
||||
|
||||
if(val === null || typeof val === 'undefined')
|
||||
return val;
|
||||
|
||||
if (isBoolean(val))
|
||||
return fromDecimal(+val);
|
||||
|
||||
@ -451,12 +448,12 @@ var isJson = function (str) {
|
||||
|
||||
module.exports = {
|
||||
padLeft: padLeft,
|
||||
findIndex: findIndex,
|
||||
toHex: toHex,
|
||||
toDecimal: toDecimal,
|
||||
fromDecimal: fromDecimal,
|
||||
toAscii: toAscii,
|
||||
fromAscii: fromAscii,
|
||||
transformToFullName: transformToFullName,
|
||||
extractDisplayName: extractDisplayName,
|
||||
extractTypeName: extractTypeName,
|
||||
toWei: toWei,
|
||||
|
@ -14,130 +14,38 @@
|
||||
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 contract.js
|
||||
* @authors:
|
||||
* Marek Kotewicz <marek@ethdev.com>
|
||||
/**
|
||||
* @file contract.js
|
||||
* @author Marek Kotewicz <marek@ethdev.com>
|
||||
* @date 2014
|
||||
*/
|
||||
|
||||
var web3 = require('../web3');
|
||||
var solAbi = require('../solidity/abi');
|
||||
var utils = require('../utils/utils');
|
||||
var solUtils = require('../solidity/utils');
|
||||
var eventImpl = require('./event');
|
||||
var signature = require('./signature');
|
||||
var SolidityEvent = require('./event');
|
||||
var SolidityFunction = require('./function');
|
||||
|
||||
var addFunctionRelatedPropertiesToContract = function (contract) {
|
||||
|
||||
contract.call = function (options) {
|
||||
contract._isTransaction = false;
|
||||
contract._options = options;
|
||||
return contract;
|
||||
};
|
||||
|
||||
contract.sendTransaction = function (options) {
|
||||
contract._isTransaction = true;
|
||||
contract._options = options;
|
||||
return contract;
|
||||
};
|
||||
};
|
||||
|
||||
var addFunctionsToContract = function (contract, desc, address) {
|
||||
var inputParser = solAbi.inputParser(desc);
|
||||
var outputParser = solAbi.outputParser(desc);
|
||||
|
||||
// create contract functions
|
||||
solUtils.filterFunctions(desc).forEach(function (method) {
|
||||
|
||||
var displayName = utils.extractDisplayName(method.name);
|
||||
var typeName = utils.extractTypeName(method.name);
|
||||
|
||||
var impl = function () {
|
||||
/*jshint maxcomplexity:7 */
|
||||
var params = Array.prototype.slice.call(arguments);
|
||||
var sign = signature.functionSignatureFromAscii(method.name);
|
||||
var parsed = inputParser[displayName][typeName].apply(null, params);
|
||||
|
||||
var options = contract._options || {};
|
||||
options.to = address;
|
||||
options.data = sign + parsed;
|
||||
|
||||
var isTransaction = contract._isTransaction === true || (contract._isTransaction !== false && !method.constant);
|
||||
|
||||
// reset
|
||||
contract._options = {};
|
||||
contract._isTransaction = null;
|
||||
|
||||
if (isTransaction) {
|
||||
|
||||
// transactions do not have any output, cause we do not know, when they will be processed
|
||||
web3.eth.sendTransaction(options);
|
||||
return;
|
||||
}
|
||||
|
||||
var output = web3.eth.call(options);
|
||||
var ret = outputParser[displayName][typeName](output);
|
||||
return ret.length === 1 ? ret[0] : ret;
|
||||
};
|
||||
|
||||
if (contract[displayName] === undefined) {
|
||||
contract[displayName] = impl;
|
||||
}
|
||||
|
||||
contract[displayName][typeName] = impl;
|
||||
var addFunctionsToContract = function (contract, desc) {
|
||||
desc.filter(function (json) {
|
||||
return json.type === 'function';
|
||||
}).map(function (json) {
|
||||
return new SolidityFunction(json, contract.address);
|
||||
}).forEach(function (f) {
|
||||
f.attachToContract(contract);
|
||||
});
|
||||
};
|
||||
|
||||
var addEventRelatedPropertiesToContract = function (contract, desc, address) {
|
||||
contract.address = address;
|
||||
contract._onWatchEventResult = function (data) {
|
||||
var matchingEvent = event.getMatchingEvent(solUtils.filterEvents(desc));
|
||||
var parser = eventImpl.outputParser(matchingEvent);
|
||||
return parser(data);
|
||||
};
|
||||
|
||||
Object.defineProperty(contract, 'topics', {
|
||||
get: function() {
|
||||
return solUtils.filterEvents(desc).map(function (e) {
|
||||
return signature.eventSignatureFromAscii(e.name);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
var addEventsToContract = function (contract, desc, address) {
|
||||
// create contract events
|
||||
solUtils.filterEvents(desc).forEach(function (e) {
|
||||
|
||||
var impl = function () {
|
||||
var params = Array.prototype.slice.call(arguments);
|
||||
var sign = signature.eventSignatureFromAscii(e.name);
|
||||
var event = eventImpl.inputParser(address, sign, e);
|
||||
var o = event.apply(null, params);
|
||||
var outputFormatter = function (data) {
|
||||
var parser = eventImpl.outputParser(e);
|
||||
return parser(data);
|
||||
};
|
||||
return web3.eth.filter(o, undefined, undefined, outputFormatter);
|
||||
};
|
||||
|
||||
// this property should be used by eth.filter to check if object is an event
|
||||
impl._isEvent = true;
|
||||
|
||||
var displayName = utils.extractDisplayName(e.name);
|
||||
var typeName = utils.extractTypeName(e.name);
|
||||
|
||||
if (contract[displayName] === undefined) {
|
||||
contract[displayName] = impl;
|
||||
}
|
||||
|
||||
contract[displayName][typeName] = impl;
|
||||
|
||||
var addEventsToContract = function (contract, desc) {
|
||||
desc.filter(function (json) {
|
||||
return json.type === 'event';
|
||||
}).map(function (json) {
|
||||
return new SolidityEvent(json, contract.address);
|
||||
}).forEach(function (e) {
|
||||
e.attachToContract(contract);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This method should be called when we want to call / transact some solidity method from javascript
|
||||
* it returns an object which has same methods available as solidity contract description
|
||||
@ -166,40 +74,33 @@ var contract = function (abi) {
|
||||
return Contract.bind(null, abi);
|
||||
};
|
||||
|
||||
function Contract(abi, options) {
|
||||
var Contract = function (abi, options) {
|
||||
|
||||
// workaround for invalid assumption that method.name is the full anonymous prototype of the method.
|
||||
// it's not. it's just the name. the rest of the code assumes it's actually the anonymous
|
||||
// prototype, so we make it so as a workaround.
|
||||
// TODO: we may not want to modify input params, maybe use copy instead?
|
||||
abi.forEach(function (method) {
|
||||
if (method.name.indexOf('(') === -1) {
|
||||
var displayName = method.name;
|
||||
var typeName = method.inputs.map(function(i){return i.type; }).join();
|
||||
method.name = displayName + '(' + typeName + ')';
|
||||
}
|
||||
});
|
||||
|
||||
var address = '';
|
||||
this.address = '';
|
||||
if (utils.isAddress(options)) {
|
||||
address = options;
|
||||
this.address = options;
|
||||
} else { // is an object!
|
||||
// TODO, parse the rest of the args
|
||||
options = options || {};
|
||||
var args = Array.prototype.slice.call(arguments, 2);
|
||||
var bytes = solAbi.formatConstructorParams(abi, args);
|
||||
options.data += bytes;
|
||||
address = web3.eth.sendTransaction(options);
|
||||
this.address = web3.eth.sendTransaction(options);
|
||||
}
|
||||
|
||||
var result = {};
|
||||
addFunctionRelatedPropertiesToContract(result);
|
||||
addFunctionsToContract(result, abi, address);
|
||||
addEventRelatedPropertiesToContract(result, abi, address);
|
||||
addEventsToContract(result, abi, address);
|
||||
addFunctionsToContract(this, abi);
|
||||
addEventsToContract(this, abi);
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
Contract.prototype.call = function () {
|
||||
console.error('contract.call is deprecated');
|
||||
return this;
|
||||
};
|
||||
|
||||
Contract.prototype.sendTransaction = function () {
|
||||
console.error('contract.sendTransact is deprecated');
|
||||
return this;
|
||||
};
|
||||
|
||||
module.exports = contract;
|
||||
|
||||
|
@ -14,125 +14,183 @@
|
||||
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 event.js
|
||||
* @authors:
|
||||
* Marek Kotewicz <marek@ethdev.com>
|
||||
/**
|
||||
* @file event.js
|
||||
* @author Marek Kotewicz <marek@ethdev.com>
|
||||
* @date 2014
|
||||
*/
|
||||
|
||||
var abi = require('../solidity/abi');
|
||||
var utils = require('../utils/utils');
|
||||
var signature = require('./signature');
|
||||
var coder = require('../solidity/coder');
|
||||
var web3 = require('../web3');
|
||||
|
||||
/// filter inputs array && returns only indexed (or not) inputs
|
||||
/// @param inputs array
|
||||
/// @param bool if result should be an array of indexed params on not
|
||||
/// @returns array of (not?) indexed params
|
||||
var filterInputs = function (inputs, indexed) {
|
||||
return inputs.filter(function (current) {
|
||||
return current.indexed === indexed;
|
||||
/**
|
||||
* This prototype should be used to create event filters
|
||||
*/
|
||||
var SolidityEvent = function (json, address) {
|
||||
this._params = json.inputs;
|
||||
this._name = utils.transformToFullName(json);
|
||||
this._address = address;
|
||||
this._anonymous = json.anonymous;
|
||||
};
|
||||
|
||||
/**
|
||||
* Should be used to get filtered param types
|
||||
*
|
||||
* @method types
|
||||
* @param {Bool} decide if returned typed should be indexed
|
||||
* @return {Array} array of types
|
||||
*/
|
||||
SolidityEvent.prototype.types = function (indexed) {
|
||||
return this._params.filter(function (i) {
|
||||
return i.indexed === indexed;
|
||||
}).map(function (i) {
|
||||
return i.type;
|
||||
});
|
||||
};
|
||||
|
||||
var inputWithName = function (inputs, name) {
|
||||
var index = utils.findIndex(inputs, function (input) {
|
||||
return input.name === name;
|
||||
/**
|
||||
* Should be used to get event display name
|
||||
*
|
||||
* @method displayName
|
||||
* @return {String} event display name
|
||||
*/
|
||||
SolidityEvent.prototype.displayName = function () {
|
||||
return utils.extractDisplayName(this._name);
|
||||
};
|
||||
|
||||
/**
|
||||
* Should be used to get event type name
|
||||
*
|
||||
* @method typeName
|
||||
* @return {String} event type name
|
||||
*/
|
||||
SolidityEvent.prototype.typeName = function () {
|
||||
return utils.extractTypeName(this._name);
|
||||
};
|
||||
|
||||
/**
|
||||
* Should be used to get event signature
|
||||
*
|
||||
* @method signature
|
||||
* @return {String} event signature
|
||||
*/
|
||||
SolidityEvent.prototype.signature = function () {
|
||||
return web3.sha3(web3.fromAscii(this._name)).slice(2);
|
||||
};
|
||||
|
||||
/**
|
||||
* Should be used to encode indexed params and options to one final object
|
||||
*
|
||||
* @method encode
|
||||
* @param {Object} indexed
|
||||
* @param {Object} options
|
||||
* @return {Object} everything combined together and encoded
|
||||
*/
|
||||
SolidityEvent.prototype.encode = function (indexed, options) {
|
||||
indexed = indexed || {};
|
||||
options = options || {};
|
||||
var result = {};
|
||||
|
||||
['fromBlock', 'toBlock'].filter(function (f) {
|
||||
return options[f] !== undefined;
|
||||
}).forEach(function (f) {
|
||||
result[f] = utils.toHex(options[f]);
|
||||
});
|
||||
|
||||
if (index === -1) {
|
||||
console.error('indexed param with name ' + name + ' not found');
|
||||
return undefined;
|
||||
|
||||
result.topics = [];
|
||||
|
||||
if (!this._anonymous) {
|
||||
result.address = this._address;
|
||||
result.topics.push('0x' + this.signature());
|
||||
}
|
||||
return inputs[index];
|
||||
};
|
||||
|
||||
var indexedParamsToTopics = function (event, indexed) {
|
||||
// sort keys?
|
||||
return Object.keys(indexed).map(function (key) {
|
||||
var inputs = [inputWithName(filterInputs(event.inputs, true), key)];
|
||||
|
||||
var value = indexed[key];
|
||||
if (value instanceof Array) {
|
||||
var indexedTopics = this._params.filter(function (i) {
|
||||
return i.indexed === true;
|
||||
}).map(function (i) {
|
||||
var value = indexed[i.name];
|
||||
if (value === undefined || value === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (utils.isArray(value)) {
|
||||
return value.map(function (v) {
|
||||
return abi.formatInput(inputs, [v]);
|
||||
});
|
||||
return '0x' + coder.encodeParam(i.type, v);
|
||||
});
|
||||
}
|
||||
return '0x' + abi.formatInput(inputs, [value]);
|
||||
return '0x' + coder.encodeParam(i.type, value);
|
||||
});
|
||||
|
||||
result.topics = result.topics.concat(indexedTopics);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
var inputParser = function (address, sign, event) {
|
||||
|
||||
// valid options are 'earliest', 'latest', 'offset' and 'max', as defined for 'eth.filter'
|
||||
return function (indexed, options) {
|
||||
var o = options || {};
|
||||
o.address = address;
|
||||
o.topics = [];
|
||||
o.topics.push(sign);
|
||||
if (indexed) {
|
||||
o.topics = o.topics.concat(indexedParamsToTopics(event, indexed));
|
||||
}
|
||||
return o;
|
||||
/**
|
||||
* Should be used to decode indexed params and options
|
||||
*
|
||||
* @method decode
|
||||
* @param {Object} data
|
||||
* @return {Object} result object with decoded indexed && not indexed params
|
||||
*/
|
||||
SolidityEvent.prototype.decode = function (data) {
|
||||
var result = {
|
||||
event: this.displayName(),
|
||||
args: {},
|
||||
logIndex: utils.toDecimal(data.logIndex),
|
||||
transactionIndex: utils.toDecimal(data.transactionIndex),
|
||||
transactionHash: data.transactionHash,
|
||||
address: data.address,
|
||||
blockHash: data.blockHash,
|
||||
blockNumber: utils.toDecimal(data.blockNumber)
|
||||
};
|
||||
};
|
||||
|
||||
var getArgumentsObject = function (inputs, indexed, notIndexed) {
|
||||
var indexedCopy = indexed.slice();
|
||||
var notIndexedCopy = notIndexed.slice();
|
||||
return inputs.reduce(function (acc, current) {
|
||||
var value;
|
||||
if (current.indexed)
|
||||
value = indexedCopy.splice(0, 1)[0];
|
||||
else
|
||||
value = notIndexedCopy.splice(0, 1)[0];
|
||||
data.data = data.data || '';
|
||||
data.topics = data.topics || [];
|
||||
|
||||
acc[current.name] = value;
|
||||
var argTopics = this._anonymous ? data.topics : data.topics.slice(1);
|
||||
var indexedData = argTopics.map(function (topics) { return topics.slice(2); }).join("");
|
||||
var indexedParams = coder.decodeParams(this.types(true), indexedData);
|
||||
|
||||
var notIndexedData = data.data.slice(2);
|
||||
var notIndexedParams = coder.decodeParams(this.types(false), notIndexedData);
|
||||
|
||||
result.args = this._params.reduce(function (acc, current) {
|
||||
acc[current.name] = current.indexed ? indexedParams.shift() : notIndexedParams.shift();
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
|
||||
var outputParser = function (event) {
|
||||
|
||||
return function (output) {
|
||||
var result = {
|
||||
event: utils.extractDisplayName(event.name),
|
||||
number: output.number,
|
||||
hash: output.hash,
|
||||
args: {}
|
||||
};
|
||||
}, {});
|
||||
|
||||
if (!output.topics) {
|
||||
return result;
|
||||
}
|
||||
output.data = output.data || '';
|
||||
|
||||
var indexedOutputs = filterInputs(event.inputs, true);
|
||||
var indexedData = output.topics.slice(1).map(function (topics) { return topics.slice(2); }).join("");
|
||||
var indexedRes = abi.formatOutput(indexedOutputs, indexedData);
|
||||
|
||||
var notIndexedOutputs = filterInputs(event.inputs, false);
|
||||
var notIndexedRes = abi.formatOutput(notIndexedOutputs, output.data.slice(2));
|
||||
|
||||
result.args = getArgumentsObject(event.inputs, indexedRes, notIndexedRes);
|
||||
|
||||
return result;
|
||||
};
|
||||
return result;
|
||||
};
|
||||
|
||||
var getMatchingEvent = function (events, payload) {
|
||||
for (var i = 0; i < events.length; i++) {
|
||||
var sign = signature.eventSignatureFromAscii(events[i].name);
|
||||
if (sign === payload.topics[0]) {
|
||||
return events[i];
|
||||
}
|
||||
/**
|
||||
* Should be used to create new filter object from event
|
||||
*
|
||||
* @method execute
|
||||
* @param {Object} indexed
|
||||
* @param {Object} options
|
||||
* @return {Object} filter object
|
||||
*/
|
||||
SolidityEvent.prototype.execute = function (indexed, options) {
|
||||
var o = this.encode(indexed, options);
|
||||
var formatter = this.decode.bind(this);
|
||||
return web3.eth.filter(o, undefined, undefined, formatter);
|
||||
};
|
||||
|
||||
/**
|
||||
* Should be used to attach event to contract object
|
||||
*
|
||||
* @method attachToContract
|
||||
* @param {Contract}
|
||||
*/
|
||||
SolidityEvent.prototype.attachToContract = function (contract) {
|
||||
var execute = this.execute.bind(this);
|
||||
var displayName = this.displayName();
|
||||
if (!contract[displayName]) {
|
||||
contract[displayName] = execute;
|
||||
}
|
||||
return undefined;
|
||||
contract[displayName][this.typeName()] = this.execute.bind(this, contract);
|
||||
};
|
||||
|
||||
|
||||
module.exports = {
|
||||
inputParser: inputParser,
|
||||
outputParser: outputParser,
|
||||
getMatchingEvent: getMatchingEvent
|
||||
};
|
||||
module.exports = SolidityEvent;
|
||||
|
||||
|
@ -41,10 +41,13 @@ var getOptions = function (options) {
|
||||
|
||||
// make sure topics, get converted to hex
|
||||
options.topics = options.topics || [];
|
||||
options.topics = options.topics.map(function(topic){
|
||||
return (utils.isArray(topic))
|
||||
? topic.map(utils.toHex)
|
||||
: utils.toHex(topic);
|
||||
options.topics = options.topics.map(function(topic) {
|
||||
if (topic === null || topic === undefined) {
|
||||
return null;
|
||||
} else if (utils.isArray(topic)) {
|
||||
topic = topic.map(utils.toHex);
|
||||
}
|
||||
return utils.toHex(topic);
|
||||
});
|
||||
|
||||
// lazy load
|
||||
|
149
lib/web3/function.js
Normal file
149
lib/web3/function.js
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
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 function.js
|
||||
* @author Marek Kotewicz <marek@ethdev.com>
|
||||
* @date 2015
|
||||
*/
|
||||
|
||||
var web3 = require('../web3');
|
||||
var coder = require('../solidity/coder');
|
||||
var utils = require('../utils/utils');
|
||||
|
||||
/**
|
||||
* This prototype should be used to call/sendTransaction to solidity functions
|
||||
*/
|
||||
var SolidityFunction = function (json, address) {
|
||||
this._inputTypes = json.inputs.map(function (i) {
|
||||
return i.type;
|
||||
});
|
||||
this._outputTypes = json.outputs.map(function (i) {
|
||||
return i.type;
|
||||
});
|
||||
this._constant = json.constant;
|
||||
this._name = utils.transformToFullName(json);
|
||||
this._address = address;
|
||||
};
|
||||
|
||||
/**
|
||||
* Should be used to create payload from arguments
|
||||
*
|
||||
* @method toPayload
|
||||
* @param {...} solidity function params
|
||||
* @param {Object} optional payload options
|
||||
*/
|
||||
SolidityFunction.prototype.toPayload = function () {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var options = {};
|
||||
if (utils.isObject(args[args.length -1])) {
|
||||
options = args.pop();
|
||||
}
|
||||
options.to = this._address;
|
||||
options.data = '0x' + this.signature() + coder.encodeParams(this._inputTypes, args);
|
||||
return options;
|
||||
};
|
||||
|
||||
/**
|
||||
* Should be used to get function signature
|
||||
*
|
||||
* @method signature
|
||||
* @return {String} function signature
|
||||
*/
|
||||
SolidityFunction.prototype.signature = function () {
|
||||
return web3.sha3(web3.fromAscii(this._name)).slice(2, 10);
|
||||
};
|
||||
|
||||
/**
|
||||
* Should be used to call function
|
||||
*
|
||||
* @method call
|
||||
* @param {Object} options
|
||||
* @return {String} output bytes
|
||||
*/
|
||||
SolidityFunction.prototype.call = function () {
|
||||
var payload = this.toPayload.apply(this, Array.prototype.slice.call(arguments));
|
||||
var output = web3.eth.call(payload);
|
||||
return coder.decodeParams(this._outputTypes, output);
|
||||
};
|
||||
|
||||
/**
|
||||
* Should be used to sendTransaction to solidity function
|
||||
*
|
||||
* @method sendTransaction
|
||||
* @param {Object} options
|
||||
*/
|
||||
SolidityFunction.prototype.sendTransaction = function () {
|
||||
var payload = this.toPayload.apply(this, Array.prototype.slice.call(arguments));
|
||||
web3.eth.sendTransaction(payload);
|
||||
};
|
||||
|
||||
/**
|
||||
* Should be used to get function display name
|
||||
*
|
||||
* @method displayName
|
||||
* @return {String} display name of the function
|
||||
*/
|
||||
SolidityFunction.prototype.displayName = function () {
|
||||
return utils.extractDisplayName(this._name);
|
||||
};
|
||||
|
||||
/**
|
||||
* Should be used to get function type name
|
||||
*
|
||||
* @method typeName
|
||||
* @return {String} type name of the function
|
||||
*/
|
||||
SolidityFunction.prototype.typeName = function () {
|
||||
return utils.extractTypeName(this._name);
|
||||
};
|
||||
|
||||
/**
|
||||
* Should be called to execute function
|
||||
*
|
||||
* @method execute
|
||||
*/
|
||||
SolidityFunction.prototype.execute = function () {
|
||||
var transaction = !this._constant;
|
||||
|
||||
// send transaction
|
||||
if (transaction) {
|
||||
return this.sendTransaction.apply(this, Array.prototype.slice.call(arguments));
|
||||
}
|
||||
|
||||
// call
|
||||
return this.call.apply(this, Array.prototype.slice.call(arguments));
|
||||
};
|
||||
|
||||
/**
|
||||
* Should be called to attach function to contract
|
||||
*
|
||||
* @method attachToContract
|
||||
* @param {Contract}
|
||||
*/
|
||||
SolidityFunction.prototype.attachToContract = function (contract) {
|
||||
var execute = this.execute.bind(this);
|
||||
execute.call = this.call.bind(this);
|
||||
execute.sendTransaction = this.sendTransaction.bind(this);
|
||||
var displayName = this.displayName();
|
||||
if (!contract[displayName]) {
|
||||
contract[displayName] = execute;
|
||||
}
|
||||
contract[displayName][this.typeName()] = execute; // circular!!!!
|
||||
};
|
||||
|
||||
module.exports = SolidityFunction;
|
||||
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
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 signature.js
|
||||
* @authors:
|
||||
* Marek Kotewicz <marek@ethdev.com>
|
||||
* @date 2015
|
||||
*/
|
||||
|
||||
var web3 = require('../web3');
|
||||
var c = require('../utils/config');
|
||||
|
||||
/// @param function name for which we want to get signature
|
||||
/// @returns signature of function with given name
|
||||
var functionSignatureFromAscii = function (name) {
|
||||
return web3.sha3(web3.fromAscii(name)).slice(0, 2 + c.ETH_SIGNATURE_LENGTH * 2);
|
||||
};
|
||||
|
||||
/// @param event name for which we want to get signature
|
||||
/// @returns signature of event with given name
|
||||
var eventSignatureFromAscii = function (name) {
|
||||
return web3.sha3(web3.fromAscii(name));
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
functionSignatureFromAscii: functionSignatureFromAscii,
|
||||
eventSignatureFromAscii: eventSignatureFromAscii
|
||||
};
|
||||
|
20
test/coder.decodeParam.js
Normal file
20
test/coder.decodeParam.js
Normal file
@ -0,0 +1,20 @@
|
||||
var chai = require('chai');
|
||||
var assert = chai.assert;
|
||||
var coder = require('../lib/solidity/coder');
|
||||
|
||||
var tests = [
|
||||
{ type: 'int', value: '0000000000000000000000000000000000000000000000000000000000000001', expected: 1},
|
||||
{ type: 'int', value: '0000000000000000000000000000000000000000000000000000000000000010', expected: 16},
|
||||
{ type: 'int', value: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', expected: -1}
|
||||
];
|
||||
|
||||
describe('lib/solidity/coder', function () {
|
||||
describe('decodeParam', function () {
|
||||
tests.forEach(function (test) {
|
||||
it('should turn ' + test.value + ' to ' + test.expected, function () {
|
||||
assert.equal(coder.decodeParam(test.type, test.value), test.expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
20
test/coder.encodeParam.js
Normal file
20
test/coder.encodeParam.js
Normal file
@ -0,0 +1,20 @@
|
||||
var chai = require('chai');
|
||||
var assert = chai.assert;
|
||||
var coder = require('../lib/solidity/coder');
|
||||
|
||||
var tests = [
|
||||
{ type: 'int', value: 1, expected: '0000000000000000000000000000000000000000000000000000000000000001'},
|
||||
{ type: 'int', value: 16, expected: '0000000000000000000000000000000000000000000000000000000000000010'},
|
||||
{ type: 'int', value: -1, expected: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}
|
||||
];
|
||||
|
||||
describe('lib/solidity/coder', function () {
|
||||
describe('encodeParam', function () {
|
||||
tests.forEach(function (test) {
|
||||
it('should turn ' + test.value + ' to ' + test.expected, function () {
|
||||
assert.equal(coder.encodeParam(test.type, test.value), test.expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -63,7 +63,8 @@ describe('web3.eth.contract', function () {
|
||||
assert.deepEqual(payload.params[0], {
|
||||
topics: [
|
||||
sha3,
|
||||
'0x1234567890123456789012345678901234567890'
|
||||
'0x1234567890123456789012345678901234567890',
|
||||
null
|
||||
],
|
||||
address: '0x1234567890123456789012345678901234567890'
|
||||
});
|
||||
@ -206,7 +207,40 @@ describe('web3.eth.contract', function () {
|
||||
var Contract = web3.eth.contract(desc);
|
||||
var contract = new Contract(address);
|
||||
|
||||
contract.call({from: address, gas: 50000}).balance(address);
|
||||
contract.balance(address, {from: address, gas: 50000});
|
||||
|
||||
});
|
||||
|
||||
it('should explicitly make a call with optional params', function () {
|
||||
|
||||
var provider = new FakeHttpProvider();
|
||||
web3.setProvider(provider);
|
||||
web3.reset();
|
||||
var sha3 = '0x5131231231231231231231';
|
||||
var address = '0x1234567890123456789012345678901234567890';
|
||||
provider.injectResult(sha3);
|
||||
var step = 0;
|
||||
provider.injectValidation(function (payload) {
|
||||
if (step === 0) {
|
||||
step = 1;
|
||||
assert.equal(payload.jsonrpc, '2.0');
|
||||
assert.equal(payload.method, 'web3_sha3');
|
||||
assert.equal(payload.params[0], web3.fromAscii('balance(address)'));
|
||||
} else if (step === 1) {
|
||||
assert.equal(payload.method, 'eth_call');
|
||||
assert.deepEqual(payload.params, [{
|
||||
data: sha3.slice(0, 10) + '0000000000000000000000001234567890123456789012345678901234567890',
|
||||
to: address,
|
||||
from: address,
|
||||
gas: '0xc350'
|
||||
}, 'latest']);
|
||||
}
|
||||
});
|
||||
|
||||
var Contract = web3.eth.contract(desc);
|
||||
var contract = new Contract(address);
|
||||
|
||||
contract.balance.call(address, {from: address, gas: 50000});
|
||||
|
||||
});
|
||||
|
||||
@ -242,7 +276,42 @@ describe('web3.eth.contract', function () {
|
||||
var Contract = web3.eth.contract(desc);
|
||||
var contract = new Contract(address);
|
||||
|
||||
contract.sendTransaction({from: address, gas: 50000, gasPrice: 3000, value: 10000}).send(address, 17);
|
||||
contract.send(address, 17, {from: address, gas: 50000, gasPrice: 3000, value: 10000});
|
||||
});
|
||||
|
||||
it('should explicitly sendTransaction with optional params', function () {
|
||||
var provider = new FakeHttpProvider();
|
||||
web3.setProvider(provider);
|
||||
web3.reset();
|
||||
var sha3 = '0x5131231231231231231231';
|
||||
var address = '0x1234567890123456789012345678901234567890';
|
||||
provider.injectResult(sha3);
|
||||
var step = 0;
|
||||
provider.injectValidation(function (payload) {
|
||||
if (step === 0) {
|
||||
step = 1;
|
||||
assert.equal(payload.jsonrpc, '2.0');
|
||||
assert.equal(payload.method, 'web3_sha3');
|
||||
assert.equal(payload.params[0], web3.fromAscii('send(address,uint256)'));
|
||||
} else if (step === 1) {
|
||||
assert.equal(payload.method, 'eth_sendTransaction');
|
||||
assert.deepEqual(payload.params, [{
|
||||
data: sha3.slice(0, 10) +
|
||||
'0000000000000000000000001234567890123456789012345678901234567890' +
|
||||
'0000000000000000000000000000000000000000000000000000000000000011' ,
|
||||
to: address,
|
||||
from: address,
|
||||
gas: '0xc350',
|
||||
gasPrice: '0xbb8',
|
||||
value: '0x2710'
|
||||
}]);
|
||||
}
|
||||
});
|
||||
|
||||
var Contract = web3.eth.contract(desc);
|
||||
var contract = new Contract(address);
|
||||
|
||||
contract.send.sendTransaction(address, 17, {from: address, gas: 50000, gasPrice: 3000, value: 10000});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
180
test/event.decode.js
Normal file
180
test/event.decode.js
Normal file
@ -0,0 +1,180 @@
|
||||
var chai = require('chai');
|
||||
var assert = chai.assert;
|
||||
var BigNumber = require('bignumber.js');
|
||||
var SolidityEvent = require('../lib/web3/event');
|
||||
|
||||
var name = 'event1';
|
||||
var address = '0x1234567890123456789012345678901234567890';
|
||||
|
||||
var tests = [{
|
||||
abi: {
|
||||
name: name,
|
||||
inputs: []
|
||||
},
|
||||
data: {
|
||||
logIndex: '0x1',
|
||||
transactionIndex: '0x10',
|
||||
transactionHash: '0x1234567890',
|
||||
address: address,
|
||||
blockHash: '0x1234567890',
|
||||
blockNumber: '0x1'
|
||||
},
|
||||
expected: {
|
||||
event: name,
|
||||
args: {},
|
||||
logIndex: 1,
|
||||
transactionIndex: 16,
|
||||
transactionHash: '0x1234567890',
|
||||
address: address,
|
||||
blockHash: '0x1234567890',
|
||||
blockNumber: 1
|
||||
}
|
||||
}, {
|
||||
abi: {
|
||||
name: name,
|
||||
inputs: [{
|
||||
name: 'a',
|
||||
type: 'int',
|
||||
indexed: false
|
||||
}]
|
||||
},
|
||||
data: {
|
||||
logIndex: '0x1',
|
||||
transactionIndex: '0x10',
|
||||
transactionHash: '0x1234567890',
|
||||
address: address,
|
||||
blockHash: '0x1234567890',
|
||||
blockNumber: '0x1',
|
||||
data: '0x0000000000000000000000000000000000000000000000000000000000000001'
|
||||
},
|
||||
expected: {
|
||||
event: name,
|
||||
args: {
|
||||
a: new BigNumber(1)
|
||||
},
|
||||
logIndex: 1,
|
||||
transactionIndex: 16,
|
||||
transactionHash: '0x1234567890',
|
||||
address: address,
|
||||
blockHash: '0x1234567890',
|
||||
blockNumber: 1
|
||||
}
|
||||
}, {
|
||||
abi: {
|
||||
name: name,
|
||||
inputs: [{
|
||||
name: 'a',
|
||||
type: 'int',
|
||||
indexed: false
|
||||
}, {
|
||||
name: 'b',
|
||||
type: 'int',
|
||||
indexed: true
|
||||
}, {
|
||||
name: 'c',
|
||||
type: 'int',
|
||||
indexed: false
|
||||
}, {
|
||||
name: 'd',
|
||||
type: 'int',
|
||||
indexed: true
|
||||
}]
|
||||
},
|
||||
data: {
|
||||
logIndex: '0x1',
|
||||
transactionIndex: '0x10',
|
||||
transactionHash: '0x1234567890',
|
||||
address: address,
|
||||
blockHash: '0x1234567890',
|
||||
blockNumber: '0x1',
|
||||
data: '0x' +
|
||||
'0000000000000000000000000000000000000000000000000000000000000001' +
|
||||
'0000000000000000000000000000000000000000000000000000000000000004',
|
||||
topics: [
|
||||
address,
|
||||
'0x000000000000000000000000000000000000000000000000000000000000000a',
|
||||
'0x0000000000000000000000000000000000000000000000000000000000000010'
|
||||
]
|
||||
},
|
||||
expected: {
|
||||
event: name,
|
||||
args: {
|
||||
a: new BigNumber(1),
|
||||
b: new BigNumber(10),
|
||||
c: new BigNumber(4),
|
||||
d: new BigNumber(16)
|
||||
},
|
||||
logIndex: 1,
|
||||
transactionIndex: 16,
|
||||
transactionHash: '0x1234567890',
|
||||
address: address,
|
||||
blockHash: '0x1234567890',
|
||||
blockNumber: 1
|
||||
}
|
||||
}, {
|
||||
abi: {
|
||||
name: name,
|
||||
anonymous: true,
|
||||
inputs: [{
|
||||
name: 'a',
|
||||
type: 'int',
|
||||
indexed: false
|
||||
}, {
|
||||
name: 'b',
|
||||
type: 'int',
|
||||
indexed: true
|
||||
}, {
|
||||
name: 'c',
|
||||
type: 'int',
|
||||
indexed: false
|
||||
}, {
|
||||
name: 'd',
|
||||
type: 'int',
|
||||
indexed: true
|
||||
}]
|
||||
},
|
||||
data: {
|
||||
logIndex: '0x1',
|
||||
transactionIndex: '0x10',
|
||||
transactionHash: '0x1234567890',
|
||||
address: address,
|
||||
blockHash: '0x1234567890',
|
||||
blockNumber: '0x1',
|
||||
data: '0x' +
|
||||
'0000000000000000000000000000000000000000000000000000000000000001' +
|
||||
'0000000000000000000000000000000000000000000000000000000000000004',
|
||||
topics: [
|
||||
'0x000000000000000000000000000000000000000000000000000000000000000a',
|
||||
'0x0000000000000000000000000000000000000000000000000000000000000010'
|
||||
]
|
||||
},
|
||||
expected: {
|
||||
event: name,
|
||||
args: {
|
||||
a: new BigNumber(1),
|
||||
b: new BigNumber(10),
|
||||
c: new BigNumber(4),
|
||||
d: new BigNumber(16)
|
||||
},
|
||||
logIndex: 1,
|
||||
transactionIndex: 16,
|
||||
transactionHash: '0x1234567890',
|
||||
address: address,
|
||||
blockHash: '0x1234567890',
|
||||
blockNumber: 1
|
||||
}
|
||||
}];
|
||||
|
||||
describe('lib/web3/event', function () {
|
||||
describe('decode', function () {
|
||||
tests.forEach(function (test, index) {
|
||||
it('test no: ' + index, function () {
|
||||
var event = new SolidityEvent(test.abi, address);
|
||||
|
||||
var result = event.decode(test.data);
|
||||
assert.deepEqual(result, test.expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
206
test/event.encode.js
Normal file
206
test/event.encode.js
Normal file
@ -0,0 +1,206 @@
|
||||
var chai = require('chai');
|
||||
var assert = chai.assert;
|
||||
var SolidityEvent = require('../lib/web3/event');
|
||||
|
||||
var address = '0x1234567890123456789012345678901234567890';
|
||||
var signature = '0xffff';
|
||||
|
||||
var tests = [{
|
||||
abi: {
|
||||
name: 'event1',
|
||||
inputs: []
|
||||
},
|
||||
indexed: {},
|
||||
options: {},
|
||||
expected: {
|
||||
address: address,
|
||||
topics: [
|
||||
signature
|
||||
]
|
||||
}
|
||||
}, {
|
||||
abi: {
|
||||
name: 'event1',
|
||||
inputs: [{
|
||||
type: 'int',
|
||||
name: 'a',
|
||||
indexed: true
|
||||
}]
|
||||
},
|
||||
indexed: {
|
||||
a: 16
|
||||
},
|
||||
options: {},
|
||||
expected: {
|
||||
address: address,
|
||||
topics: [
|
||||
signature,
|
||||
'0x0000000000000000000000000000000000000000000000000000000000000010'
|
||||
]
|
||||
}
|
||||
},{
|
||||
abi: {
|
||||
name: 'event1',
|
||||
inputs: [{
|
||||
type: 'int',
|
||||
name: 'a',
|
||||
indexed: true
|
||||
}, {
|
||||
type: 'int',
|
||||
name: 'b',
|
||||
indexed: true
|
||||
}, {
|
||||
type: 'int',
|
||||
name: 'c',
|
||||
indexed: false
|
||||
}, {
|
||||
type: 'int',
|
||||
name: 'd',
|
||||
indexed: true
|
||||
}]
|
||||
},
|
||||
indexed: {
|
||||
b: 4
|
||||
},
|
||||
options: {},
|
||||
expected: {
|
||||
address: address,
|
||||
topics: [
|
||||
signature, // signature
|
||||
null, // a
|
||||
'0x0000000000000000000000000000000000000000000000000000000000000004', // b
|
||||
null // d
|
||||
]
|
||||
}
|
||||
}, {
|
||||
abi: {
|
||||
name: 'event1',
|
||||
inputs: [{
|
||||
type: 'int',
|
||||
name: 'a',
|
||||
indexed: true
|
||||
}, {
|
||||
type: 'int',
|
||||
name: 'b',
|
||||
indexed: true
|
||||
}]
|
||||
},
|
||||
indexed: {
|
||||
a: [16, 1],
|
||||
b: 2
|
||||
},
|
||||
options: {},
|
||||
expected: {
|
||||
address: address,
|
||||
topics: [
|
||||
signature,
|
||||
['0x0000000000000000000000000000000000000000000000000000000000000010', '0x0000000000000000000000000000000000000000000000000000000000000001'],
|
||||
'0x0000000000000000000000000000000000000000000000000000000000000002'
|
||||
]
|
||||
}
|
||||
}, {
|
||||
abi: {
|
||||
name: 'event1',
|
||||
inputs: [{
|
||||
type: 'int',
|
||||
name: 'a',
|
||||
indexed: true
|
||||
}]
|
||||
},
|
||||
indexed: {
|
||||
a: null
|
||||
},
|
||||
options: {},
|
||||
expected: {
|
||||
address: address,
|
||||
topics: [
|
||||
signature,
|
||||
null
|
||||
]
|
||||
}
|
||||
}, {
|
||||
abi: {
|
||||
name: 'event1',
|
||||
inputs: [{
|
||||
type: 'int',
|
||||
name: 'a',
|
||||
indexed: true
|
||||
}]
|
||||
},
|
||||
indexed: {
|
||||
a: 1
|
||||
},
|
||||
options: {
|
||||
fromBlock: 4,
|
||||
toBlock: 10
|
||||
},
|
||||
expected: {
|
||||
address: address,
|
||||
fromBlock: '0x4',
|
||||
toBlock: '0xa',
|
||||
topics: [
|
||||
signature,
|
||||
'0x0000000000000000000000000000000000000000000000000000000000000001'
|
||||
]
|
||||
}
|
||||
}, {
|
||||
abi: {
|
||||
name: 'event1',
|
||||
inputs: [{
|
||||
type: 'int',
|
||||
name: 'a',
|
||||
indexed: true
|
||||
}],
|
||||
anonymous: true
|
||||
},
|
||||
indexed: {
|
||||
a: 1
|
||||
},
|
||||
options: {},
|
||||
expected: {
|
||||
topics: [
|
||||
'0x0000000000000000000000000000000000000000000000000000000000000001'
|
||||
]
|
||||
}
|
||||
}, {
|
||||
abi: {
|
||||
name: 'event1',
|
||||
inputs: [{
|
||||
type: 'int',
|
||||
name: 'a',
|
||||
indexed: true
|
||||
}, {
|
||||
type: 'int',
|
||||
name: 'b',
|
||||
indexed: true
|
||||
}],
|
||||
anonymous: true
|
||||
},
|
||||
indexed: {
|
||||
b: 1
|
||||
},
|
||||
options: {},
|
||||
expected: {
|
||||
topics: [
|
||||
null,
|
||||
'0x0000000000000000000000000000000000000000000000000000000000000001'
|
||||
]
|
||||
}
|
||||
}];
|
||||
|
||||
describe('lib/web3/event', function () {
|
||||
describe('encode', function () {
|
||||
tests.forEach(function (test, index) {
|
||||
it('test no: ' + index, function () {
|
||||
var event = new SolidityEvent(test.abi, address);
|
||||
event.signature = function () { // inject signature
|
||||
return signature.slice(2);
|
||||
};
|
||||
|
||||
var result = event.encode(test.indexed, test.options);
|
||||
assert.deepEqual(result, test.expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,113 +0,0 @@
|
||||
var assert = require('assert');
|
||||
var event = require('../lib/web3/event.js');
|
||||
var f = require('../lib/solidity/formatters.js');
|
||||
|
||||
describe('lib/web3/event', function () {
|
||||
describe('inputParser', function () {
|
||||
it('should create basic filter input object', function () {
|
||||
|
||||
// given
|
||||
var address = '0x012345';
|
||||
var signature = '0x987654';
|
||||
var e = {
|
||||
name: 'Event',
|
||||
inputs: [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"hash256","indexed":false}]
|
||||
};
|
||||
|
||||
// when
|
||||
var impl = event.inputParser(address, signature, e);
|
||||
var result = impl();
|
||||
|
||||
// then
|
||||
assert.equal(result.address, address);
|
||||
assert.equal(result.topics.length, 1);
|
||||
assert.equal(result.topics[0], signature);
|
||||
|
||||
});
|
||||
|
||||
it('should create filter input object with options', function () {
|
||||
|
||||
// given
|
||||
var address = '0x012345';
|
||||
var signature = '0x987654';
|
||||
var options = {
|
||||
fromBlock: 1,
|
||||
toBlock: 2,
|
||||
};
|
||||
var e = {
|
||||
name: 'Event',
|
||||
inputs: [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"hash256","indexed":false}]
|
||||
};
|
||||
|
||||
// when
|
||||
var impl = event.inputParser(address, signature, e);
|
||||
var result = impl({}, options);
|
||||
|
||||
// then
|
||||
assert.equal(result.address, address);
|
||||
assert.equal(result.topics.length, 1);
|
||||
assert.equal(result.topics[0], signature);
|
||||
assert.equal(result.fromBlock, options.fromBlock);
|
||||
assert.equal(result.toBlock, options.toBlock);
|
||||
|
||||
});
|
||||
|
||||
it('should create filter input object with indexed params', function () {
|
||||
|
||||
// given
|
||||
var address = '0x012345';
|
||||
var signature = '0x987654';
|
||||
var options = {
|
||||
fromBlock: 1,
|
||||
toBlock: 2
|
||||
};
|
||||
var e = {
|
||||
name: 'Event',
|
||||
inputs: [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"hash256","indexed":false}]
|
||||
};
|
||||
|
||||
// when
|
||||
var impl = event.inputParser(address, signature, e);
|
||||
var result = impl({a: 4}, options);
|
||||
|
||||
// then
|
||||
assert.equal(result.address, address);
|
||||
assert.equal(result.topics.length, 2);
|
||||
assert.equal(result.topics[0], signature);
|
||||
assert.equal(result.topics[1], '0x' + f.formatInputInt(4).encode());
|
||||
assert.equal(result.fromBlock, options.fromBlock);
|
||||
assert.equal(result.toBlock, options.toBlock);
|
||||
|
||||
});
|
||||
|
||||
it('should create filter input object with an array of indexed params', function () {
|
||||
|
||||
// given
|
||||
var address = '0x012345';
|
||||
var signature = '0x987654';
|
||||
var options = {
|
||||
fromBlock: 1,
|
||||
toBlock: 2,
|
||||
};
|
||||
var e = {
|
||||
name: 'Event',
|
||||
inputs: [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"hash256","indexed":false}]
|
||||
};
|
||||
|
||||
// when
|
||||
var impl = event.inputParser(address, signature, e);
|
||||
var result = impl({a: [4, 69]}, options);
|
||||
|
||||
// then
|
||||
assert.equal(result.address, address);
|
||||
assert.equal(result.topics.length, 2);
|
||||
assert.equal(result.topics[0], signature);
|
||||
assert.equal(result.topics[1][0], f.formatInputInt(4).encode());
|
||||
assert.equal(result.topics[1][1], f.formatInputInt(69).encode());
|
||||
assert.equal(result.fromBlock, options.fromBlock);
|
||||
assert.equal(result.toBlock, options.toBlock);
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,81 +0,0 @@
|
||||
var assert = require('assert');
|
||||
var event = require('../lib/web3/event.js');
|
||||
|
||||
describe('lib/web3/event', function () {
|
||||
describe('outputParser', function () {
|
||||
it('should parse basic event output object', function () {
|
||||
|
||||
// given
|
||||
var output = {
|
||||
"address":"0x78dfc5983baecf65f73e3de3a96cee24e6b7981e",
|
||||
"data":"0x000000000000000000000000000000000000000000000000000000000000004b",
|
||||
"number":2,
|
||||
"topics":[
|
||||
"0x6e61ef44ac2747ff8b84d353a908eb8bd5c3fb118334d57698c5cfc7041196ad",
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000001"
|
||||
]
|
||||
};
|
||||
|
||||
var e = {
|
||||
name: 'Event',
|
||||
inputs: [{"name":"a","type":"bool","indexed":true},{"name":"b","type":"uint256","indexed":false}]
|
||||
};
|
||||
|
||||
// when
|
||||
var impl = event.outputParser(e);
|
||||
var result = impl(output);
|
||||
|
||||
// then
|
||||
assert.equal(result.event, 'Event');
|
||||
assert.equal(result.number, 2);
|
||||
assert.equal(Object.keys(result.args).length, 2);
|
||||
assert.equal(result.args.a, true);
|
||||
assert.equal(result.args.b, 75);
|
||||
});
|
||||
|
||||
it('should parse event output object arguments in correct order', function () {
|
||||
|
||||
// given
|
||||
var output = {
|
||||
"address":"0x78dfc5983baecf65f73e3de3a96cee24e6b7981e",
|
||||
"data": "0x" +
|
||||
"000000000000000000000000000000000000000000000000000000000000004b" +
|
||||
"000000000000000000000000000000000000000000000000000000000000004c" +
|
||||
"0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"number":3,
|
||||
"topics":[
|
||||
"0x6e61ef44ac2747ff8b84d353a908eb8bd5c3fb118334d57698c5cfc7041196ad",
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000005"
|
||||
]
|
||||
};
|
||||
|
||||
var e = {
|
||||
name: 'Event2',
|
||||
inputs: [
|
||||
{"name":"a","type":"bool","indexed":true},
|
||||
{"name":"b","type":"int","indexed":false},
|
||||
{"name":"c","type":"int","indexed":false},
|
||||
{"name":"d","type":"int","indexed":true},
|
||||
{"name":"e","type":"bool","indexed":false}
|
||||
]
|
||||
};
|
||||
|
||||
// when
|
||||
var impl = event.outputParser(e);
|
||||
var result = impl(output);
|
||||
|
||||
// then
|
||||
assert.equal(result.event, 'Event2');
|
||||
assert.equal(result.number, 3);
|
||||
assert.equal(Object.keys(result.args).length, 5);
|
||||
assert.equal(result.args.a, true);
|
||||
assert.equal(result.args.b, 75);
|
||||
assert.equal(result.args.c, 76);
|
||||
assert.equal(result.args.d, 5);
|
||||
assert.equal(result.args.e, true);
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,4 +1,5 @@
|
||||
var assert = require('assert');
|
||||
var chai = require('chai');
|
||||
var assert = chai.assert;
|
||||
var formatters = require('../lib/web3/formatters.js');
|
||||
var BigNumber = require('bignumber.js');
|
||||
|
||||
|
@ -1,48 +0,0 @@
|
||||
var chai = require('chai');
|
||||
var assert = chai.assert;
|
||||
var utils = require('../lib/utils/utils');
|
||||
var FakeHttpProvider = require('./helpers/FakeHttpProvider');
|
||||
var signature = require('../lib/web3/signature');
|
||||
var web3 = require('../index');
|
||||
|
||||
var tests = [{
|
||||
method: 'functionSignatureFromAscii',
|
||||
call: 'web3_sha3',
|
||||
request: 'multiply',
|
||||
formattedRequest: utils.fromAscii('multiply'),
|
||||
result: '0x255d31552d29a21e93334e96055c6dca7cd329f5420ae74ec166d0c47f9f9843',
|
||||
formattedResult: '0x255d3155'
|
||||
},{
|
||||
method: 'eventSignatureFromAscii',
|
||||
call: 'web3_sha3',
|
||||
request: 'multiply',
|
||||
formattedRequest: utils.fromAscii('multiply'),
|
||||
result: '0x255d31552d29a21e93334e96055c6dca7cd329f5420ae74ec166d0c47f9f9843',
|
||||
formattedResult: '0x255d31552d29a21e93334e96055c6dca7cd329f5420ae74ec166d0c47f9f9843'
|
||||
}];
|
||||
|
||||
describe('lib/web3/signature', function () {
|
||||
tests.forEach(function (test, index) {
|
||||
describe(test.method, function () {
|
||||
it('should properly format and return signature of solidity functioni ' + index, function () {
|
||||
|
||||
// given
|
||||
var provider = new FakeHttpProvider();
|
||||
web3.setProvider(provider);
|
||||
provider.injectResult(test.result);
|
||||
provider.injectValidation(function (payload) {
|
||||
assert.equal(payload.method, test.call);
|
||||
assert.equal(payload.jsonrpc, '2.0');
|
||||
assert.equal(payload.params[0], test.formattedRequest);
|
||||
});
|
||||
|
||||
// when
|
||||
var result = signature[test.method].call(null, test.request);
|
||||
|
||||
// then
|
||||
assert.equal(result, test.formattedResult);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,49 +0,0 @@
|
||||
var assert = require('assert');
|
||||
var utils = require('../lib/solidity/utils');
|
||||
|
||||
describe('lib/utils/utils', function() {
|
||||
it('should filter functions and events from input array properly', function () {
|
||||
|
||||
// given
|
||||
var description = [{
|
||||
"name": "test",
|
||||
"type": "function",
|
||||
"inputs": [{
|
||||
"name": "a",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "d",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
}, {
|
||||
"name": "test2",
|
||||
"type": "event",
|
||||
"inputs": [{
|
||||
"name": "a",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "d",
|
||||
"type": "uint256"
|
||||
}
|
||||
]
|
||||
}];
|
||||
|
||||
// when
|
||||
var events = utils.filterEvents(description);
|
||||
var functions = utils.filterFunctions(description);
|
||||
|
||||
// then
|
||||
assert.equal(events.length, 1);
|
||||
assert.equal(events[0].name, 'test2');
|
||||
assert.equal(functions.length, 1);
|
||||
assert.equal(functions[0].name, 'test');
|
||||
|
||||
});
|
||||
});
|
@ -4,7 +4,6 @@ var BigNumber = require('bignumber.js');
|
||||
var assert = chai.assert;
|
||||
|
||||
var tests = [
|
||||
{ value: null, expected: null },
|
||||
{ value: 1, expected: '0x1' },
|
||||
{ value: '1', expected: '0x1' },
|
||||
{ value: '0x1', expected: '0x1'},
|
||||
|
Loading…
x
Reference in New Issue
Block a user