Browse Source

Squashed 'libjsqrc/ethereumjs/' changes from 3b799d1..e908439

e908439 version 0.3.6
091c8e5 Merge branch 'develop' into tcoulter
272837e cleaned up param.js
38a13bc removed unused functions from coder.js
8e3158f Merge pull request #196 from debris/new_abi
c6a57b3 cleanup and documentation
6e60e1f new solidity abi decoding
3f0d1c8 new abi proposal implementation of encoding
39d70e8 Merge pull request #195 from debris/fixed_abi
f963855 removed unused functions from abi.js
c59419e added new "dave" example
860ad2c fixed #194
22ca9b0 Merge branch 'develop' of https://github.com/ethereum/ethereum.js into develop
6739a1b "dave" example
08f3aae add optional nonce property to sendTransaction
2ca4240 Add error handling to synchronous methods (obligatory warning against using synchronous calls at all).
4690130 version 0.3.5
7949f6a Merge pull request #187 from debris/encoding
944c5cc removed unused test files
8a9c9c5 Merge branch 'develop' into encoding
330b0da more tests for encoding and decoding solidity params
b064eab Handle this error properly. For instance, without this, if we cannot connect to the RPC client, JSON won't be able to parse the result (there is none), in which case would cause a RuntimeException.
7989607 version 0.3.4
afb61d5 Merge branch 'master' into develop
97f6e7d build files again
539ef7b Merge pull request #186 from ethereum/eventFilterFix
ec0dc44 Merge pull request #188 from ethereum/develop
bd73ccc added eth_hashrate
baed4c8 fixed old encoding
e9ec708 fixed event from and toBlock

git-subtree-dir: libjsqrc/ethereumjs
git-subtree-split: e90843973f3ae554069347b61cb5b393091c34d1
cl-refactor
Marek Kotewicz 10 years ago
parent
commit
13a7445597
  1. 2
      bower.json
  2. 448
      dist/web3-light.js
  3. 22
      dist/web3-light.js.map
  4. 4
      dist/web3-light.min.js
  5. 448
      dist/web3.js
  6. 22
      dist/web3.js.map
  7. 4
      dist/web3.min.js
  8. 2
      example/event_inc.html
  9. 103
      lib/solidity/abi.js
  10. 85
      lib/solidity/coder.js
  11. 14
      lib/solidity/formatters.js
  12. 191
      lib/solidity/param.js
  13. 5
      lib/solidity/utils.js
  14. 2
      lib/version.json
  15. 17
      lib/web3/eth.js
  16. 2
      lib/web3/event.js
  17. 2
      lib/web3/formatters.js
  18. 23
      lib/web3/httpprovider.js
  19. 2
      package.js
  20. 2
      package.json
  21. 515
      test/abi.inputParser.js
  22. 419
      test/abi.outputParser.js
  23. 45
      test/coder.decodeParam.js
  24. 82
      test/coder.encodeParam.js
  25. 1
      test/contract.js
  26. 26
      test/event.encode.js
  27. 70
      test/formatters.inputTransactionFormatter.js
  28. 15
      test/web3.eth.filter.js
  29. 38
      test/web3.eth.hashRate.js

2
bower.json

@ -1,7 +1,7 @@
{ {
"name": "web3", "name": "web3",
"namespace": "ethereum", "namespace": "ethereum",
"version": "0.3.3", "version": "0.3.6",
"description": "Ethereum Compatible JavaScript API", "description": "Ethereum Compatible JavaScript API",
"main": [ "main": [
"./dist/web3.js", "./dist/web3.js",

448
dist/web3-light.js

@ -22,118 +22,29 @@ require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof requ
* @date 2014 * @date 2014
*/ */
var utils = require('../utils/utils');
var coder = require('./coder'); var coder = require('./coder');
var solUtils = require('./utils'); var utils = require('./utils');
/**
* Formats input params to bytes
*
* @method formatInput
* @param {Array} abi inputs of method
* @param {Array} params that will be formatted to bytes
* @returns bytes representation of input params
*/
var formatInput = function (inputs, params) {
var i = inputs.map(function (input) {
return input.type;
});
return coder.encodeParams(i, params);
};
/**
* Formats output bytes back to param list
*
* @method formatOutput
* @param {Array} abi outputs of method
* @param {String} bytes represention of output
* @returns {Array} output params
*/
var formatOutput = function (outs, bytes) {
var o = outs.map(function (out) {
return out.type;
});
return coder.decodeParams(o, bytes);
};
/**
* Should be called to create input parser for contract with given abi
*
* @method inputParser
* @param {Array} contract abi
* @returns {Object} input parser object for given json abi
* TODO: refactor creating the parser, do not double logic from contract
*/
var inputParser = function (json) {
var parser = {};
json.forEach(function (method) {
var displayName = utils.extractDisplayName(method.name);
var typeName = utils.extractTypeName(method.name);
var impl = function () {
var params = Array.prototype.slice.call(arguments);
return formatInput(method.inputs, params);
};
if (parser[displayName] === undefined) {
parser[displayName] = impl;
}
parser[displayName][typeName] = impl;
});
return parser;
};
/**
* Should be called to create output parser for contract with given abi
*
* @method outputParser
* @param {Array} contract abi
* @returns {Object} output parser for given json abi
*/
var outputParser = function (json) {
var parser = {};
json.forEach(function (method) {
var displayName = utils.extractDisplayName(method.name);
var typeName = utils.extractTypeName(method.name);
var impl = function (output) {
return formatOutput(method.outputs, output);
};
if (parser[displayName] === undefined) {
parser[displayName] = impl;
}
parser[displayName][typeName] = impl;
});
return parser;
};
var formatConstructorParams = function (abi, params) { var formatConstructorParams = function (abi, params) {
var constructor = solUtils.getConstructor(abi, params.length); var constructor = utils.getConstructor(abi, params.length);
if (!constructor) { if (!constructor) {
if (params.length > 0) { if (params.length > 0) {
console.warn("didn't found matching constructor, using default one"); console.warn("didn't found matching constructor, using default one");
} }
return ''; return '';
} }
return formatInput(constructor.inputs, params);
return coder.encodeParams(constructor.inputs.map(function (input) {
return input.type;
}), params);
}; };
module.exports = { module.exports = {
inputParser: inputParser,
outputParser: outputParser,
formatInput: formatInput,
formatOutput: formatOutput,
formatConstructorParams: formatConstructorParams formatConstructorParams: formatConstructorParams
}; };
},{"../utils/utils":8,"./coder":2,"./utils":5}],2:[function(require,module,exports){
},{"./coder":2,"./utils":5}],2:[function(require,module,exports){
/* /*
This file is part of ethereum.js. This file is part of ethereum.js.
@ -213,9 +124,8 @@ SolidityType.prototype.formatInput = function (param, arrayType) {
return param.map(function (p) { return param.map(function (p) {
return self._inputFormatter(p); return self._inputFormatter(p);
}).reduce(function (acc, current) { }).reduce(function (acc, current) {
acc.appendArrayElement(current); return acc.combine(current);
return acc; }, f.formatInputInt(param.length)).withOffset(32);
}, new SolidityParam('', f.formatInputInt(param.length).value));
} }
return this._inputFormatter(param); return this._inputFormatter(param);
}; };
@ -232,9 +142,9 @@ SolidityType.prototype.formatOutput = function (param, arrayType) {
if (arrayType) { if (arrayType) {
// let's assume, that we solidity will never return long arrays :P // let's assume, that we solidity will never return long arrays :P
var result = []; var result = [];
var length = new BigNumber(param.prefix, 16); var length = new BigNumber(param.dynamicPart().slice(0, 64), 16);
for (var i = 0; i < length * 64; i += 64) { for (var i = 0; i < length * 64; i += 64) {
result.push(this._outputFormatter(new SolidityParam(param.suffix.slice(i, i + 64)))); result.push(this._outputFormatter(new SolidityParam(param.dynamicPart().substr(i + 64, 64))));
} }
return result; return result;
} }
@ -242,31 +152,21 @@ SolidityType.prototype.formatOutput = function (param, arrayType) {
}; };
/** /**
* Should be used to check if a type is variadic * Should be used to slice single param from bytes
* *
* @method isVariadicType * @method sliceParam
* @param {String} type * @param {String} bytes
* @returns {Bool} true if the type is variadic * @param {Number} index of param to slice
*/
SolidityType.prototype.isVariadicType = function (type) {
return isArrayType(type) || this._mode === 'bytes';
};
/**
* Should be used to shift param from params group
*
* @method shiftParam
* @param {String} type * @param {String} type
* @returns {SolidityParam} shifted param * @returns {SolidityParam} param
*/ */
SolidityType.prototype.shiftParam = function (type, param) { SolidityType.prototype.sliceParam = function (bytes, index, type) {
if (this._mode === 'bytes') { if (this._mode === 'bytes') {
return param.shiftBytes(); return SolidityParam.decodeBytes(bytes, index);
} else if (isArrayType(type)) { } else if (isArrayType(type)) {
var length = new BigNumber(param.prefix.slice(0, 64), 16); return SolidityParam.decodeArray(bytes, index);
return param.shiftArray(length);
} }
return param.shiftValue(); return SolidityParam.decodeParam(bytes, index);
}; };
/** /**
@ -296,28 +196,6 @@ SolidityCoder.prototype._requireType = function (type) {
return solidityType; return solidityType;
}; };
/**
* Should be used to transform plain bytes to SolidityParam object
*
* @method _bytesToParam
* @param {Array} types of params
* @param {String} bytes to be transformed to SolidityParam
* @return {SolidityParam} SolidityParam for this group of params
*/
SolidityCoder.prototype._bytesToParam = function (types, bytes) {
var self = this;
var prefixTypes = types.reduce(function (acc, type) {
return self._requireType(type).isVariadicType(type) ? acc + 1 : acc;
}, 0);
var valueTypes = types.length - prefixTypes;
var prefix = bytes.slice(0, prefixTypes * 64);
bytes = bytes.slice(prefixTypes * 64);
var value = bytes.slice(0, valueTypes * 64);
var suffix = bytes.slice(valueTypes * 64);
return new SolidityParam(value, prefix, suffix);
};
/** /**
* Should be used to transform plain param of given type to SolidityParam * Should be used to transform plain param of given type to SolidityParam
* *
@ -352,24 +230,11 @@ SolidityCoder.prototype.encodeParam = function (type, param) {
*/ */
SolidityCoder.prototype.encodeParams = function (types, params) { SolidityCoder.prototype.encodeParams = function (types, params) {
var self = this; var self = this;
return types.map(function (type, index) { var solidityParams = types.map(function (type, index) {
return self._formatInput(type, params[index]); return self._formatInput(type, params[index]);
}).reduce(function (acc, solidityParam) { });
acc.append(solidityParam);
return acc;
}, new SolidityParam()).encode();
};
/** return SolidityParam.encodeList(solidityParams);
* Should be used to transform SolidityParam to plain param
*
* @method _formatOutput
* @param {String} type
* @param {SolidityParam} param
* @return {Object} plain param
*/
SolidityCoder.prototype._formatOutput = function (type, param) {
return this._requireType(type).formatOutput(param, isArrayType(type));
}; };
/** /**
@ -381,7 +246,7 @@ SolidityCoder.prototype._formatOutput = function (type, param) {
* @return {Object} plain param * @return {Object} plain param
*/ */
SolidityCoder.prototype.decodeParam = function (type, bytes) { SolidityCoder.prototype.decodeParam = function (type, bytes) {
return this._formatOutput(type, this._bytesToParam([type], bytes)); return this.decodeParams([type], bytes)[0];
}; };
/** /**
@ -394,10 +259,9 @@ SolidityCoder.prototype.decodeParam = function (type, bytes) {
*/ */
SolidityCoder.prototype.decodeParams = function (types, bytes) { SolidityCoder.prototype.decodeParams = function (types, bytes) {
var self = this; var self = this;
var param = this._bytesToParam(types, bytes); return types.map(function (type, index) {
return types.map(function (type) {
var solidityType = self._requireType(type); var solidityType = self._requireType(type);
var p = solidityType.shiftParam(type, param); var p = solidityType.sliceParam(bytes, index, type);
return solidityType.formatOutput(p, isArrayType(type)); return solidityType.formatOutput(p, isArrayType(type));
}); });
}; };
@ -530,7 +394,7 @@ var formatInputBytes = function (value) {
*/ */
var formatInputDynamicBytes = function (value) { var formatInputDynamicBytes = function (value) {
var result = utils.fromAscii(value, c.ETH_PADDING).substr(2); var result = utils.fromAscii(value, c.ETH_PADDING).substr(2);
return new SolidityParam('', formatInputInt(value.length).value, result); return new SolidityParam(formatInputInt(value.length).value + result, 32);
}; };
/** /**
@ -576,7 +440,7 @@ var signedIsNegative = function (value) {
* @returns {BigNumber} right-aligned output bytes formatted to big number * @returns {BigNumber} right-aligned output bytes formatted to big number
*/ */
var formatOutputInt = function (param) { var formatOutputInt = function (param) {
var value = param.value || "0"; var value = param.staticPart() || "0";
// check if it's negative number // check if it's negative number
// it it is, return two's complement // it it is, return two's complement
@ -594,7 +458,7 @@ var formatOutputInt = function (param) {
* @returns {BigNumeber} right-aligned output bytes formatted to uint * @returns {BigNumeber} right-aligned output bytes formatted to uint
*/ */
var formatOutputUInt = function (param) { var formatOutputUInt = function (param) {
var value = param.value || "0"; var value = param.staticPart() || "0";
return new BigNumber(value, 16); return new BigNumber(value, 16);
}; };
@ -628,7 +492,7 @@ var formatOutputUReal = function (param) {
* @returns {Boolean} right-aligned input bytes formatted to bool * @returns {Boolean} right-aligned input bytes formatted to bool
*/ */
var formatOutputBool = function (param) { var formatOutputBool = function (param) {
return param.value === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false; return param.staticPart() === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false;
}; };
/** /**
@ -640,7 +504,7 @@ var formatOutputBool = function (param) {
*/ */
var formatOutputBytes = function (param) { var formatOutputBytes = function (param) {
// length might also be important! // length might also be important!
return utils.toAscii(param.value); return utils.toAscii(param.staticPart());
}; };
/** /**
@ -652,7 +516,7 @@ var formatOutputBytes = function (param) {
*/ */
var formatOutputDynamicBytes = function (param) { var formatOutputDynamicBytes = function (param) {
// length might also be important! // length might also be important!
return utils.toAscii(param.suffix); return utils.toAscii(param.dynamicPart().slice(64));
}; };
/** /**
@ -663,7 +527,7 @@ var formatOutputDynamicBytes = function (param) {
* @returns {String} address * @returns {String} address
*/ */
var formatOutputAddress = function (param) { var formatOutputAddress = function (param) {
var value = param.value; var value = param.staticPart();
return "0x" + value.slice(value.length - 40, value.length); return "0x" + value.slice(value.length - 40, value.length);
}; };
@ -707,91 +571,196 @@ module.exports = {
* @date 2015 * @date 2015
*/ */
var utils = require('../utils/utils');
/** /**
* SolidityParam object prototype. * SolidityParam object prototype.
* Should be used when encoding, decoding solidity bytes * Should be used when encoding, decoding solidity bytes
*/ */
var SolidityParam = function (value, prefix, suffix) { var SolidityParam = function (value, offset) {
this.prefix = prefix || '';
this.value = value || ''; this.value = value || '';
this.suffix = suffix || ''; this.offset = offset; // offset in bytes
};
/**
* This method should be used to get length of params's dynamic part
*
* @method dynamicPartLength
* @returns {Number} length of dynamic part (in bytes)
*/
SolidityParam.prototype.dynamicPartLength = function () {
return this.dynamicPart().length / 2;
};
/**
* This method should be used to create copy of solidity param with different offset
*
* @method withOffset
* @param {Number} offset length in bytes
* @returns {SolidityParam} new solidity param with applied offset
*/
SolidityParam.prototype.withOffset = function (offset) {
return new SolidityParam(this.value, offset);
}; };
/** /**
* This method should be used to encode two params one after another * This method should be used to combine solidity params together
* eg. when appending an array
* *
* @method append * @method combine
* @param {SolidityParam} param that it appended after this * @param {SolidityParam} param with which we should combine
* @param {SolidityParam} result of combination
*/ */
SolidityParam.prototype.append = function (param) { SolidityParam.prototype.combine = function (param) {
this.prefix += param.prefix; return new SolidityParam(this.value + param.value);
this.value += param.value;
this.suffix += param.suffix;
}; };
/** /**
* This method should be used to encode next param in an array * This method should be called to check if param has dynamic size.
* If it has, it returns true, otherwise false
* *
* @method appendArrayElement * @method isDynamic
* @param {SolidityParam} param that is appended to an array * @returns {Boolean}
*/ */
SolidityParam.prototype.appendArrayElement = function (param) { SolidityParam.prototype.isDynamic = function () {
this.suffix += param.value; return this.value.length > 64;
this.prefix += param.prefix;
// TODO: suffix not supported = it's required for nested arrays;
}; };
/** /**
* This method should be used to create bytearrays from param * This method should be called to transform offset to bytes
*
* @method offsetAsBytes
* @returns {String} bytes representation of offset
*/
SolidityParam.prototype.offsetAsBytes = function () {
return !this.isDynamic() ? '' : utils.padLeft(utils.toTwosComplement(this.offset).toString(16), 64);
};
/**
* This method should be called to get static part of param
*
* @method staticPart
* @returns {String} offset if it is a dynamic param, otherwise value
*/
SolidityParam.prototype.staticPart = function () {
if (!this.isDynamic()) {
return this.value;
}
return this.offsetAsBytes();
};
/**
* This method should be called to get dynamic part of param
*
* @method dynamicPart
* @returns {String} returns a value if it is a dynamic param, otherwise empty string
*/
SolidityParam.prototype.dynamicPart = function () {
return this.isDynamic() ? this.value : '';
};
/**
* This method should be called to encode param
* *
* @method encode * @method encode
* @return {String} encoded param(s) * @returns {String}
*/ */
SolidityParam.prototype.encode = function () { SolidityParam.prototype.encode = function () {
return this.prefix + this.value + this.suffix; return this.staticPart() + this.dynamicPart();
}; };
/** /**
* This method should be used to shift first param from group of params * This method should be called to encode array of params
* *
* @method shiftValue * @method encodeList
* @return {SolidityParam} first value param * @param {Array[SolidityParam]} params
* @returns {String}
*/ */
SolidityParam.prototype.shiftValue = function () { SolidityParam.encodeList = function (params) {
var value = this.value.slice(0, 64);
this.value = this.value.slice(64); // updating offsets
return new SolidityParam(value); var totalOffset = params.length * 32;
var offsetParams = params.map(function (param) {
if (!param.isDynamic()) {
return param;
}
var offset = totalOffset;
totalOffset += param.dynamicPartLength();
return param.withOffset(offset);
});
// encode everything!
return offsetParams.reduce(function (result, param) {
return result + param.dynamicPart();
}, offsetParams.reduce(function (result, param) {
return result + param.staticPart();
}, ''));
}; };
/** /**
* This method should be used to first bytes param from group of params * This method should be used to decode plain (static) solidity param at given index
* *
* @method shiftBytes * @method decodeParam
* @return {SolidityParam} first bytes param * @param {String} bytes
* @param {Number} index
* @returns {SolidityParam}
*/ */
SolidityParam.prototype.shiftBytes = function () { SolidityParam.decodeParam = function (bytes, index) {
return this.shiftArray(1); index = index || 0;
return new SolidityParam(bytes.substr(index * 64, 64));
}; };
/** /**
* This method should be used to shift an array from group of params * This method should be called to get offset value from bytes at given index
* *
* @method shiftArray * @method getOffset
* @param {Number} size of an array to shift * @param {String} bytes
* @return {SolidityParam} first array param * @param {Number} index
* @returns {Number} offset as number
*/
var getOffset = function (bytes, index) {
// we can do this cause offset is rather small
return parseInt('0x' + bytes.substr(index * 64, 64));
};
/**
* This method should be called to decode solidity bytes param at given index
*
* @method decodeBytes
* @param {String} bytes
* @param {Number} index
* @returns {SolidityParam}
*/
SolidityParam.decodeBytes = function (bytes, index) {
index = index || 0;
//TODO add support for strings longer than 32 bytes
//var length = parseInt('0x' + bytes.substr(offset * 64, 64));
var offset = getOffset(bytes, index);
// 2 * , cause we also parse length
return new SolidityParam(bytes.substr(offset * 2, 2 * 64));
};
/**
* This method should be used to decode solidity array at given index
*
* @method decodeArray
* @param {String} bytes
* @param {Number} index
* @returns {SolidityParam}
*/ */
SolidityParam.prototype.shiftArray = function (length) { SolidityParam.decodeArray = function (bytes, index) {
var prefix = this.prefix.slice(0, 64); index = index || 0;
this.prefix = this.value.slice(64); var offset = getOffset(bytes, index);
var suffix = this.suffix.slice(0, 64 * length); var length = parseInt('0x' + bytes.substr(offset * 2, 64));
this.suffix = this.suffix.slice(64 * length); return new SolidityParam(bytes.substr(offset * 2, (length + 1) * 64));
return new SolidityParam('', prefix, suffix);
}; };
module.exports = SolidityParam; module.exports = SolidityParam;
},{}],5:[function(require,module,exports){ },{"../utils/utils":8}],5:[function(require,module,exports){
/* /*
This file is part of ethereum.js. This file is part of ethereum.js.
@ -828,6 +797,11 @@ var getConstructor = function (abi, numberOfArgs) {
})[0]; })[0];
}; };
//var getSupremeType = function (type) {
//return type.substr(0, type.indexOf('[')) + ']';
//};
module.exports = { module.exports = {
getConstructor: getConstructor getConstructor: getConstructor
}; };
@ -1394,7 +1368,7 @@ module.exports = {
},{"bignumber.js":"bignumber.js"}],9:[function(require,module,exports){ },{"bignumber.js":"bignumber.js"}],9:[function(require,module,exports){
module.exports={ module.exports={
"version": "0.3.3" "version": "0.3.6"
} }
},{}],10:[function(require,module,exports){ },{}],10:[function(require,module,exports){
@ -1796,7 +1770,7 @@ module.exports = {
/** /**
* Web3 * Web3
* *
* @module web3 * @module web3
*/ */
@ -1850,16 +1824,16 @@ var uncleCountCall = function (args) {
/// @returns an array of objects describing web3.eth api methods /// @returns an array of objects describing web3.eth api methods
var getBalance = new Method({ var getBalance = new Method({
name: 'getBalance', name: 'getBalance',
call: 'eth_getBalance', call: 'eth_getBalance',
params: 2, params: 2,
inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter], inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter],
outputFormatter: formatters.outputBigNumberFormatter outputFormatter: formatters.outputBigNumberFormatter
}); });
var getStorageAt = new Method({ var getStorageAt = new Method({
name: 'getStorageAt', name: 'getStorageAt',
call: 'eth_getStorageAt', call: 'eth_getStorageAt',
params: 3, params: 3,
inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter] inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter]
}); });
@ -1872,7 +1846,7 @@ var getCode = new Method({
}); });
var getBlock = new Method({ var getBlock = new Method({
name: 'getBlock', name: 'getBlock',
call: blockCall, call: blockCall,
params: 2, params: 2,
inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }], inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }],
@ -1997,6 +1971,11 @@ var properties = [
name: 'mining', name: 'mining',
getter: 'eth_mining' getter: 'eth_mining'
}), }),
new Property({
name: 'hashrate',
getter: 'eth_hashrate',
outputFormatter: utils.toDecimal
}),
new Property({ new Property({
name: 'gasPrice', name: 'gasPrice',
getter: 'eth_gasPrice', getter: 'eth_gasPrice',
@ -2118,7 +2097,7 @@ SolidityEvent.prototype.encode = function (indexed, options) {
['fromBlock', 'toBlock'].filter(function (f) { ['fromBlock', 'toBlock'].filter(function (f) {
return options[f] !== undefined; return options[f] !== undefined;
}).forEach(function (f) { }).forEach(function (f) {
result[f] = utils.toHex(options[f]); result[f] = formatters.inputBlockNumberFormatter(options[f]);
}); });
result.topics = []; result.topics = [];
@ -2447,7 +2426,7 @@ var inputTransactionFormatter = function (options){
delete options.code; delete options.code;
} }
['gasPrice', 'gas', 'value'].filter(function (key) { ['gasPrice', 'gas', 'value', 'nonce'].filter(function (key) {
return options[key] !== undefined; return options[key] !== undefined;
}).forEach(function(key){ }).forEach(function(key){
options[key] = utils.fromDecimal(options[key]); options[key] = utils.fromDecimal(options[key]);
@ -2796,15 +2775,32 @@ HttpProvider.prototype.send = function (payload) {
//if (request.status !== 200) { //if (request.status !== 200) {
//return; //return;
//} //}
return JSON.parse(request.responseText);
var result = request.responseText;
try {
result = JSON.parse(result);
} catch(e) {
throw errors.InvalidResponse(result);
}
return result;
}; };
HttpProvider.prototype.sendAsync = function (payload, callback) { HttpProvider.prototype.sendAsync = function (payload, callback) {
var request = new XMLHttpRequest(); var request = new XMLHttpRequest();
request.onreadystatechange = function() { request.onreadystatechange = function() {
if (request.readyState === 4) { if (request.readyState === 4) {
// TODO: handle the error properly here!!! var result = request.responseText;
callback(null, JSON.parse(request.responseText)); var error = null;
try {
result = JSON.parse(result);
} catch(e) {
error = errors.InvalidResponse(result);
}
callback(error, result);
} }
}; };

22
dist/web3-light.js.map

File diff suppressed because one or more lines are too long

4
dist/web3-light.min.js

File diff suppressed because one or more lines are too long

448
dist/web3.js

@ -22,118 +22,29 @@ require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof requ
* @date 2014 * @date 2014
*/ */
var utils = require('../utils/utils');
var coder = require('./coder'); var coder = require('./coder');
var solUtils = require('./utils'); var utils = require('./utils');
/**
* Formats input params to bytes
*
* @method formatInput
* @param {Array} abi inputs of method
* @param {Array} params that will be formatted to bytes
* @returns bytes representation of input params
*/
var formatInput = function (inputs, params) {
var i = inputs.map(function (input) {
return input.type;
});
return coder.encodeParams(i, params);
};
/**
* Formats output bytes back to param list
*
* @method formatOutput
* @param {Array} abi outputs of method
* @param {String} bytes represention of output
* @returns {Array} output params
*/
var formatOutput = function (outs, bytes) {
var o = outs.map(function (out) {
return out.type;
});
return coder.decodeParams(o, bytes);
};
/**
* Should be called to create input parser for contract with given abi
*
* @method inputParser
* @param {Array} contract abi
* @returns {Object} input parser object for given json abi
* TODO: refactor creating the parser, do not double logic from contract
*/
var inputParser = function (json) {
var parser = {};
json.forEach(function (method) {
var displayName = utils.extractDisplayName(method.name);
var typeName = utils.extractTypeName(method.name);
var impl = function () {
var params = Array.prototype.slice.call(arguments);
return formatInput(method.inputs, params);
};
if (parser[displayName] === undefined) {
parser[displayName] = impl;
}
parser[displayName][typeName] = impl;
});
return parser;
};
/**
* Should be called to create output parser for contract with given abi
*
* @method outputParser
* @param {Array} contract abi
* @returns {Object} output parser for given json abi
*/
var outputParser = function (json) {
var parser = {};
json.forEach(function (method) {
var displayName = utils.extractDisplayName(method.name);
var typeName = utils.extractTypeName(method.name);
var impl = function (output) {
return formatOutput(method.outputs, output);
};
if (parser[displayName] === undefined) {
parser[displayName] = impl;
}
parser[displayName][typeName] = impl;
});
return parser;
};
var formatConstructorParams = function (abi, params) { var formatConstructorParams = function (abi, params) {
var constructor = solUtils.getConstructor(abi, params.length); var constructor = utils.getConstructor(abi, params.length);
if (!constructor) { if (!constructor) {
if (params.length > 0) { if (params.length > 0) {
console.warn("didn't found matching constructor, using default one"); console.warn("didn't found matching constructor, using default one");
} }
return ''; return '';
} }
return formatInput(constructor.inputs, params);
return coder.encodeParams(constructor.inputs.map(function (input) {
return input.type;
}), params);
}; };
module.exports = { module.exports = {
inputParser: inputParser,
outputParser: outputParser,
formatInput: formatInput,
formatOutput: formatOutput,
formatConstructorParams: formatConstructorParams formatConstructorParams: formatConstructorParams
}; };
},{"../utils/utils":8,"./coder":2,"./utils":5}],2:[function(require,module,exports){
},{"./coder":2,"./utils":5}],2:[function(require,module,exports){
/* /*
This file is part of ethereum.js. This file is part of ethereum.js.
@ -213,9 +124,8 @@ SolidityType.prototype.formatInput = function (param, arrayType) {
return param.map(function (p) { return param.map(function (p) {
return self._inputFormatter(p); return self._inputFormatter(p);
}).reduce(function (acc, current) { }).reduce(function (acc, current) {
acc.appendArrayElement(current); return acc.combine(current);
return acc; }, f.formatInputInt(param.length)).withOffset(32);
}, new SolidityParam('', f.formatInputInt(param.length).value));
} }
return this._inputFormatter(param); return this._inputFormatter(param);
}; };
@ -232,9 +142,9 @@ SolidityType.prototype.formatOutput = function (param, arrayType) {
if (arrayType) { if (arrayType) {
// let's assume, that we solidity will never return long arrays :P // let's assume, that we solidity will never return long arrays :P
var result = []; var result = [];
var length = new BigNumber(param.prefix, 16); var length = new BigNumber(param.dynamicPart().slice(0, 64), 16);
for (var i = 0; i < length * 64; i += 64) { for (var i = 0; i < length * 64; i += 64) {
result.push(this._outputFormatter(new SolidityParam(param.suffix.slice(i, i + 64)))); result.push(this._outputFormatter(new SolidityParam(param.dynamicPart().substr(i + 64, 64))));
} }
return result; return result;
} }
@ -242,31 +152,21 @@ SolidityType.prototype.formatOutput = function (param, arrayType) {
}; };
/** /**
* Should be used to check if a type is variadic * Should be used to slice single param from bytes
* *
* @method isVariadicType * @method sliceParam
* @param {String} type * @param {String} bytes
* @returns {Bool} true if the type is variadic * @param {Number} index of param to slice
*/
SolidityType.prototype.isVariadicType = function (type) {
return isArrayType(type) || this._mode === 'bytes';
};
/**
* Should be used to shift param from params group
*
* @method shiftParam
* @param {String} type * @param {String} type
* @returns {SolidityParam} shifted param * @returns {SolidityParam} param
*/ */
SolidityType.prototype.shiftParam = function (type, param) { SolidityType.prototype.sliceParam = function (bytes, index, type) {
if (this._mode === 'bytes') { if (this._mode === 'bytes') {
return param.shiftBytes(); return SolidityParam.decodeBytes(bytes, index);
} else if (isArrayType(type)) { } else if (isArrayType(type)) {
var length = new BigNumber(param.prefix.slice(0, 64), 16); return SolidityParam.decodeArray(bytes, index);
return param.shiftArray(length);
} }
return param.shiftValue(); return SolidityParam.decodeParam(bytes, index);
}; };
/** /**
@ -296,28 +196,6 @@ SolidityCoder.prototype._requireType = function (type) {
return solidityType; return solidityType;
}; };
/**
* Should be used to transform plain bytes to SolidityParam object
*
* @method _bytesToParam
* @param {Array} types of params
* @param {String} bytes to be transformed to SolidityParam
* @return {SolidityParam} SolidityParam for this group of params
*/
SolidityCoder.prototype._bytesToParam = function (types, bytes) {
var self = this;
var prefixTypes = types.reduce(function (acc, type) {
return self._requireType(type).isVariadicType(type) ? acc + 1 : acc;
}, 0);
var valueTypes = types.length - prefixTypes;
var prefix = bytes.slice(0, prefixTypes * 64);
bytes = bytes.slice(prefixTypes * 64);
var value = bytes.slice(0, valueTypes * 64);
var suffix = bytes.slice(valueTypes * 64);
return new SolidityParam(value, prefix, suffix);
};
/** /**
* Should be used to transform plain param of given type to SolidityParam * Should be used to transform plain param of given type to SolidityParam
* *
@ -352,24 +230,11 @@ SolidityCoder.prototype.encodeParam = function (type, param) {
*/ */
SolidityCoder.prototype.encodeParams = function (types, params) { SolidityCoder.prototype.encodeParams = function (types, params) {
var self = this; var self = this;
return types.map(function (type, index) { var solidityParams = types.map(function (type, index) {
return self._formatInput(type, params[index]); return self._formatInput(type, params[index]);
}).reduce(function (acc, solidityParam) { });
acc.append(solidityParam);
return acc;
}, new SolidityParam()).encode();
};
/** return SolidityParam.encodeList(solidityParams);
* Should be used to transform SolidityParam to plain param
*
* @method _formatOutput
* @param {String} type
* @param {SolidityParam} param
* @return {Object} plain param
*/
SolidityCoder.prototype._formatOutput = function (type, param) {
return this._requireType(type).formatOutput(param, isArrayType(type));
}; };
/** /**
@ -381,7 +246,7 @@ SolidityCoder.prototype._formatOutput = function (type, param) {
* @return {Object} plain param * @return {Object} plain param
*/ */
SolidityCoder.prototype.decodeParam = function (type, bytes) { SolidityCoder.prototype.decodeParam = function (type, bytes) {
return this._formatOutput(type, this._bytesToParam([type], bytes)); return this.decodeParams([type], bytes)[0];
}; };
/** /**
@ -394,10 +259,9 @@ SolidityCoder.prototype.decodeParam = function (type, bytes) {
*/ */
SolidityCoder.prototype.decodeParams = function (types, bytes) { SolidityCoder.prototype.decodeParams = function (types, bytes) {
var self = this; var self = this;
var param = this._bytesToParam(types, bytes); return types.map(function (type, index) {
return types.map(function (type) {
var solidityType = self._requireType(type); var solidityType = self._requireType(type);
var p = solidityType.shiftParam(type, param); var p = solidityType.sliceParam(bytes, index, type);
return solidityType.formatOutput(p, isArrayType(type)); return solidityType.formatOutput(p, isArrayType(type));
}); });
}; };
@ -530,7 +394,7 @@ var formatInputBytes = function (value) {
*/ */
var formatInputDynamicBytes = function (value) { var formatInputDynamicBytes = function (value) {
var result = utils.fromAscii(value, c.ETH_PADDING).substr(2); var result = utils.fromAscii(value, c.ETH_PADDING).substr(2);
return new SolidityParam('', formatInputInt(value.length).value, result); return new SolidityParam(formatInputInt(value.length).value + result, 32);
}; };
/** /**
@ -576,7 +440,7 @@ var signedIsNegative = function (value) {
* @returns {BigNumber} right-aligned output bytes formatted to big number * @returns {BigNumber} right-aligned output bytes formatted to big number
*/ */
var formatOutputInt = function (param) { var formatOutputInt = function (param) {
var value = param.value || "0"; var value = param.staticPart() || "0";
// check if it's negative number // check if it's negative number
// it it is, return two's complement // it it is, return two's complement
@ -594,7 +458,7 @@ var formatOutputInt = function (param) {
* @returns {BigNumeber} right-aligned output bytes formatted to uint * @returns {BigNumeber} right-aligned output bytes formatted to uint
*/ */
var formatOutputUInt = function (param) { var formatOutputUInt = function (param) {
var value = param.value || "0"; var value = param.staticPart() || "0";
return new BigNumber(value, 16); return new BigNumber(value, 16);
}; };
@ -628,7 +492,7 @@ var formatOutputUReal = function (param) {
* @returns {Boolean} right-aligned input bytes formatted to bool * @returns {Boolean} right-aligned input bytes formatted to bool
*/ */
var formatOutputBool = function (param) { var formatOutputBool = function (param) {
return param.value === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false; return param.staticPart() === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false;
}; };
/** /**
@ -640,7 +504,7 @@ var formatOutputBool = function (param) {
*/ */
var formatOutputBytes = function (param) { var formatOutputBytes = function (param) {
// length might also be important! // length might also be important!
return utils.toAscii(param.value); return utils.toAscii(param.staticPart());
}; };
/** /**
@ -652,7 +516,7 @@ var formatOutputBytes = function (param) {
*/ */
var formatOutputDynamicBytes = function (param) { var formatOutputDynamicBytes = function (param) {
// length might also be important! // length might also be important!
return utils.toAscii(param.suffix); return utils.toAscii(param.dynamicPart().slice(64));
}; };
/** /**
@ -663,7 +527,7 @@ var formatOutputDynamicBytes = function (param) {
* @returns {String} address * @returns {String} address
*/ */
var formatOutputAddress = function (param) { var formatOutputAddress = function (param) {
var value = param.value; var value = param.staticPart();
return "0x" + value.slice(value.length - 40, value.length); return "0x" + value.slice(value.length - 40, value.length);
}; };
@ -707,91 +571,196 @@ module.exports = {
* @date 2015 * @date 2015
*/ */
var utils = require('../utils/utils');
/** /**
* SolidityParam object prototype. * SolidityParam object prototype.
* Should be used when encoding, decoding solidity bytes * Should be used when encoding, decoding solidity bytes
*/ */
var SolidityParam = function (value, prefix, suffix) { var SolidityParam = function (value, offset) {
this.prefix = prefix || '';
this.value = value || ''; this.value = value || '';
this.suffix = suffix || ''; this.offset = offset; // offset in bytes
};
/**
* This method should be used to get length of params's dynamic part
*
* @method dynamicPartLength
* @returns {Number} length of dynamic part (in bytes)
*/
SolidityParam.prototype.dynamicPartLength = function () {
return this.dynamicPart().length / 2;
};
/**
* This method should be used to create copy of solidity param with different offset
*
* @method withOffset
* @param {Number} offset length in bytes
* @returns {SolidityParam} new solidity param with applied offset
*/
SolidityParam.prototype.withOffset = function (offset) {
return new SolidityParam(this.value, offset);
}; };
/** /**
* This method should be used to encode two params one after another * This method should be used to combine solidity params together
* eg. when appending an array
* *
* @method append * @method combine
* @param {SolidityParam} param that it appended after this * @param {SolidityParam} param with which we should combine
* @param {SolidityParam} result of combination
*/ */
SolidityParam.prototype.append = function (param) { SolidityParam.prototype.combine = function (param) {
this.prefix += param.prefix; return new SolidityParam(this.value + param.value);
this.value += param.value;
this.suffix += param.suffix;
}; };
/** /**
* This method should be used to encode next param in an array * This method should be called to check if param has dynamic size.
* If it has, it returns true, otherwise false
* *
* @method appendArrayElement * @method isDynamic
* @param {SolidityParam} param that is appended to an array * @returns {Boolean}
*/ */
SolidityParam.prototype.appendArrayElement = function (param) { SolidityParam.prototype.isDynamic = function () {
this.suffix += param.value; return this.value.length > 64;
this.prefix += param.prefix;
// TODO: suffix not supported = it's required for nested arrays;
}; };
/** /**
* This method should be used to create bytearrays from param * This method should be called to transform offset to bytes
*
* @method offsetAsBytes
* @returns {String} bytes representation of offset
*/
SolidityParam.prototype.offsetAsBytes = function () {
return !this.isDynamic() ? '' : utils.padLeft(utils.toTwosComplement(this.offset).toString(16), 64);
};
/**
* This method should be called to get static part of param
*
* @method staticPart
* @returns {String} offset if it is a dynamic param, otherwise value
*/
SolidityParam.prototype.staticPart = function () {
if (!this.isDynamic()) {
return this.value;
}
return this.offsetAsBytes();
};
/**
* This method should be called to get dynamic part of param
*
* @method dynamicPart
* @returns {String} returns a value if it is a dynamic param, otherwise empty string
*/
SolidityParam.prototype.dynamicPart = function () {
return this.isDynamic() ? this.value : '';
};
/**
* This method should be called to encode param
* *
* @method encode * @method encode
* @return {String} encoded param(s) * @returns {String}
*/ */
SolidityParam.prototype.encode = function () { SolidityParam.prototype.encode = function () {
return this.prefix + this.value + this.suffix; return this.staticPart() + this.dynamicPart();
}; };
/** /**
* This method should be used to shift first param from group of params * This method should be called to encode array of params
* *
* @method shiftValue * @method encodeList
* @return {SolidityParam} first value param * @param {Array[SolidityParam]} params
* @returns {String}
*/ */
SolidityParam.prototype.shiftValue = function () { SolidityParam.encodeList = function (params) {
var value = this.value.slice(0, 64);
this.value = this.value.slice(64); // updating offsets
return new SolidityParam(value); var totalOffset = params.length * 32;
var offsetParams = params.map(function (param) {
if (!param.isDynamic()) {
return param;
}
var offset = totalOffset;
totalOffset += param.dynamicPartLength();
return param.withOffset(offset);
});
// encode everything!
return offsetParams.reduce(function (result, param) {
return result + param.dynamicPart();
}, offsetParams.reduce(function (result, param) {
return result + param.staticPart();
}, ''));
}; };
/** /**
* This method should be used to first bytes param from group of params * This method should be used to decode plain (static) solidity param at given index
* *
* @method shiftBytes * @method decodeParam
* @return {SolidityParam} first bytes param * @param {String} bytes
* @param {Number} index
* @returns {SolidityParam}
*/ */
SolidityParam.prototype.shiftBytes = function () { SolidityParam.decodeParam = function (bytes, index) {
return this.shiftArray(1); index = index || 0;
return new SolidityParam(bytes.substr(index * 64, 64));
}; };
/** /**
* This method should be used to shift an array from group of params * This method should be called to get offset value from bytes at given index
* *
* @method shiftArray * @method getOffset
* @param {Number} size of an array to shift * @param {String} bytes
* @return {SolidityParam} first array param * @param {Number} index
* @returns {Number} offset as number
*/
var getOffset = function (bytes, index) {
// we can do this cause offset is rather small
return parseInt('0x' + bytes.substr(index * 64, 64));
};
/**
* This method should be called to decode solidity bytes param at given index
*
* @method decodeBytes
* @param {String} bytes
* @param {Number} index
* @returns {SolidityParam}
*/
SolidityParam.decodeBytes = function (bytes, index) {
index = index || 0;
//TODO add support for strings longer than 32 bytes
//var length = parseInt('0x' + bytes.substr(offset * 64, 64));
var offset = getOffset(bytes, index);
// 2 * , cause we also parse length
return new SolidityParam(bytes.substr(offset * 2, 2 * 64));
};
/**
* This method should be used to decode solidity array at given index
*
* @method decodeArray
* @param {String} bytes
* @param {Number} index
* @returns {SolidityParam}
*/ */
SolidityParam.prototype.shiftArray = function (length) { SolidityParam.decodeArray = function (bytes, index) {
var prefix = this.prefix.slice(0, 64); index = index || 0;
this.prefix = this.value.slice(64); var offset = getOffset(bytes, index);
var suffix = this.suffix.slice(0, 64 * length); var length = parseInt('0x' + bytes.substr(offset * 2, 64));
this.suffix = this.suffix.slice(64 * length); return new SolidityParam(bytes.substr(offset * 2, (length + 1) * 64));
return new SolidityParam('', prefix, suffix);
}; };
module.exports = SolidityParam; module.exports = SolidityParam;
},{}],5:[function(require,module,exports){ },{"../utils/utils":8}],5:[function(require,module,exports){
/* /*
This file is part of ethereum.js. This file is part of ethereum.js.
@ -828,6 +797,11 @@ var getConstructor = function (abi, numberOfArgs) {
})[0]; })[0];
}; };
//var getSupremeType = function (type) {
//return type.substr(0, type.indexOf('[')) + ']';
//};
module.exports = { module.exports = {
getConstructor: getConstructor getConstructor: getConstructor
}; };
@ -1394,7 +1368,7 @@ module.exports = {
},{"bignumber.js":"bignumber.js"}],9:[function(require,module,exports){ },{"bignumber.js":"bignumber.js"}],9:[function(require,module,exports){
module.exports={ module.exports={
"version": "0.3.3" "version": "0.3.6"
} }
},{}],10:[function(require,module,exports){ },{}],10:[function(require,module,exports){
@ -1796,7 +1770,7 @@ module.exports = {
/** /**
* Web3 * Web3
* *
* @module web3 * @module web3
*/ */
@ -1850,16 +1824,16 @@ var uncleCountCall = function (args) {
/// @returns an array of objects describing web3.eth api methods /// @returns an array of objects describing web3.eth api methods
var getBalance = new Method({ var getBalance = new Method({
name: 'getBalance', name: 'getBalance',
call: 'eth_getBalance', call: 'eth_getBalance',
params: 2, params: 2,
inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter], inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter],
outputFormatter: formatters.outputBigNumberFormatter outputFormatter: formatters.outputBigNumberFormatter
}); });
var getStorageAt = new Method({ var getStorageAt = new Method({
name: 'getStorageAt', name: 'getStorageAt',
call: 'eth_getStorageAt', call: 'eth_getStorageAt',
params: 3, params: 3,
inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter] inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter]
}); });
@ -1872,7 +1846,7 @@ var getCode = new Method({
}); });
var getBlock = new Method({ var getBlock = new Method({
name: 'getBlock', name: 'getBlock',
call: blockCall, call: blockCall,
params: 2, params: 2,
inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }], inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }],
@ -1997,6 +1971,11 @@ var properties = [
name: 'mining', name: 'mining',
getter: 'eth_mining' getter: 'eth_mining'
}), }),
new Property({
name: 'hashrate',
getter: 'eth_hashrate',
outputFormatter: utils.toDecimal
}),
new Property({ new Property({
name: 'gasPrice', name: 'gasPrice',
getter: 'eth_gasPrice', getter: 'eth_gasPrice',
@ -2118,7 +2097,7 @@ SolidityEvent.prototype.encode = function (indexed, options) {
['fromBlock', 'toBlock'].filter(function (f) { ['fromBlock', 'toBlock'].filter(function (f) {
return options[f] !== undefined; return options[f] !== undefined;
}).forEach(function (f) { }).forEach(function (f) {
result[f] = utils.toHex(options[f]); result[f] = formatters.inputBlockNumberFormatter(options[f]);
}); });
result.topics = []; result.topics = [];
@ -2447,7 +2426,7 @@ var inputTransactionFormatter = function (options){
delete options.code; delete options.code;
} }
['gasPrice', 'gas', 'value'].filter(function (key) { ['gasPrice', 'gas', 'value', 'nonce'].filter(function (key) {
return options[key] !== undefined; return options[key] !== undefined;
}).forEach(function(key){ }).forEach(function(key){
options[key] = utils.fromDecimal(options[key]); options[key] = utils.fromDecimal(options[key]);
@ -2796,15 +2775,32 @@ HttpProvider.prototype.send = function (payload) {
//if (request.status !== 200) { //if (request.status !== 200) {
//return; //return;
//} //}
return JSON.parse(request.responseText);
var result = request.responseText;
try {
result = JSON.parse(result);
} catch(e) {
throw errors.InvalidResponse(result);
}
return result;
}; };
HttpProvider.prototype.sendAsync = function (payload, callback) { HttpProvider.prototype.sendAsync = function (payload, callback) {
var request = new XMLHttpRequest(); var request = new XMLHttpRequest();
request.onreadystatechange = function() { request.onreadystatechange = function() {
if (request.readyState === 4) { if (request.readyState === 4) {
// TODO: handle the error properly here!!! var result = request.responseText;
callback(null, JSON.parse(request.responseText)); var error = null;
try {
result = JSON.parse(result);
} catch(e) {
error = errors.InvalidResponse(result);
}
callback(error, result);
} }
}; };

22
dist/web3.js.map

File diff suppressed because one or more lines are too long

4
dist/web3.min.js

File diff suppressed because one or more lines are too long

2
example/event_inc.html

@ -45,7 +45,7 @@
var contract; var contract;
var update = function (err, x) { var update = function (err, x) {
document.getElementById('result').innerText = JSON.stringify(x, null, 2); document.getElementById('result').textContent = JSON.stringify(x, null, 2);
}; };
var createContract = function () { var createContract = function () {

103
lib/solidity/abi.js

@ -21,113 +21,24 @@
* @date 2014 * @date 2014
*/ */
var utils = require('../utils/utils');
var coder = require('./coder'); var coder = require('./coder');
var solUtils = require('./utils'); var utils = require('./utils');
/**
* Formats input params to bytes
*
* @method formatInput
* @param {Array} abi inputs of method
* @param {Array} params that will be formatted to bytes
* @returns bytes representation of input params
*/
var formatInput = function (inputs, params) {
var i = inputs.map(function (input) {
return input.type;
});
return coder.encodeParams(i, params);
};
/**
* Formats output bytes back to param list
*
* @method formatOutput
* @param {Array} abi outputs of method
* @param {String} bytes represention of output
* @returns {Array} output params
*/
var formatOutput = function (outs, bytes) {
var o = outs.map(function (out) {
return out.type;
});
return coder.decodeParams(o, bytes);
};
/**
* Should be called to create input parser for contract with given abi
*
* @method inputParser
* @param {Array} contract abi
* @returns {Object} input parser object for given json abi
* TODO: refactor creating the parser, do not double logic from contract
*/
var inputParser = function (json) {
var parser = {};
json.forEach(function (method) {
var displayName = utils.extractDisplayName(method.name);
var typeName = utils.extractTypeName(method.name);
var impl = function () {
var params = Array.prototype.slice.call(arguments);
return formatInput(method.inputs, params);
};
if (parser[displayName] === undefined) {
parser[displayName] = impl;
}
parser[displayName][typeName] = impl;
});
return parser;
};
/**
* Should be called to create output parser for contract with given abi
*
* @method outputParser
* @param {Array} contract abi
* @returns {Object} output parser for given json abi
*/
var outputParser = function (json) {
var parser = {};
json.forEach(function (method) {
var displayName = utils.extractDisplayName(method.name);
var typeName = utils.extractTypeName(method.name);
var impl = function (output) {
return formatOutput(method.outputs, output);
};
if (parser[displayName] === undefined) {
parser[displayName] = impl;
}
parser[displayName][typeName] = impl;
});
return parser;
};
var formatConstructorParams = function (abi, params) { var formatConstructorParams = function (abi, params) {
var constructor = solUtils.getConstructor(abi, params.length); var constructor = utils.getConstructor(abi, params.length);
if (!constructor) { if (!constructor) {
if (params.length > 0) { if (params.length > 0) {
console.warn("didn't found matching constructor, using default one"); console.warn("didn't found matching constructor, using default one");
} }
return ''; return '';
} }
return formatInput(constructor.inputs, params);
return coder.encodeParams(constructor.inputs.map(function (input) {
return input.type;
}), params);
}; };
module.exports = { module.exports = {
inputParser: inputParser,
outputParser: outputParser,
formatInput: formatInput,
formatOutput: formatOutput,
formatConstructorParams: formatConstructorParams formatConstructorParams: formatConstructorParams
}; };

85
lib/solidity/coder.js

@ -77,9 +77,8 @@ SolidityType.prototype.formatInput = function (param, arrayType) {
return param.map(function (p) { return param.map(function (p) {
return self._inputFormatter(p); return self._inputFormatter(p);
}).reduce(function (acc, current) { }).reduce(function (acc, current) {
acc.appendArrayElement(current); return acc.combine(current);
return acc; }, f.formatInputInt(param.length)).withOffset(32);
}, new SolidityParam('', f.formatInputInt(param.length).value));
} }
return this._inputFormatter(param); return this._inputFormatter(param);
}; };
@ -96,9 +95,9 @@ SolidityType.prototype.formatOutput = function (param, arrayType) {
if (arrayType) { if (arrayType) {
// let's assume, that we solidity will never return long arrays :P // let's assume, that we solidity will never return long arrays :P
var result = []; var result = [];
var length = new BigNumber(param.prefix, 16); var length = new BigNumber(param.dynamicPart().slice(0, 64), 16);
for (var i = 0; i < length * 64; i += 64) { for (var i = 0; i < length * 64; i += 64) {
result.push(this._outputFormatter(new SolidityParam(param.suffix.slice(i, i + 64)))); result.push(this._outputFormatter(new SolidityParam(param.dynamicPart().substr(i + 64, 64))));
} }
return result; return result;
} }
@ -106,31 +105,21 @@ SolidityType.prototype.formatOutput = function (param, arrayType) {
}; };
/** /**
* Should be used to check if a type is variadic * Should be used to slice single param from bytes
* *
* @method isVariadicType * @method sliceParam
* @param {String} type * @param {String} bytes
* @returns {Bool} true if the type is variadic * @param {Number} index of param to slice
*/
SolidityType.prototype.isVariadicType = function (type) {
return isArrayType(type) || this._mode === 'bytes';
};
/**
* Should be used to shift param from params group
*
* @method shiftParam
* @param {String} type * @param {String} type
* @returns {SolidityParam} shifted param * @returns {SolidityParam} param
*/ */
SolidityType.prototype.shiftParam = function (type, param) { SolidityType.prototype.sliceParam = function (bytes, index, type) {
if (this._mode === 'bytes') { if (this._mode === 'bytes') {
return param.shiftBytes(); return SolidityParam.decodeBytes(bytes, index);
} else if (isArrayType(type)) { } else if (isArrayType(type)) {
var length = new BigNumber(param.prefix.slice(0, 64), 16); return SolidityParam.decodeArray(bytes, index);
return param.shiftArray(length);
} }
return param.shiftValue(); return SolidityParam.decodeParam(bytes, index);
}; };
/** /**
@ -160,28 +149,6 @@ SolidityCoder.prototype._requireType = function (type) {
return solidityType; return solidityType;
}; };
/**
* Should be used to transform plain bytes to SolidityParam object
*
* @method _bytesToParam
* @param {Array} types of params
* @param {String} bytes to be transformed to SolidityParam
* @return {SolidityParam} SolidityParam for this group of params
*/
SolidityCoder.prototype._bytesToParam = function (types, bytes) {
var self = this;
var prefixTypes = types.reduce(function (acc, type) {
return self._requireType(type).isVariadicType(type) ? acc + 1 : acc;
}, 0);
var valueTypes = types.length - prefixTypes;
var prefix = bytes.slice(0, prefixTypes * 64);
bytes = bytes.slice(prefixTypes * 64);
var value = bytes.slice(0, valueTypes * 64);
var suffix = bytes.slice(valueTypes * 64);
return new SolidityParam(value, prefix, suffix);
};
/** /**
* Should be used to transform plain param of given type to SolidityParam * Should be used to transform plain param of given type to SolidityParam
* *
@ -216,24 +183,11 @@ SolidityCoder.prototype.encodeParam = function (type, param) {
*/ */
SolidityCoder.prototype.encodeParams = function (types, params) { SolidityCoder.prototype.encodeParams = function (types, params) {
var self = this; var self = this;
return types.map(function (type, index) { var solidityParams = types.map(function (type, index) {
return self._formatInput(type, params[index]); return self._formatInput(type, params[index]);
}).reduce(function (acc, solidityParam) { });
acc.append(solidityParam);
return acc;
}, new SolidityParam()).encode();
};
/** return SolidityParam.encodeList(solidityParams);
* Should be used to transform SolidityParam to plain param
*
* @method _formatOutput
* @param {String} type
* @param {SolidityParam} param
* @return {Object} plain param
*/
SolidityCoder.prototype._formatOutput = function (type, param) {
return this._requireType(type).formatOutput(param, isArrayType(type));
}; };
/** /**
@ -245,7 +199,7 @@ SolidityCoder.prototype._formatOutput = function (type, param) {
* @return {Object} plain param * @return {Object} plain param
*/ */
SolidityCoder.prototype.decodeParam = function (type, bytes) { SolidityCoder.prototype.decodeParam = function (type, bytes) {
return this._formatOutput(type, this._bytesToParam([type], bytes)); return this.decodeParams([type], bytes)[0];
}; };
/** /**
@ -258,10 +212,9 @@ SolidityCoder.prototype.decodeParam = function (type, bytes) {
*/ */
SolidityCoder.prototype.decodeParams = function (types, bytes) { SolidityCoder.prototype.decodeParams = function (types, bytes) {
var self = this; var self = this;
var param = this._bytesToParam(types, bytes); return types.map(function (type, index) {
return types.map(function (type) {
var solidityType = self._requireType(type); var solidityType = self._requireType(type);
var p = solidityType.shiftParam(type, param); var p = solidityType.sliceParam(bytes, index, type);
return solidityType.formatOutput(p, isArrayType(type)); return solidityType.formatOutput(p, isArrayType(type));
}); });
}; };

14
lib/solidity/formatters.js

@ -63,7 +63,7 @@ var formatInputBytes = function (value) {
*/ */
var formatInputDynamicBytes = function (value) { var formatInputDynamicBytes = function (value) {
var result = utils.fromAscii(value, c.ETH_PADDING).substr(2); var result = utils.fromAscii(value, c.ETH_PADDING).substr(2);
return new SolidityParam('', formatInputInt(value.length).value, result); return new SolidityParam(formatInputInt(value.length).value + result, 32);
}; };
/** /**
@ -109,7 +109,7 @@ var signedIsNegative = function (value) {
* @returns {BigNumber} right-aligned output bytes formatted to big number * @returns {BigNumber} right-aligned output bytes formatted to big number
*/ */
var formatOutputInt = function (param) { var formatOutputInt = function (param) {
var value = param.value || "0"; var value = param.staticPart() || "0";
// check if it's negative number // check if it's negative number
// it it is, return two's complement // it it is, return two's complement
@ -127,7 +127,7 @@ var formatOutputInt = function (param) {
* @returns {BigNumeber} right-aligned output bytes formatted to uint * @returns {BigNumeber} right-aligned output bytes formatted to uint
*/ */
var formatOutputUInt = function (param) { var formatOutputUInt = function (param) {
var value = param.value || "0"; var value = param.staticPart() || "0";
return new BigNumber(value, 16); return new BigNumber(value, 16);
}; };
@ -161,7 +161,7 @@ var formatOutputUReal = function (param) {
* @returns {Boolean} right-aligned input bytes formatted to bool * @returns {Boolean} right-aligned input bytes formatted to bool
*/ */
var formatOutputBool = function (param) { var formatOutputBool = function (param) {
return param.value === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false; return param.staticPart() === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false;
}; };
/** /**
@ -173,7 +173,7 @@ var formatOutputBool = function (param) {
*/ */
var formatOutputBytes = function (param) { var formatOutputBytes = function (param) {
// length might also be important! // length might also be important!
return utils.toAscii(param.value); return utils.toAscii(param.staticPart());
}; };
/** /**
@ -185,7 +185,7 @@ var formatOutputBytes = function (param) {
*/ */
var formatOutputDynamicBytes = function (param) { var formatOutputDynamicBytes = function (param) {
// length might also be important! // length might also be important!
return utils.toAscii(param.suffix); return utils.toAscii(param.dynamicPart().slice(64));
}; };
/** /**
@ -196,7 +196,7 @@ var formatOutputDynamicBytes = function (param) {
* @returns {String} address * @returns {String} address
*/ */
var formatOutputAddress = function (param) { var formatOutputAddress = function (param) {
var value = param.value; var value = param.staticPart();
return "0x" + value.slice(value.length - 40, value.length); return "0x" + value.slice(value.length - 40, value.length);
}; };

191
lib/solidity/param.js

@ -20,85 +20,190 @@
* @date 2015 * @date 2015
*/ */
var utils = require('../utils/utils');
/** /**
* SolidityParam object prototype. * SolidityParam object prototype.
* Should be used when encoding, decoding solidity bytes * Should be used when encoding, decoding solidity bytes
*/ */
var SolidityParam = function (value, prefix, suffix) { var SolidityParam = function (value, offset) {
this.prefix = prefix || '';
this.value = value || ''; this.value = value || '';
this.suffix = suffix || ''; this.offset = offset; // offset in bytes
};
/**
* This method should be used to get length of params's dynamic part
*
* @method dynamicPartLength
* @returns {Number} length of dynamic part (in bytes)
*/
SolidityParam.prototype.dynamicPartLength = function () {
return this.dynamicPart().length / 2;
};
/**
* This method should be used to create copy of solidity param with different offset
*
* @method withOffset
* @param {Number} offset length in bytes
* @returns {SolidityParam} new solidity param with applied offset
*/
SolidityParam.prototype.withOffset = function (offset) {
return new SolidityParam(this.value, offset);
};
/**
* This method should be used to combine solidity params together
* eg. when appending an array
*
* @method combine
* @param {SolidityParam} param with which we should combine
* @param {SolidityParam} result of combination
*/
SolidityParam.prototype.combine = function (param) {
return new SolidityParam(this.value + param.value);
};
/**
* This method should be called to check if param has dynamic size.
* If it has, it returns true, otherwise false
*
* @method isDynamic
* @returns {Boolean}
*/
SolidityParam.prototype.isDynamic = function () {
return this.value.length > 64;
}; };
/** /**
* This method should be used to encode two params one after another * This method should be called to transform offset to bytes
* *
* @method append * @method offsetAsBytes
* @param {SolidityParam} param that it appended after this * @returns {String} bytes representation of offset
*/ */
SolidityParam.prototype.append = function (param) { SolidityParam.prototype.offsetAsBytes = function () {
this.prefix += param.prefix; return !this.isDynamic() ? '' : utils.padLeft(utils.toTwosComplement(this.offset).toString(16), 64);
this.value += param.value;
this.suffix += param.suffix;
}; };
/** /**
* This method should be used to encode next param in an array * This method should be called to get static part of param
* *
* @method appendArrayElement * @method staticPart
* @param {SolidityParam} param that is appended to an array * @returns {String} offset if it is a dynamic param, otherwise value
*/ */
SolidityParam.prototype.appendArrayElement = function (param) { SolidityParam.prototype.staticPart = function () {
this.suffix += param.value; if (!this.isDynamic()) {
this.prefix += param.prefix; return this.value;
// TODO: suffix not supported = it's required for nested arrays; }
return this.offsetAsBytes();
}; };
/** /**
* This method should be used to create bytearrays from param * This method should be called to get dynamic part of param
*
* @method dynamicPart
* @returns {String} returns a value if it is a dynamic param, otherwise empty string
*/
SolidityParam.prototype.dynamicPart = function () {
return this.isDynamic() ? this.value : '';
};
/**
* This method should be called to encode param
* *
* @method encode * @method encode
* @return {String} encoded param(s) * @returns {String}
*/ */
SolidityParam.prototype.encode = function () { SolidityParam.prototype.encode = function () {
return this.prefix + this.value + this.suffix; return this.staticPart() + this.dynamicPart();
}; };
/** /**
* This method should be used to shift first param from group of params * This method should be called to encode array of params
* *
* @method shiftValue * @method encodeList
* @return {SolidityParam} first value param * @param {Array[SolidityParam]} params
* @returns {String}
*/ */
SolidityParam.prototype.shiftValue = function () { SolidityParam.encodeList = function (params) {
var value = this.value.slice(0, 64);
this.value = this.value.slice(64); // updating offsets
return new SolidityParam(value); var totalOffset = params.length * 32;
var offsetParams = params.map(function (param) {
if (!param.isDynamic()) {
return param;
}
var offset = totalOffset;
totalOffset += param.dynamicPartLength();
return param.withOffset(offset);
});
// encode everything!
return offsetParams.reduce(function (result, param) {
return result + param.dynamicPart();
}, offsetParams.reduce(function (result, param) {
return result + param.staticPart();
}, ''));
}; };
/** /**
* This method should be used to first bytes param from group of params * This method should be used to decode plain (static) solidity param at given index
* *
* @method shiftBytes * @method decodeParam
* @return {SolidityParam} first bytes param * @param {String} bytes
* @param {Number} index
* @returns {SolidityParam}
*/ */
SolidityParam.prototype.shiftBytes = function () { SolidityParam.decodeParam = function (bytes, index) {
return this.shiftArray(1); index = index || 0;
return new SolidityParam(bytes.substr(index * 64, 64));
}; };
/** /**
* This method should be used to shift an array from group of params * This method should be called to get offset value from bytes at given index
* *
* @method shiftArray * @method getOffset
* @param {Number} size of an array to shift * @param {String} bytes
* @return {SolidityParam} first array param * @param {Number} index
* @returns {Number} offset as number
*/
var getOffset = function (bytes, index) {
// we can do this cause offset is rather small
return parseInt('0x' + bytes.substr(index * 64, 64));
};
/**
* This method should be called to decode solidity bytes param at given index
*
* @method decodeBytes
* @param {String} bytes
* @param {Number} index
* @returns {SolidityParam}
*/
SolidityParam.decodeBytes = function (bytes, index) {
index = index || 0;
//TODO add support for strings longer than 32 bytes
//var length = parseInt('0x' + bytes.substr(offset * 64, 64));
var offset = getOffset(bytes, index);
// 2 * , cause we also parse length
return new SolidityParam(bytes.substr(offset * 2, 2 * 64));
};
/**
* This method should be used to decode solidity array at given index
*
* @method decodeArray
* @param {String} bytes
* @param {Number} index
* @returns {SolidityParam}
*/ */
SolidityParam.prototype.shiftArray = function (length) { SolidityParam.decodeArray = function (bytes, index) {
var prefix = this.prefix.slice(0, 64); index = index || 0;
this.prefix = this.value.slice(64); var offset = getOffset(bytes, index);
var suffix = this.suffix.slice(0, 64 * length); var length = parseInt('0x' + bytes.substr(offset * 2, 64));
this.suffix = this.suffix.slice(64 * length); return new SolidityParam(bytes.substr(offset * 2, (length + 1) * 64));
return new SolidityParam('', prefix, suffix);
}; };
module.exports = SolidityParam; module.exports = SolidityParam;

5
lib/solidity/utils.js

@ -34,6 +34,11 @@ var getConstructor = function (abi, numberOfArgs) {
})[0]; })[0];
}; };
//var getSupremeType = function (type) {
//return type.substr(0, type.indexOf('[')) + ']';
//};
module.exports = { module.exports = {
getConstructor: getConstructor getConstructor: getConstructor
}; };

2
lib/version.json

@ -1,3 +1,3 @@
{ {
"version": "0.3.3" "version": "0.3.6"
} }

17
lib/web3/eth.js

@ -23,7 +23,7 @@
/** /**
* Web3 * Web3
* *
* @module web3 * @module web3
*/ */
@ -77,16 +77,16 @@ var uncleCountCall = function (args) {
/// @returns an array of objects describing web3.eth api methods /// @returns an array of objects describing web3.eth api methods
var getBalance = new Method({ var getBalance = new Method({
name: 'getBalance', name: 'getBalance',
call: 'eth_getBalance', call: 'eth_getBalance',
params: 2, params: 2,
inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter], inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter],
outputFormatter: formatters.outputBigNumberFormatter outputFormatter: formatters.outputBigNumberFormatter
}); });
var getStorageAt = new Method({ var getStorageAt = new Method({
name: 'getStorageAt', name: 'getStorageAt',
call: 'eth_getStorageAt', call: 'eth_getStorageAt',
params: 3, params: 3,
inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter] inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter]
}); });
@ -99,7 +99,7 @@ var getCode = new Method({
}); });
var getBlock = new Method({ var getBlock = new Method({
name: 'getBlock', name: 'getBlock',
call: blockCall, call: blockCall,
params: 2, params: 2,
inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }], inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }],
@ -224,6 +224,11 @@ var properties = [
name: 'mining', name: 'mining',
getter: 'eth_mining' getter: 'eth_mining'
}), }),
new Property({
name: 'hashrate',
getter: 'eth_hashrate',
outputFormatter: utils.toDecimal
}),
new Property({ new Property({
name: 'gasPrice', name: 'gasPrice',
getter: 'eth_gasPrice', getter: 'eth_gasPrice',

2
lib/web3/event.js

@ -96,7 +96,7 @@ SolidityEvent.prototype.encode = function (indexed, options) {
['fromBlock', 'toBlock'].filter(function (f) { ['fromBlock', 'toBlock'].filter(function (f) {
return options[f] !== undefined; return options[f] !== undefined;
}).forEach(function (f) { }).forEach(function (f) {
result[f] = utils.toHex(options[f]); result[f] = formatters.inputBlockNumberFormatter(options[f]);
}); });
result.topics = []; result.topics = [];

2
lib/web3/formatters.js

@ -72,7 +72,7 @@ var inputTransactionFormatter = function (options){
delete options.code; delete options.code;
} }
['gasPrice', 'gas', 'value'].filter(function (key) { ['gasPrice', 'gas', 'value', 'nonce'].filter(function (key) {
return options[key] !== undefined; return options[key] !== undefined;
}).forEach(function(key){ }).forEach(function(key){
options[key] = utils.fromDecimal(options[key]); options[key] = utils.fromDecimal(options[key]);

23
lib/web3/httpprovider.js

@ -48,15 +48,32 @@ HttpProvider.prototype.send = function (payload) {
//if (request.status !== 200) { //if (request.status !== 200) {
//return; //return;
//} //}
return JSON.parse(request.responseText);
var result = request.responseText;
try {
result = JSON.parse(result);
} catch(e) {
throw errors.InvalidResponse(result);
}
return result;
}; };
HttpProvider.prototype.sendAsync = function (payload, callback) { HttpProvider.prototype.sendAsync = function (payload, callback) {
var request = new XMLHttpRequest(); var request = new XMLHttpRequest();
request.onreadystatechange = function() { request.onreadystatechange = function() {
if (request.readyState === 4) { if (request.readyState === 4) {
// TODO: handle the error properly here!!! var result = request.responseText;
callback(null, JSON.parse(request.responseText)); var error = null;
try {
result = JSON.parse(result);
} catch(e) {
error = errors.InvalidResponse(result);
}
callback(error, result);
} }
}; };

2
package.js

@ -1,7 +1,7 @@
/* jshint ignore:start */ /* jshint ignore:start */
Package.describe({ Package.describe({
name: 'ethereum:web3', name: 'ethereum:web3',
version: '0.3.3', version: '0.3.6',
summary: 'Ethereum JavaScript API, middleware to talk to a ethreum node over RPC', summary: 'Ethereum JavaScript API, middleware to talk to a ethreum node over RPC',
git: 'https://github.com/ethereum/ethereum.js', git: 'https://github.com/ethereum/ethereum.js',
// By default, Meteor will default to using README.md for documentation. // By default, Meteor will default to using README.md for documentation.

2
package.json

@ -1,7 +1,7 @@
{ {
"name": "web3", "name": "web3",
"namespace": "ethereum", "namespace": "ethereum",
"version": "0.3.3", "version": "0.3.6",
"description": "Ethereum JavaScript API, middleware to talk to a ethereum node over RPC", "description": "Ethereum JavaScript API, middleware to talk to a ethereum node over RPC",
"main": "./index.js", "main": "./index.js",
"directories": { "directories": {

515
test/abi.inputParser.js

@ -1,515 +0,0 @@
var chai = require('chai');
var assert = chai.assert;
var BigNumber = require('bignumber.js');
var abi = require('../lib/solidity/abi');
var clone = function (object) { return JSON.parse(JSON.stringify(object)); };
var description = [{
"name": "test",
"type": "function",
"inputs": [{
"name": "a",
"type": "uint256"
}
],
"outputs": [
{
"name": "d",
"type": "uint256"
}
]
}];
describe('lib/solidity/abi', function () {
describe('inputParser', function () {
it('should parse input uint', function () {
// given
var d = clone(description);
d[0].inputs = [
{ type: "uint" }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001");
assert.equal(parser.test(10), "000000000000000000000000000000000000000000000000000000000000000a");
assert.equal(
parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
);
assert.equal(
parser.test(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)),
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
);
assert.equal(parser.test(0.1), "0000000000000000000000000000000000000000000000000000000000000000");
assert.equal(parser.test(3.9), "0000000000000000000000000000000000000000000000000000000000000003");
assert.equal(parser.test('0.1'), "0000000000000000000000000000000000000000000000000000000000000000");
assert.equal(parser.test('3.9'), "0000000000000000000000000000000000000000000000000000000000000003");
});
it('should parse input uint128', function() {
// given
var d = clone(description);
d[0].inputs = [
{ type: "uint128" }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001");
assert.equal(parser.test(10), "000000000000000000000000000000000000000000000000000000000000000a");
assert.equal(
parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
);
assert.equal(
parser.test(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)),
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
);
assert.equal(parser.test(0.1), "0000000000000000000000000000000000000000000000000000000000000000");
assert.equal(parser.test(3.9), "0000000000000000000000000000000000000000000000000000000000000003");
assert.equal(parser.test('0.1'), "0000000000000000000000000000000000000000000000000000000000000000");
assert.equal(parser.test('3.9'), "0000000000000000000000000000000000000000000000000000000000000003");
});
it('should parse input uint256', function() {
// given
var d = clone(description);
d[0].inputs = [
{ type: "uint256" }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001");
assert.equal(parser.test(10), "000000000000000000000000000000000000000000000000000000000000000a");
assert.equal(
parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
);
assert.equal(
parser.test(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)),
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
);
assert.equal(parser.test(0.1), "0000000000000000000000000000000000000000000000000000000000000000");
assert.equal(parser.test(3.9), "0000000000000000000000000000000000000000000000000000000000000003");
assert.equal(parser.test('0.1'), "0000000000000000000000000000000000000000000000000000000000000000");
assert.equal(parser.test('3.9'), "0000000000000000000000000000000000000000000000000000000000000003");
});
it('should parse input int', function() {
// given
var d = clone(description);
d[0].inputs = [
{ type: "int" }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001");
assert.equal(parser.test(10), "000000000000000000000000000000000000000000000000000000000000000a");
assert.equal(parser.test(-1), "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
assert.equal(parser.test(-2), "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe");
assert.equal(parser.test(-16), "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0");
assert.equal(
parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
);
assert.equal(
parser.test(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)),
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
);
assert.equal(parser.test(0.1), "0000000000000000000000000000000000000000000000000000000000000000");
assert.equal(parser.test(3.9), "0000000000000000000000000000000000000000000000000000000000000003");
assert.equal(parser.test('0.1'), "0000000000000000000000000000000000000000000000000000000000000000");
assert.equal(parser.test('3.9'), "0000000000000000000000000000000000000000000000000000000000000003");
});
it('should parse input int128', function() {
// given
var d = clone(description);
d[0].inputs = [
{ type: "int128" }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001");
assert.equal(parser.test(10), "000000000000000000000000000000000000000000000000000000000000000a");
assert.equal(parser.test(-1), "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
assert.equal(parser.test(-2), "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe");
assert.equal(parser.test(-16), "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0");
assert.equal(
parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
);
assert.equal(
parser.test(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)),
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
);
assert.equal(parser.test(0.1), "0000000000000000000000000000000000000000000000000000000000000000");
assert.equal(parser.test(3.9), "0000000000000000000000000000000000000000000000000000000000000003");
assert.equal(parser.test('0.1'), "0000000000000000000000000000000000000000000000000000000000000000");
assert.equal(parser.test('3.9'), "0000000000000000000000000000000000000000000000000000000000000003");
});
it('should parse input int256', function() {
// given
var d = clone(description);
d[0].inputs = [
{ type: "int256" }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001");
assert.equal(parser.test(10), "000000000000000000000000000000000000000000000000000000000000000a");
assert.equal(parser.test(-1), "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
assert.equal(parser.test(-2), "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe");
assert.equal(parser.test(-16), "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0");
assert.equal(
parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
);
assert.equal(
parser.test(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)),
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
);
assert.equal(parser.test(0.1), "0000000000000000000000000000000000000000000000000000000000000000");
assert.equal(parser.test(3.9), "0000000000000000000000000000000000000000000000000000000000000003");
assert.equal(parser.test('0.1'), "0000000000000000000000000000000000000000000000000000000000000000");
assert.equal(parser.test('3.9'), "0000000000000000000000000000000000000000000000000000000000000003");
});
it('should parse input bool', function() {
// given
var d = clone(description);
d[0].inputs = [
{ type: 'bool' }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(parser.test(true), "0000000000000000000000000000000000000000000000000000000000000001");
assert.equal(parser.test(false), "0000000000000000000000000000000000000000000000000000000000000000");
});
it('should parse input address', function () {
// given
var d = clone(description);
d[0].inputs = [
{ type: "address" }
];
// when
var parser = abi.inputParser(d)
// then
assert.equal(parser.test("0x407d73d8a49eeb85d32cf465507dd71d507100c1"), "000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1");
});
it('should parse input fixed bytes type', function () {
// given
var d = clone(description);
d[0].inputs = [
{ type: "bytes" }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(
parser.test('hello'),
"0000000000000000000000000000000000000000000000000000000000000005" +
"68656c6c6f000000000000000000000000000000000000000000000000000000"
);
assert.equal(
parser.test('world'),
"0000000000000000000000000000000000000000000000000000000000000005776f726c64000000000000000000000000000000000000000000000000000000"
);
});
it('should parse input int followed by a fixed bytes type', function () {
// given
var d = clone(description);
d[0].inputs = [
{ type: "int" },
{ type: "bytes" }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(
parser.test(9, 'hello'),
"0000000000000000000000000000000000000000000000000000000000000005" +
"0000000000000000000000000000000000000000000000000000000000000009" +
"68656c6c6f000000000000000000000000000000000000000000000000000000"
);
});
it('should parse input fixed bytes type followed by an int', function () {
// given
var d = clone(description);
d[0].inputs = [
{ type: "bytes" },
{ type: "int" }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(
parser.test('hello', 9),
"0000000000000000000000000000000000000000000000000000000000000005" +
"0000000000000000000000000000000000000000000000000000000000000009" +
"68656c6c6f000000000000000000000000000000000000000000000000000000"
);
});
it('should use proper method name', function () {
// given
var d = clone(description);
d[0].name = 'helloworld(int)';
d[0].inputs = [
{ type: "int" }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(parser.helloworld(1), "0000000000000000000000000000000000000000000000000000000000000001");
assert.equal(parser.helloworld['int'](1), "0000000000000000000000000000000000000000000000000000000000000001");
});
it('should parse multiple methods', function () {
// given
var d = [{
name: "test",
type: "function",
inputs: [{ type: "int" }],
outputs: [{ type: "int" }]
},{
name: "test2",
type: "function",
inputs: [{ type: "bytes" }],
outputs: [{ type: "bytes" }]
}];
// when
var parser = abi.inputParser(d);
//then
assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001");
assert.equal(
parser.test2('hello'),
"000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000"
);
});
it('should parse input array of ints', function () {
// given
var d = clone(description);
d[0].inputs = [
{ type: "int[]" }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(
parser.test([5, 6]),
"0000000000000000000000000000000000000000000000000000000000000002" +
"0000000000000000000000000000000000000000000000000000000000000005" +
"0000000000000000000000000000000000000000000000000000000000000006"
);
});
it('should parse an array followed by an int', function () {
// given
var d = clone(description);
d[0].inputs = [
{ type: "int[]" },
{ type: "int" }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(
parser.test([5, 6], 3),
"0000000000000000000000000000000000000000000000000000000000000002" +
"0000000000000000000000000000000000000000000000000000000000000003" +
"0000000000000000000000000000000000000000000000000000000000000005" +
"0000000000000000000000000000000000000000000000000000000000000006"
);
});
it('should parse an int followed by an array', function () {
// given
var d = clone(description);
d[0].inputs = [
{ type: "int" },
{ type: "int[]" }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(
parser.test(3, [5, 6]),
"0000000000000000000000000000000000000000000000000000000000000002" +
"0000000000000000000000000000000000000000000000000000000000000003" +
"0000000000000000000000000000000000000000000000000000000000000005" +
"0000000000000000000000000000000000000000000000000000000000000006"
);
});
it('should parse mixture of arrays and ints', function () {
// given
var d = clone(description);
d[0].inputs = [
{ type: "int" },
{ type: "int[]" },
{ type: "int" },
{ type: "int[]" }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(
parser.test(3, [5, 6, 1, 2], 7, [8, 9]),
"0000000000000000000000000000000000000000000000000000000000000004" +
"0000000000000000000000000000000000000000000000000000000000000002" +
"0000000000000000000000000000000000000000000000000000000000000003" +
"0000000000000000000000000000000000000000000000000000000000000007" +
"0000000000000000000000000000000000000000000000000000000000000005" +
"0000000000000000000000000000000000000000000000000000000000000006" +
"0000000000000000000000000000000000000000000000000000000000000001" +
"0000000000000000000000000000000000000000000000000000000000000002" +
"0000000000000000000000000000000000000000000000000000000000000008" +
"0000000000000000000000000000000000000000000000000000000000000009"
);
});
it('should parse input real', function () {
// given
var d = clone(description);
d[0].inputs = [
{ type: 'real' }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(parser.test(1), "0000000000000000000000000000000100000000000000000000000000000000");
assert.equal(parser.test(2.125), "0000000000000000000000000000000220000000000000000000000000000000");
assert.equal(parser.test(8.5), "0000000000000000000000000000000880000000000000000000000000000000");
assert.equal(parser.test(-1), "ffffffffffffffffffffffffffffffff00000000000000000000000000000000");
});
it('should parse input ureal', function () {
// given
var d = clone(description);
d[0].inputs = [
{ type: 'ureal' }
];
// when
var parser = abi.inputParser(d);
// then
assert.equal(parser.test(1), "0000000000000000000000000000000100000000000000000000000000000000");
assert.equal(parser.test(2.125), "0000000000000000000000000000000220000000000000000000000000000000");
assert.equal(parser.test(8.5), "0000000000000000000000000000000880000000000000000000000000000000");
});
it('should throw an incorrect type error', function () {
// given
var d = clone(description);
d[0].inputs = [
{ type: 'uin' }
]
// when
var parser = abi.inputParser(d);
// then
assert.throws(function () {parser.test('0x')}, Error);
});
});
});

419
test/abi.outputParser.js

@ -1,419 +0,0 @@
var assert = require('assert');
var BigNumber = require('bignumber.js');
var abi = require('../lib/solidity/abi.js');
var clone = function (object) { return JSON.parse(JSON.stringify(object)); };
var description = [{
"name": "test",
"type": "function",
"inputs": [{
"name": "a",
"type": "uint256"
}
],
"outputs": [
{
"name": "d",
"type": "uint256"
}
]
}];
describe('lib/solidity/abi', function() {
describe('outputParser', function() {
it('should parse output fixed bytes type', function() {
// given
var d = clone(description);
d[0].outputs = [
{ type: "bytes" }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(
parser.test(
"0000000000000000000000000000000000000000000000000000000000000005" +
"68656c6c6f000000000000000000000000000000000000000000000000000000")[0],
'hello'
);
assert.equal(
parser.test(
"0000000000000000000000000000000000000000000000000000000000000005" +
"776f726c64000000000000000000000000000000000000000000000000000000")[0],
'world'
);
});
it('should parse output uint', function() {
// given
var d = clone(description);
d[0].outputs = [
{ type: 'uint' }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(parser.test("0000000000000000000000000000000000000000000000000000000000000001")[0], 1);
assert.equal(parser.test("000000000000000000000000000000000000000000000000000000000000000a")[0], 10);
assert.equal(
parser.test("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[0].toString(10),
new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16).toString(10)
);
assert.equal(
parser.test("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0].toString(10),
new BigNumber("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0", 16).toString(10)
);
});
it('should parse output uint256', function() {
// given
var d = clone(description);
d[0].outputs = [
{ type: 'uint256' }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(parser.test("0000000000000000000000000000000000000000000000000000000000000001")[0], 1);
assert.equal(parser.test("000000000000000000000000000000000000000000000000000000000000000a")[0], 10);
assert.equal(
parser.test("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[0].toString(10),
new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16).toString(10)
);
assert.equal(
parser.test("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0].toString(10),
new BigNumber("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0", 16).toString(10)
);
});
it('should parse output uint128', function() {
// given
var d = clone(description);
d[0].outputs = [
{ type: 'uint128' }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(parser.test("0000000000000000000000000000000000000000000000000000000000000001")[0], 1);
assert.equal(parser.test("000000000000000000000000000000000000000000000000000000000000000a")[0], 10);
assert.equal(
parser.test("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[0].toString(10),
new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16).toString(10)
);
assert.equal(
parser.test("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0].toString(10),
new BigNumber("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0", 16).toString(10)
);
});
it('should parse output int', function() {
// given
var d = clone(description);
d[0].outputs = [
{ type: 'int' }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(parser.test("0000000000000000000000000000000000000000000000000000000000000001")[0], 1);
assert.equal(parser.test("000000000000000000000000000000000000000000000000000000000000000a")[0], 10);
assert.equal(parser.test("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[0], -1);
assert.equal(parser.test("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0], -16);
});
it('should parse output int256', function() {
// given
var d = clone(description);
d[0].outputs = [
{ type: 'int256' }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(parser.test("0000000000000000000000000000000000000000000000000000000000000001")[0], 1);
assert.equal(parser.test("000000000000000000000000000000000000000000000000000000000000000a")[0], 10);
assert.equal(parser.test("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[0], -1);
assert.equal(parser.test("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0], -16);
});
it('should parse output int128', function() {
// given
var d = clone(description);
d[0].outputs = [
{ type: 'int128' }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(parser.test("0000000000000000000000000000000000000000000000000000000000000001")[0], 1);
assert.equal(parser.test("000000000000000000000000000000000000000000000000000000000000000a")[0], 10);
assert.equal(parser.test("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[0], -1);
assert.equal(parser.test("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0], -16);
});
it('should parse output address', function() {
// given
var d = clone(description);
d[0].outputs = [
{ type: 'address' }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(
parser.test("000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1")[0],
"0x407d73d8a49eeb85d32cf465507dd71d507100c1"
);
});
it('should parse output bool', function() {
// given
var d = clone(description);
d[0].outputs = [
{ type: 'bool' }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(parser.test("0000000000000000000000000000000000000000000000000000000000000001")[0], true);
assert.equal(parser.test("0000000000000000000000000000000000000000000000000000000000000000")[0], false);
});
it('should parse output real', function() {
// given
var d = clone(description);
d[0].outputs = [
{ type: 'real' }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(parser.test("0000000000000000000000000000000100000000000000000000000000000000")[0], 1);
assert.equal(parser.test("0000000000000000000000000000000220000000000000000000000000000000")[0], 2.125);
assert.equal(parser.test("0000000000000000000000000000000880000000000000000000000000000000")[0], 8.5);
assert.equal(parser.test("ffffffffffffffffffffffffffffffff00000000000000000000000000000000")[0], -1);
});
it('should parse output ureal', function() {
// given
var d = clone(description);
d[0].outputs = [
{ type: 'ureal' }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(parser.test("0000000000000000000000000000000100000000000000000000000000000000")[0], 1);
assert.equal(parser.test("0000000000000000000000000000000220000000000000000000000000000000")[0], 2.125);
assert.equal(parser.test("0000000000000000000000000000000880000000000000000000000000000000")[0], 8.5);
});
it('should parse multiple output fixed bytes type', function() {
// given
var d = clone(description);
d[0].outputs = [
{ type: "bytes" },
{ type: "bytes" }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(
parser.test(
"0000000000000000000000000000000000000000000000000000000000000005" +
"0000000000000000000000000000000000000000000000000000000000000005" +
"68656c6c6f000000000000000000000000000000000000000000000000000000" +
"776f726c64000000000000000000000000000000000000000000000000000000")[0],
'hello'
);
assert.equal(
parser.test(
"0000000000000000000000000000000000000000000000000000000000000005" +
"0000000000000000000000000000000000000000000000000000000000000005" +
"68656c6c6f000000000000000000000000000000000000000000000000000000" +
"776f726c64000000000000000000000000000000000000000000000000000000")[1],
'world'
);
});
it('should use proper method name', function () {
// given
var d = clone(description);
d[0].name = 'helloworld(int)';
d[0].outputs = [
{ type: "int" }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(parser.helloworld("0000000000000000000000000000000000000000000000000000000000000001")[0], 1);
assert.equal(parser.helloworld['int']("0000000000000000000000000000000000000000000000000000000000000001")[0], 1);
});
it('should parse multiple methods', function () {
// given
var d = [{
name: "test",
type: "function",
inputs: [{ type: "int" }],
outputs: [{ type: "int" }]
},{
name: "test2",
type: "function",
inputs: [{ type: "bytes" }],
outputs: [{ type: "bytes" }]
}];
// when
var parser = abi.outputParser(d);
//then
assert.equal(parser.test("00000000000000000000000000000000000000000000000000000000000001")[0], 1);
assert.equal(parser.test2(
"0000000000000000000000000000000000000000000000000000000000000005" +
"68656c6c6f000000000000000000000000000000000000000000000000000000")[0],
"hello"
);
});
it('should parse output array', function () {
// given
var d = clone(description);
d[0].outputs = [
{ type: 'int[]' }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(parser.test(
"0000000000000000000000000000000000000000000000000000000000000002" +
"0000000000000000000000000000000000000000000000000000000000000005" +
"0000000000000000000000000000000000000000000000000000000000000006")[0][0],
5
);
assert.equal(parser.test(
"0000000000000000000000000000000000000000000000000000000000000002" +
"0000000000000000000000000000000000000000000000000000000000000005" +
"0000000000000000000000000000000000000000000000000000000000000006")[0][1],
6
);
});
it('should parse 0x0 value', function () {
// given
var d = clone(description);
d[0].outputs = [
{ type: 'int' }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(parser.test("0x0")[0], 0);
});
it('should parse 0x0 value', function () {
// given
var d = clone(description);
d[0].outputs = [
{ type: 'uint' }
];
// when
var parser = abi.outputParser(d);
// then
assert.equal(parser.test("0x0")[0], 0);
});
it('should throw an incorrect type error', function () {
// given
var d = clone(description);
d[0].outputs = [
{ type: 'uin' }
]
// when
var parser = abi.outputParser(d);
// then
assert.throws(function () {parser.test('0x')}, Error);
});
});
});

45
test/coder.decodeParam.js

@ -21,17 +21,32 @@ describe('lib/solidity/coder', function () {
test({ type: 'int256', expected: new bn(16), value: '0000000000000000000000000000000000000000000000000000000000000010'}); test({ type: 'int256', expected: new bn(16), value: '0000000000000000000000000000000000000000000000000000000000000010'});
test({ type: 'int256', expected: new bn(-1), value: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); test({ type: 'int256', expected: new bn(-1), value: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'});
test({ type: 'bytes32', expected: 'gavofyork', value: '6761766f66796f726b0000000000000000000000000000000000000000000000'}); test({ type: 'bytes32', expected: 'gavofyork', value: '6761766f66796f726b0000000000000000000000000000000000000000000000'});
test({ type: 'bytes', expected: 'gavofyork', value: '0000000000000000000000000000000000000000000000000000000000000009' + test({ type: 'bytes', expected: 'gavofyork', value: '0000000000000000000000000000000000000000000000000000000000000020' +
'0000000000000000000000000000000000000000000000000000000000000009' +
'6761766f66796f726b0000000000000000000000000000000000000000000000'}); '6761766f66796f726b0000000000000000000000000000000000000000000000'});
test({ type: 'int[]', expected: [new bn(3)], value: '0000000000000000000000000000000000000000000000000000000000000001' + test({ type: 'int[]', expected: [new bn(3)], value: '0000000000000000000000000000000000000000000000000000000000000020' +
'0000000000000000000000000000000000000000000000000000000000000001' +
'0000000000000000000000000000000000000000000000000000000000000003'}); '0000000000000000000000000000000000000000000000000000000000000003'});
test({ type: 'int256[]', expected: [new bn(3)], value: '0000000000000000000000000000000000000000000000000000000000000001' + test({ type: 'int256[]', expected: [new bn(3)], value: '0000000000000000000000000000000000000000000000000000000000000020' +
'0000000000000000000000000000000000000000000000000000000000000001' +
'0000000000000000000000000000000000000000000000000000000000000003'}); '0000000000000000000000000000000000000000000000000000000000000003'});
test({ type: 'int[]', expected: [new bn(1), new bn(2), new bn(3)], test({ type: 'int[]', expected: [new bn(1), new bn(2), new bn(3)],
value: '0000000000000000000000000000000000000000000000000000000000000003' + value: '0000000000000000000000000000000000000000000000000000000000000020' +
'0000000000000000000000000000000000000000000000000000000000000003' +
'0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000001' +
'0000000000000000000000000000000000000000000000000000000000000002' + '0000000000000000000000000000000000000000000000000000000000000002' +
'0000000000000000000000000000000000000000000000000000000000000003'}); '0000000000000000000000000000000000000000000000000000000000000003'});
test({ type: 'bool', expected: true, value: '0000000000000000000000000000000000000000000000000000000000000001'});
test({ type: 'bool', expected: false, value: '0000000000000000000000000000000000000000000000000000000000000000'});
test({ type: 'real', expected: new bn(1), value: '0000000000000000000000000000000100000000000000000000000000000000'});
test({ type: 'real', expected: new bn(2.125), value: '0000000000000000000000000000000220000000000000000000000000000000'});
test({ type: 'real', expected: new bn(8.5), value: '0000000000000000000000000000000880000000000000000000000000000000'});
test({ type: 'real', expected: new bn(-1), value: 'ffffffffffffffffffffffffffffffff00000000000000000000000000000000'});
test({ type: 'ureal', expected: new bn(1), value: '0000000000000000000000000000000100000000000000000000000000000000'});
test({ type: 'ureal', expected: new bn(2.125), value: '0000000000000000000000000000000220000000000000000000000000000000'});
test({ type: 'ureal', expected: new bn(8.5), value: '0000000000000000000000000000000880000000000000000000000000000000'});
test({ type: 'address', expected: '0x407d73d8a49eeb85d32cf465507dd71d507100c1',
value: '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1'});
}); });
}); });
@ -53,16 +68,18 @@ describe('lib/solidity/coder', function () {
'6761766f66796f726b0000000000000000000000000000000000000000000000'}); '6761766f66796f726b0000000000000000000000000000000000000000000000'});
test({ types: ['int', 'bytes', 'int', 'int', 'int', 'int[]'], expected: [new bn(1), 'gavofyork', new bn(2), new bn(3), new bn(4), test({ types: ['int', 'bytes', 'int', 'int', 'int', 'int[]'], expected: [new bn(1), 'gavofyork', new bn(2), new bn(3), new bn(4),
[new bn(5), new bn(6), new bn(7)]], [new bn(5), new bn(6), new bn(7)]],
values: '0000000000000000000000000000000000000000000000000000000000000009' + values: '0000000000000000000000000000000000000000000000000000000000000001' +
'0000000000000000000000000000000000000000000000000000000000000003' + '00000000000000000000000000000000000000000000000000000000000000c0' +
'0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000002' +
'0000000000000000000000000000000000000000000000000000000000000002' + '0000000000000000000000000000000000000000000000000000000000000003' +
'0000000000000000000000000000000000000000000000000000000000000003' + '0000000000000000000000000000000000000000000000000000000000000004' +
'0000000000000000000000000000000000000000000000000000000000000004' + '0000000000000000000000000000000000000000000000000000000000000100' +
'6761766f66796f726b0000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000000000009' +
'0000000000000000000000000000000000000000000000000000000000000005' + '6761766f66796f726b0000000000000000000000000000000000000000000000' +
'0000000000000000000000000000000000000000000000000000000000000006' + '0000000000000000000000000000000000000000000000000000000000000003' +
'0000000000000000000000000000000000000000000000000000000000000007'}); '0000000000000000000000000000000000000000000000000000000000000005' +
'0000000000000000000000000000000000000000000000000000000000000006' +
'0000000000000000000000000000000000000000000000000000000000000007'});
}); });
}); });

82
test/coder.encodeParam.js

@ -15,20 +15,37 @@ describe('lib/solidity/coder', function () {
test({ type: 'int', value: 1, expected: '0000000000000000000000000000000000000000000000000000000000000001'}); test({ type: 'int', value: 1, expected: '0000000000000000000000000000000000000000000000000000000000000001'});
test({ type: 'int', value: 16, expected: '0000000000000000000000000000000000000000000000000000000000000010'}); test({ type: 'int', value: 16, expected: '0000000000000000000000000000000000000000000000000000000000000010'});
test({ type: 'int', value: -1, expected: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); test({ type: 'int', value: -1, expected: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'});
test({ type: 'int', value: 0.1, expected: '0000000000000000000000000000000000000000000000000000000000000000'});
test({ type: 'int', value: 3.9, expected: '0000000000000000000000000000000000000000000000000000000000000003'});
test({ type: 'int256', value: 1, expected: '0000000000000000000000000000000000000000000000000000000000000001'}); test({ type: 'int256', value: 1, expected: '0000000000000000000000000000000000000000000000000000000000000001'});
test({ type: 'int256', value: 16, expected: '0000000000000000000000000000000000000000000000000000000000000010'}); test({ type: 'int256', value: 16, expected: '0000000000000000000000000000000000000000000000000000000000000010'});
test({ type: 'int256', value: -1, expected: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); test({ type: 'int256', value: -1, expected: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'});
test({ type: 'bytes32', value: 'gavofyork', expected: '6761766f66796f726b0000000000000000000000000000000000000000000000'}); test({ type: 'bytes32', value: 'gavofyork', expected: '6761766f66796f726b0000000000000000000000000000000000000000000000'});
test({ type: 'bytes', value: 'gavofyork', expected: '0000000000000000000000000000000000000000000000000000000000000009' + test({ type: 'bytes', value: 'gavofyork', expected: '0000000000000000000000000000000000000000000000000000000000000020' +
'0000000000000000000000000000000000000000000000000000000000000009' +
'6761766f66796f726b0000000000000000000000000000000000000000000000'}); '6761766f66796f726b0000000000000000000000000000000000000000000000'});
test({ type: 'int[]', value: [3], expected: '0000000000000000000000000000000000000000000000000000000000000001' + test({ type: 'int[]', value: [3], expected: '0000000000000000000000000000000000000000000000000000000000000020' +
'0000000000000000000000000000000000000000000000000000000000000001' +
'0000000000000000000000000000000000000000000000000000000000000003'}); '0000000000000000000000000000000000000000000000000000000000000003'});
test({ type: 'int256[]', value: [3], expected: '0000000000000000000000000000000000000000000000000000000000000001' + test({ type: 'int256[]', value: [3], expected: '0000000000000000000000000000000000000000000000000000000000000020' +
'0000000000000000000000000000000000000000000000000000000000000001' +
'0000000000000000000000000000000000000000000000000000000000000003'}); '0000000000000000000000000000000000000000000000000000000000000003'});
test({ type: 'int[]', value: [1,2,3], expected: '0000000000000000000000000000000000000000000000000000000000000003' + test({ type: 'int[]', value: [1,2,3], expected: '0000000000000000000000000000000000000000000000000000000000000020' +
'0000000000000000000000000000000000000000000000000000000000000003' +
'0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000001' +
'0000000000000000000000000000000000000000000000000000000000000002' + '0000000000000000000000000000000000000000000000000000000000000002' +
'0000000000000000000000000000000000000000000000000000000000000003'}); '0000000000000000000000000000000000000000000000000000000000000003'});
test({ type: 'bool', value: true, expected: '0000000000000000000000000000000000000000000000000000000000000001'});
test({ type: 'bool', value: false, expected: '0000000000000000000000000000000000000000000000000000000000000000'});
test({ type: 'address', value: '0x407d73d8a49eeb85d32cf465507dd71d507100c1',
expected: '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1'});
test({ type: 'real', value: 1, expected: '0000000000000000000000000000000100000000000000000000000000000000'});
test({ type: 'real', value: 2.125, expected: '0000000000000000000000000000000220000000000000000000000000000000'});
test({ type: 'real', value: 8.5, expected: '0000000000000000000000000000000880000000000000000000000000000000'});
test({ type: 'real', value: -1, expected: 'ffffffffffffffffffffffffffffffff00000000000000000000000000000000'});
test({ type: 'ureal', value: 1, expected: '0000000000000000000000000000000100000000000000000000000000000000'});
test({ type: 'ureal', value: 2.125, expected: '0000000000000000000000000000000220000000000000000000000000000000'});
test({ type: 'ureal', value: 8.5, expected: '0000000000000000000000000000000880000000000000000000000000000000'});
}); });
}); });
@ -49,16 +66,29 @@ describe('lib/solidity/coder', function () {
test({ types: ['int256'], values: [16], expected: '0000000000000000000000000000000000000000000000000000000000000010'}); test({ types: ['int256'], values: [16], expected: '0000000000000000000000000000000000000000000000000000000000000010'});
test({ types: ['int256'], values: [-1], expected: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); test({ types: ['int256'], values: [-1], expected: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'});
test({ types: ['bytes32'], values: ['gavofyork'], expected: '6761766f66796f726b0000000000000000000000000000000000000000000000'}); test({ types: ['bytes32'], values: ['gavofyork'], expected: '6761766f66796f726b0000000000000000000000000000000000000000000000'});
test({ types: ['bytes'], values: ['gavofyork'], expected: '0000000000000000000000000000000000000000000000000000000000000009' + test({ types: ['bytes'], values: ['gavofyork'], expected: '0000000000000000000000000000000000000000000000000000000000000020' +
'0000000000000000000000000000000000000000000000000000000000000009' +
'6761766f66796f726b0000000000000000000000000000000000000000000000'}); '6761766f66796f726b0000000000000000000000000000000000000000000000'});
test({ types: ['int[]'], values: [[3]], expected: '0000000000000000000000000000000000000000000000000000000000000001' + test({ types: ['int[]'], values: [[3]], expected: '0000000000000000000000000000000000000000000000000000000000000020' +
'0000000000000000000000000000000000000000000000000000000000000001' +
'0000000000000000000000000000000000000000000000000000000000000003'}); '0000000000000000000000000000000000000000000000000000000000000003'});
test({ types: ['int256[]'], values: [[3]], expected: '0000000000000000000000000000000000000000000000000000000000000001' + test({ types: ['int256[]'], values: [[3]], expected: '0000000000000000000000000000000000000000000000000000000000000020' +
'0000000000000000000000000000000000000000000000000000000000000001' +
'0000000000000000000000000000000000000000000000000000000000000003'}); '0000000000000000000000000000000000000000000000000000000000000003'});
test({ types: ['int256[]'], values: [[1,2,3]], expected: '0000000000000000000000000000000000000000000000000000000000000003' + test({ types: ['int256[]'], values: [[1,2,3]], expected: '0000000000000000000000000000000000000000000000000000000000000020' +
'0000000000000000000000000000000000000000000000000000000000000003' +
'0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000001' +
'0000000000000000000000000000000000000000000000000000000000000002' + '0000000000000000000000000000000000000000000000000000000000000002' +
'0000000000000000000000000000000000000000000000000000000000000003'}); '0000000000000000000000000000000000000000000000000000000000000003'});
test({ types: ['int[]', 'int[]'], values: [[1,2], [3,4]],
expected: '0000000000000000000000000000000000000000000000000000000000000040' +
'00000000000000000000000000000000000000000000000000000000000000a0' +
'0000000000000000000000000000000000000000000000000000000000000002' +
'0000000000000000000000000000000000000000000000000000000000000001' +
'0000000000000000000000000000000000000000000000000000000000000002' +
'0000000000000000000000000000000000000000000000000000000000000002' +
'0000000000000000000000000000000000000000000000000000000000000003' +
'0000000000000000000000000000000000000000000000000000000000000004'});
test({ types: ['bytes32', 'int'], values: ['gavofyork', 5], test({ types: ['bytes32', 'int'], values: ['gavofyork', 5],
expected: '6761766f66796f726b0000000000000000000000000000000000000000000000' + expected: '6761766f66796f726b0000000000000000000000000000000000000000000000' +
'0000000000000000000000000000000000000000000000000000000000000005'}); '0000000000000000000000000000000000000000000000000000000000000005'});
@ -66,25 +96,47 @@ describe('lib/solidity/coder', function () {
expected: '0000000000000000000000000000000000000000000000000000000000000005' + expected: '0000000000000000000000000000000000000000000000000000000000000005' +
'6761766f66796f726b0000000000000000000000000000000000000000000000'}); '6761766f66796f726b0000000000000000000000000000000000000000000000'});
test({ types: ['bytes', 'int'], values: ['gavofyork', 5], test({ types: ['bytes', 'int'], values: ['gavofyork', 5],
expected: '0000000000000000000000000000000000000000000000000000000000000009' + expected: '0000000000000000000000000000000000000000000000000000000000000040' +
'0000000000000000000000000000000000000000000000000000000000000005' + '0000000000000000000000000000000000000000000000000000000000000005' +
'0000000000000000000000000000000000000000000000000000000000000009' +
'6761766f66796f726b0000000000000000000000000000000000000000000000'}); '6761766f66796f726b0000000000000000000000000000000000000000000000'});
test({ types: ['bytes', 'bool', 'int[]'], values: ['gavofyork', true, [1, 2, 3]],
expected: '0000000000000000000000000000000000000000000000000000000000000060' +
'0000000000000000000000000000000000000000000000000000000000000001' +
'00000000000000000000000000000000000000000000000000000000000000a0' +
'0000000000000000000000000000000000000000000000000000000000000009' +
'6761766f66796f726b0000000000000000000000000000000000000000000000' +
'0000000000000000000000000000000000000000000000000000000000000003' +
'0000000000000000000000000000000000000000000000000000000000000001' +
'0000000000000000000000000000000000000000000000000000000000000002' +
'0000000000000000000000000000000000000000000000000000000000000003'});
test({ types: ['bytes', 'int[]'], values: ['gavofyork', [1, 2, 3]],
expected: '0000000000000000000000000000000000000000000000000000000000000040' +
'0000000000000000000000000000000000000000000000000000000000000080' +
'0000000000000000000000000000000000000000000000000000000000000009' +
'6761766f66796f726b0000000000000000000000000000000000000000000000' +
'0000000000000000000000000000000000000000000000000000000000000003' +
'0000000000000000000000000000000000000000000000000000000000000001' +
'0000000000000000000000000000000000000000000000000000000000000002' +
'0000000000000000000000000000000000000000000000000000000000000003'});
test({ types: ['int', 'bytes'], values: [5, 'gavofyork'], test({ types: ['int', 'bytes'], values: [5, 'gavofyork'],
expected: '0000000000000000000000000000000000000000000000000000000000000009' + expected: '0000000000000000000000000000000000000000000000000000000000000005' +
'0000000000000000000000000000000000000000000000000000000000000005' + '0000000000000000000000000000000000000000000000000000000000000040' +
'0000000000000000000000000000000000000000000000000000000000000009' +
'6761766f66796f726b0000000000000000000000000000000000000000000000'}); '6761766f66796f726b0000000000000000000000000000000000000000000000'});
test({ types: ['int', 'bytes', 'int', 'int', 'int', 'int[]'], values: [1, 'gavofyork', 2, 3, 4, [5, 6, 7]], test({ types: ['int', 'bytes', 'int', 'int', 'int', 'int[]'], values: [1, 'gavofyork', 2, 3, 4, [5, 6, 7]],
expected: '0000000000000000000000000000000000000000000000000000000000000009' + expected: '0000000000000000000000000000000000000000000000000000000000000001' +
'0000000000000000000000000000000000000000000000000000000000000003' + '00000000000000000000000000000000000000000000000000000000000000c0' +
'0000000000000000000000000000000000000000000000000000000000000001' +
'0000000000000000000000000000000000000000000000000000000000000002' + '0000000000000000000000000000000000000000000000000000000000000002' +
'0000000000000000000000000000000000000000000000000000000000000003' + '0000000000000000000000000000000000000000000000000000000000000003' +
'0000000000000000000000000000000000000000000000000000000000000004' + '0000000000000000000000000000000000000000000000000000000000000004' +
'0000000000000000000000000000000000000000000000000000000000000100' +
'0000000000000000000000000000000000000000000000000000000000000009' +
'6761766f66796f726b0000000000000000000000000000000000000000000000' + '6761766f66796f726b0000000000000000000000000000000000000000000000' +
'0000000000000000000000000000000000000000000000000000000000000003' +
'0000000000000000000000000000000000000000000000000000000000000005' + '0000000000000000000000000000000000000000000000000000000000000005' +
'0000000000000000000000000000000000000000000000000000000000000006' + '0000000000000000000000000000000000000000000000000000000000000006' +
'0000000000000000000000000000000000000000000000000000000000000007'}); '0000000000000000000000000000000000000000000000000000000000000007'});
}); });
}); });

1
test/contract.js

@ -345,6 +345,7 @@ describe('web3.eth.contract', function () {
assert.equal(payload.method, 'eth_call'); assert.equal(payload.method, 'eth_call');
assert.deepEqual(payload.params, [{ assert.deepEqual(payload.params, [{
data: sha3.slice(0, 10) + data: sha3.slice(0, 10) +
'0000000000000000000000000000000000000000000000000000000000000020' +
'0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000001' +
'0000000000000000000000000000000000000000000000000000000000000003', '0000000000000000000000000000000000000000000000000000000000000003',
to: address to: address

26
test/event.encode.js

@ -119,6 +119,32 @@ var tests = [{
] ]
} }
}, { }, {
abi: {
name: 'event1',
inputs: [{
type: 'int',
name: 'a',
indexed: true
}]
},
indexed: {
a: 1
},
options: {
fromBlock: 'latest',
toBlock: 'pending'
},
expected: {
address: address,
fromBlock: 'latest',
toBlock: 'pending',
topics: [
signature,
'0x0000000000000000000000000000000000000000000000000000000000000001'
]
}
},
{
abi: { abi: {
name: 'event1', name: 'event1',
inputs: [{ inputs: [{

70
test/formatters.inputTransactionFormatter.js

@ -3,24 +3,62 @@ var assert = chai.assert;
var formatters = require('../lib/web3/formatters.js'); var formatters = require('../lib/web3/formatters.js');
var BigNumber = require('bignumber.js'); var BigNumber = require('bignumber.js');
var tests = [{
input: {
data: '0x34234bf23bf4234',
value: new BigNumber(100),
from: '0x00000',
to: '0x00000',
nonce: 1000,
gas: 1000,
gasPrice: new BigNumber(1000)
},
result: {
data: '0x34234bf23bf4234',
value: '0x64',
from: '0x00000',
to: '0x00000',
nonce: '0x3e8',
gas: '0x3e8',
gasPrice: '0x3e8'
}
},{
input: {
data: '0x34234bf23bf4234',
value: new BigNumber(100),
from: '0x00000',
to: '0x00000',
},
result: {
data: '0x34234bf23bf4234',
value: '0x64',
from: '0x00000',
to: '0x00000',
}
},{
input: {
data: '0x34234bf23bf4234',
value: new BigNumber(100),
from: '0x00000',
to: '0x00000',
gas: '1000',
gasPrice: new BigNumber(1000)
},
result: {
data: '0x34234bf23bf4234',
value: '0x64',
from: '0x00000',
to: '0x00000',
gas: '0x3e8',
gasPrice: '0x3e8'
}
}];
describe('formatters', function () { describe('formatters', function () {
describe('inputTransactionFormatter', function () { describe('inputTransactionFormatter', function () {
it('should return the correct value', function () { tests.forEach(function(test){
it('should return the correct value', function () {
assert.deepEqual(formatters.inputTransactionFormatter({ assert.deepEqual(formatters.inputTransactionFormatter(test.input), test.result);
data: '0x34234bf23bf4234',
value: new BigNumber(100),
from: '0x00000',
to: '0x00000',
gas: 1000,
gasPrice: new BigNumber(1000)
}), {
data: '0x34234bf23bf4234',
value: '0x64',
from: '0x00000',
to: '0x00000',
gas: '0x3e8',
gasPrice: '0x3e8'
}); });
}); });
}); });

15
test/web3.eth.filter.js

@ -21,6 +21,21 @@ var tests = [{
result: '0xf', result: '0xf',
formattedResult: '0xf', formattedResult: '0xf',
call: 'eth_newFilter' call: 'eth_newFilter'
},{
args: [{
fromBlock: 'latest',
toBlock: 'latest',
address: '0x47d33b27bb249a2dbab4c0612bf9caf4c1950855'
}],
formattedArgs: [{
fromBlock: 'latest',
toBlock: 'latest',
address: '0x47d33b27bb249a2dbab4c0612bf9caf4c1950855',
topics: []
}],
result: '0xf',
formattedResult: '0xf',
call: 'eth_newFilter'
},{ },{
args: ['pending'], args: ['pending'],
formattedArgs: ['pending'], formattedArgs: ['pending'],

38
test/web3.eth.hashRate.js

@ -0,0 +1,38 @@
var chai = require('chai');
var assert = chai.assert;
var web3 = require('../index');
var FakeHttpProvider = require('./helpers/FakeHttpProvider');
var method = 'hashrate';
var tests = [{
result: '0x788a8',
formattedResult: 493736,
call: 'eth_'+ method
}];
describe('web3.eth', function () {
describe(method, function () {
tests.forEach(function (test, index) {
it('property test: ' + index, function () {
// given
var provider = new FakeHttpProvider();
web3.setProvider(provider);
provider.injectResult(test.result);
provider.injectValidation(function (payload) {
assert.equal(payload.jsonrpc, '2.0');
assert.equal(payload.method, test.call);
assert.deepEqual(payload.params, []);
});
// when
var result = web3.eth[method];
// then
assert.strictEqual(test.formattedResult, result);
});
});
});
});
Loading…
Cancel
Save