From d24b48853dcd444c2bf0844c967da50e88cf20ee Mon Sep 17 00:00:00 2001 From: arkpar Date: Fri, 8 May 2015 16:45:23 +0200 Subject: [PATCH 01/30] new abi --- mix/ContractCallDataEncoder.cpp | 18 +++++++++++++++--- mix/ContractCallDataEncoder.h | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/mix/ContractCallDataEncoder.cpp b/mix/ContractCallDataEncoder.cpp index 6b29d8b98..9ea1c3510 100644 --- a/mix/ContractCallDataEncoder.cpp +++ b/mix/ContractCallDataEncoder.cpp @@ -36,6 +36,14 @@ using namespace dev::mix; bytes ContractCallDataEncoder::encodedData() { bytes r(m_encodedData); + size_t headerSize = m_encodedData.size() & ~0x1fUL; //ignore any prefix that is not 32-byte aligned + //apply offsets + for (auto const& p: m_offsetMap) + { + vector_ref offsetRef(r.data() + p.first, 32); + toBigEndian>(p.second + headerSize, offsetRef); //add header size minus signature hash + } + r.insert(r.end(), m_dynamicData.begin(), m_dynamicData.end()); return r; } @@ -64,6 +72,9 @@ void ContractCallDataEncoder::encode(QVariant const& _data, SolidityType const& if (_type.dynamicSize) { + bytes empty(32); + size_t sizePos = m_dynamicData.size(); + m_dynamicData.insert(m_dynamicData.end(), empty.begin(), empty.end()); //reserve space for count if (_type.type == SolidityType::Type::Bytes) count = encodeSingleItem(_data.toString(), _type, m_dynamicData); else @@ -72,9 +83,10 @@ void ContractCallDataEncoder::encode(QVariant const& _data, SolidityType const& for (auto const& item: strList) encodeSingleItem(item, _type, m_dynamicData); } - bytes sizeEnc(32); - toBigEndian(count, sizeEnc); - m_encodedData.insert(m_encodedData.end(), sizeEnc.begin(), sizeEnc.end()); + vector_ref sizeRef(m_dynamicData.data() + sizePos, 32); + toBigEndian(count, sizeRef); + m_offsetMap.push_back(std::make_pair(m_encodedData.size(), sizePos)); + m_encodedData.insert(m_encodedData.end(), empty.begin(), empty.end()); //reserve space for offset } else { diff --git a/mix/ContractCallDataEncoder.h b/mix/ContractCallDataEncoder.h index cab00dd93..2707845ae 100644 --- a/mix/ContractCallDataEncoder.h +++ b/mix/ContractCallDataEncoder.h @@ -73,6 +73,7 @@ private: private: bytes m_encodedData; bytes m_dynamicData; + std::vector> m_offsetMap; }; } From 37440f3a01df38850dd3046b54ed2f36fad4c566 Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 8 May 2015 16:54:39 +0200 Subject: [PATCH 02/30] New ABI encoding for dynamic types. --- libsolidity/Compiler.cpp | 46 +++++++++-------------- test/libsolidity/SolidityCompiler.cpp | 10 ++--- test/libsolidity/SolidityEndToEndTest.cpp | 17 +++++---- 3 files changed, 33 insertions(+), 40 deletions(-) diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index fb2ab3156..bcd4f9d68 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -206,16 +206,9 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract) void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool _fromMemory) { - // We do not check the calldata size, everything is zero-padded. - unsigned offset(CompilerUtils::dataStartOffset); + // We do not check the calldata size, everything is zero-paddedd - bigint parameterHeadEnd = offset; - for (TypePointer const& type: _typeParameters) - parameterHeadEnd += type->isDynamicallySized() ? 32 : type->getCalldataEncodedSize(); - solAssert(parameterHeadEnd <= numeric_limits::max(), "Arguments too large."); - - unsigned stackHeightOfPreviousDynamicArgument = 0; - ArrayType const* previousDynamicType = nullptr; + m_context << u256(CompilerUtils::dataStartOffset); for (TypePointer const& type: _typeParameters) { switch (type->getCategory()) @@ -223,34 +216,31 @@ void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool case Type::Category::Array: if (type->isDynamicallySized()) { - // put on stack: data_offset length - unsigned newStackHeight = m_context.getStackHeight(); - if (previousDynamicType) - { - // Retrieve data start offset by adding length to start offset of previous dynamic type - unsigned stackDepth = m_context.getStackHeight() - stackHeightOfPreviousDynamicArgument; - solAssert(stackDepth <= 16, "Stack too deep."); - m_context << eth::dupInstruction(stackDepth) << eth::dupInstruction(stackDepth); - ArrayUtils(m_context).convertLengthToSize(*previousDynamicType, true); - m_context << eth::Instruction::ADD; - } - else - m_context << u256(parameterHeadEnd); - stackHeightOfPreviousDynamicArgument = newStackHeight; - previousDynamicType = &dynamic_cast(*type); - offset += CompilerUtils(m_context).loadFromMemory(offset, IntegerType(256), !_fromMemory); + // put on stack: data_pointer length + CompilerUtils(m_context).loadFromMemoryDynamic(IntegerType(256), !_fromMemory); + // stack: data_offset next_pointer + //@todo once we support nested arrays, this offset needs to be dynamic. + m_context << eth::Instruction::SWAP1 << u256(CompilerUtils::dataStartOffset); + m_context << eth::Instruction::ADD; + // stack: next_pointer data_pointer + // retrieve length + CompilerUtils(m_context).loadFromMemoryDynamic(IntegerType(256), !_fromMemory, true); + // stack: next_pointer length data_pointer + m_context << eth::Instruction::SWAP2; } else { - m_context << u256(offset); - offset += type->getCalldataEncodedSize(); + // leave the pointer on the stack + m_context << eth::Instruction::DUP1; + m_context << u256(type->getCalldataEncodedSize()) << eth::Instruction::ADD; } break; default: solAssert(!type->isDynamicallySized(), "Unknown dynamically sized type: " + type->toString()); - offset += CompilerUtils(m_context).loadFromMemory(offset, *type, !_fromMemory, true); + CompilerUtils(m_context).loadFromMemoryDynamic(*type, !_fromMemory, true); } } + m_context << eth::Instruction::POP; } void Compiler::appendReturnValuePacker(TypePointers const& _typeParameters) diff --git a/test/libsolidity/SolidityCompiler.cpp b/test/libsolidity/SolidityCompiler.cpp index 7b0ceedb6..aa83c4650 100644 --- a/test/libsolidity/SolidityCompiler.cpp +++ b/test/libsolidity/SolidityCompiler.cpp @@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE(smoke_test) "}\n"; bytes code = compileContract(sourceCode); - unsigned boilerplateSize = 70; + unsigned boilerplateSize = 73; bytes expectation({byte(Instruction::JUMPDEST), byte(Instruction::PUSH1), 0x0, // initialize local variable x byte(Instruction::PUSH1), 0x2, @@ -114,8 +114,8 @@ BOOST_AUTO_TEST_CASE(ifStatement) " function f() { bool x; if (x) 77; else if (!x) 78; else 79; }" "}\n"; bytes code = compileContract(sourceCode); - unsigned shift = 57; - unsigned boilerplateSize = 70; + unsigned shift = 60; + unsigned boilerplateSize = 73; bytes expectation({byte(Instruction::JUMPDEST), byte(Instruction::PUSH1), 0x0, byte(Instruction::DUP1), @@ -155,8 +155,8 @@ BOOST_AUTO_TEST_CASE(loops) " function f() { while(true){1;break;2;continue;3;return;4;} }" "}\n"; bytes code = compileContract(sourceCode); - unsigned shift = 57; - unsigned boilerplateSize = 70; + unsigned shift = 60; + unsigned boilerplateSize = 73; bytes expectation({byte(Instruction::JUMPDEST), byte(Instruction::JUMPDEST), byte(Instruction::PUSH1), 0x1, diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index f168ad454..fd4c83b09 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -2962,12 +2962,13 @@ BOOST_AUTO_TEST_CASE(bytes_in_arguments) } )"; compileAndRun(sourceCode); + string innercalldata1 = asString(FixedHash<4>(dev::sha3("f(uint256,uint256)")).asBytes() + encodeArgs(8, 9)); - bytes calldata1 = encodeArgs(u256(innercalldata1.length()), 12, innercalldata1, 13); string innercalldata2 = asString(FixedHash<4>(dev::sha3("g(uint256)")).asBytes() + encodeArgs(3)); bytes calldata = encodeArgs( - 12, u256(innercalldata1.length()), u256(innercalldata2.length()), 13, - innercalldata1, innercalldata2); + 12, 32 * 4, u256(32 * 4 + 32 + (innercalldata1.length() + 31) / 32 * 32), 13, + u256(innercalldata1.length()), innercalldata1, + u256(innercalldata2.length()), innercalldata2); BOOST_CHECK(callContractFunction("test(uint256,bytes,bytes,uint256)", calldata) == encodeArgs(12, (8 + 9) * 3, 13, u256(innercalldata1.length()))); } @@ -3383,9 +3384,10 @@ BOOST_AUTO_TEST_CASE(external_array_args) compileAndRun(sourceCode); bytes params = encodeArgs( 1, 2, 3, 4, 5, 6, 7, 8, // a - 3, // b.length + 32 * (8 + 1 + 5 + 1 + 1 + 1), // offset to b 21, 22, 23, 24, 25, // c 0, 1, 2, // (a,b,c)_index + 3, // b.length 11, 12, 13 // b ); BOOST_CHECK(callContractFunction("test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256)", params) == encodeArgs(1, 12, 23)); @@ -3422,8 +3424,8 @@ BOOST_AUTO_TEST_CASE(bytes_index_access) 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33}; - BOOST_CHECK(callContractFunction("direct(bytes,uint256)", u256(array.length()), 32, array) == encodeArgs(32)); - BOOST_CHECK(callContractFunction("storageCopyRead(bytes,uint256)", u256(array.length()), 32, array) == encodeArgs(32)); + BOOST_CHECK(callContractFunction("direct(bytes,uint256)", 64, 33, u256(array.length()), array) == encodeArgs(33)); + BOOST_CHECK(callContractFunction("storageCopyRead(bytes,uint256)", 64, 33, u256(array.length()), array) == encodeArgs(33)); BOOST_CHECK(callContractFunction("storageWrite()") == encodeArgs(0x193)); } @@ -3474,6 +3476,7 @@ BOOST_AUTO_TEST_CASE(array_copy_calldata_storage) compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("store(uint256[9],uint8[3][])", encodeArgs( 21, 22, 23, 24, 25, 26, 27, 28, 29, // a + u256(32 * (9 + 1)), 4, // size of b 1, 2, 3, // b[0] 11, 12, 13, // b[1] @@ -3502,7 +3505,7 @@ BOOST_AUTO_TEST_CASE(array_copy_nested_array) )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("test(uint256[2][])", encodeArgs( - 3, + 32, 3, 7, 8, 9, 10, 11, 12 From b75a90bc722d51b2790a9b2dad18b814f327533c Mon Sep 17 00:00:00 2001 From: arkpar Date: Fri, 8 May 2015 21:52:20 +0200 Subject: [PATCH 03/30] used operator+= for bytes --- mix/ContractCallDataEncoder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mix/ContractCallDataEncoder.cpp b/mix/ContractCallDataEncoder.cpp index 9ea1c3510..07ab8dd73 100644 --- a/mix/ContractCallDataEncoder.cpp +++ b/mix/ContractCallDataEncoder.cpp @@ -74,7 +74,7 @@ void ContractCallDataEncoder::encode(QVariant const& _data, SolidityType const& { bytes empty(32); size_t sizePos = m_dynamicData.size(); - m_dynamicData.insert(m_dynamicData.end(), empty.begin(), empty.end()); //reserve space for count + m_dynamicData += empty; //reserve space for count if (_type.type == SolidityType::Type::Bytes) count = encodeSingleItem(_data.toString(), _type, m_dynamicData); else @@ -86,7 +86,7 @@ void ContractCallDataEncoder::encode(QVariant const& _data, SolidityType const& vector_ref sizeRef(m_dynamicData.data() + sizePos, 32); toBigEndian(count, sizeRef); m_offsetMap.push_back(std::make_pair(m_encodedData.size(), sizePos)); - m_encodedData.insert(m_encodedData.end(), empty.begin(), empty.end()); //reserve space for offset + m_encodedData += empty; //reserve space for offset } else { From 10aec68f63132c57091a995dae15aeb5df551b7d Mon Sep 17 00:00:00 2001 From: arkpar Date: Sat, 9 May 2015 21:52:21 +0200 Subject: [PATCH 04/30] fixed transaction signatures --- mix/MixClient.cpp | 39 +++++++++++++++++++++++---------------- mix/MixClient.h | 4 ++-- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index 94bd0d71f..09fed6fc6 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -98,22 +98,30 @@ void MixClient::resetState(std::unordered_map const& _accounts m_executions.clear(); } -Transaction MixClient::replaceGas(Transaction const& _t, u256 const& _gas) +Transaction MixClient::replaceGas(Transaction const& _t, Secret const& _secret, u256 const& _gas) { Transaction ret; - if (_t.isCreation()) - ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce()); + if (_secret) + { + if (_t.isCreation()) + ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce(), _secret); + else + ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.receiveAddress(), _t.data(), _t.nonce(), _secret); + } else - ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.receiveAddress(), _t.data(), _t.nonce()); - ret.forceSender(_t.safeSender()); + { + if (_t.isCreation()) + ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce()); + else + ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.receiveAddress(), _t.data(), _t.nonce()); + ret.forceSender(_t.safeSender()); + } return ret; } -void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _call, bool _gasAuto) +void MixClient::executeTransaction(Transaction const& _t, Secret const& _secret, State& _state, bool _call, bool _gasAuto) { - Transaction t = _gasAuto ? replaceGas(_t, m_state.gasLimitRemaining()) : _t; - bytes rlp = t.rlp(); - + Transaction t = _gasAuto ? replaceGas(_t, Secret(), m_state.gasLimitRemaining()) : _t; // do debugging run first LastHashes lastHashes(256); lastHashes[0] = bc().numberHash(bc().number()); @@ -123,7 +131,7 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c State execState = _state; execState.addBalance(t.sender(), t.gas() * t.gasPrice()); //give it enough balance for gas estimation Executive execution(execState, lastHashes, 0); - execution.initialize(&rlp); + execution.initialize(t); execution.execute(); std::vector machineStates; std::vector levels; @@ -222,7 +230,7 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c // execute on a state if (!_call) { - t = _gasAuto ? replaceGas(_t, d.gasUsed) : _t; + t = _gasAuto ? replaceGas(_t, _secret, d.gasUsed) : _t; er =_state.execute(lastHashes, t); if (t.isCreation() && _state.code(d.contractAddress).empty()) BOOST_THROW_EXCEPTION(OutOfGas() << errinfo_comment("Not enough gas for contract deployment")); @@ -285,7 +293,7 @@ void MixClient::submitTransaction(Secret _secret, u256 _value, Address _dest, by WriteGuard l(x_state); u256 n = m_state.transactionsFrom(toAddress(_secret)); Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); - executeTransaction(t, m_state, false, _gasAuto); + executeTransaction(t, _secret, m_state, false, _gasAuto); } Address MixClient::submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice, bool _gasAuto) @@ -293,7 +301,7 @@ Address MixClient::submitTransaction(Secret _secret, u256 _endowment, bytes cons WriteGuard l(x_state); u256 n = m_state.transactionsFrom(toAddress(_secret)); eth::Transaction t(_endowment, _gasPrice, _gas, _init, n, _secret); - executeTransaction(t, m_state, false, _gasAuto); + executeTransaction(t, _secret, m_state, false, _gasAuto); Address address = right160(sha3(rlpList(t.sender(), t.nonce()))); return address; } @@ -307,9 +315,8 @@ dev::eth::ExecutionResult MixClient::call(Address const& _from, u256 _value, Add t.forceSender(_from); if (_ff == FudgeFactor::Lenient) temp.addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value())); - bytes rlp = t.rlp(); WriteGuard lw(x_state); //TODO: lock is required only for last execution state - executeTransaction(t, temp, true, _gasAuto); + executeTransaction(t, Secret(), temp, true, _gasAuto); return lastExecution().result; } @@ -343,7 +350,7 @@ dev::eth::ExecutionResult MixClient::create(Address const& _from, u256 _value, b if (_ff == FudgeFactor::Lenient) temp.addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value())); WriteGuard lw(x_state); //TODO: lock is required only for last execution state - executeTransaction(t, temp, true, false); + executeTransaction(t, Secret(), temp, true, false); return lastExecution().result; } diff --git a/mix/MixClient.h b/mix/MixClient.h index f7687c488..5988286d0 100644 --- a/mix/MixClient.h +++ b/mix/MixClient.h @@ -87,9 +87,9 @@ protected: virtual void prepareForTransaction() override {} private: - void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state, bool _call, bool _gasAuto); + void executeTransaction(dev::eth::Transaction const& _t, dev::Secret const& _secret, eth::State& _state, bool _call, bool _gasAuto); void noteChanged(h256Set const& _filters); - dev::eth::Transaction replaceGas(dev::eth::Transaction const& _t, dev::u256 const& _gas); + dev::eth::Transaction replaceGas(dev::eth::Transaction const& _t, dev::Secret const& _secret, dev::u256 const& _gas); eth::State m_state; eth::State m_startState; From 13a744559744831e4cb0c13592df070148077359 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Sun, 10 May 2015 15:52:25 +0200 Subject: [PATCH 05/30] 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 --- bower.json | 2 +- dist/web3-light.js | 448 ++++++++-------- dist/web3-light.js.map | 22 +- dist/web3-light.min.js | 4 +- dist/web3.js | 448 ++++++++-------- dist/web3.js.map | 22 +- dist/web3.min.js | 4 +- example/event_inc.html | 2 +- lib/solidity/abi.js | 103 +--- lib/solidity/coder.js | 85 +-- lib/solidity/formatters.js | 14 +- lib/solidity/param.js | 191 +++++-- lib/solidity/utils.js | 5 + lib/version.json | 2 +- lib/web3/eth.js | 17 +- lib/web3/event.js | 2 +- lib/web3/formatters.js | 2 +- lib/web3/httpprovider.js | 23 +- package.js | 2 +- package.json | 2 +- test/abi.inputParser.js | 515 ------------------- test/abi.outputParser.js | 419 --------------- test/coder.decodeParam.js | 45 +- test/coder.encodeParam.js | 82 ++- test/contract.js | 1 + test/event.encode.js | 26 + test/formatters.inputTransactionFormatter.js | 70 ++- test/web3.eth.filter.js | 15 + test/web3.eth.hashRate.js | 38 ++ 29 files changed, 926 insertions(+), 1685 deletions(-) delete mode 100644 test/abi.inputParser.js delete mode 100644 test/abi.outputParser.js create mode 100644 test/web3.eth.hashRate.js diff --git a/bower.json b/bower.json index f8abf431d..db9a4702d 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "web3", "namespace": "ethereum", - "version": "0.3.3", + "version": "0.3.6", "description": "Ethereum Compatible JavaScript API", "main": [ "./dist/web3.js", diff --git a/dist/web3-light.js b/dist/web3-light.js index bfc246f66..c128634de 100644 --- a/dist/web3-light.js +++ b/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 */ -var utils = require('../utils/utils'); var coder = require('./coder'); -var solUtils = 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 utils = require('./utils'); var formatConstructorParams = function (abi, params) { - var constructor = solUtils.getConstructor(abi, params.length); + var constructor = utils.getConstructor(abi, params.length); if (!constructor) { if (params.length > 0) { console.warn("didn't found matching constructor, using default one"); } return ''; } - return formatInput(constructor.inputs, params); + + return coder.encodeParams(constructor.inputs.map(function (input) { + return input.type; + }), params); }; module.exports = { - inputParser: inputParser, - outputParser: outputParser, - formatInput: formatInput, - formatOutput: formatOutput, 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. @@ -213,9 +124,8 @@ SolidityType.prototype.formatInput = function (param, arrayType) { return param.map(function (p) { return self._inputFormatter(p); }).reduce(function (acc, current) { - acc.appendArrayElement(current); - return acc; - }, new SolidityParam('', f.formatInputInt(param.length).value)); + return acc.combine(current); + }, f.formatInputInt(param.length)).withOffset(32); } return this._inputFormatter(param); }; @@ -232,9 +142,9 @@ SolidityType.prototype.formatOutput = function (param, arrayType) { if (arrayType) { // let's assume, that we solidity will never return long arrays :P 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) { - 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; } @@ -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 - * @param {String} type - * @returns {Bool} true if the type is variadic - */ -SolidityType.prototype.isVariadicType = function (type) { - return isArrayType(type) || this._mode === 'bytes'; -}; - -/** - * Should be used to shift param from params group - * - * @method shiftParam + * @method sliceParam + * @param {String} bytes + * @param {Number} index of param to slice * @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') { - return param.shiftBytes(); + return SolidityParam.decodeBytes(bytes, index); } else if (isArrayType(type)) { - var length = new BigNumber(param.prefix.slice(0, 64), 16); - return param.shiftArray(length); + return SolidityParam.decodeArray(bytes, index); } - return param.shiftValue(); + return SolidityParam.decodeParam(bytes, index); }; /** @@ -296,28 +196,6 @@ SolidityCoder.prototype._requireType = function (type) { 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 * @@ -352,24 +230,11 @@ SolidityCoder.prototype.encodeParam = function (type, param) { */ SolidityCoder.prototype.encodeParams = function (types, params) { var self = this; - return types.map(function (type, index) { + var solidityParams = types.map(function (type, index) { return self._formatInput(type, params[index]); - }).reduce(function (acc, solidityParam) { - acc.append(solidityParam); - return acc; - }, new SolidityParam()).encode(); -}; + }); -/** - * 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)); + return SolidityParam.encodeList(solidityParams); }; /** @@ -381,7 +246,7 @@ SolidityCoder.prototype._formatOutput = function (type, param) { * @return {Object} plain param */ 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) { var self = this; - var param = this._bytesToParam(types, bytes); - return types.map(function (type) { + return types.map(function (type, index) { var solidityType = self._requireType(type); - var p = solidityType.shiftParam(type, param); + var p = solidityType.sliceParam(bytes, index, type); return solidityType.formatOutput(p, isArrayType(type)); }); }; @@ -530,7 +394,7 @@ var formatInputBytes = function (value) { */ var formatInputDynamicBytes = function (value) { 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 */ var formatOutputInt = function (param) { - var value = param.value || "0"; + var value = param.staticPart() || "0"; // check if it's negative number // it it is, return two's complement @@ -594,7 +458,7 @@ var formatOutputInt = function (param) { * @returns {BigNumeber} right-aligned output bytes formatted to uint */ var formatOutputUInt = function (param) { - var value = param.value || "0"; + var value = param.staticPart() || "0"; return new BigNumber(value, 16); }; @@ -628,7 +492,7 @@ var formatOutputUReal = function (param) { * @returns {Boolean} right-aligned input bytes formatted to bool */ 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) { // 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) { // 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 */ var formatOutputAddress = function (param) { - var value = param.value; + var value = param.staticPart(); return "0x" + value.slice(value.length - 40, value.length); }; @@ -707,91 +571,196 @@ module.exports = { * @date 2015 */ +var utils = require('../utils/utils'); + /** * SolidityParam object prototype. * Should be used when encoding, decoding solidity bytes */ -var SolidityParam = function (value, prefix, suffix) { - this.prefix = prefix || ''; +var SolidityParam = function (value, offset) { 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 - * @param {SolidityParam} param that it appended after this + * @method combine + * @param {SolidityParam} param with which we should combine + * @param {SolidityParam} result of combination */ -SolidityParam.prototype.append = function (param) { - this.prefix += param.prefix; - this.value += param.value; - this.suffix += param.suffix; +SolidityParam.prototype.combine = function (param) { + return new SolidityParam(this.value + param.value); }; /** - * 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 - * @param {SolidityParam} param that is appended to an array + * @method isDynamic + * @returns {Boolean} */ -SolidityParam.prototype.appendArrayElement = function (param) { - this.suffix += param.value; - this.prefix += param.prefix; - // TODO: suffix not supported = it's required for nested arrays; +SolidityParam.prototype.isDynamic = function () { + return this.value.length > 64; }; /** - * 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 - * @return {String} encoded param(s) + * @returns {String} */ 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 - * @return {SolidityParam} first value param + * @method encodeList + * @param {Array[SolidityParam]} params + * @returns {String} */ -SolidityParam.prototype.shiftValue = function () { - var value = this.value.slice(0, 64); - this.value = this.value.slice(64); - return new SolidityParam(value); +SolidityParam.encodeList = function (params) { + + // updating offsets + 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 - * @return {SolidityParam} first bytes param + * @method decodeParam + * @param {String} bytes + * @param {Number} index + * @returns {SolidityParam} */ -SolidityParam.prototype.shiftBytes = function () { - return this.shiftArray(1); +SolidityParam.decodeParam = function (bytes, index) { + index = index || 0; + return new SolidityParam(bytes.substr(index * 64, 64)); }; /** - * This method should be used to shift an array from group of params - * - * @method shiftArray - * @param {Number} size of an array to shift - * @return {SolidityParam} first array param + * This method should be called to get offset value from bytes at given index + * + * @method getOffset + * @param {String} bytes + * @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) { - var prefix = this.prefix.slice(0, 64); - this.prefix = this.value.slice(64); - var suffix = this.suffix.slice(0, 64 * length); - this.suffix = this.suffix.slice(64 * length); - return new SolidityParam('', prefix, suffix); +SolidityParam.decodeArray = function (bytes, index) { + index = index || 0; + var offset = getOffset(bytes, index); + var length = parseInt('0x' + bytes.substr(offset * 2, 64)); + return new SolidityParam(bytes.substr(offset * 2, (length + 1) * 64)); }; module.exports = SolidityParam; -},{}],5:[function(require,module,exports){ +},{"../utils/utils":8}],5:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -828,6 +797,11 @@ var getConstructor = function (abi, numberOfArgs) { })[0]; }; +//var getSupremeType = function (type) { + //return type.substr(0, type.indexOf('[')) + ']'; +//}; + + module.exports = { getConstructor: getConstructor }; @@ -1394,7 +1368,7 @@ module.exports = { },{"bignumber.js":"bignumber.js"}],9:[function(require,module,exports){ module.exports={ - "version": "0.3.3" + "version": "0.3.6" } },{}],10:[function(require,module,exports){ @@ -1796,7 +1770,7 @@ module.exports = { /** * Web3 - * + * * @module web3 */ @@ -1850,16 +1824,16 @@ var uncleCountCall = function (args) { /// @returns an array of objects describing web3.eth api methods var getBalance = new Method({ - name: 'getBalance', - call: 'eth_getBalance', + name: 'getBalance', + call: 'eth_getBalance', params: 2, inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter], outputFormatter: formatters.outputBigNumberFormatter }); var getStorageAt = new Method({ - name: 'getStorageAt', - call: 'eth_getStorageAt', + name: 'getStorageAt', + call: 'eth_getStorageAt', params: 3, inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter] }); @@ -1872,7 +1846,7 @@ var getCode = new Method({ }); var getBlock = new Method({ - name: 'getBlock', + name: 'getBlock', call: blockCall, params: 2, inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }], @@ -1997,6 +1971,11 @@ var properties = [ name: 'mining', getter: 'eth_mining' }), + new Property({ + name: 'hashrate', + getter: 'eth_hashrate', + outputFormatter: utils.toDecimal + }), new Property({ name: 'gasPrice', getter: 'eth_gasPrice', @@ -2118,7 +2097,7 @@ SolidityEvent.prototype.encode = function (indexed, options) { ['fromBlock', 'toBlock'].filter(function (f) { return options[f] !== undefined; }).forEach(function (f) { - result[f] = utils.toHex(options[f]); + result[f] = formatters.inputBlockNumberFormatter(options[f]); }); result.topics = []; @@ -2447,7 +2426,7 @@ var inputTransactionFormatter = function (options){ delete options.code; } - ['gasPrice', 'gas', 'value'].filter(function (key) { + ['gasPrice', 'gas', 'value', 'nonce'].filter(function (key) { return options[key] !== undefined; }).forEach(function(key){ options[key] = utils.fromDecimal(options[key]); @@ -2796,15 +2775,32 @@ HttpProvider.prototype.send = function (payload) { //if (request.status !== 200) { //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) { var request = new XMLHttpRequest(); request.onreadystatechange = function() { if (request.readyState === 4) { - // TODO: handle the error properly here!!! - callback(null, JSON.parse(request.responseText)); + var result = request.responseText; + var error = null; + + try { + result = JSON.parse(result); + } catch(e) { + error = errors.InvalidResponse(result); + } + + callback(error, result); } }; diff --git a/dist/web3-light.js.map b/dist/web3-light.js.map index 41c3fe4e1..31e9b5a44 100644 --- a/dist/web3-light.js.map +++ b/dist/web3-light.js.map @@ -34,30 +34,30 @@ "index.js" ], "names": [], - "mappings": "AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1dA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrGA;;ACAA;AACA;AACA;AACA;AACA;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA", + "mappings": "AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1dA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5PA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrGA;;ACAA;AACA;AACA;AACA;AACA;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA", "file": "generated.js", "sourceRoot": "", "sourcesContent": [ "(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o.\n*/\n/** \n * @file abi.js\n * @author Marek Kotewicz \n * @author Gav Wood \n * @date 2014\n */\n\nvar utils = require('../utils/utils');\nvar coder = require('./coder');\nvar solUtils = require('./utils');\n\n/**\n * Formats input params to bytes\n *\n * @method formatInput\n * @param {Array} abi inputs of method\n * @param {Array} params that will be formatted to bytes\n * @returns bytes representation of input params\n */\nvar formatInput = function (inputs, params) {\n var i = inputs.map(function (input) {\n return input.type;\n });\n return coder.encodeParams(i, params);\n};\n\n/** \n * Formats output bytes back to param list\n *\n * @method formatOutput\n * @param {Array} abi outputs of method\n * @param {String} bytes represention of output\n * @returns {Array} output params\n */\nvar formatOutput = function (outs, bytes) {\n var o = outs.map(function (out) {\n return out.type;\n });\n \n return coder.decodeParams(o, bytes); \n};\n\n/**\n * Should be called to create input parser for contract with given abi\n *\n * @method inputParser\n * @param {Array} contract abi\n * @returns {Object} input parser object for given json abi\n * TODO: refactor creating the parser, do not double logic from contract\n */\nvar inputParser = function (json) {\n var parser = {};\n json.forEach(function (method) {\n var displayName = utils.extractDisplayName(method.name);\n var typeName = utils.extractTypeName(method.name);\n\n var impl = function () {\n var params = Array.prototype.slice.call(arguments);\n return formatInput(method.inputs, params);\n };\n\n if (parser[displayName] === undefined) {\n parser[displayName] = impl;\n }\n\n parser[displayName][typeName] = impl;\n });\n\n return parser;\n};\n\n/**\n * Should be called to create output parser for contract with given abi\n *\n * @method outputParser\n * @param {Array} contract abi\n * @returns {Object} output parser for given json abi\n */\nvar outputParser = function (json) {\n var parser = {};\n json.forEach(function (method) {\n\n var displayName = utils.extractDisplayName(method.name);\n var typeName = utils.extractTypeName(method.name);\n\n var impl = function (output) {\n return formatOutput(method.outputs, output);\n };\n\n if (parser[displayName] === undefined) {\n parser[displayName] = impl;\n }\n\n parser[displayName][typeName] = impl;\n });\n\n return parser;\n};\n\nvar formatConstructorParams = function (abi, params) {\n var constructor = solUtils.getConstructor(abi, params.length);\n if (!constructor) {\n if (params.length > 0) {\n console.warn(\"didn't found matching constructor, using default one\");\n }\n return '';\n }\n return formatInput(constructor.inputs, params);\n};\n\nmodule.exports = {\n inputParser: inputParser,\n outputParser: outputParser,\n formatInput: formatInput,\n formatOutput: formatOutput,\n formatConstructorParams: formatConstructorParams\n};\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file coder.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar BigNumber = require('bignumber.js');\nvar utils = require('../utils/utils');\nvar f = require('./formatters');\nvar SolidityParam = require('./param');\n\n/**\n * Should be used to check if a type is an array type\n *\n * @method isArrayType\n * @param {String} type\n * @return {Bool} true is the type is an array, otherwise false\n */\nvar isArrayType = function (type) {\n return type.slice(-2) === '[]';\n};\n\n/**\n * SolidityType prototype is used to encode/decode solidity params of certain type\n */\nvar SolidityType = function (config) {\n this._name = config.name;\n this._match = config.match;\n this._mode = config.mode;\n this._inputFormatter = config.inputFormatter;\n this._outputFormatter = config.outputFormatter;\n};\n\n/**\n * Should be used to determine if this SolidityType do match given type\n *\n * @method isType\n * @param {String} name\n * @return {Bool} true if type match this SolidityType, otherwise false\n */\nSolidityType.prototype.isType = function (name) {\n if (this._match === 'strict') {\n return this._name === name || (name.indexOf(this._name) === 0 && name.slice(this._name.length) === '[]');\n } else if (this._match === 'prefix') {\n // TODO better type detection!\n return name.indexOf(this._name) === 0;\n }\n};\n\n/**\n * Should be used to transform plain param to SolidityParam object\n *\n * @method formatInput\n * @param {Object} param - plain object, or an array of objects\n * @param {Bool} arrayType - true if a param should be encoded as an array\n * @return {SolidityParam} encoded param wrapped in SolidityParam object \n */\nSolidityType.prototype.formatInput = function (param, arrayType) {\n if (utils.isArray(param) && arrayType) { // TODO: should fail if this two are not the same\n var self = this;\n return param.map(function (p) {\n return self._inputFormatter(p);\n }).reduce(function (acc, current) {\n acc.appendArrayElement(current);\n return acc;\n }, new SolidityParam('', f.formatInputInt(param.length).value));\n } \n return this._inputFormatter(param);\n};\n\n/**\n * Should be used to transoform SolidityParam to plain param\n *\n * @method formatOutput\n * @param {SolidityParam} byteArray\n * @param {Bool} arrayType - true if a param should be decoded as an array\n * @return {Object} plain decoded param\n */\nSolidityType.prototype.formatOutput = function (param, arrayType) {\n if (arrayType) {\n // let's assume, that we solidity will never return long arrays :P \n var result = [];\n var length = new BigNumber(param.prefix, 16);\n for (var i = 0; i < length * 64; i += 64) {\n result.push(this._outputFormatter(new SolidityParam(param.suffix.slice(i, i + 64))));\n }\n return result;\n }\n return this._outputFormatter(param);\n};\n\n/**\n * Should be used to check if a type is variadic\n *\n * @method isVariadicType\n * @param {String} type\n * @returns {Bool} true if the type is variadic\n */\nSolidityType.prototype.isVariadicType = function (type) {\n return isArrayType(type) || this._mode === 'bytes';\n};\n\n/**\n * Should be used to shift param from params group\n *\n * @method shiftParam\n * @param {String} type\n * @returns {SolidityParam} shifted param\n */\nSolidityType.prototype.shiftParam = function (type, param) {\n if (this._mode === 'bytes') {\n return param.shiftBytes();\n } else if (isArrayType(type)) {\n var length = new BigNumber(param.prefix.slice(0, 64), 16);\n return param.shiftArray(length);\n }\n return param.shiftValue();\n};\n\n/**\n * SolidityCoder prototype should be used to encode/decode solidity params of any type\n */\nvar SolidityCoder = function (types) {\n this._types = types;\n};\n\n/**\n * This method should be used to transform type to SolidityType\n *\n * @method _requireType\n * @param {String} type\n * @returns {SolidityType} \n * @throws {Error} throws if no matching type is found\n */\nSolidityCoder.prototype._requireType = function (type) {\n var solidityType = this._types.filter(function (t) {\n return t.isType(type);\n })[0];\n\n if (!solidityType) {\n throw Error('invalid solidity type!: ' + type);\n }\n\n return solidityType;\n};\n\n/**\n * Should be used to transform plain bytes to SolidityParam object\n *\n * @method _bytesToParam\n * @param {Array} types of params\n * @param {String} bytes to be transformed to SolidityParam\n * @return {SolidityParam} SolidityParam for this group of params\n */\nSolidityCoder.prototype._bytesToParam = function (types, bytes) {\n var self = this;\n var prefixTypes = types.reduce(function (acc, type) {\n return self._requireType(type).isVariadicType(type) ? acc + 1 : acc;\n }, 0);\n var valueTypes = types.length - prefixTypes;\n\n var prefix = bytes.slice(0, prefixTypes * 64);\n bytes = bytes.slice(prefixTypes * 64);\n var value = bytes.slice(0, valueTypes * 64);\n var suffix = bytes.slice(valueTypes * 64);\n return new SolidityParam(value, prefix, suffix); \n};\n\n/**\n * Should be used to transform plain param of given type to SolidityParam\n *\n * @method _formatInput\n * @param {String} type of param\n * @param {Object} plain param\n * @return {SolidityParam}\n */\nSolidityCoder.prototype._formatInput = function (type, param) {\n return this._requireType(type).formatInput(param, isArrayType(type));\n};\n\n/**\n * Should be used to encode plain param\n *\n * @method encodeParam\n * @param {String} type\n * @param {Object} plain param\n * @return {String} encoded plain param\n */\nSolidityCoder.prototype.encodeParam = function (type, param) {\n return this._formatInput(type, param).encode();\n};\n\n/**\n * Should be used to encode list of params\n *\n * @method encodeParams\n * @param {Array} types\n * @param {Array} params\n * @return {String} encoded list of params\n */\nSolidityCoder.prototype.encodeParams = function (types, params) {\n var self = this;\n return types.map(function (type, index) {\n return self._formatInput(type, params[index]);\n }).reduce(function (acc, solidityParam) {\n acc.append(solidityParam);\n return acc;\n }, new SolidityParam()).encode();\n};\n\n/**\n * Should be used to transform SolidityParam to plain param\n *\n * @method _formatOutput\n * @param {String} type\n * @param {SolidityParam} param\n * @return {Object} plain param\n */\nSolidityCoder.prototype._formatOutput = function (type, param) {\n return this._requireType(type).formatOutput(param, isArrayType(type));\n};\n\n/**\n * Should be used to decode bytes to plain param\n *\n * @method decodeParam\n * @param {String} type\n * @param {String} bytes\n * @return {Object} plain param\n */\nSolidityCoder.prototype.decodeParam = function (type, bytes) {\n return this._formatOutput(type, this._bytesToParam([type], bytes));\n};\n\n/**\n * Should be used to decode list of params\n *\n * @method decodeParam\n * @param {Array} types\n * @param {String} bytes\n * @return {Array} array of plain params\n */\nSolidityCoder.prototype.decodeParams = function (types, bytes) {\n var self = this;\n var param = this._bytesToParam(types, bytes);\n return types.map(function (type) {\n var solidityType = self._requireType(type);\n var p = solidityType.shiftParam(type, param);\n return solidityType.formatOutput(p, isArrayType(type));\n });\n};\n\nvar coder = new SolidityCoder([\n new SolidityType({\n name: 'address',\n match: 'strict',\n mode: 'value',\n inputFormatter: f.formatInputInt,\n outputFormatter: f.formatOutputAddress\n }),\n new SolidityType({\n name: 'bool',\n match: 'strict',\n mode: 'value',\n inputFormatter: f.formatInputBool,\n outputFormatter: f.formatOutputBool\n }),\n new SolidityType({\n name: 'int',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputInt,\n outputFormatter: f.formatOutputInt,\n }),\n new SolidityType({\n name: 'uint',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputInt,\n outputFormatter: f.formatOutputUInt\n }),\n new SolidityType({\n name: 'bytes',\n match: 'strict',\n mode: 'bytes',\n inputFormatter: f.formatInputDynamicBytes,\n outputFormatter: f.formatOutputDynamicBytes\n }),\n new SolidityType({\n name: 'bytes',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputBytes,\n outputFormatter: f.formatOutputBytes\n }),\n new SolidityType({\n name: 'real',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputReal,\n outputFormatter: f.formatOutputReal\n }),\n new SolidityType({\n name: 'ureal',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputReal,\n outputFormatter: f.formatOutputUReal\n })\n]);\n\nmodule.exports = coder;\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file formatters.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar BigNumber = require('bignumber.js');\nvar utils = require('../utils/utils');\nvar c = require('../utils/config');\nvar SolidityParam = require('./param');\n\n\n/**\n * Formats input value to byte representation of int\n * If value is negative, return it's two's complement\n * If the value is floating point, round it down\n *\n * @method formatInputInt\n * @param {String|Number|BigNumber} value that needs to be formatted\n * @returns {SolidityParam}\n */\nvar formatInputInt = function (value) {\n var padding = c.ETH_PADDING * 2;\n BigNumber.config(c.ETH_BIGNUMBER_ROUNDING_MODE);\n var result = utils.padLeft(utils.toTwosComplement(value).round().toString(16), padding);\n return new SolidityParam(result);\n};\n\n/**\n * Formats input value to byte representation of string\n *\n * @method formatInputBytes\n * @param {String}\n * @returns {SolidityParam}\n */\nvar formatInputBytes = function (value) {\n var result = utils.fromAscii(value, c.ETH_PADDING).substr(2);\n return new SolidityParam(result);\n};\n\n/**\n * Formats input value to byte representation of string\n *\n * @method formatInputDynamicBytes\n * @param {String}\n * @returns {SolidityParam}\n */\nvar formatInputDynamicBytes = function (value) {\n var result = utils.fromAscii(value, c.ETH_PADDING).substr(2);\n return new SolidityParam('', formatInputInt(value.length).value, result);\n};\n\n/**\n * Formats input value to byte representation of bool\n *\n * @method formatInputBool\n * @param {Boolean}\n * @returns {SolidityParam}\n */\nvar formatInputBool = function (value) {\n var result = '000000000000000000000000000000000000000000000000000000000000000' + (value ? '1' : '0');\n return new SolidityParam(result);\n};\n\n/**\n * Formats input value to byte representation of real\n * Values are multiplied by 2^m and encoded as integers\n *\n * @method formatInputReal\n * @param {String|Number|BigNumber}\n * @returns {SolidityParam}\n */\nvar formatInputReal = function (value) {\n return formatInputInt(new BigNumber(value).times(new BigNumber(2).pow(128)));\n};\n\n/**\n * Check if input value is negative\n *\n * @method signedIsNegative\n * @param {String} value is hex format\n * @returns {Boolean} true if it is negative, otherwise false\n */\nvar signedIsNegative = function (value) {\n return (new BigNumber(value.substr(0, 1), 16).toString(2).substr(0, 1)) === '1';\n};\n\n/**\n * Formats right-aligned output bytes to int\n *\n * @method formatOutputInt\n * @param {SolidityParam} param\n * @returns {BigNumber} right-aligned output bytes formatted to big number\n */\nvar formatOutputInt = function (param) {\n var value = param.value || \"0\";\n\n // check if it's negative number\n // it it is, return two's complement\n if (signedIsNegative(value)) {\n return new BigNumber(value, 16).minus(new BigNumber('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16)).minus(1);\n }\n return new BigNumber(value, 16);\n};\n\n/**\n * Formats right-aligned output bytes to uint\n *\n * @method formatOutputUInt\n * @param {SolidityParam}\n * @returns {BigNumeber} right-aligned output bytes formatted to uint\n */\nvar formatOutputUInt = function (param) {\n var value = param.value || \"0\";\n return new BigNumber(value, 16);\n};\n\n/**\n * Formats right-aligned output bytes to real\n *\n * @method formatOutputReal\n * @param {SolidityParam}\n * @returns {BigNumber} input bytes formatted to real\n */\nvar formatOutputReal = function (param) {\n return formatOutputInt(param).dividedBy(new BigNumber(2).pow(128)); \n};\n\n/**\n * Formats right-aligned output bytes to ureal\n *\n * @method formatOutputUReal\n * @param {SolidityParam}\n * @returns {BigNumber} input bytes formatted to ureal\n */\nvar formatOutputUReal = function (param) {\n return formatOutputUInt(param).dividedBy(new BigNumber(2).pow(128)); \n};\n\n/**\n * Should be used to format output bool\n *\n * @method formatOutputBool\n * @param {SolidityParam}\n * @returns {Boolean} right-aligned input bytes formatted to bool\n */\nvar formatOutputBool = function (param) {\n return param.value === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false;\n};\n\n/**\n * Should be used to format output string\n *\n * @method formatOutputBytes\n * @param {SolidityParam} left-aligned hex representation of string\n * @returns {String} ascii string\n */\nvar formatOutputBytes = function (param) {\n // length might also be important!\n return utils.toAscii(param.value);\n};\n\n/**\n * Should be used to format output string\n *\n * @method formatOutputDynamicBytes\n * @param {SolidityParam} left-aligned hex representation of string\n * @returns {String} ascii string\n */\nvar formatOutputDynamicBytes = function (param) {\n // length might also be important!\n return utils.toAscii(param.suffix);\n};\n\n/**\n * Should be used to format output address\n *\n * @method formatOutputAddress\n * @param {SolidityParam} right-aligned input bytes\n * @returns {String} address\n */\nvar formatOutputAddress = function (param) {\n var value = param.value;\n return \"0x\" + value.slice(value.length - 40, value.length);\n};\n\nmodule.exports = {\n formatInputInt: formatInputInt,\n formatInputBytes: formatInputBytes,\n formatInputDynamicBytes: formatInputDynamicBytes,\n formatInputBool: formatInputBool,\n formatInputReal: formatInputReal,\n formatOutputInt: formatOutputInt,\n formatOutputUInt: formatOutputUInt,\n formatOutputReal: formatOutputReal,\n formatOutputUReal: formatOutputUReal,\n formatOutputBool: formatOutputBool,\n formatOutputBytes: formatOutputBytes,\n formatOutputDynamicBytes: formatOutputDynamicBytes,\n formatOutputAddress: formatOutputAddress\n};\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file param.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\n/**\n * SolidityParam object prototype.\n * Should be used when encoding, decoding solidity bytes\n */\nvar SolidityParam = function (value, prefix, suffix) {\n this.prefix = prefix || '';\n this.value = value || '';\n this.suffix = suffix || '';\n};\n\n/**\n * This method should be used to encode two params one after another\n *\n * @method append\n * @param {SolidityParam} param that it appended after this\n */\nSolidityParam.prototype.append = function (param) {\n this.prefix += param.prefix;\n this.value += param.value;\n this.suffix += param.suffix;\n};\n\n/**\n * This method should be used to encode next param in an array\n *\n * @method appendArrayElement\n * @param {SolidityParam} param that is appended to an array\n */\nSolidityParam.prototype.appendArrayElement = function (param) {\n this.suffix += param.value;\n this.prefix += param.prefix;\n // TODO: suffix not supported = it's required for nested arrays;\n};\n\n/**\n * This method should be used to create bytearrays from param\n *\n * @method encode\n * @return {String} encoded param(s)\n */\nSolidityParam.prototype.encode = function () {\n return this.prefix + this.value + this.suffix;\n};\n\n/**\n * This method should be used to shift first param from group of params\n *\n * @method shiftValue\n * @return {SolidityParam} first value param\n */\nSolidityParam.prototype.shiftValue = function () {\n var value = this.value.slice(0, 64);\n this.value = this.value.slice(64);\n return new SolidityParam(value);\n};\n\n/**\n * This method should be used to first bytes param from group of params\n *\n * @method shiftBytes\n * @return {SolidityParam} first bytes param\n */\nSolidityParam.prototype.shiftBytes = function () {\n return this.shiftArray(1); \n};\n\n/**\n * This method should be used to shift an array from group of params \n * \n * @method shiftArray\n * @param {Number} size of an array to shift\n * @return {SolidityParam} first array param\n */\nSolidityParam.prototype.shiftArray = function (length) {\n var prefix = this.prefix.slice(0, 64);\n this.prefix = this.value.slice(64);\n var suffix = this.suffix.slice(0, 64 * length);\n this.suffix = this.suffix.slice(64 * length);\n return new SolidityParam('', prefix, suffix);\n};\n\nmodule.exports = SolidityParam;\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/**\n * @file utils.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\n/**\n * Returns the contstructor with matching number of arguments\n *\n * @method getConstructor\n * @param {Array} abi\n * @param {Number} numberOfArgs\n * @returns {Object} constructor function abi\n */\nvar getConstructor = function (abi, numberOfArgs) {\n return abi.filter(function (f) {\n return f.type === 'constructor' && f.inputs.length === numberOfArgs;\n })[0];\n};\n\nmodule.exports = {\n getConstructor: getConstructor\n};\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file abi.js\n * @author Marek Kotewicz \n * @author Gav Wood \n * @date 2014\n */\n\nvar coder = require('./coder');\nvar utils = require('./utils');\n\nvar formatConstructorParams = function (abi, params) {\n var constructor = utils.getConstructor(abi, params.length);\n if (!constructor) {\n if (params.length > 0) {\n console.warn(\"didn't found matching constructor, using default one\");\n }\n return '';\n }\n\n return coder.encodeParams(constructor.inputs.map(function (input) {\n return input.type;\n }), params);\n};\n\nmodule.exports = {\n formatConstructorParams: formatConstructorParams\n};\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file coder.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar BigNumber = require('bignumber.js');\nvar utils = require('../utils/utils');\nvar f = require('./formatters');\nvar SolidityParam = require('./param');\n\n/**\n * Should be used to check if a type is an array type\n *\n * @method isArrayType\n * @param {String} type\n * @return {Bool} true is the type is an array, otherwise false\n */\nvar isArrayType = function (type) {\n return type.slice(-2) === '[]';\n};\n\n/**\n * SolidityType prototype is used to encode/decode solidity params of certain type\n */\nvar SolidityType = function (config) {\n this._name = config.name;\n this._match = config.match;\n this._mode = config.mode;\n this._inputFormatter = config.inputFormatter;\n this._outputFormatter = config.outputFormatter;\n};\n\n/**\n * Should be used to determine if this SolidityType do match given type\n *\n * @method isType\n * @param {String} name\n * @return {Bool} true if type match this SolidityType, otherwise false\n */\nSolidityType.prototype.isType = function (name) {\n if (this._match === 'strict') {\n return this._name === name || (name.indexOf(this._name) === 0 && name.slice(this._name.length) === '[]');\n } else if (this._match === 'prefix') {\n // TODO better type detection!\n return name.indexOf(this._name) === 0;\n }\n};\n\n/**\n * Should be used to transform plain param to SolidityParam object\n *\n * @method formatInput\n * @param {Object} param - plain object, or an array of objects\n * @param {Bool} arrayType - true if a param should be encoded as an array\n * @return {SolidityParam} encoded param wrapped in SolidityParam object \n */\nSolidityType.prototype.formatInput = function (param, arrayType) {\n if (utils.isArray(param) && arrayType) { // TODO: should fail if this two are not the same\n var self = this;\n return param.map(function (p) {\n return self._inputFormatter(p);\n }).reduce(function (acc, current) {\n return acc.combine(current);\n }, f.formatInputInt(param.length)).withOffset(32);\n } \n return this._inputFormatter(param);\n};\n\n/**\n * Should be used to transoform SolidityParam to plain param\n *\n * @method formatOutput\n * @param {SolidityParam} byteArray\n * @param {Bool} arrayType - true if a param should be decoded as an array\n * @return {Object} plain decoded param\n */\nSolidityType.prototype.formatOutput = function (param, arrayType) {\n if (arrayType) {\n // let's assume, that we solidity will never return long arrays :P \n var result = [];\n var length = new BigNumber(param.dynamicPart().slice(0, 64), 16);\n for (var i = 0; i < length * 64; i += 64) {\n result.push(this._outputFormatter(new SolidityParam(param.dynamicPart().substr(i + 64, 64))));\n }\n return result;\n }\n return this._outputFormatter(param);\n};\n\n/**\n * Should be used to slice single param from bytes\n *\n * @method sliceParam\n * @param {String} bytes\n * @param {Number} index of param to slice\n * @param {String} type\n * @returns {SolidityParam} param\n */\nSolidityType.prototype.sliceParam = function (bytes, index, type) {\n if (this._mode === 'bytes') {\n return SolidityParam.decodeBytes(bytes, index);\n } else if (isArrayType(type)) {\n return SolidityParam.decodeArray(bytes, index);\n }\n return SolidityParam.decodeParam(bytes, index);\n};\n\n/**\n * SolidityCoder prototype should be used to encode/decode solidity params of any type\n */\nvar SolidityCoder = function (types) {\n this._types = types;\n};\n\n/**\n * This method should be used to transform type to SolidityType\n *\n * @method _requireType\n * @param {String} type\n * @returns {SolidityType} \n * @throws {Error} throws if no matching type is found\n */\nSolidityCoder.prototype._requireType = function (type) {\n var solidityType = this._types.filter(function (t) {\n return t.isType(type);\n })[0];\n\n if (!solidityType) {\n throw Error('invalid solidity type!: ' + type);\n }\n\n return solidityType;\n};\n\n/**\n * Should be used to transform plain param of given type to SolidityParam\n *\n * @method _formatInput\n * @param {String} type of param\n * @param {Object} plain param\n * @return {SolidityParam}\n */\nSolidityCoder.prototype._formatInput = function (type, param) {\n return this._requireType(type).formatInput(param, isArrayType(type));\n};\n\n/**\n * Should be used to encode plain param\n *\n * @method encodeParam\n * @param {String} type\n * @param {Object} plain param\n * @return {String} encoded plain param\n */\nSolidityCoder.prototype.encodeParam = function (type, param) {\n return this._formatInput(type, param).encode();\n};\n\n/**\n * Should be used to encode list of params\n *\n * @method encodeParams\n * @param {Array} types\n * @param {Array} params\n * @return {String} encoded list of params\n */\nSolidityCoder.prototype.encodeParams = function (types, params) {\n var self = this;\n var solidityParams = types.map(function (type, index) {\n return self._formatInput(type, params[index]);\n });\n\n return SolidityParam.encodeList(solidityParams);\n};\n\n/**\n * Should be used to decode bytes to plain param\n *\n * @method decodeParam\n * @param {String} type\n * @param {String} bytes\n * @return {Object} plain param\n */\nSolidityCoder.prototype.decodeParam = function (type, bytes) {\n return this.decodeParams([type], bytes)[0];\n};\n\n/**\n * Should be used to decode list of params\n *\n * @method decodeParam\n * @param {Array} types\n * @param {String} bytes\n * @return {Array} array of plain params\n */\nSolidityCoder.prototype.decodeParams = function (types, bytes) {\n var self = this;\n return types.map(function (type, index) {\n var solidityType = self._requireType(type);\n var p = solidityType.sliceParam(bytes, index, type);\n return solidityType.formatOutput(p, isArrayType(type));\n });\n};\n\nvar coder = new SolidityCoder([\n new SolidityType({\n name: 'address',\n match: 'strict',\n mode: 'value',\n inputFormatter: f.formatInputInt,\n outputFormatter: f.formatOutputAddress\n }),\n new SolidityType({\n name: 'bool',\n match: 'strict',\n mode: 'value',\n inputFormatter: f.formatInputBool,\n outputFormatter: f.formatOutputBool\n }),\n new SolidityType({\n name: 'int',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputInt,\n outputFormatter: f.formatOutputInt,\n }),\n new SolidityType({\n name: 'uint',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputInt,\n outputFormatter: f.formatOutputUInt\n }),\n new SolidityType({\n name: 'bytes',\n match: 'strict',\n mode: 'bytes',\n inputFormatter: f.formatInputDynamicBytes,\n outputFormatter: f.formatOutputDynamicBytes\n }),\n new SolidityType({\n name: 'bytes',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputBytes,\n outputFormatter: f.formatOutputBytes\n }),\n new SolidityType({\n name: 'real',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputReal,\n outputFormatter: f.formatOutputReal\n }),\n new SolidityType({\n name: 'ureal',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputReal,\n outputFormatter: f.formatOutputUReal\n })\n]);\n\nmodule.exports = coder;\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file formatters.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar BigNumber = require('bignumber.js');\nvar utils = require('../utils/utils');\nvar c = require('../utils/config');\nvar SolidityParam = require('./param');\n\n\n/**\n * Formats input value to byte representation of int\n * If value is negative, return it's two's complement\n * If the value is floating point, round it down\n *\n * @method formatInputInt\n * @param {String|Number|BigNumber} value that needs to be formatted\n * @returns {SolidityParam}\n */\nvar formatInputInt = function (value) {\n var padding = c.ETH_PADDING * 2;\n BigNumber.config(c.ETH_BIGNUMBER_ROUNDING_MODE);\n var result = utils.padLeft(utils.toTwosComplement(value).round().toString(16), padding);\n return new SolidityParam(result);\n};\n\n/**\n * Formats input value to byte representation of string\n *\n * @method formatInputBytes\n * @param {String}\n * @returns {SolidityParam}\n */\nvar formatInputBytes = function (value) {\n var result = utils.fromAscii(value, c.ETH_PADDING).substr(2);\n return new SolidityParam(result);\n};\n\n/**\n * Formats input value to byte representation of string\n *\n * @method formatInputDynamicBytes\n * @param {String}\n * @returns {SolidityParam}\n */\nvar formatInputDynamicBytes = function (value) {\n var result = utils.fromAscii(value, c.ETH_PADDING).substr(2);\n return new SolidityParam(formatInputInt(value.length).value + result, 32);\n};\n\n/**\n * Formats input value to byte representation of bool\n *\n * @method formatInputBool\n * @param {Boolean}\n * @returns {SolidityParam}\n */\nvar formatInputBool = function (value) {\n var result = '000000000000000000000000000000000000000000000000000000000000000' + (value ? '1' : '0');\n return new SolidityParam(result);\n};\n\n/**\n * Formats input value to byte representation of real\n * Values are multiplied by 2^m and encoded as integers\n *\n * @method formatInputReal\n * @param {String|Number|BigNumber}\n * @returns {SolidityParam}\n */\nvar formatInputReal = function (value) {\n return formatInputInt(new BigNumber(value).times(new BigNumber(2).pow(128)));\n};\n\n/**\n * Check if input value is negative\n *\n * @method signedIsNegative\n * @param {String} value is hex format\n * @returns {Boolean} true if it is negative, otherwise false\n */\nvar signedIsNegative = function (value) {\n return (new BigNumber(value.substr(0, 1), 16).toString(2).substr(0, 1)) === '1';\n};\n\n/**\n * Formats right-aligned output bytes to int\n *\n * @method formatOutputInt\n * @param {SolidityParam} param\n * @returns {BigNumber} right-aligned output bytes formatted to big number\n */\nvar formatOutputInt = function (param) {\n var value = param.staticPart() || \"0\";\n\n // check if it's negative number\n // it it is, return two's complement\n if (signedIsNegative(value)) {\n return new BigNumber(value, 16).minus(new BigNumber('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16)).minus(1);\n }\n return new BigNumber(value, 16);\n};\n\n/**\n * Formats right-aligned output bytes to uint\n *\n * @method formatOutputUInt\n * @param {SolidityParam}\n * @returns {BigNumeber} right-aligned output bytes formatted to uint\n */\nvar formatOutputUInt = function (param) {\n var value = param.staticPart() || \"0\";\n return new BigNumber(value, 16);\n};\n\n/**\n * Formats right-aligned output bytes to real\n *\n * @method formatOutputReal\n * @param {SolidityParam}\n * @returns {BigNumber} input bytes formatted to real\n */\nvar formatOutputReal = function (param) {\n return formatOutputInt(param).dividedBy(new BigNumber(2).pow(128)); \n};\n\n/**\n * Formats right-aligned output bytes to ureal\n *\n * @method formatOutputUReal\n * @param {SolidityParam}\n * @returns {BigNumber} input bytes formatted to ureal\n */\nvar formatOutputUReal = function (param) {\n return formatOutputUInt(param).dividedBy(new BigNumber(2).pow(128)); \n};\n\n/**\n * Should be used to format output bool\n *\n * @method formatOutputBool\n * @param {SolidityParam}\n * @returns {Boolean} right-aligned input bytes formatted to bool\n */\nvar formatOutputBool = function (param) {\n return param.staticPart() === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false;\n};\n\n/**\n * Should be used to format output string\n *\n * @method formatOutputBytes\n * @param {SolidityParam} left-aligned hex representation of string\n * @returns {String} ascii string\n */\nvar formatOutputBytes = function (param) {\n // length might also be important!\n return utils.toAscii(param.staticPart());\n};\n\n/**\n * Should be used to format output string\n *\n * @method formatOutputDynamicBytes\n * @param {SolidityParam} left-aligned hex representation of string\n * @returns {String} ascii string\n */\nvar formatOutputDynamicBytes = function (param) {\n // length might also be important!\n return utils.toAscii(param.dynamicPart().slice(64));\n};\n\n/**\n * Should be used to format output address\n *\n * @method formatOutputAddress\n * @param {SolidityParam} right-aligned input bytes\n * @returns {String} address\n */\nvar formatOutputAddress = function (param) {\n var value = param.staticPart();\n return \"0x\" + value.slice(value.length - 40, value.length);\n};\n\nmodule.exports = {\n formatInputInt: formatInputInt,\n formatInputBytes: formatInputBytes,\n formatInputDynamicBytes: formatInputDynamicBytes,\n formatInputBool: formatInputBool,\n formatInputReal: formatInputReal,\n formatOutputInt: formatOutputInt,\n formatOutputUInt: formatOutputUInt,\n formatOutputReal: formatOutputReal,\n formatOutputUReal: formatOutputUReal,\n formatOutputBool: formatOutputBool,\n formatOutputBytes: formatOutputBytes,\n formatOutputDynamicBytes: formatOutputDynamicBytes,\n formatOutputAddress: formatOutputAddress\n};\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file param.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar utils = require('../utils/utils');\n\n/**\n * SolidityParam object prototype.\n * Should be used when encoding, decoding solidity bytes\n */\nvar SolidityParam = function (value, offset) {\n this.value = value || '';\n this.offset = offset; // offset in bytes\n};\n\n/**\n * This method should be used to get length of params's dynamic part\n * \n * @method dynamicPartLength\n * @returns {Number} length of dynamic part (in bytes)\n */\nSolidityParam.prototype.dynamicPartLength = function () {\n return this.dynamicPart().length / 2;\n};\n\n/**\n * This method should be used to create copy of solidity param with different offset\n *\n * @method withOffset\n * @param {Number} offset length in bytes\n * @returns {SolidityParam} new solidity param with applied offset\n */\nSolidityParam.prototype.withOffset = function (offset) {\n return new SolidityParam(this.value, offset);\n};\n\n/**\n * This method should be used to combine solidity params together\n * eg. when appending an array\n *\n * @method combine\n * @param {SolidityParam} param with which we should combine\n * @param {SolidityParam} result of combination\n */\nSolidityParam.prototype.combine = function (param) {\n return new SolidityParam(this.value + param.value); \n};\n\n/**\n * This method should be called to check if param has dynamic size.\n * If it has, it returns true, otherwise false\n *\n * @method isDynamic\n * @returns {Boolean}\n */\nSolidityParam.prototype.isDynamic = function () {\n return this.value.length > 64;\n};\n\n/**\n * This method should be called to transform offset to bytes\n *\n * @method offsetAsBytes\n * @returns {String} bytes representation of offset\n */\nSolidityParam.prototype.offsetAsBytes = function () {\n return !this.isDynamic() ? '' : utils.padLeft(utils.toTwosComplement(this.offset).toString(16), 64);\n};\n\n/**\n * This method should be called to get static part of param\n *\n * @method staticPart\n * @returns {String} offset if it is a dynamic param, otherwise value\n */\nSolidityParam.prototype.staticPart = function () {\n if (!this.isDynamic()) {\n return this.value; \n } \n return this.offsetAsBytes();\n};\n\n/**\n * This method should be called to get dynamic part of param\n *\n * @method dynamicPart\n * @returns {String} returns a value if it is a dynamic param, otherwise empty string\n */\nSolidityParam.prototype.dynamicPart = function () {\n return this.isDynamic() ? this.value : '';\n};\n\n/**\n * This method should be called to encode param\n *\n * @method encode\n * @returns {String}\n */\nSolidityParam.prototype.encode = function () {\n return this.staticPart() + this.dynamicPart();\n};\n\n/**\n * This method should be called to encode array of params\n *\n * @method encodeList\n * @param {Array[SolidityParam]} params\n * @returns {String}\n */\nSolidityParam.encodeList = function (params) {\n \n // updating offsets\n var totalOffset = params.length * 32;\n var offsetParams = params.map(function (param) {\n if (!param.isDynamic()) {\n return param;\n }\n var offset = totalOffset;\n totalOffset += param.dynamicPartLength();\n return param.withOffset(offset);\n });\n\n // encode everything!\n return offsetParams.reduce(function (result, param) {\n return result + param.dynamicPart();\n }, offsetParams.reduce(function (result, param) {\n return result + param.staticPart();\n }, ''));\n};\n\n/**\n * This method should be used to decode plain (static) solidity param at given index\n *\n * @method decodeParam\n * @param {String} bytes\n * @param {Number} index\n * @returns {SolidityParam}\n */\nSolidityParam.decodeParam = function (bytes, index) {\n index = index || 0;\n return new SolidityParam(bytes.substr(index * 64, 64)); \n};\n\n/**\n * This method should be called to get offset value from bytes at given index\n *\n * @method getOffset\n * @param {String} bytes\n * @param {Number} index\n * @returns {Number} offset as number\n */\nvar getOffset = function (bytes, index) {\n // we can do this cause offset is rather small\n return parseInt('0x' + bytes.substr(index * 64, 64));\n};\n\n/**\n * This method should be called to decode solidity bytes param at given index\n *\n * @method decodeBytes\n * @param {String} bytes\n * @param {Number} index\n * @returns {SolidityParam}\n */\nSolidityParam.decodeBytes = function (bytes, index) {\n index = index || 0;\n //TODO add support for strings longer than 32 bytes\n //var length = parseInt('0x' + bytes.substr(offset * 64, 64));\n\n var offset = getOffset(bytes, index);\n\n // 2 * , cause we also parse length\n return new SolidityParam(bytes.substr(offset * 2, 2 * 64));\n};\n\n/**\n * This method should be used to decode solidity array at given index\n *\n * @method decodeArray\n * @param {String} bytes\n * @param {Number} index\n * @returns {SolidityParam}\n */\nSolidityParam.decodeArray = function (bytes, index) {\n index = index || 0;\n var offset = getOffset(bytes, index);\n var length = parseInt('0x' + bytes.substr(offset * 2, 64));\n return new SolidityParam(bytes.substr(offset * 2, (length + 1) * 64));\n};\n\nmodule.exports = SolidityParam;\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/**\n * @file utils.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\n/**\n * Returns the contstructor with matching number of arguments\n *\n * @method getConstructor\n * @param {Array} abi\n * @param {Number} numberOfArgs\n * @returns {Object} constructor function abi\n */\nvar getConstructor = function (abi, numberOfArgs) {\n return abi.filter(function (f) {\n return f.type === 'constructor' && f.inputs.length === numberOfArgs;\n })[0];\n};\n\n//var getSupremeType = function (type) {\n //return type.substr(0, type.indexOf('[')) + ']';\n//};\n\n\nmodule.exports = {\n getConstructor: getConstructor\n};\n\n", "'use strict';\n\n// go env doesn't have and need XMLHttpRequest\nif (typeof XMLHttpRequest === 'undefined') {\n exports.XMLHttpRequest = {};\n} else {\n exports.XMLHttpRequest = XMLHttpRequest; // jshint ignore:line\n}\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file config.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\n/**\n * Utils\n * \n * @module utils\n */\n\n/**\n * Utility functions\n * \n * @class [utils] config\n * @constructor\n */\n\n/// required to define ETH_BIGNUMBER_ROUNDING_MODE\nvar BigNumber = require('bignumber.js');\n\nvar ETH_UNITS = [ \n 'wei', \n 'Kwei', \n 'Mwei', \n 'Gwei', \n 'szabo', \n 'finney', \n 'ether', \n 'grand', \n 'Mether', \n 'Gether', \n 'Tether', \n 'Pether', \n 'Eether', \n 'Zether', \n 'Yether', \n 'Nether', \n 'Dether', \n 'Vether', \n 'Uether' \n];\n\nmodule.exports = {\n ETH_PADDING: 32,\n ETH_SIGNATURE_LENGTH: 4,\n ETH_UNITS: ETH_UNITS,\n ETH_BIGNUMBER_ROUNDING_MODE: { ROUNDING_MODE: BigNumber.ROUND_DOWN },\n ETH_POLLING_TIMEOUT: 1000,\n defaultBlock: 'latest',\n defaultAccount: undefined\n};\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file utils.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\n/**\n * Utils\n * \n * @module utils\n */\n\n/**\n * Utility functions\n * \n * @class [utils] utils\n * @constructor\n */\n\nvar BigNumber = require('bignumber.js');\n\nvar unitMap = {\n 'wei': '1',\n 'kwei': '1000',\n 'ada': '1000',\n 'mwei': '1000000',\n 'babbage': '1000000',\n 'gwei': '1000000000',\n 'shannon': '1000000000',\n 'szabo': '1000000000000',\n 'finney': '1000000000000000',\n 'ether': '1000000000000000000',\n 'kether': '1000000000000000000000',\n 'grand': '1000000000000000000000',\n 'einstein': '1000000000000000000000',\n 'mether': '1000000000000000000000000',\n 'gether': '1000000000000000000000000000',\n 'tether': '1000000000000000000000000000000'\n};\n\n/**\n * Should be called to pad string to expected length\n *\n * @method padLeft\n * @param {String} string to be padded\n * @param {Number} characters that result string should have\n * @param {String} sign, by default 0\n * @returns {String} right aligned string\n */\nvar padLeft = function (string, chars, sign) {\n return new Array(chars - string.length + 1).join(sign ? sign : \"0\") + string;\n};\n\n/** \n * Should be called to get sting from it's hex representation\n *\n * @method toAscii\n * @param {String} string in hex\n * @returns {String} ascii string representation of hex value\n */\nvar toAscii = function(hex) {\n// Find termination\n var str = \"\";\n var i = 0, l = hex.length;\n if (hex.substring(0, 2) === '0x') {\n i = 2;\n }\n for (; i < l; i+=2) {\n var code = parseInt(hex.substr(i, 2), 16);\n if (code === 0) {\n break;\n }\n\n str += String.fromCharCode(code);\n }\n\n return str;\n};\n \n/**\n * Shold be called to get hex representation (prefixed by 0x) of ascii string \n *\n * @method toHexNative\n * @param {String} string\n * @returns {String} hex representation of input string\n */\nvar toHexNative = function(str) {\n var hex = \"\";\n for(var i = 0; i < str.length; i++) {\n var n = str.charCodeAt(i).toString(16);\n hex += n.length < 2 ? '0' + n : n;\n }\n\n return hex;\n};\n\n/**\n * Shold be called to get hex representation (prefixed by 0x) of ascii string \n *\n * @method fromAscii\n * @param {String} string\n * @param {Number} optional padding\n * @returns {String} hex representation of input string\n */\nvar fromAscii = function(str, pad) {\n pad = pad === undefined ? 0 : pad;\n var hex = toHexNative(str);\n while (hex.length < pad*2)\n hex += \"00\";\n return \"0x\" + hex;\n};\n\n/**\n * Should be used to create full function/event name from json abi\n *\n * @method transformToFullName\n * @param {Object} json-abi\n * @return {String} full fnction/event name\n */\nvar transformToFullName = function (json) {\n if (json.name.indexOf('(') !== -1) {\n return json.name;\n }\n\n var typeName = json.inputs.map(function(i){return i.type; }).join();\n return json.name + '(' + typeName + ')';\n};\n\n/**\n * Should be called to get display name of contract function\n * \n * @method extractDisplayName\n * @param {String} name of function/event\n * @returns {String} display name for function/event eg. multiply(uint256) -> multiply\n */\nvar extractDisplayName = function (name) {\n var length = name.indexOf('('); \n return length !== -1 ? name.substr(0, length) : name;\n};\n\n/// @returns overloaded part of function/event name\nvar extractTypeName = function (name) {\n /// TODO: make it invulnerable\n var length = name.indexOf('(');\n return length !== -1 ? name.substr(length + 1, name.length - 1 - (length + 1)).replace(' ', '') : \"\";\n};\n\n/**\n * Converts value to it's decimal representation in string\n *\n * @method toDecimal\n * @param {String|Number|BigNumber}\n * @return {String}\n */\nvar toDecimal = function (value) {\n return toBigNumber(value).toNumber();\n};\n\n/**\n * Converts value to it's hex representation\n *\n * @method fromDecimal\n * @param {String|Number|BigNumber}\n * @return {String}\n */\nvar fromDecimal = function (value) {\n var number = toBigNumber(value);\n var result = number.toString(16);\n\n return number.lessThan(0) ? '-0x' + result.substr(1) : '0x' + result;\n};\n\n/**\n * Auto converts any given value into it's hex representation.\n *\n * And even stringifys objects before.\n *\n * @method toHex\n * @param {String|Number|BigNumber|Object}\n * @return {String}\n */\nvar toHex = function (val) {\n /*jshint maxcomplexity:7 */\n\n if (isBoolean(val))\n return fromDecimal(+val);\n\n if (isBigNumber(val))\n return fromDecimal(val);\n\n if (isObject(val))\n return fromAscii(JSON.stringify(val));\n\n // if its a negative number, pass it through fromDecimal\n if (isString(val)) {\n if (val.indexOf('-0x') === 0)\n return fromDecimal(val);\n else if (!isFinite(val))\n return fromAscii(val);\n }\n\n return fromDecimal(val);\n};\n\n/**\n * Returns value of unit in Wei\n *\n * @method getValueOfUnit\n * @param {String} unit the unit to convert to, default ether\n * @returns {BigNumber} value of the unit (in Wei)\n * @throws error if the unit is not correct:w\n */\nvar getValueOfUnit = function (unit) {\n unit = unit ? unit.toLowerCase() : 'ether';\n var unitValue = unitMap[unit];\n if (unitValue === undefined) {\n throw new Error('This unit doesn\\'t exists, please use the one of the following units' + JSON.stringify(unitMap, null, 2));\n }\n return new BigNumber(unitValue, 10);\n};\n\n/**\n * Takes a number of wei and converts it to any other ether unit.\n *\n * Possible units are:\n * - kwei/ada\n * - mwei/babbage\n * - gwei/shannon\n * - szabo\n * - finney\n * - ether\n * - kether/grand/einstein\n * - mether\n * - gether\n * - tether\n *\n * @method fromWei\n * @param {Number|String} number can be a number, number string or a HEX of a decimal\n * @param {String} unit the unit to convert to, default ether\n * @return {String|Object} When given a BigNumber object it returns one as well, otherwise a number\n*/\nvar fromWei = function(number, unit) {\n var returnValue = toBigNumber(number).dividedBy(getValueOfUnit(unit));\n\n return isBigNumber(number) ? returnValue : returnValue.toString(10); \n};\n\n/**\n * Takes a number of a unit and converts it to wei.\n *\n * Possible units are:\n * - kwei/ada\n * - mwei/babbage\n * - gwei/shannon\n * - szabo\n * - finney\n * - ether\n * - kether/grand/einstein\n * - mether\n * - gether\n * - tether\n *\n * @method toWei\n * @param {Number|String|BigNumber} number can be a number, number string or a HEX of a decimal\n * @param {String} unit the unit to convert from, default ether\n * @return {String|Object} When given a BigNumber object it returns one as well, otherwise a number\n*/\nvar toWei = function(number, unit) {\n var returnValue = toBigNumber(number).times(getValueOfUnit(unit));\n\n return isBigNumber(number) ? returnValue : returnValue.toString(10); \n};\n\n/**\n * Takes an input and transforms it into an bignumber\n *\n * @method toBigNumber\n * @param {Number|String|BigNumber} a number, string, HEX string or BigNumber\n * @return {BigNumber} BigNumber\n*/\nvar toBigNumber = function(number) {\n /*jshint maxcomplexity:5 */\n number = number || 0;\n if (isBigNumber(number))\n return number;\n\n if (isString(number) && (number.indexOf('0x') === 0 || number.indexOf('-0x') === 0)) {\n return new BigNumber(number.replace('0x',''), 16);\n }\n \n return new BigNumber(number.toString(10), 10);\n};\n\n/**\n * Takes and input transforms it into bignumber and if it is negative value, into two's complement\n *\n * @method toTwosComplement\n * @param {Number|String|BigNumber}\n * @return {BigNumber}\n */\nvar toTwosComplement = function (number) {\n var bigNumber = toBigNumber(number);\n if (bigNumber.lessThan(0)) {\n return new BigNumber(\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\", 16).plus(bigNumber).plus(1);\n }\n return bigNumber;\n};\n\n/**\n * Checks if the given string is strictly an address\n *\n * @method isStrictAddress\n * @param {String} address the given HEX adress\n * @return {Boolean}\n*/\nvar isStrictAddress = function (address) {\n return /^0x[0-9a-f]{40}$/.test(address);\n};\n\n/**\n * Checks if the given string is an address\n *\n * @method isAddress\n * @param {String} address the given HEX adress\n * @return {Boolean}\n*/\nvar isAddress = function (address) {\n return /^(0x)?[0-9a-f]{40}$/.test(address);\n};\n\n/**\n * Transforms given string to valid 20 bytes-length addres with 0x prefix\n *\n * @method toAddress\n * @param {String} address\n * @return {String} formatted address\n */\nvar toAddress = function (address) {\n if (isStrictAddress(address)) {\n return address;\n }\n \n if (/^[0-9a-f]{40}$/.test(address)) {\n return '0x' + address;\n }\n\n return '0x' + padLeft(toHex(address).substr(2), 40);\n};\n\n/**\n * Returns true if object is BigNumber, otherwise false\n *\n * @method isBigNumber\n * @param {Object}\n * @return {Boolean} \n */\nvar isBigNumber = function (object) {\n return object instanceof BigNumber ||\n (object && object.constructor && object.constructor.name === 'BigNumber');\n};\n\n/**\n * Returns true if object is string, otherwise false\n * \n * @method isString\n * @param {Object}\n * @return {Boolean}\n */\nvar isString = function (object) {\n return typeof object === 'string' ||\n (object && object.constructor && object.constructor.name === 'String');\n};\n\n/**\n * Returns true if object is function, otherwise false\n *\n * @method isFunction\n * @param {Object}\n * @return {Boolean}\n */\nvar isFunction = function (object) {\n return typeof object === 'function';\n};\n\n/**\n * Returns true if object is Objet, otherwise false\n *\n * @method isObject\n * @param {Object}\n * @return {Boolean}\n */\nvar isObject = function (object) {\n return typeof object === 'object';\n};\n\n/**\n * Returns true if object is boolean, otherwise false\n *\n * @method isBoolean\n * @param {Object}\n * @return {Boolean}\n */\nvar isBoolean = function (object) {\n return typeof object === 'boolean';\n};\n\n/**\n * Returns true if object is array, otherwise false\n *\n * @method isArray\n * @param {Object}\n * @return {Boolean}\n */\nvar isArray = function (object) {\n return object instanceof Array; \n};\n\n/**\n * Returns true if given string is valid json object\n * \n * @method isJson\n * @param {String}\n * @return {Boolean}\n */\nvar isJson = function (str) {\n try {\n return !!JSON.parse(str);\n } catch (e) {\n return false;\n }\n};\n\nmodule.exports = {\n padLeft: padLeft,\n toHex: toHex,\n toDecimal: toDecimal,\n fromDecimal: fromDecimal,\n toAscii: toAscii,\n fromAscii: fromAscii,\n transformToFullName: transformToFullName,\n extractDisplayName: extractDisplayName,\n extractTypeName: extractTypeName,\n toWei: toWei,\n fromWei: fromWei,\n toBigNumber: toBigNumber,\n toTwosComplement: toTwosComplement,\n toAddress: toAddress,\n isBigNumber: isBigNumber,\n isStrictAddress: isStrictAddress,\n isAddress: isAddress,\n isFunction: isFunction,\n isString: isString,\n isObject: isObject,\n isBoolean: isBoolean,\n isArray: isArray,\n isJson: isJson\n};\n\n", - "module.exports={\n \"version\": \"0.3.3\"\n}\n", + "module.exports={\n \"version\": \"0.3.6\"\n}\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file web3.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * Fabian Vogelsteller \n * Gav Wood \n * @date 2014\n */\n\nvar version = require('./version.json');\nvar net = require('./web3/net');\nvar eth = require('./web3/eth');\nvar db = require('./web3/db');\nvar shh = require('./web3/shh');\nvar watches = require('./web3/watches');\nvar Filter = require('./web3/filter');\nvar utils = require('./utils/utils');\nvar formatters = require('./web3/formatters');\nvar RequestManager = require('./web3/requestmanager');\nvar c = require('./utils/config');\nvar Method = require('./web3/method');\nvar Property = require('./web3/property');\n\nvar web3Methods = [\n new Method({\n name: 'sha3',\n call: 'web3_sha3',\n params: 1\n })\n];\n\nvar web3Properties = [\n new Property({\n name: 'version.client',\n getter: 'web3_clientVersion'\n }),\n new Property({\n name: 'version.network',\n getter: 'net_version',\n inputFormatter: utils.toDecimal\n }),\n new Property({\n name: 'version.ethereum',\n getter: 'eth_protocolVersion',\n inputFormatter: utils.toDecimal\n }),\n new Property({\n name: 'version.whisper',\n getter: 'shh_version',\n inputFormatter: utils.toDecimal\n })\n];\n\n/// creates methods in a given object based on method description on input\n/// setups api calls for these methods\nvar setupMethods = function (obj, methods) {\n methods.forEach(function (method) {\n method.attachToObject(obj);\n });\n};\n\n/// creates properties in a given object based on properties description on input\n/// setups api calls for these properties\nvar setupProperties = function (obj, properties) {\n properties.forEach(function (property) {\n property.attachToObject(obj);\n });\n};\n\n/// setups web3 object, and it's in-browser executed methods\nvar web3 = {};\nweb3.providers = {};\nweb3.version = {};\nweb3.version.api = version.version;\nweb3.eth = {};\n\n/*jshint maxparams:4 */\nweb3.eth.filter = function (fil, eventParams, options, formatter) {\n\n // if its event, treat it differently\n // TODO: simplify and remove\n if (fil._isEvent) {\n return fil(eventParams, options);\n }\n\n // what outputLogFormatter? that's wrong\n //return new Filter(fil, watches.eth(), formatters.outputLogFormatter);\n return new Filter(fil, watches.eth(), formatter || formatters.outputLogFormatter);\n};\n/*jshint maxparams:3 */\n\nweb3.shh = {};\nweb3.shh.filter = function (fil) {\n return new Filter(fil, watches.shh(), formatters.outputPostFormatter);\n};\nweb3.net = {};\nweb3.db = {};\nweb3.setProvider = function (provider) {\n RequestManager.getInstance().setProvider(provider);\n};\nweb3.reset = function () {\n RequestManager.getInstance().reset();\n c.defaultBlock = 'latest';\n c.defaultAccount = undefined;\n};\nweb3.toHex = utils.toHex;\nweb3.toAscii = utils.toAscii;\nweb3.fromAscii = utils.fromAscii;\nweb3.toDecimal = utils.toDecimal;\nweb3.fromDecimal = utils.fromDecimal;\nweb3.toBigNumber = utils.toBigNumber;\nweb3.toWei = utils.toWei;\nweb3.fromWei = utils.fromWei;\nweb3.isAddress = utils.isAddress;\n\n// ADD defaultblock\nObject.defineProperty(web3.eth, 'defaultBlock', {\n get: function () {\n return c.defaultBlock;\n },\n set: function (val) {\n c.defaultBlock = val;\n return val;\n }\n});\n\nObject.defineProperty(web3.eth, 'defaultAccount', {\n get: function () {\n return c.defaultAccount;\n },\n set: function (val) {\n c.defaultAccount = val;\n return val;\n }\n});\n\n/// setups all api methods\nsetupMethods(web3, web3Methods);\nsetupProperties(web3, web3Properties);\nsetupMethods(web3.net, net.methods);\nsetupProperties(web3.net, net.properties);\nsetupMethods(web3.eth, eth.methods);\nsetupProperties(web3.eth, eth.properties);\nsetupMethods(web3.db, db.methods);\nsetupMethods(web3.shh, shh.methods);\n\nmodule.exports = web3;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file contract.js\n * @author Marek Kotewicz \n * @date 2014\n */\n\nvar web3 = require('../web3'); \nvar solAbi = require('../solidity/abi');\nvar utils = require('../utils/utils');\nvar SolidityEvent = require('./event');\nvar SolidityFunction = require('./function');\n\nvar addFunctionsToContract = function (contract, desc) {\n desc.filter(function (json) {\n return json.type === 'function';\n }).map(function (json) {\n return new SolidityFunction(json, contract.address);\n }).forEach(function (f) {\n f.attachToContract(contract);\n });\n};\n\nvar addEventsToContract = function (contract, desc) {\n desc.filter(function (json) {\n return json.type === 'event';\n }).map(function (json) {\n return new SolidityEvent(json, contract.address);\n }).forEach(function (e) {\n e.attachToContract(contract);\n });\n};\n\n/**\n * This method should be called when we want to call / transact some solidity method from javascript\n * it returns an object which has same methods available as solidity contract description\n * usage example: \n *\n * var abi = [{\n * name: 'myMethod',\n * inputs: [{ name: 'a', type: 'string' }],\n * outputs: [{name: 'd', type: 'string' }]\n * }]; // contract abi\n *\n * var MyContract = web3.eth.contract(abi); // creation of contract prototype\n *\n * var contractInstance = new MyContract('0x0123123121');\n *\n * contractInstance.myMethod('this is test string param for call'); // myMethod call (implicit, default)\n * contractInstance.call().myMethod('this is test string param for call'); // myMethod call (explicit)\n * contractInstance.sendTransaction().myMethod('this is test string param for transact'); // myMethod sendTransaction\n *\n * @param abi - abi json description of the contract, which is being created\n * @returns contract object\n */\nvar contract = function (abi) {\n\n // return prototype\n return Contract.bind(null, abi);\n};\n\nvar Contract = function (abi, options) {\n\n this.address = '';\n if (utils.isAddress(options)) {\n this.address = options;\n } else { // is an object!\n // TODO, parse the rest of the args\n options = options || {};\n var args = Array.prototype.slice.call(arguments, 2);\n var bytes = solAbi.formatConstructorParams(abi, args);\n options.data += bytes;\n this.address = web3.eth.sendTransaction(options);\n }\n\n addFunctionsToContract(this, abi);\n addEventsToContract(this, abi);\n};\n\nContract.prototype.call = function () {\n console.error('contract.call is deprecated');\n return this;\n};\n\nContract.prototype.sendTransaction = function () {\n console.error('contract.sendTransact is deprecated');\n return this;\n};\n\nmodule.exports = contract;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file db.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\nvar Method = require('./method');\n\nvar putString = new Method({\n name: 'putString',\n call: 'db_putString',\n params: 3\n});\n\n\nvar getString = new Method({\n name: 'getString',\n call: 'db_getString',\n params: 2\n});\n\nvar putHex = new Method({\n name: 'putHex',\n call: 'db_putHex',\n params: 3\n});\n\nvar getHex = new Method({\n name: 'getHex',\n call: 'db_getHex',\n params: 2\n});\n\nvar methods = [\n putString, getString, putHex, getHex\n];\n\nmodule.exports = {\n methods: methods\n};\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file errors.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nmodule.exports = {\n InvalidNumberOfParams: function () {\n return new Error('Invalid number of input parameters');\n },\n InvalidConnection: function (host){\n return new Error('CONNECTION ERROR: Couldn\\'t connect to node '+ host +', is it running?');\n },\n InvalidProvider: function () {\n return new Error('Providor not set or invalid');\n },\n InvalidResponse: function (result){\n var message = !!result && !!result.error && !!result.error.message ? result.error.message : 'Invalid JSON RPC response';\n return new Error(message);\n }\n};\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/**\n * @file eth.js\n * @author Marek Kotewicz \n * @author Fabian Vogelsteller \n * @date 2015\n */\n\n/**\n * Web3\n * \n * @module web3\n */\n\n/**\n * Eth methods and properties\n *\n * An example method object can look as follows:\n *\n * {\n * name: 'getBlock',\n * call: blockCall,\n * params: 2,\n * outputFormatter: formatters.outputBlockFormatter,\n * inputFormatter: [ // can be a formatter funciton or an array of functions. Where each item in the array will be used for one parameter\n * utils.toHex, // formats paramter 1\n * function(param){ return !!param; } // formats paramter 2\n * ]\n * },\n *\n * @class [web3] eth\n * @constructor\n */\n\n\"use strict\";\n\nvar formatters = require('./formatters');\nvar utils = require('../utils/utils');\nvar Method = require('./method');\nvar Property = require('./property');\n\nvar blockCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? \"eth_getBlockByHash\" : \"eth_getBlockByNumber\";\n};\n\nvar transactionFromBlockCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getTransactionByBlockHashAndIndex' : 'eth_getTransactionByBlockNumberAndIndex';\n};\n\nvar uncleCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleByBlockHashAndIndex' : 'eth_getUncleByBlockNumberAndIndex';\n};\n\nvar getBlockTransactionCountCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getBlockTransactionCountByHash' : 'eth_getBlockTransactionCountByNumber';\n};\n\nvar uncleCountCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleCountByBlockHash' : 'eth_getUncleCountByBlockNumber';\n};\n\n/// @returns an array of objects describing web3.eth api methods\n\nvar getBalance = new Method({\n name: 'getBalance', \n call: 'eth_getBalance', \n params: 2,\n inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter],\n outputFormatter: formatters.outputBigNumberFormatter\n});\n\nvar getStorageAt = new Method({\n name: 'getStorageAt', \n call: 'eth_getStorageAt', \n params: 3,\n inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar getCode = new Method({\n name: 'getCode',\n call: 'eth_getCode',\n params: 2,\n inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar getBlock = new Method({\n name: 'getBlock', \n call: blockCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }],\n outputFormatter: formatters.outputBlockFormatter\n});\n\nvar getUncle = new Method({\n name: 'getUncle',\n call: uncleCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex],\n outputFormatter: formatters.outputBlockFormatter,\n\n});\n\nvar getCompilers = new Method({\n name: 'getCompilers',\n call: 'eth_getCompilers',\n params: 0\n});\n\nvar getBlockTransactionCount = new Method({\n name: 'getBlockTransactionCount',\n call: getBlockTransactionCountCall,\n params: 1,\n inputFormatter: [formatters.inputBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar getBlockUncleCount = new Method({\n name: 'getBlockUncleCount',\n call: uncleCountCall,\n params: 1,\n inputFormatter: [formatters.inputBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar getTransaction = new Method({\n name: 'getTransaction',\n call: 'eth_getTransactionByHash',\n params: 1,\n outputFormatter: formatters.outputTransactionFormatter\n});\n\nvar getTransactionFromBlock = new Method({\n name: 'getTransactionFromBlock',\n call: transactionFromBlockCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex],\n outputFormatter: formatters.outputTransactionFormatter\n});\n\nvar getTransactionCount = new Method({\n name: 'getTransactionCount',\n call: 'eth_getTransactionCount',\n params: 2,\n inputFormatter: [null, formatters.inputDefaultBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar sendTransaction = new Method({\n name: 'sendTransaction',\n call: 'eth_sendTransaction',\n params: 1,\n inputFormatter: [formatters.inputTransactionFormatter]\n});\n\nvar call = new Method({\n name: 'call',\n call: 'eth_call',\n params: 2,\n inputFormatter: [formatters.inputTransactionFormatter, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar compileSolidity = new Method({\n name: 'compile.solidity',\n call: 'eth_compileSolidity',\n params: 1\n});\n\nvar compileLLL = new Method({\n name: 'compile.lll',\n call: 'eth_compileLLL',\n params: 1\n});\n\nvar compileSerpent = new Method({\n name: 'compile.serpent',\n call: 'eth_compileSerpent',\n params: 1\n});\n\nvar methods = [\n getBalance,\n getStorageAt,\n getCode,\n getBlock,\n getUncle,\n getCompilers,\n getBlockTransactionCount,\n getBlockUncleCount,\n getTransaction,\n getTransactionFromBlock,\n getTransactionCount,\n call,\n sendTransaction,\n compileSolidity,\n compileLLL,\n compileSerpent,\n];\n\n/// @returns an array of objects describing web3.eth api properties\n\n\n\nvar properties = [\n new Property({\n name: 'coinbase',\n getter: 'eth_coinbase'\n }),\n new Property({\n name: 'mining',\n getter: 'eth_mining'\n }),\n new Property({\n name: 'gasPrice',\n getter: 'eth_gasPrice',\n outputFormatter: formatters.outputBigNumberFormatter\n }),\n new Property({\n name: 'accounts',\n getter: 'eth_accounts'\n }),\n new Property({\n name: 'blockNumber',\n getter: 'eth_blockNumber',\n outputFormatter: utils.toDecimal\n })\n];\n\nmodule.exports = {\n methods: methods,\n properties: properties\n};\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file event.js\n * @author Marek Kotewicz \n * @date 2014\n */\n\nvar utils = require('../utils/utils');\nvar coder = require('../solidity/coder');\nvar web3 = require('../web3');\nvar formatters = require('./formatters');\n\n/**\n * This prototype should be used to create event filters\n */\nvar SolidityEvent = function (json, address) {\n this._params = json.inputs;\n this._name = utils.transformToFullName(json);\n this._address = address;\n this._anonymous = json.anonymous;\n};\n\n/**\n * Should be used to get filtered param types\n *\n * @method types\n * @param {Bool} decide if returned typed should be indexed\n * @return {Array} array of types\n */\nSolidityEvent.prototype.types = function (indexed) {\n return this._params.filter(function (i) {\n return i.indexed === indexed;\n }).map(function (i) {\n return i.type;\n });\n};\n\n/**\n * Should be used to get event display name\n *\n * @method displayName\n * @return {String} event display name\n */\nSolidityEvent.prototype.displayName = function () {\n return utils.extractDisplayName(this._name);\n};\n\n/**\n * Should be used to get event type name\n *\n * @method typeName\n * @return {String} event type name\n */\nSolidityEvent.prototype.typeName = function () {\n return utils.extractTypeName(this._name);\n};\n\n/**\n * Should be used to get event signature\n *\n * @method signature\n * @return {String} event signature\n */\nSolidityEvent.prototype.signature = function () {\n return web3.sha3(web3.fromAscii(this._name)).slice(2);\n};\n\n/**\n * Should be used to encode indexed params and options to one final object\n * \n * @method encode\n * @param {Object} indexed\n * @param {Object} options\n * @return {Object} everything combined together and encoded\n */\nSolidityEvent.prototype.encode = function (indexed, options) {\n indexed = indexed || {};\n options = options || {};\n var result = {};\n\n ['fromBlock', 'toBlock'].filter(function (f) {\n return options[f] !== undefined;\n }).forEach(function (f) {\n result[f] = utils.toHex(options[f]);\n });\n\n result.topics = [];\n\n if (!this._anonymous) {\n result.address = this._address;\n result.topics.push('0x' + this.signature());\n }\n\n var indexedTopics = this._params.filter(function (i) {\n return i.indexed === true;\n }).map(function (i) {\n var value = indexed[i.name];\n if (value === undefined || value === null) {\n return null;\n }\n \n if (utils.isArray(value)) {\n return value.map(function (v) {\n return '0x' + coder.encodeParam(i.type, v);\n });\n }\n return '0x' + coder.encodeParam(i.type, value);\n });\n\n result.topics = result.topics.concat(indexedTopics);\n\n return result;\n};\n\n/**\n * Should be used to decode indexed params and options\n *\n * @method decode\n * @param {Object} data\n * @return {Object} result object with decoded indexed && not indexed params\n */\nSolidityEvent.prototype.decode = function (data) {\n \n data.data = data.data || '';\n data.topics = data.topics || [];\n\n var argTopics = this._anonymous ? data.topics : data.topics.slice(1);\n var indexedData = argTopics.map(function (topics) { return topics.slice(2); }).join(\"\");\n var indexedParams = coder.decodeParams(this.types(true), indexedData); \n\n var notIndexedData = data.data.slice(2);\n var notIndexedParams = coder.decodeParams(this.types(false), notIndexedData);\n \n var result = formatters.outputLogFormatter(data);\n result.event = this.displayName();\n result.address = data.address;\n\n result.args = this._params.reduce(function (acc, current) {\n acc[current.name] = current.indexed ? indexedParams.shift() : notIndexedParams.shift();\n return acc;\n }, {});\n\n delete result.data;\n delete result.topics;\n\n return result;\n};\n\n/**\n * Should be used to create new filter object from event\n *\n * @method execute\n * @param {Object} indexed\n * @param {Object} options\n * @return {Object} filter object\n */\nSolidityEvent.prototype.execute = function (indexed, options) {\n var o = this.encode(indexed, options);\n var formatter = this.decode.bind(this);\n return web3.eth.filter(o, undefined, undefined, formatter);\n};\n\n/**\n * Should be used to attach event to contract object\n *\n * @method attachToContract\n * @param {Contract}\n */\nSolidityEvent.prototype.attachToContract = function (contract) {\n var execute = this.execute.bind(this);\n var displayName = this.displayName();\n if (!contract[displayName]) {\n contract[displayName] = execute;\n }\n contract[displayName][this.typeName()] = this.execute.bind(this, contract);\n};\n\nmodule.exports = SolidityEvent;\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/**\n * @file eth.js\n * @author Marek Kotewicz \n * @author Fabian Vogelsteller \n * @date 2015\n */\n\n/**\n * Web3\n *\n * @module web3\n */\n\n/**\n * Eth methods and properties\n *\n * An example method object can look as follows:\n *\n * {\n * name: 'getBlock',\n * call: blockCall,\n * params: 2,\n * outputFormatter: formatters.outputBlockFormatter,\n * inputFormatter: [ // can be a formatter funciton or an array of functions. Where each item in the array will be used for one parameter\n * utils.toHex, // formats paramter 1\n * function(param){ return !!param; } // formats paramter 2\n * ]\n * },\n *\n * @class [web3] eth\n * @constructor\n */\n\n\"use strict\";\n\nvar formatters = require('./formatters');\nvar utils = require('../utils/utils');\nvar Method = require('./method');\nvar Property = require('./property');\n\nvar blockCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? \"eth_getBlockByHash\" : \"eth_getBlockByNumber\";\n};\n\nvar transactionFromBlockCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getTransactionByBlockHashAndIndex' : 'eth_getTransactionByBlockNumberAndIndex';\n};\n\nvar uncleCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleByBlockHashAndIndex' : 'eth_getUncleByBlockNumberAndIndex';\n};\n\nvar getBlockTransactionCountCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getBlockTransactionCountByHash' : 'eth_getBlockTransactionCountByNumber';\n};\n\nvar uncleCountCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleCountByBlockHash' : 'eth_getUncleCountByBlockNumber';\n};\n\n/// @returns an array of objects describing web3.eth api methods\n\nvar getBalance = new Method({\n name: 'getBalance',\n call: 'eth_getBalance',\n params: 2,\n inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter],\n outputFormatter: formatters.outputBigNumberFormatter\n});\n\nvar getStorageAt = new Method({\n name: 'getStorageAt',\n call: 'eth_getStorageAt',\n params: 3,\n inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar getCode = new Method({\n name: 'getCode',\n call: 'eth_getCode',\n params: 2,\n inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar getBlock = new Method({\n name: 'getBlock',\n call: blockCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }],\n outputFormatter: formatters.outputBlockFormatter\n});\n\nvar getUncle = new Method({\n name: 'getUncle',\n call: uncleCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex],\n outputFormatter: formatters.outputBlockFormatter,\n\n});\n\nvar getCompilers = new Method({\n name: 'getCompilers',\n call: 'eth_getCompilers',\n params: 0\n});\n\nvar getBlockTransactionCount = new Method({\n name: 'getBlockTransactionCount',\n call: getBlockTransactionCountCall,\n params: 1,\n inputFormatter: [formatters.inputBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar getBlockUncleCount = new Method({\n name: 'getBlockUncleCount',\n call: uncleCountCall,\n params: 1,\n inputFormatter: [formatters.inputBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar getTransaction = new Method({\n name: 'getTransaction',\n call: 'eth_getTransactionByHash',\n params: 1,\n outputFormatter: formatters.outputTransactionFormatter\n});\n\nvar getTransactionFromBlock = new Method({\n name: 'getTransactionFromBlock',\n call: transactionFromBlockCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex],\n outputFormatter: formatters.outputTransactionFormatter\n});\n\nvar getTransactionCount = new Method({\n name: 'getTransactionCount',\n call: 'eth_getTransactionCount',\n params: 2,\n inputFormatter: [null, formatters.inputDefaultBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar sendTransaction = new Method({\n name: 'sendTransaction',\n call: 'eth_sendTransaction',\n params: 1,\n inputFormatter: [formatters.inputTransactionFormatter]\n});\n\nvar call = new Method({\n name: 'call',\n call: 'eth_call',\n params: 2,\n inputFormatter: [formatters.inputTransactionFormatter, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar compileSolidity = new Method({\n name: 'compile.solidity',\n call: 'eth_compileSolidity',\n params: 1\n});\n\nvar compileLLL = new Method({\n name: 'compile.lll',\n call: 'eth_compileLLL',\n params: 1\n});\n\nvar compileSerpent = new Method({\n name: 'compile.serpent',\n call: 'eth_compileSerpent',\n params: 1\n});\n\nvar methods = [\n getBalance,\n getStorageAt,\n getCode,\n getBlock,\n getUncle,\n getCompilers,\n getBlockTransactionCount,\n getBlockUncleCount,\n getTransaction,\n getTransactionFromBlock,\n getTransactionCount,\n call,\n sendTransaction,\n compileSolidity,\n compileLLL,\n compileSerpent,\n];\n\n/// @returns an array of objects describing web3.eth api properties\n\n\n\nvar properties = [\n new Property({\n name: 'coinbase',\n getter: 'eth_coinbase'\n }),\n new Property({\n name: 'mining',\n getter: 'eth_mining'\n }),\n new Property({\n name: 'hashrate',\n getter: 'eth_hashrate',\n outputFormatter: utils.toDecimal\n }),\n new Property({\n name: 'gasPrice',\n getter: 'eth_gasPrice',\n outputFormatter: formatters.outputBigNumberFormatter\n }),\n new Property({\n name: 'accounts',\n getter: 'eth_accounts'\n }),\n new Property({\n name: 'blockNumber',\n getter: 'eth_blockNumber',\n outputFormatter: utils.toDecimal\n })\n];\n\nmodule.exports = {\n methods: methods,\n properties: properties\n};\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file event.js\n * @author Marek Kotewicz \n * @date 2014\n */\n\nvar utils = require('../utils/utils');\nvar coder = require('../solidity/coder');\nvar web3 = require('../web3');\nvar formatters = require('./formatters');\n\n/**\n * This prototype should be used to create event filters\n */\nvar SolidityEvent = function (json, address) {\n this._params = json.inputs;\n this._name = utils.transformToFullName(json);\n this._address = address;\n this._anonymous = json.anonymous;\n};\n\n/**\n * Should be used to get filtered param types\n *\n * @method types\n * @param {Bool} decide if returned typed should be indexed\n * @return {Array} array of types\n */\nSolidityEvent.prototype.types = function (indexed) {\n return this._params.filter(function (i) {\n return i.indexed === indexed;\n }).map(function (i) {\n return i.type;\n });\n};\n\n/**\n * Should be used to get event display name\n *\n * @method displayName\n * @return {String} event display name\n */\nSolidityEvent.prototype.displayName = function () {\n return utils.extractDisplayName(this._name);\n};\n\n/**\n * Should be used to get event type name\n *\n * @method typeName\n * @return {String} event type name\n */\nSolidityEvent.prototype.typeName = function () {\n return utils.extractTypeName(this._name);\n};\n\n/**\n * Should be used to get event signature\n *\n * @method signature\n * @return {String} event signature\n */\nSolidityEvent.prototype.signature = function () {\n return web3.sha3(web3.fromAscii(this._name)).slice(2);\n};\n\n/**\n * Should be used to encode indexed params and options to one final object\n * \n * @method encode\n * @param {Object} indexed\n * @param {Object} options\n * @return {Object} everything combined together and encoded\n */\nSolidityEvent.prototype.encode = function (indexed, options) {\n indexed = indexed || {};\n options = options || {};\n var result = {};\n\n ['fromBlock', 'toBlock'].filter(function (f) {\n return options[f] !== undefined;\n }).forEach(function (f) {\n result[f] = formatters.inputBlockNumberFormatter(options[f]);\n });\n\n result.topics = [];\n\n if (!this._anonymous) {\n result.address = this._address;\n result.topics.push('0x' + this.signature());\n }\n\n var indexedTopics = this._params.filter(function (i) {\n return i.indexed === true;\n }).map(function (i) {\n var value = indexed[i.name];\n if (value === undefined || value === null) {\n return null;\n }\n \n if (utils.isArray(value)) {\n return value.map(function (v) {\n return '0x' + coder.encodeParam(i.type, v);\n });\n }\n return '0x' + coder.encodeParam(i.type, value);\n });\n\n result.topics = result.topics.concat(indexedTopics);\n\n return result;\n};\n\n/**\n * Should be used to decode indexed params and options\n *\n * @method decode\n * @param {Object} data\n * @return {Object} result object with decoded indexed && not indexed params\n */\nSolidityEvent.prototype.decode = function (data) {\n \n data.data = data.data || '';\n data.topics = data.topics || [];\n\n var argTopics = this._anonymous ? data.topics : data.topics.slice(1);\n var indexedData = argTopics.map(function (topics) { return topics.slice(2); }).join(\"\");\n var indexedParams = coder.decodeParams(this.types(true), indexedData); \n\n var notIndexedData = data.data.slice(2);\n var notIndexedParams = coder.decodeParams(this.types(false), notIndexedData);\n \n var result = formatters.outputLogFormatter(data);\n result.event = this.displayName();\n result.address = data.address;\n\n result.args = this._params.reduce(function (acc, current) {\n acc[current.name] = current.indexed ? indexedParams.shift() : notIndexedParams.shift();\n return acc;\n }, {});\n\n delete result.data;\n delete result.topics;\n\n return result;\n};\n\n/**\n * Should be used to create new filter object from event\n *\n * @method execute\n * @param {Object} indexed\n * @param {Object} options\n * @return {Object} filter object\n */\nSolidityEvent.prototype.execute = function (indexed, options) {\n var o = this.encode(indexed, options);\n var formatter = this.decode.bind(this);\n return web3.eth.filter(o, undefined, undefined, formatter);\n};\n\n/**\n * Should be used to attach event to contract object\n *\n * @method attachToContract\n * @param {Contract}\n */\nSolidityEvent.prototype.attachToContract = function (contract) {\n var execute = this.execute.bind(this);\n var displayName = this.displayName();\n if (!contract[displayName]) {\n contract[displayName] = execute;\n }\n contract[displayName][this.typeName()] = this.execute.bind(this, contract);\n};\n\nmodule.exports = SolidityEvent;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file filter.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * Fabian Vogelsteller \n * Gav Wood \n * @date 2014\n */\n\nvar RequestManager = require('./requestmanager');\nvar formatters = require('./formatters');\nvar utils = require('../utils/utils');\n\n/**\n* Converts a given topic to a hex string, but also allows null values.\n*\n* @param {Mixed} value\n* @return {String}\n*/\nvar toTopic = function(value){\n\n if(value === null || typeof value === 'undefined')\n return null;\n\n value = String(value);\n\n if(value.indexOf('0x') === 0)\n return value;\n else\n return utils.fromAscii(value);\n};\n\n/// This method should be called on options object, to verify deprecated properties && lazy load dynamic ones\n/// @param should be string or object\n/// @returns options string or object\nvar getOptions = function (options) {\n\n if (utils.isString(options)) {\n return options;\n } \n\n options = options || {};\n\n // make sure topics, get converted to hex\n options.topics = options.topics || [];\n options.topics = options.topics.map(function(topic){\n return (utils.isArray(topic)) ? topic.map(toTopic) : toTopic(topic);\n });\n\n // lazy load\n return {\n topics: options.topics,\n to: options.to,\n address: options.address,\n fromBlock: formatters.inputBlockNumberFormatter(options.fromBlock),\n toBlock: formatters.inputBlockNumberFormatter(options.toBlock) \n }; \n};\n\nvar Filter = function (options, methods, formatter) {\n var implementation = {};\n methods.forEach(function (method) {\n method.attachToObject(implementation);\n });\n this.options = getOptions(options);\n this.implementation = implementation;\n this.callbacks = [];\n this.formatter = formatter;\n this.filterId = this.implementation.newFilter(this.options);\n};\n\nFilter.prototype.watch = function (callback) {\n this.callbacks.push(callback);\n var self = this;\n\n var onMessage = function (error, messages) {\n if (error) {\n return self.callbacks.forEach(function (callback) {\n callback(error);\n });\n }\n\n messages.forEach(function (message) {\n message = self.formatter ? self.formatter(message) : message;\n self.callbacks.forEach(function (callback) {\n callback(null, message);\n });\n });\n };\n\n // call getFilterLogs on start\n if (!utils.isString(this.options)) {\n this.get(function (err, messages) {\n // don't send all the responses to all the watches again... just to this one\n if (err) {\n callback(err);\n }\n\n messages.forEach(function (message) {\n callback(null, message);\n });\n });\n }\n\n RequestManager.getInstance().startPolling({\n method: this.implementation.poll.call,\n params: [this.filterId],\n }, this.filterId, onMessage, this.stopWatching.bind(this));\n};\n\nFilter.prototype.stopWatching = function () {\n RequestManager.getInstance().stopPolling(this.filterId);\n this.implementation.uninstallFilter(this.filterId);\n this.callbacks = [];\n};\n\nFilter.prototype.get = function (callback) {\n var self = this;\n if (utils.isFunction(callback)) {\n this.implementation.getLogs(this.filterId, function(err, res){\n if (err) {\n callback(err);\n } else {\n callback(null, res.map(function (log) {\n return self.formatter ? self.formatter(log) : log;\n }));\n }\n });\n } else {\n var logs = this.implementation.getLogs(this.filterId);\n return logs.map(function (log) {\n return self.formatter ? self.formatter(log) : log;\n });\n }\n};\n\nmodule.exports = Filter;\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file formatters.js\n * @author Marek Kotewicz \n * @author Fabian Vogelsteller \n * @date 2015\n */\n\nvar utils = require('../utils/utils');\nvar config = require('../utils/config');\n\n/**\n * Should the format output to a big number\n *\n * @method outputBigNumberFormatter\n * @param {String|Number|BigNumber}\n * @returns {BigNumber} object\n */\nvar outputBigNumberFormatter = function (number) {\n return utils.toBigNumber(number);\n};\n\nvar isPredefinedBlockNumber = function (blockNumber) {\n return blockNumber === 'latest' || blockNumber === 'pending' || blockNumber === 'earliest';\n};\n\nvar inputDefaultBlockNumberFormatter = function (blockNumber) {\n if (blockNumber === undefined) {\n return config.defaultBlock;\n }\n return inputBlockNumberFormatter(blockNumber);\n};\n\nvar inputBlockNumberFormatter = function (blockNumber) {\n if (blockNumber === undefined) {\n return undefined;\n } else if (isPredefinedBlockNumber(blockNumber)) {\n return blockNumber;\n }\n return utils.toHex(blockNumber);\n};\n\n/**\n * Formats the input of a transaction and converts all values to HEX\n *\n * @method inputTransactionFormatter\n * @param {Object} transaction options\n * @returns object\n*/\nvar inputTransactionFormatter = function (options){\n\n options.from = options.from || config.defaultAccount;\n\n // make code -> data\n if (options.code) {\n options.data = options.code;\n delete options.code;\n }\n\n ['gasPrice', 'gas', 'value'].filter(function (key) {\n return options[key] !== undefined;\n }).forEach(function(key){\n options[key] = utils.fromDecimal(options[key]);\n });\n\n return options; \n};\n\n/**\n * Formats the output of a transaction to its proper values\n * \n * @method outputTransactionFormatter\n * @param {Object} transaction\n * @returns {Object} transaction\n*/\nvar outputTransactionFormatter = function (tx){\n tx.blockNumber = utils.toDecimal(tx.blockNumber);\n tx.transactionIndex = utils.toDecimal(tx.transactionIndex);\n tx.nonce = utils.toDecimal(tx.nonce);\n tx.gas = utils.toDecimal(tx.gas);\n tx.gasPrice = utils.toBigNumber(tx.gasPrice);\n tx.value = utils.toBigNumber(tx.value);\n return tx;\n};\n\n/**\n * Formats the output of a block to its proper values\n *\n * @method outputBlockFormatter\n * @param {Object} block object \n * @returns {Object} block object\n*/\nvar outputBlockFormatter = function(block) {\n\n // transform to number\n block.gasLimit = utils.toDecimal(block.gasLimit);\n block.gasUsed = utils.toDecimal(block.gasUsed);\n block.size = utils.toDecimal(block.size);\n block.timestamp = utils.toDecimal(block.timestamp);\n block.number = utils.toDecimal(block.number);\n\n block.difficulty = utils.toBigNumber(block.difficulty);\n block.totalDifficulty = utils.toBigNumber(block.totalDifficulty);\n\n if (utils.isArray(block.transactions)) {\n block.transactions.forEach(function(item){\n if(!utils.isString(item))\n return outputTransactionFormatter(item);\n });\n }\n\n return block;\n};\n\n/**\n * Formats the output of a log\n * \n * @method outputLogFormatter\n * @param {Object} log object\n * @returns {Object} log\n*/\nvar outputLogFormatter = function(log) {\n if (log === null) { // 'pending' && 'latest' filters are nulls\n return null;\n }\n\n log.blockNumber = utils.toDecimal(log.blockNumber);\n log.transactionIndex = utils.toDecimal(log.transactionIndex);\n log.logIndex = utils.toDecimal(log.logIndex);\n\n return log;\n};\n\n/**\n * Formats the input of a whisper post and converts all values to HEX\n *\n * @method inputPostFormatter\n * @param {Object} transaction object\n * @returns {Object}\n*/\nvar inputPostFormatter = function(post) {\n\n post.payload = utils.toHex(post.payload);\n post.ttl = utils.fromDecimal(post.ttl);\n post.workToProve = utils.fromDecimal(post.workToProve);\n post.priority = utils.fromDecimal(post.priority);\n\n // fallback\n if (!utils.isArray(post.topics)) {\n post.topics = post.topics ? [post.topics] : [];\n }\n\n // format the following options\n post.topics = post.topics.map(function(topic){\n return utils.fromAscii(topic);\n });\n\n return post; \n};\n\n/**\n * Formats the output of a received post message\n *\n * @method outputPostFormatter\n * @param {Object}\n * @returns {Object}\n */\nvar outputPostFormatter = function(post){\n\n post.expiry = utils.toDecimal(post.expiry);\n post.sent = utils.toDecimal(post.sent);\n post.ttl = utils.toDecimal(post.ttl);\n post.workProved = utils.toDecimal(post.workProved);\n post.payloadRaw = post.payload;\n post.payload = utils.toAscii(post.payload);\n\n if (utils.isJson(post.payload)) {\n post.payload = JSON.parse(post.payload);\n }\n\n // format the following options\n if (!post.topics) {\n post.topics = [];\n }\n post.topics = post.topics.map(function(topic){\n return utils.toAscii(topic);\n });\n\n return post;\n};\n\nmodule.exports = {\n inputDefaultBlockNumberFormatter: inputDefaultBlockNumberFormatter,\n inputBlockNumberFormatter: inputBlockNumberFormatter,\n inputTransactionFormatter: inputTransactionFormatter,\n inputPostFormatter: inputPostFormatter,\n outputBigNumberFormatter: outputBigNumberFormatter,\n outputTransactionFormatter: outputTransactionFormatter,\n outputBlockFormatter: outputBlockFormatter,\n outputLogFormatter: outputLogFormatter,\n outputPostFormatter: outputPostFormatter\n};\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file formatters.js\n * @author Marek Kotewicz \n * @author Fabian Vogelsteller \n * @date 2015\n */\n\nvar utils = require('../utils/utils');\nvar config = require('../utils/config');\n\n/**\n * Should the format output to a big number\n *\n * @method outputBigNumberFormatter\n * @param {String|Number|BigNumber}\n * @returns {BigNumber} object\n */\nvar outputBigNumberFormatter = function (number) {\n return utils.toBigNumber(number);\n};\n\nvar isPredefinedBlockNumber = function (blockNumber) {\n return blockNumber === 'latest' || blockNumber === 'pending' || blockNumber === 'earliest';\n};\n\nvar inputDefaultBlockNumberFormatter = function (blockNumber) {\n if (blockNumber === undefined) {\n return config.defaultBlock;\n }\n return inputBlockNumberFormatter(blockNumber);\n};\n\nvar inputBlockNumberFormatter = function (blockNumber) {\n if (blockNumber === undefined) {\n return undefined;\n } else if (isPredefinedBlockNumber(blockNumber)) {\n return blockNumber;\n }\n return utils.toHex(blockNumber);\n};\n\n/**\n * Formats the input of a transaction and converts all values to HEX\n *\n * @method inputTransactionFormatter\n * @param {Object} transaction options\n * @returns object\n*/\nvar inputTransactionFormatter = function (options){\n\n options.from = options.from || config.defaultAccount;\n\n // make code -> data\n if (options.code) {\n options.data = options.code;\n delete options.code;\n }\n\n ['gasPrice', 'gas', 'value', 'nonce'].filter(function (key) {\n return options[key] !== undefined;\n }).forEach(function(key){\n options[key] = utils.fromDecimal(options[key]);\n });\n\n return options; \n};\n\n/**\n * Formats the output of a transaction to its proper values\n * \n * @method outputTransactionFormatter\n * @param {Object} transaction\n * @returns {Object} transaction\n*/\nvar outputTransactionFormatter = function (tx){\n tx.blockNumber = utils.toDecimal(tx.blockNumber);\n tx.transactionIndex = utils.toDecimal(tx.transactionIndex);\n tx.nonce = utils.toDecimal(tx.nonce);\n tx.gas = utils.toDecimal(tx.gas);\n tx.gasPrice = utils.toBigNumber(tx.gasPrice);\n tx.value = utils.toBigNumber(tx.value);\n return tx;\n};\n\n/**\n * Formats the output of a block to its proper values\n *\n * @method outputBlockFormatter\n * @param {Object} block object \n * @returns {Object} block object\n*/\nvar outputBlockFormatter = function(block) {\n\n // transform to number\n block.gasLimit = utils.toDecimal(block.gasLimit);\n block.gasUsed = utils.toDecimal(block.gasUsed);\n block.size = utils.toDecimal(block.size);\n block.timestamp = utils.toDecimal(block.timestamp);\n block.number = utils.toDecimal(block.number);\n\n block.difficulty = utils.toBigNumber(block.difficulty);\n block.totalDifficulty = utils.toBigNumber(block.totalDifficulty);\n\n if (utils.isArray(block.transactions)) {\n block.transactions.forEach(function(item){\n if(!utils.isString(item))\n return outputTransactionFormatter(item);\n });\n }\n\n return block;\n};\n\n/**\n * Formats the output of a log\n * \n * @method outputLogFormatter\n * @param {Object} log object\n * @returns {Object} log\n*/\nvar outputLogFormatter = function(log) {\n if (log === null) { // 'pending' && 'latest' filters are nulls\n return null;\n }\n\n log.blockNumber = utils.toDecimal(log.blockNumber);\n log.transactionIndex = utils.toDecimal(log.transactionIndex);\n log.logIndex = utils.toDecimal(log.logIndex);\n\n return log;\n};\n\n/**\n * Formats the input of a whisper post and converts all values to HEX\n *\n * @method inputPostFormatter\n * @param {Object} transaction object\n * @returns {Object}\n*/\nvar inputPostFormatter = function(post) {\n\n post.payload = utils.toHex(post.payload);\n post.ttl = utils.fromDecimal(post.ttl);\n post.workToProve = utils.fromDecimal(post.workToProve);\n post.priority = utils.fromDecimal(post.priority);\n\n // fallback\n if (!utils.isArray(post.topics)) {\n post.topics = post.topics ? [post.topics] : [];\n }\n\n // format the following options\n post.topics = post.topics.map(function(topic){\n return utils.fromAscii(topic);\n });\n\n return post; \n};\n\n/**\n * Formats the output of a received post message\n *\n * @method outputPostFormatter\n * @param {Object}\n * @returns {Object}\n */\nvar outputPostFormatter = function(post){\n\n post.expiry = utils.toDecimal(post.expiry);\n post.sent = utils.toDecimal(post.sent);\n post.ttl = utils.toDecimal(post.ttl);\n post.workProved = utils.toDecimal(post.workProved);\n post.payloadRaw = post.payload;\n post.payload = utils.toAscii(post.payload);\n\n if (utils.isJson(post.payload)) {\n post.payload = JSON.parse(post.payload);\n }\n\n // format the following options\n if (!post.topics) {\n post.topics = [];\n }\n post.topics = post.topics.map(function(topic){\n return utils.toAscii(topic);\n });\n\n return post;\n};\n\nmodule.exports = {\n inputDefaultBlockNumberFormatter: inputDefaultBlockNumberFormatter,\n inputBlockNumberFormatter: inputBlockNumberFormatter,\n inputTransactionFormatter: inputTransactionFormatter,\n inputPostFormatter: inputPostFormatter,\n outputBigNumberFormatter: outputBigNumberFormatter,\n outputTransactionFormatter: outputTransactionFormatter,\n outputBlockFormatter: outputBlockFormatter,\n outputLogFormatter: outputLogFormatter,\n outputPostFormatter: outputPostFormatter\n};\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file function.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar web3 = require('../web3');\nvar coder = require('../solidity/coder');\nvar utils = require('../utils/utils');\n\n/**\n * This prototype should be used to call/sendTransaction to solidity functions\n */\nvar SolidityFunction = function (json, address) {\n this._inputTypes = json.inputs.map(function (i) {\n return i.type;\n });\n this._outputTypes = json.outputs.map(function (i) {\n return i.type;\n });\n this._constant = json.constant;\n this._name = utils.transformToFullName(json);\n this._address = address;\n};\n\n/**\n * Should be used to create payload from arguments\n *\n * @method toPayload\n * @param {...} solidity function params\n * @param {Object} optional payload options\n */\nSolidityFunction.prototype.toPayload = function () {\n var args = Array.prototype.slice.call(arguments);\n var options = {};\n if (args.length > this._inputTypes.length && utils.isObject(args[args.length -1])) {\n options = args.pop();\n }\n options.to = this._address;\n options.data = '0x' + this.signature() + coder.encodeParams(this._inputTypes, args);\n return options;\n};\n\n/**\n * Should be used to get function signature\n *\n * @method signature\n * @return {String} function signature\n */\nSolidityFunction.prototype.signature = function () {\n return web3.sha3(web3.fromAscii(this._name)).slice(2, 10);\n};\n\n/**\n * Should be used to call function\n * \n * @method call\n * @param {Object} options\n * @return {String} output bytes\n */\nSolidityFunction.prototype.call = function () {\n var payload = this.toPayload.apply(this, Array.prototype.slice.call(arguments));\n var output = web3.eth.call(payload);\n output = output.length >= 2 ? output.slice(2) : output;\n var result = coder.decodeParams(this._outputTypes, output);\n return result.length === 1 ? result[0] : result;\n};\n\n/**\n * Should be used to sendTransaction to solidity function\n *\n * @method sendTransaction\n * @param {Object} options\n */\nSolidityFunction.prototype.sendTransaction = function () {\n var payload = this.toPayload.apply(this, Array.prototype.slice.call(arguments));\n web3.eth.sendTransaction(payload);\n};\n\n/**\n * Should be used to get function display name\n *\n * @method displayName\n * @return {String} display name of the function\n */\nSolidityFunction.prototype.displayName = function () {\n return utils.extractDisplayName(this._name);\n};\n\n/**\n * Should be used to get function type name\n * \n * @method typeName\n * @return {String} type name of the function\n */\nSolidityFunction.prototype.typeName = function () {\n return utils.extractTypeName(this._name);\n};\n\n/**\n * Should be called to execute function\n *\n * @method execute\n */\nSolidityFunction.prototype.execute = function () {\n var transaction = !this._constant;\n \n // send transaction\n if (transaction) {\n return this.sendTransaction.apply(this, Array.prototype.slice.call(arguments));\n }\n\n // call\n return this.call.apply(this, Array.prototype.slice.call(arguments));\n};\n\n/**\n * Should be called to attach function to contract\n *\n * @method attachToContract\n * @param {Contract}\n */\nSolidityFunction.prototype.attachToContract = function (contract) {\n var execute = this.execute.bind(this);\n execute.call = this.call.bind(this);\n execute.sendTransaction = this.sendTransaction.bind(this);\n var displayName = this.displayName();\n if (!contract[displayName]) {\n contract[displayName] = execute;\n }\n contract[displayName][this.typeName()] = execute; // circular!!!!\n};\n\nmodule.exports = SolidityFunction;\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file httpprovider.js\n * @authors:\n * Marek Kotewicz \n * Marian Oancea \n * Fabian Vogelsteller \n * @date 2014\n */\n\n\"use strict\";\n\nvar XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line\nvar errors = require('./errors');\n\nvar HttpProvider = function (host) {\n this.host = host || 'http://localhost:8545';\n};\n\nHttpProvider.prototype.send = function (payload) {\n var request = new XMLHttpRequest();\n\n request.open('POST', this.host, false);\n \n try {\n request.send(JSON.stringify(payload));\n } catch(error) {\n throw errors.InvalidConnection(this.host);\n }\n\n\n // check request.status\n // TODO: throw an error here! it cannot silently fail!!!\n //if (request.status !== 200) {\n //return;\n //}\n return JSON.parse(request.responseText);\n};\n\nHttpProvider.prototype.sendAsync = function (payload, callback) {\n var request = new XMLHttpRequest();\n request.onreadystatechange = function() {\n if (request.readyState === 4) {\n // TODO: handle the error properly here!!!\n callback(null, JSON.parse(request.responseText));\n }\n };\n\n request.open('POST', this.host, true);\n\n try {\n request.send(JSON.stringify(payload));\n } catch(error) {\n callback(errors.InvalidConnection(this.host));\n }\n};\n\nmodule.exports = HttpProvider;\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file httpprovider.js\n * @authors:\n * Marek Kotewicz \n * Marian Oancea \n * Fabian Vogelsteller \n * @date 2014\n */\n\n\"use strict\";\n\nvar XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line\nvar errors = require('./errors');\n\nvar HttpProvider = function (host) {\n this.host = host || 'http://localhost:8545';\n};\n\nHttpProvider.prototype.send = function (payload) {\n var request = new XMLHttpRequest();\n\n request.open('POST', this.host, false);\n \n try {\n request.send(JSON.stringify(payload));\n } catch(error) {\n throw errors.InvalidConnection(this.host);\n }\n\n\n // check request.status\n // TODO: throw an error here! it cannot silently fail!!!\n //if (request.status !== 200) {\n //return;\n //}\n\n var result = request.responseText;\n\n try {\n result = JSON.parse(result);\n } catch(e) {\n throw errors.InvalidResponse(result); \n }\n\n return result;\n};\n\nHttpProvider.prototype.sendAsync = function (payload, callback) {\n var request = new XMLHttpRequest();\n request.onreadystatechange = function() {\n if (request.readyState === 4) {\n var result = request.responseText;\n var error = null;\n\n try {\n result = JSON.parse(result);\n } catch(e) {\n error = errors.InvalidResponse(result); \n }\n\n callback(error, result);\n }\n };\n\n request.open('POST', this.host, true);\n\n try {\n request.send(JSON.stringify(payload));\n } catch(error) {\n callback(errors.InvalidConnection(this.host));\n }\n};\n\nmodule.exports = HttpProvider;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file jsonrpc.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\nvar Jsonrpc = function () {\n // singleton pattern\n if (arguments.callee._singletonInstance) {\n return arguments.callee._singletonInstance;\n }\n arguments.callee._singletonInstance = this;\n\n this.messageId = 1;\n};\n\n/**\n * @return {Jsonrpc} singleton\n */\nJsonrpc.getInstance = function () {\n var instance = new Jsonrpc();\n return instance;\n};\n\n/**\n * Should be called to valid json create payload object\n *\n * @method toPayload\n * @param {Function} method of jsonrpc call, required\n * @param {Array} params, an array of method params, optional\n * @returns {Object} valid jsonrpc payload object\n */\nJsonrpc.prototype.toPayload = function (method, params) {\n if (!method)\n console.error('jsonrpc method should be specified!');\n\n return {\n jsonrpc: '2.0',\n method: method,\n params: params || [],\n id: this.messageId++\n };\n};\n\n/**\n * Should be called to check if jsonrpc response is valid\n *\n * @method isValidResponse\n * @param {Object}\n * @returns {Boolean} true if response is valid, otherwise false\n */\nJsonrpc.prototype.isValidResponse = function (response) {\n return !!response &&\n !response.error &&\n response.jsonrpc === '2.0' &&\n typeof response.id === 'number' &&\n response.result !== undefined; // only undefined is not valid json object\n};\n\n/**\n * Should be called to create batch payload object\n *\n * @method toBatchPayload\n * @param {Array} messages, an array of objects with method (required) and params (optional) fields\n * @returns {Array} batch payload\n */\nJsonrpc.prototype.toBatchPayload = function (messages) {\n var self = this;\n return messages.map(function (message) {\n return self.toPayload(message.method, message.params);\n });\n};\n\nmodule.exports = Jsonrpc;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/**\n * @file method.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar RequestManager = require('./requestmanager');\nvar utils = require('../utils/utils');\nvar errors = require('./errors');\n\nvar Method = function (options) {\n this.name = options.name;\n this.call = options.call;\n this.params = options.params || 0;\n this.inputFormatter = options.inputFormatter;\n this.outputFormatter = options.outputFormatter;\n};\n\n/**\n * Should be used to determine name of the jsonrpc method based on arguments\n *\n * @method getCall\n * @param {Array} arguments\n * @return {String} name of jsonrpc method\n */\nMethod.prototype.getCall = function (args) {\n return utils.isFunction(this.call) ? this.call(args) : this.call;\n};\n\n/**\n * Should be used to extract callback from array of arguments. Modifies input param\n *\n * @method extractCallback\n * @param {Array} arguments\n * @return {Function|Null} callback, if exists\n */\nMethod.prototype.extractCallback = function (args) {\n if (utils.isFunction(args[args.length - 1])) {\n return args.pop(); // modify the args array!\n }\n return null;\n};\n\n/**\n * Should be called to check if the number of arguments is correct\n * \n * @method validateArgs\n * @param {Array} arguments\n * @throws {Error} if it is not\n */\nMethod.prototype.validateArgs = function (args) {\n if (args.length !== this.params) {\n throw errors.InvalidNumberOfParams();\n }\n};\n\n/**\n * Should be called to format input args of method\n * \n * @method formatInput\n * @param {Array}\n * @return {Array}\n */\nMethod.prototype.formatInput = function (args) {\n if (!this.inputFormatter) {\n return args;\n }\n\n return this.inputFormatter.map(function (formatter, index) {\n return formatter ? formatter(args[index]) : args[index];\n });\n};\n\n/**\n * Should be called to format output(result) of method\n *\n * @method formatOutput\n * @param {Object}\n * @return {Object}\n */\nMethod.prototype.formatOutput = function (result) {\n return this.outputFormatter && result !== null ? this.outputFormatter(result) : result;\n};\n\n/**\n * Should attach function to method\n * \n * @method attachToObject\n * @param {Object}\n * @param {Function}\n */\nMethod.prototype.attachToObject = function (obj) {\n var func = this.send.bind(this);\n func.call = this.call; // that's ugly. filter.js uses it\n var name = this.name.split('.');\n if (name.length > 1) {\n obj[name[0]] = obj[name[0]] || {};\n obj[name[0]][name[1]] = func;\n } else {\n obj[name[0]] = func; \n }\n};\n\n/**\n * Should create payload from given input args\n *\n * @method toPayload\n * @param {Array} args\n * @return {Object}\n */\nMethod.prototype.toPayload = function (args) {\n var call = this.getCall(args);\n var callback = this.extractCallback(args);\n var params = this.formatInput(args);\n this.validateArgs(params);\n\n return {\n method: call,\n params: params,\n callback: callback\n };\n};\n\n/**\n * Should send request to the API\n *\n * @method send\n * @param list of params\n * @return result\n */\nMethod.prototype.send = function () {\n var payload = this.toPayload(Array.prototype.slice.call(arguments));\n if (payload.callback) {\n var self = this;\n return RequestManager.getInstance().sendAsync(payload, function (err, result) {\n payload.callback(null, self.formatOutput(result));\n });\n }\n return this.formatOutput(RequestManager.getInstance().send(payload));\n};\n\nmodule.exports = Method;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file eth.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\nvar utils = require('../utils/utils');\nvar Property = require('./property');\n\n/// @returns an array of objects describing web3.eth api methods\nvar methods = [\n];\n\n/// @returns an array of objects describing web3.eth api properties\nvar properties = [\n new Property({\n name: 'listening',\n getter: 'net_listening'\n }),\n new Property({\n name: 'peerCount',\n getter: 'net_peerCount',\n outputFormatter: utils.toDecimal\n })\n];\n\n\nmodule.exports = {\n methods: methods,\n properties: properties\n};\n\n", diff --git a/dist/web3-light.min.js b/dist/web3-light.min.js index e45033791..4c0fd2930 100644 --- a/dist/web3-light.min.js +++ b/dist/web3-light.min.js @@ -1,2 +1,2 @@ -require=function t(e,r,n){function o(a,s){if(!r[a]){if(!e[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(i)return i(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var l=r[a]={exports:{}};e[a][0].call(l.exports,function(t){var r=e[a][1][t];return o(r?r:t)},l,l.exports,t,e,r,n)}return r[a].exports}for(var i="function"==typeof require&&require,a=0;a0&&console.warn("didn't found matching constructor, using default one"),"")};e.exports={inputParser:u,outputParser:c,formatInput:a,formatOutput:s,formatConstructorParams:l}},{"../utils/utils":8,"./coder":2,"./utils":5}],2:[function(t,e,r){var n=t("bignumber.js"),o=t("../utils/utils"),i=t("./formatters"),a=t("./param"),s=function(t){return"[]"===t.slice(-2)},u=function(t){this._name=t.name,this._match=t.match,this._mode=t.mode,this._inputFormatter=t.inputFormatter,this._outputFormatter=t.outputFormatter};u.prototype.isType=function(t){return"strict"===this._match?this._name===t||0===t.indexOf(this._name)&&"[]"===t.slice(this._name.length):"prefix"===this._match?0===t.indexOf(this._name):void 0},u.prototype.formatInput=function(t,e){if(o.isArray(t)&&e){var r=this;return t.map(function(t){return r._inputFormatter(t)}).reduce(function(t,e){return t.appendArrayElement(e),t},new a("",i.formatInputInt(t.length).value))}return this._inputFormatter(t)},u.prototype.formatOutput=function(t,e){if(e){for(var r=[],o=new n(t.prefix,16),i=0;64*o>i;i+=64)r.push(this._outputFormatter(new a(t.suffix.slice(i,i+64))));return r}return this._outputFormatter(t)},u.prototype.isVariadicType=function(t){return s(t)||"bytes"===this._mode},u.prototype.shiftParam=function(t,e){if("bytes"===this._mode)return e.shiftBytes();if(s(t)){var r=new n(e.prefix.slice(0,64),16);return e.shiftArray(r)}return e.shiftValue()};var c=function(t){this._types=t};c.prototype._requireType=function(t){var e=this._types.filter(function(e){return e.isType(t)})[0];if(!e)throw Error("invalid solidity type!: "+t);return e},c.prototype._bytesToParam=function(t,e){var r=this,n=t.reduce(function(t,e){return r._requireType(e).isVariadicType(e)?t+1:t},0),o=t.length-n,i=e.slice(0,64*n);e=e.slice(64*n);var s=e.slice(0,64*o),u=e.slice(64*o);return new a(s,i,u)},c.prototype._formatInput=function(t,e){return this._requireType(t).formatInput(e,s(t))},c.prototype.encodeParam=function(t,e){return this._formatInput(t,e).encode()},c.prototype.encodeParams=function(t,e){var r=this;return t.map(function(t,n){return r._formatInput(t,e[n])}).reduce(function(t,e){return t.append(e),t},new a).encode()},c.prototype._formatOutput=function(t,e){return this._requireType(t).formatOutput(e,s(t))},c.prototype.decodeParam=function(t,e){return this._formatOutput(t,this._bytesToParam([t],e))},c.prototype.decodeParams=function(t,e){var r=this,n=this._bytesToParam(t,e);return t.map(function(t){var e=r._requireType(t),o=e.shiftParam(t,n);return e.formatOutput(o,s(t))})};var l=new c([new u({name:"address",match:"strict",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputAddress}),new u({name:"bool",match:"strict",mode:"value",inputFormatter:i.formatInputBool,outputFormatter:i.formatOutputBool}),new u({name:"int",match:"prefix",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputInt}),new u({name:"uint",match:"prefix",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputUInt}),new u({name:"bytes",match:"strict",mode:"bytes",inputFormatter:i.formatInputDynamicBytes,outputFormatter:i.formatOutputDynamicBytes}),new u({name:"bytes",match:"prefix",mode:"value",inputFormatter:i.formatInputBytes,outputFormatter:i.formatOutputBytes}),new u({name:"real",match:"prefix",mode:"value",inputFormatter:i.formatInputReal,outputFormatter:i.formatOutputReal}),new u({name:"ureal",match:"prefix",mode:"value",inputFormatter:i.formatInputReal,outputFormatter:i.formatOutputUReal})]);e.exports=l},{"../utils/utils":8,"./formatters":3,"./param":4,"bignumber.js":"bignumber.js"}],3:[function(t,e,r){var n=t("bignumber.js"),o=t("../utils/utils"),i=t("../utils/config"),a=t("./param"),s=function(t){var e=2*i.ETH_PADDING;n.config(i.ETH_BIGNUMBER_ROUNDING_MODE);var r=o.padLeft(o.toTwosComplement(t).round().toString(16),e);return new a(r)},u=function(t){var e=o.fromAscii(t,i.ETH_PADDING).substr(2);return new a(e)},c=function(t){var e=o.fromAscii(t,i.ETH_PADDING).substr(2);return new a("",s(t.length).value,e)},l=function(t){var e="000000000000000000000000000000000000000000000000000000000000000"+(t?"1":"0");return new a(e)},p=function(t){return s(new n(t).times(new n(2).pow(128)))},f=function(t){return"1"===new n(t.substr(0,1),16).toString(2).substr(0,1)},m=function(t){var e=t.value||"0";return f(e)?new n(e,16).minus(new n("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16)).minus(1):new n(e,16)},h=function(t){var e=t.value||"0";return new n(e,16)},d=function(t){return m(t).dividedBy(new n(2).pow(128))},y=function(t){return h(t).dividedBy(new n(2).pow(128))},g=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t.value?!0:!1},v=function(t){return o.toAscii(t.value)},b=function(t){return o.toAscii(t.suffix)},w=function(t){var e=t.value;return"0x"+e.slice(e.length-40,e.length)};e.exports={formatInputInt:s,formatInputBytes:u,formatInputDynamicBytes:c,formatInputBool:l,formatInputReal:p,formatOutputInt:m,formatOutputUInt:h,formatOutputReal:d,formatOutputUReal:y,formatOutputBool:g,formatOutputBytes:v,formatOutputDynamicBytes:b,formatOutputAddress:w}},{"../utils/config":7,"../utils/utils":8,"./param":4,"bignumber.js":"bignumber.js"}],4:[function(t,e,r){var n=function(t,e,r){this.prefix=e||"",this.value=t||"",this.suffix=r||""};n.prototype.append=function(t){this.prefix+=t.prefix,this.value+=t.value,this.suffix+=t.suffix},n.prototype.appendArrayElement=function(t){this.suffix+=t.value,this.prefix+=t.prefix},n.prototype.encode=function(){return this.prefix+this.value+this.suffix},n.prototype.shiftValue=function(){var t=this.value.slice(0,64);return this.value=this.value.slice(64),new n(t)},n.prototype.shiftBytes=function(){return this.shiftArray(1)},n.prototype.shiftArray=function(t){var e=this.prefix.slice(0,64);this.prefix=this.value.slice(64);var r=this.suffix.slice(0,64*t);return this.suffix=this.suffix.slice(64*t),new n("",e,r)},e.exports=n},{}],5:[function(t,e,r){var n=function(t,e){return t.filter(function(t){return"constructor"===t.type&&t.inputs.length===e})[0]};e.exports={getConstructor:n}},{}],6:[function(t,e,r){"use strict";r.XMLHttpRequest="undefined"==typeof XMLHttpRequest?{}:XMLHttpRequest},{}],7:[function(t,e,r){var n=t("bignumber.js"),o=["wei","Kwei","Mwei","Gwei","szabo","finney","ether","grand","Mether","Gether","Tether","Pether","Eether","Zether","Yether","Nether","Dether","Vether","Uether"];e.exports={ETH_PADDING:32,ETH_SIGNATURE_LENGTH:4,ETH_UNITS:o,ETH_BIGNUMBER_ROUNDING_MODE:{ROUNDING_MODE:n.ROUND_DOWN},ETH_POLLING_TIMEOUT:1e3,defaultBlock:"latest",defaultAccount:void 0}},{"bignumber.js":"bignumber.js"}],8:[function(t,e,r){var n=t("bignumber.js"),o={wei:"1",kwei:"1000",ada:"1000",mwei:"1000000",babbage:"1000000",gwei:"1000000000",shannon:"1000000000",szabo:"1000000000000",finney:"1000000000000000",ether:"1000000000000000000",kether:"1000000000000000000000",grand:"1000000000000000000000",einstein:"1000000000000000000000",mether:"1000000000000000000000000",gether:"1000000000000000000000000000",tether:"1000000000000000000000000000000"},i=function(t,e,r){return new Array(e-t.length+1).join(r?r:"0")+t},a=function(t){var e="",r=0,n=t.length;for("0x"===t.substring(0,2)&&(r=2);n>r;r+=2){var o=parseInt(t.substr(r,2),16);if(0===o)break;e+=String.fromCharCode(o)}return e},s=function(t){for(var e="",r=0;rthis._inputTypes.length&&i.isObject(t[t.length-1])&&(e=t.pop()),e.to=this._address,e.data="0x"+this.signature()+o.encodeParams(this._inputTypes,t),e},a.prototype.signature=function(){return n.sha3(n.fromAscii(this._name)).slice(2,10)},a.prototype.call=function(){var t=this.toPayload.apply(this,Array.prototype.slice.call(arguments)),e=n.eth.call(t);e=e.length>=2?e.slice(2):e;var r=o.decodeParams(this._outputTypes,e);return 1===r.length?r[0]:r},a.prototype.sendTransaction=function(){var t=this.toPayload.apply(this,Array.prototype.slice.call(arguments));n.eth.sendTransaction(t)},a.prototype.displayName=function(){return i.extractDisplayName(this._name)},a.prototype.typeName=function(){return i.extractTypeName(this._name)},a.prototype.execute=function(){var t=!this._constant;return t?this.sendTransaction.apply(this,Array.prototype.slice.call(arguments)):this.call.apply(this,Array.prototype.slice.call(arguments))},a.prototype.attachToContract=function(t){var e=this.execute.bind(this);e.call=this.call.bind(this),e.sendTransaction=this.sendTransaction.bind(this);var r=this.displayName();t[r]||(t[r]=e),t[r][this.typeName()]=e},e.exports=a},{"../solidity/coder":2,"../utils/utils":8,"../web3":10}],19:[function(t,e,r){"use strict";var n=t("xmlhttprequest").XMLHttpRequest,o=t("./errors"),i=function(t){this.host=t||"http://localhost:8545"};i.prototype.send=function(t){var e=new n;e.open("POST",this.host,!1);try{e.send(JSON.stringify(t))}catch(r){throw o.InvalidConnection(this.host)}return JSON.parse(e.responseText)},i.prototype.sendAsync=function(t,e){var r=new n;r.onreadystatechange=function(){4===r.readyState&&e(null,JSON.parse(r.responseText))},r.open("POST",this.host,!0);try{r.send(JSON.stringify(t))}catch(i){e(o.InvalidConnection(this.host))}},e.exports=i},{"./errors":13,xmlhttprequest:6}],20:[function(t,e,r){var n=function(){return arguments.callee._singletonInstance?arguments.callee._singletonInstance:(arguments.callee._singletonInstance=this,void(this.messageId=1))};n.getInstance=function(){var t=new n;return t},n.prototype.toPayload=function(t,e){return t||console.error("jsonrpc method should be specified!"),{jsonrpc:"2.0",method:t,params:e||[],id:this.messageId++}},n.prototype.isValidResponse=function(t){return!!t&&!t.error&&"2.0"===t.jsonrpc&&"number"==typeof t.id&&void 0!==t.result},n.prototype.toBatchPayload=function(t){var e=this;return t.map(function(t){return e.toPayload(t.method,t.params)})},e.exports=n},{}],21:[function(t,e,r){var n=t("./requestmanager"),o=t("../utils/utils"),i=t("./errors"),a=function(t){this.name=t.name,this.call=t.call,this.params=t.params||0,this.inputFormatter=t.inputFormatter,this.outputFormatter=t.outputFormatter};a.prototype.getCall=function(t){return o.isFunction(this.call)?this.call(t):this.call},a.prototype.extractCallback=function(t){return o.isFunction(t[t.length-1])?t.pop():null},a.prototype.validateArgs=function(t){if(t.length!==this.params)throw i.InvalidNumberOfParams()},a.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter.map(function(e,r){return e?e(t[r]):t[r]}):t},a.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},a.prototype.attachToObject=function(t){var e=this.send.bind(this);e.call=this.call;var r=this.name.split(".");r.length>1?(t[r[0]]=t[r[0]]||{},t[r[0]][r[1]]=e):t[r[0]]=e},a.prototype.toPayload=function(t){var e=this.getCall(t),r=this.extractCallback(t),n=this.formatInput(t);return this.validateArgs(n),{method:e,params:n,callback:r}},a.prototype.send=function(){var t=this.toPayload(Array.prototype.slice.call(arguments));if(t.callback){var e=this;return n.getInstance().sendAsync(t,function(r,n){t.callback(null,e.formatOutput(n))})}return this.formatOutput(n.getInstance().send(t))},e.exports=a},{"../utils/utils":8,"./errors":13,"./requestmanager":25}],22:[function(t,e,r){var n=t("../utils/utils"),o=t("./property"),i=[],a=[new o({name:"listening",getter:"net_listening"}),new o({name:"peerCount",getter:"net_peerCount",outputFormatter:n.toDecimal})];e.exports={methods:i,properties:a}},{"../utils/utils":8,"./property":23}],23:[function(t,e,r){var n=t("./requestmanager"),o=function(t){this.name=t.name,this.getter=t.getter,this.setter=t.setter,this.outputFormatter=t.outputFormatter,this.inputFormatter=t.inputFormatter};o.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter(t):t},o.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},o.prototype.attachToObject=function(t){var e={get:this.get.bind(this),set:this.set.bind(this)},r=this.name.split(".");r.length>1?(t[r[0]]=t[r[0]]||{},Object.defineProperty(t[r[0]],r[1],e)):Object.defineProperty(t,r[0],e)},o.prototype.get=function(){return this.formatOutput(n.getInstance().send({method:this.getter}))},o.prototype.set=function(t){return n.getInstance().send({method:this.setter,params:[this.formatInput(t)]})},e.exports=o},{"./requestmanager":25}],24:[function(t,e,r){var n=function(){};n.prototype.send=function(t){var e=navigator.qt.callMethod(JSON.stringify(t));return JSON.parse(e)},e.exports=n},{}],25:[function(t,e,r){var n=t("./jsonrpc"),o=t("../utils/utils"),i=t("../utils/config"),a=t("./errors"),s=function(t){return arguments.callee._singletonInstance?arguments.callee._singletonInstance:(arguments.callee._singletonInstance=this,this.provider=t,this.polls=[],this.timeout=null,void this.poll())};s.getInstance=function(){var t=new s;return t},s.prototype.send=function(t){if(!this.provider)return console.error(a.InvalidProvider()),null;var e=n.getInstance().toPayload(t.method,t.params),r=this.provider.send(e);if(!n.getInstance().isValidResponse(r))throw a.InvalidResponse(r);return r.result},s.prototype.sendAsync=function(t,e){if(!this.provider)return e(a.InvalidProvider());var r=n.getInstance().toPayload(t.method,t.params);this.provider.sendAsync(r,function(t,r){return t?e(t):n.getInstance().isValidResponse(r)?void e(null,r.result):e(a.InvalidResponse(r))})},s.prototype.setProvider=function(t){this.provider=t},s.prototype.startPolling=function(t,e,r,n){this.polls.push({data:t,id:e,callback:r,uninstall:n})},s.prototype.stopPolling=function(t){for(var e=this.polls.length;e--;){var r=this.polls[e];r.id===t&&this.polls.splice(e,1)}},s.prototype.reset=function(){this.polls.forEach(function(t){t.uninstall(t.id)}),this.polls=[],this.timeout&&(clearTimeout(this.timeout),this.timeout=null),this.poll()},s.prototype.poll=function(){if(this.timeout=setTimeout(this.poll.bind(this),i.ETH_POLLING_TIMEOUT),this.polls.length){if(!this.provider)return void console.error(a.InvalidProvider());var t=n.getInstance().toBatchPayload(this.polls.map(function(t){return t.data})),e=this;this.provider.sendAsync(t,function(t,r){if(!t){if(!o.isArray(r))throw a.InvalidResponse(r);r.map(function(t,r){return t.callback=e.polls[r].callback,t}).filter(function(t){var e=n.getInstance().isValidResponse(t);return e||t.callback(a.InvalidResponse(t)),e}).filter(function(t){return o.isArray(t.result)&&t.result.length>0}).forEach(function(t){t.callback(null,t.result)})}})}},e.exports=s},{"../utils/config":7,"../utils/utils":8,"./errors":13,"./jsonrpc":20}],26:[function(t,e,r){var n=t("./method"),o=t("./formatters"),i=new n({name:"post",call:"shh_post",params:1,inputFormatter:[o.inputPostFormatter]}),a=new n({name:"newIdentity",call:"shh_newIdentity",params:0}),s=new n({name:"hasIdentity",call:"shh_hasIdentity",params:1}),u=new n({name:"newGroup",call:"shh_newGroup",params:0}),c=new n({name:"addToGroup",call:"shh_addToGroup",params:0}),l=[i,a,s,u,c];e.exports={methods:l}},{"./formatters":17,"./method":21}],27:[function(t,e,r){var n=t("./method"),o=function(){var t=function(t){return"string"==typeof t[0]?"eth_newBlockFilter":"eth_newFilter"},e=new n({name:"newFilter",call:t,params:1}),r=new n({name:"uninstallFilter",call:"eth_uninstallFilter",params:1}),o=new n({name:"getLogs",call:"eth_getFilterLogs",params:1}),i=new n({name:"poll",call:"eth_getFilterChanges",params:1 -});return[e,r,o,i]},i=function(){var t=new n({name:"newFilter",call:"shh_newFilter",params:1}),e=new n({name:"uninstallFilter",call:"shh_uninstallFilter",params:1}),r=new n({name:"getLogs",call:"shh_getMessages",params:1}),o=new n({name:"poll",call:"shh_getFilterChanges",params:1});return[t,e,r,o]};e.exports={eth:o,shh:i}},{"./method":21}],28:[function(t,e,r){},{}],"bignumber.js":[function(t,e,r){"use strict";e.exports=BigNumber},{}],web3:[function(t,e,r){var n=t("./lib/web3");n.providers.HttpProvider=t("./lib/web3/httpprovider"),n.providers.QtSyncProvider=t("./lib/web3/qtsync"),n.eth.contract=t("./lib/web3/contract"),n.abi=t("./lib/solidity/abi"),"undefined"!=typeof window&&"undefined"==typeof window.web3&&(window.web3=n),e.exports=n},{"./lib/solidity/abi":1,"./lib/web3":10,"./lib/web3/contract":11,"./lib/web3/httpprovider":19,"./lib/web3/qtsync":24}]},{},["web3"]); \ No newline at end of file +require=function t(e,r,n){function o(a,s){if(!r[a]){if(!e[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(i)return i(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var l=r[a]={exports:{}};e[a][0].call(l.exports,function(t){var r=e[a][1][t];return o(r?r:t)},l,l.exports,t,e,r,n)}return r[a].exports}for(var i="function"==typeof require&&require,a=0;a0&&console.warn("didn't found matching constructor, using default one"),"")};e.exports={formatConstructorParams:i}},{"./coder":2,"./utils":5}],2:[function(t,e,r){var n=t("bignumber.js"),o=t("../utils/utils"),i=t("./formatters"),a=t("./param"),s=function(t){return"[]"===t.slice(-2)},u=function(t){this._name=t.name,this._match=t.match,this._mode=t.mode,this._inputFormatter=t.inputFormatter,this._outputFormatter=t.outputFormatter};u.prototype.isType=function(t){return"strict"===this._match?this._name===t||0===t.indexOf(this._name)&&"[]"===t.slice(this._name.length):"prefix"===this._match?0===t.indexOf(this._name):void 0},u.prototype.formatInput=function(t,e){if(o.isArray(t)&&e){var r=this;return t.map(function(t){return r._inputFormatter(t)}).reduce(function(t,e){return t.combine(e)},i.formatInputInt(t.length)).withOffset(32)}return this._inputFormatter(t)},u.prototype.formatOutput=function(t,e){if(e){for(var r=[],o=new n(t.dynamicPart().slice(0,64),16),i=0;64*o>i;i+=64)r.push(this._outputFormatter(new a(t.dynamicPart().substr(i+64,64))));return r}return this._outputFormatter(t)},u.prototype.sliceParam=function(t,e,r){return"bytes"===this._mode?a.decodeBytes(t,e):s(r)?a.decodeArray(t,e):a.decodeParam(t,e)};var c=function(t){this._types=t};c.prototype._requireType=function(t){var e=this._types.filter(function(e){return e.isType(t)})[0];if(!e)throw Error("invalid solidity type!: "+t);return e},c.prototype._formatInput=function(t,e){return this._requireType(t).formatInput(e,s(t))},c.prototype.encodeParam=function(t,e){return this._formatInput(t,e).encode()},c.prototype.encodeParams=function(t,e){var r=this,n=t.map(function(t,n){return r._formatInput(t,e[n])});return a.encodeList(n)},c.prototype.decodeParam=function(t,e){return this.decodeParams([t],e)[0]},c.prototype.decodeParams=function(t,e){var r=this;return t.map(function(t,n){var o=r._requireType(t),i=o.sliceParam(e,n,t);return o.formatOutput(i,s(t))})};var l=new c([new u({name:"address",match:"strict",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputAddress}),new u({name:"bool",match:"strict",mode:"value",inputFormatter:i.formatInputBool,outputFormatter:i.formatOutputBool}),new u({name:"int",match:"prefix",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputInt}),new u({name:"uint",match:"prefix",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputUInt}),new u({name:"bytes",match:"strict",mode:"bytes",inputFormatter:i.formatInputDynamicBytes,outputFormatter:i.formatOutputDynamicBytes}),new u({name:"bytes",match:"prefix",mode:"value",inputFormatter:i.formatInputBytes,outputFormatter:i.formatOutputBytes}),new u({name:"real",match:"prefix",mode:"value",inputFormatter:i.formatInputReal,outputFormatter:i.formatOutputReal}),new u({name:"ureal",match:"prefix",mode:"value",inputFormatter:i.formatInputReal,outputFormatter:i.formatOutputUReal})]);e.exports=l},{"../utils/utils":8,"./formatters":3,"./param":4,"bignumber.js":"bignumber.js"}],3:[function(t,e,r){var n=t("bignumber.js"),o=t("../utils/utils"),i=t("../utils/config"),a=t("./param"),s=function(t){var e=2*i.ETH_PADDING;n.config(i.ETH_BIGNUMBER_ROUNDING_MODE);var r=o.padLeft(o.toTwosComplement(t).round().toString(16),e);return new a(r)},u=function(t){var e=o.fromAscii(t,i.ETH_PADDING).substr(2);return new a(e)},c=function(t){var e=o.fromAscii(t,i.ETH_PADDING).substr(2);return new a(s(t.length).value+e,32)},l=function(t){var e="000000000000000000000000000000000000000000000000000000000000000"+(t?"1":"0");return new a(e)},p=function(t){return s(new n(t).times(new n(2).pow(128)))},f=function(t){return"1"===new n(t.substr(0,1),16).toString(2).substr(0,1)},m=function(t){var e=t.staticPart()||"0";return f(e)?new n(e,16).minus(new n("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16)).minus(1):new n(e,16)},h=function(t){var e=t.staticPart()||"0";return new n(e,16)},d=function(t){return m(t).dividedBy(new n(2).pow(128))},y=function(t){return h(t).dividedBy(new n(2).pow(128))},g=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t.staticPart()?!0:!1},b=function(t){return o.toAscii(t.staticPart())},v=function(t){return o.toAscii(t.dynamicPart().slice(64))},w=function(t){var e=t.staticPart();return"0x"+e.slice(e.length-40,e.length)};e.exports={formatInputInt:s,formatInputBytes:u,formatInputDynamicBytes:c,formatInputBool:l,formatInputReal:p,formatOutputInt:m,formatOutputUInt:h,formatOutputReal:d,formatOutputUReal:y,formatOutputBool:g,formatOutputBytes:b,formatOutputDynamicBytes:v,formatOutputAddress:w}},{"../utils/config":7,"../utils/utils":8,"./param":4,"bignumber.js":"bignumber.js"}],4:[function(t,e,r){var n=t("../utils/utils"),o=function(t,e){this.value=t||"",this.offset=e};o.prototype.dynamicPartLength=function(){return this.dynamicPart().length/2},o.prototype.withOffset=function(t){return new o(this.value,t)},o.prototype.combine=function(t){return new o(this.value+t.value)},o.prototype.isDynamic=function(){return this.value.length>64},o.prototype.offsetAsBytes=function(){return this.isDynamic()?n.padLeft(n.toTwosComplement(this.offset).toString(16),64):""},o.prototype.staticPart=function(){return this.isDynamic()?this.offsetAsBytes():this.value},o.prototype.dynamicPart=function(){return this.isDynamic()?this.value:""},o.prototype.encode=function(){return this.staticPart()+this.dynamicPart()},o.encodeList=function(t){var e=32*t.length,r=t.map(function(t){if(!t.isDynamic())return t;var r=e;return e+=t.dynamicPartLength(),t.withOffset(r)});return r.reduce(function(t,e){return t+e.dynamicPart()},r.reduce(function(t,e){return t+e.staticPart()},""))},o.decodeParam=function(t,e){return e=e||0,new o(t.substr(64*e,64))};var i=function(t,e){return parseInt("0x"+t.substr(64*e,64))};o.decodeBytes=function(t,e){e=e||0;var r=i(t,e);return new o(t.substr(2*r,128))},o.decodeArray=function(t,e){e=e||0;var r=i(t,e),n=parseInt("0x"+t.substr(2*r,64));return new o(t.substr(2*r,64*(n+1)))},e.exports=o},{"../utils/utils":8}],5:[function(t,e,r){var n=function(t,e){return t.filter(function(t){return"constructor"===t.type&&t.inputs.length===e})[0]};e.exports={getConstructor:n}},{}],6:[function(t,e,r){"use strict";r.XMLHttpRequest="undefined"==typeof XMLHttpRequest?{}:XMLHttpRequest},{}],7:[function(t,e,r){var n=t("bignumber.js"),o=["wei","Kwei","Mwei","Gwei","szabo","finney","ether","grand","Mether","Gether","Tether","Pether","Eether","Zether","Yether","Nether","Dether","Vether","Uether"];e.exports={ETH_PADDING:32,ETH_SIGNATURE_LENGTH:4,ETH_UNITS:o,ETH_BIGNUMBER_ROUNDING_MODE:{ROUNDING_MODE:n.ROUND_DOWN},ETH_POLLING_TIMEOUT:1e3,defaultBlock:"latest",defaultAccount:void 0}},{"bignumber.js":"bignumber.js"}],8:[function(t,e,r){var n=t("bignumber.js"),o={wei:"1",kwei:"1000",ada:"1000",mwei:"1000000",babbage:"1000000",gwei:"1000000000",shannon:"1000000000",szabo:"1000000000000",finney:"1000000000000000",ether:"1000000000000000000",kether:"1000000000000000000000",grand:"1000000000000000000000",einstein:"1000000000000000000000",mether:"1000000000000000000000000",gether:"1000000000000000000000000000",tether:"1000000000000000000000000000000"},i=function(t,e,r){return new Array(e-t.length+1).join(r?r:"0")+t},a=function(t){var e="",r=0,n=t.length;for("0x"===t.substring(0,2)&&(r=2);n>r;r+=2){var o=parseInt(t.substr(r,2),16);if(0===o)break;e+=String.fromCharCode(o)}return e},s=function(t){for(var e="",r=0;rthis._inputTypes.length&&i.isObject(t[t.length-1])&&(e=t.pop()),e.to=this._address,e.data="0x"+this.signature()+o.encodeParams(this._inputTypes,t),e},a.prototype.signature=function(){return n.sha3(n.fromAscii(this._name)).slice(2,10)},a.prototype.call=function(){var t=this.toPayload.apply(this,Array.prototype.slice.call(arguments)),e=n.eth.call(t);e=e.length>=2?e.slice(2):e;var r=o.decodeParams(this._outputTypes,e);return 1===r.length?r[0]:r},a.prototype.sendTransaction=function(){var t=this.toPayload.apply(this,Array.prototype.slice.call(arguments));n.eth.sendTransaction(t)},a.prototype.displayName=function(){return i.extractDisplayName(this._name)},a.prototype.typeName=function(){return i.extractTypeName(this._name)},a.prototype.execute=function(){var t=!this._constant;return t?this.sendTransaction.apply(this,Array.prototype.slice.call(arguments)):this.call.apply(this,Array.prototype.slice.call(arguments))},a.prototype.attachToContract=function(t){var e=this.execute.bind(this);e.call=this.call.bind(this),e.sendTransaction=this.sendTransaction.bind(this);var r=this.displayName();t[r]||(t[r]=e),t[r][this.typeName()]=e},e.exports=a},{"../solidity/coder":2,"../utils/utils":8,"../web3":10}],19:[function(t,e,r){"use strict";var n=t("xmlhttprequest").XMLHttpRequest,o=t("./errors"),i=function(t){this.host=t||"http://localhost:8545"};i.prototype.send=function(t){var e=new n;e.open("POST",this.host,!1);try{e.send(JSON.stringify(t))}catch(r){throw o.InvalidConnection(this.host)}var i=e.responseText;try{i=JSON.parse(i)}catch(a){throw o.InvalidResponse(i)}return i},i.prototype.sendAsync=function(t,e){var r=new n;r.onreadystatechange=function(){if(4===r.readyState){var t=r.responseText,n=null;try{t=JSON.parse(t)}catch(i){n=o.InvalidResponse(t)}e(n,t)}},r.open("POST",this.host,!0);try{r.send(JSON.stringify(t))}catch(i){e(o.InvalidConnection(this.host))}},e.exports=i},{"./errors":13,xmlhttprequest:6}],20:[function(t,e,r){var n=function(){return arguments.callee._singletonInstance?arguments.callee._singletonInstance:(arguments.callee._singletonInstance=this,void(this.messageId=1))};n.getInstance=function(){var t=new n;return t},n.prototype.toPayload=function(t,e){return t||console.error("jsonrpc method should be specified!"),{jsonrpc:"2.0",method:t,params:e||[],id:this.messageId++}},n.prototype.isValidResponse=function(t){return!!t&&!t.error&&"2.0"===t.jsonrpc&&"number"==typeof t.id&&void 0!==t.result},n.prototype.toBatchPayload=function(t){var e=this;return t.map(function(t){return e.toPayload(t.method,t.params)})},e.exports=n},{}],21:[function(t,e,r){var n=t("./requestmanager"),o=t("../utils/utils"),i=t("./errors"),a=function(t){this.name=t.name,this.call=t.call,this.params=t.params||0,this.inputFormatter=t.inputFormatter,this.outputFormatter=t.outputFormatter};a.prototype.getCall=function(t){return o.isFunction(this.call)?this.call(t):this.call},a.prototype.extractCallback=function(t){return o.isFunction(t[t.length-1])?t.pop():null},a.prototype.validateArgs=function(t){if(t.length!==this.params)throw i.InvalidNumberOfParams()},a.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter.map(function(e,r){return e?e(t[r]):t[r]}):t},a.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},a.prototype.attachToObject=function(t){var e=this.send.bind(this);e.call=this.call;var r=this.name.split(".");r.length>1?(t[r[0]]=t[r[0]]||{},t[r[0]][r[1]]=e):t[r[0]]=e},a.prototype.toPayload=function(t){var e=this.getCall(t),r=this.extractCallback(t),n=this.formatInput(t);return this.validateArgs(n),{method:e,params:n,callback:r}},a.prototype.send=function(){var t=this.toPayload(Array.prototype.slice.call(arguments));if(t.callback){var e=this;return n.getInstance().sendAsync(t,function(r,n){t.callback(null,e.formatOutput(n))})}return this.formatOutput(n.getInstance().send(t))},e.exports=a},{"../utils/utils":8,"./errors":13,"./requestmanager":25}],22:[function(t,e,r){var n=t("../utils/utils"),o=t("./property"),i=[],a=[new o({name:"listening",getter:"net_listening"}),new o({name:"peerCount",getter:"net_peerCount",outputFormatter:n.toDecimal})];e.exports={methods:i,properties:a}},{"../utils/utils":8,"./property":23}],23:[function(t,e,r){var n=t("./requestmanager"),o=function(t){this.name=t.name,this.getter=t.getter,this.setter=t.setter,this.outputFormatter=t.outputFormatter,this.inputFormatter=t.inputFormatter};o.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter(t):t},o.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},o.prototype.attachToObject=function(t){var e={get:this.get.bind(this),set:this.set.bind(this)},r=this.name.split(".");r.length>1?(t[r[0]]=t[r[0]]||{},Object.defineProperty(t[r[0]],r[1],e)):Object.defineProperty(t,r[0],e)},o.prototype.get=function(){return this.formatOutput(n.getInstance().send({method:this.getter}))},o.prototype.set=function(t){return n.getInstance().send({method:this.setter,params:[this.formatInput(t)]})},e.exports=o},{"./requestmanager":25}],24:[function(t,e,r){var n=function(){};n.prototype.send=function(t){var e=navigator.qt.callMethod(JSON.stringify(t));return JSON.parse(e)},e.exports=n},{}],25:[function(t,e,r){var n=t("./jsonrpc"),o=t("../utils/utils"),i=t("../utils/config"),a=t("./errors"),s=function(t){return arguments.callee._singletonInstance?arguments.callee._singletonInstance:(arguments.callee._singletonInstance=this,this.provider=t,this.polls=[],this.timeout=null,void this.poll())};s.getInstance=function(){var t=new s;return t},s.prototype.send=function(t){if(!this.provider)return console.error(a.InvalidProvider()),null;var e=n.getInstance().toPayload(t.method,t.params),r=this.provider.send(e);if(!n.getInstance().isValidResponse(r))throw a.InvalidResponse(r);return r.result},s.prototype.sendAsync=function(t,e){if(!this.provider)return e(a.InvalidProvider());var r=n.getInstance().toPayload(t.method,t.params);this.provider.sendAsync(r,function(t,r){return t?e(t):n.getInstance().isValidResponse(r)?void e(null,r.result):e(a.InvalidResponse(r))})},s.prototype.setProvider=function(t){this.provider=t},s.prototype.startPolling=function(t,e,r,n){this.polls.push({data:t,id:e,callback:r,uninstall:n})},s.prototype.stopPolling=function(t){for(var e=this.polls.length;e--;){var r=this.polls[e];r.id===t&&this.polls.splice(e,1)}},s.prototype.reset=function(){this.polls.forEach(function(t){t.uninstall(t.id)}),this.polls=[],this.timeout&&(clearTimeout(this.timeout),this.timeout=null),this.poll()},s.prototype.poll=function(){if(this.timeout=setTimeout(this.poll.bind(this),i.ETH_POLLING_TIMEOUT),this.polls.length){if(!this.provider)return void console.error(a.InvalidProvider());var t=n.getInstance().toBatchPayload(this.polls.map(function(t){return t.data})),e=this;this.provider.sendAsync(t,function(t,r){if(!t){if(!o.isArray(r))throw a.InvalidResponse(r);r.map(function(t,r){return t.callback=e.polls[r].callback,t}).filter(function(t){var e=n.getInstance().isValidResponse(t);return e||t.callback(a.InvalidResponse(t)),e}).filter(function(t){return o.isArray(t.result)&&t.result.length>0}).forEach(function(t){t.callback(null,t.result)})}})}},e.exports=s},{"../utils/config":7,"../utils/utils":8,"./errors":13,"./jsonrpc":20}],26:[function(t,e,r){var n=t("./method"),o=t("./formatters"),i=new n({name:"post",call:"shh_post",params:1,inputFormatter:[o.inputPostFormatter]}),a=new n({name:"newIdentity",call:"shh_newIdentity",params:0}),s=new n({name:"hasIdentity",call:"shh_hasIdentity",params:1}),u=new n({name:"newGroup",call:"shh_newGroup",params:0}),c=new n({name:"addToGroup",call:"shh_addToGroup",params:0}),l=[i,a,s,u,c];e.exports={methods:l}},{"./formatters":17,"./method":21}],27:[function(t,e,r){var n=t("./method"),o=function(){var t=function(t){return"string"==typeof t[0]?"eth_newBlockFilter":"eth_newFilter"},e=new n({name:"newFilter",call:t,params:1}),r=new n({name:"uninstallFilter",call:"eth_uninstallFilter",params:1}),o=new n({name:"getLogs",call:"eth_getFilterLogs",params:1}),i=new n({name:"poll",call:"eth_getFilterChanges",params:1});return[e,r,o,i]},i=function(){var t=new n({name:"newFilter",call:"shh_newFilter",params:1}),e=new n({name:"uninstallFilter",call:"shh_uninstallFilter",params:1}),r=new n({name:"getLogs",call:"shh_getMessages",params:1}),o=new n({name:"poll",call:"shh_getFilterChanges",params:1 +});return[t,e,r,o]};e.exports={eth:o,shh:i}},{"./method":21}],28:[function(t,e,r){},{}],"bignumber.js":[function(t,e,r){"use strict";e.exports=BigNumber},{}],web3:[function(t,e,r){var n=t("./lib/web3");n.providers.HttpProvider=t("./lib/web3/httpprovider"),n.providers.QtSyncProvider=t("./lib/web3/qtsync"),n.eth.contract=t("./lib/web3/contract"),n.abi=t("./lib/solidity/abi"),"undefined"!=typeof window&&"undefined"==typeof window.web3&&(window.web3=n),e.exports=n},{"./lib/solidity/abi":1,"./lib/web3":10,"./lib/web3/contract":11,"./lib/web3/httpprovider":19,"./lib/web3/qtsync":24}]},{},["web3"]); \ No newline at end of file diff --git a/dist/web3.js b/dist/web3.js index db554daea..ec66a38d8 100644 --- a/dist/web3.js +++ b/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 */ -var utils = require('../utils/utils'); var coder = require('./coder'); -var solUtils = 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 utils = require('./utils'); var formatConstructorParams = function (abi, params) { - var constructor = solUtils.getConstructor(abi, params.length); + var constructor = utils.getConstructor(abi, params.length); if (!constructor) { if (params.length > 0) { console.warn("didn't found matching constructor, using default one"); } return ''; } - return formatInput(constructor.inputs, params); + + return coder.encodeParams(constructor.inputs.map(function (input) { + return input.type; + }), params); }; module.exports = { - inputParser: inputParser, - outputParser: outputParser, - formatInput: formatInput, - formatOutput: formatOutput, 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. @@ -213,9 +124,8 @@ SolidityType.prototype.formatInput = function (param, arrayType) { return param.map(function (p) { return self._inputFormatter(p); }).reduce(function (acc, current) { - acc.appendArrayElement(current); - return acc; - }, new SolidityParam('', f.formatInputInt(param.length).value)); + return acc.combine(current); + }, f.formatInputInt(param.length)).withOffset(32); } return this._inputFormatter(param); }; @@ -232,9 +142,9 @@ SolidityType.prototype.formatOutput = function (param, arrayType) { if (arrayType) { // let's assume, that we solidity will never return long arrays :P 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) { - 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; } @@ -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 - * @param {String} type - * @returns {Bool} true if the type is variadic - */ -SolidityType.prototype.isVariadicType = function (type) { - return isArrayType(type) || this._mode === 'bytes'; -}; - -/** - * Should be used to shift param from params group - * - * @method shiftParam + * @method sliceParam + * @param {String} bytes + * @param {Number} index of param to slice * @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') { - return param.shiftBytes(); + return SolidityParam.decodeBytes(bytes, index); } else if (isArrayType(type)) { - var length = new BigNumber(param.prefix.slice(0, 64), 16); - return param.shiftArray(length); + return SolidityParam.decodeArray(bytes, index); } - return param.shiftValue(); + return SolidityParam.decodeParam(bytes, index); }; /** @@ -296,28 +196,6 @@ SolidityCoder.prototype._requireType = function (type) { 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 * @@ -352,24 +230,11 @@ SolidityCoder.prototype.encodeParam = function (type, param) { */ SolidityCoder.prototype.encodeParams = function (types, params) { var self = this; - return types.map(function (type, index) { + var solidityParams = types.map(function (type, index) { return self._formatInput(type, params[index]); - }).reduce(function (acc, solidityParam) { - acc.append(solidityParam); - return acc; - }, new SolidityParam()).encode(); -}; + }); -/** - * 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)); + return SolidityParam.encodeList(solidityParams); }; /** @@ -381,7 +246,7 @@ SolidityCoder.prototype._formatOutput = function (type, param) { * @return {Object} plain param */ 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) { var self = this; - var param = this._bytesToParam(types, bytes); - return types.map(function (type) { + return types.map(function (type, index) { var solidityType = self._requireType(type); - var p = solidityType.shiftParam(type, param); + var p = solidityType.sliceParam(bytes, index, type); return solidityType.formatOutput(p, isArrayType(type)); }); }; @@ -530,7 +394,7 @@ var formatInputBytes = function (value) { */ var formatInputDynamicBytes = function (value) { 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 */ var formatOutputInt = function (param) { - var value = param.value || "0"; + var value = param.staticPart() || "0"; // check if it's negative number // it it is, return two's complement @@ -594,7 +458,7 @@ var formatOutputInt = function (param) { * @returns {BigNumeber} right-aligned output bytes formatted to uint */ var formatOutputUInt = function (param) { - var value = param.value || "0"; + var value = param.staticPart() || "0"; return new BigNumber(value, 16); }; @@ -628,7 +492,7 @@ var formatOutputUReal = function (param) { * @returns {Boolean} right-aligned input bytes formatted to bool */ 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) { // 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) { // 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 */ var formatOutputAddress = function (param) { - var value = param.value; + var value = param.staticPart(); return "0x" + value.slice(value.length - 40, value.length); }; @@ -707,91 +571,196 @@ module.exports = { * @date 2015 */ +var utils = require('../utils/utils'); + /** * SolidityParam object prototype. * Should be used when encoding, decoding solidity bytes */ -var SolidityParam = function (value, prefix, suffix) { - this.prefix = prefix || ''; +var SolidityParam = function (value, offset) { 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 - * @param {SolidityParam} param that it appended after this + * @method combine + * @param {SolidityParam} param with which we should combine + * @param {SolidityParam} result of combination */ -SolidityParam.prototype.append = function (param) { - this.prefix += param.prefix; - this.value += param.value; - this.suffix += param.suffix; +SolidityParam.prototype.combine = function (param) { + return new SolidityParam(this.value + param.value); }; /** - * 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 - * @param {SolidityParam} param that is appended to an array + * @method isDynamic + * @returns {Boolean} */ -SolidityParam.prototype.appendArrayElement = function (param) { - this.suffix += param.value; - this.prefix += param.prefix; - // TODO: suffix not supported = it's required for nested arrays; +SolidityParam.prototype.isDynamic = function () { + return this.value.length > 64; }; /** - * 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 - * @return {String} encoded param(s) + * @returns {String} */ 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 - * @return {SolidityParam} first value param + * @method encodeList + * @param {Array[SolidityParam]} params + * @returns {String} */ -SolidityParam.prototype.shiftValue = function () { - var value = this.value.slice(0, 64); - this.value = this.value.slice(64); - return new SolidityParam(value); +SolidityParam.encodeList = function (params) { + + // updating offsets + 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 - * @return {SolidityParam} first bytes param + * @method decodeParam + * @param {String} bytes + * @param {Number} index + * @returns {SolidityParam} */ -SolidityParam.prototype.shiftBytes = function () { - return this.shiftArray(1); +SolidityParam.decodeParam = function (bytes, index) { + index = index || 0; + return new SolidityParam(bytes.substr(index * 64, 64)); }; /** - * This method should be used to shift an array from group of params - * - * @method shiftArray - * @param {Number} size of an array to shift - * @return {SolidityParam} first array param + * This method should be called to get offset value from bytes at given index + * + * @method getOffset + * @param {String} bytes + * @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) { - var prefix = this.prefix.slice(0, 64); - this.prefix = this.value.slice(64); - var suffix = this.suffix.slice(0, 64 * length); - this.suffix = this.suffix.slice(64 * length); - return new SolidityParam('', prefix, suffix); +SolidityParam.decodeArray = function (bytes, index) { + index = index || 0; + var offset = getOffset(bytes, index); + var length = parseInt('0x' + bytes.substr(offset * 2, 64)); + return new SolidityParam(bytes.substr(offset * 2, (length + 1) * 64)); }; module.exports = SolidityParam; -},{}],5:[function(require,module,exports){ +},{"../utils/utils":8}],5:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -828,6 +797,11 @@ var getConstructor = function (abi, numberOfArgs) { })[0]; }; +//var getSupremeType = function (type) { + //return type.substr(0, type.indexOf('[')) + ']'; +//}; + + module.exports = { getConstructor: getConstructor }; @@ -1394,7 +1368,7 @@ module.exports = { },{"bignumber.js":"bignumber.js"}],9:[function(require,module,exports){ module.exports={ - "version": "0.3.3" + "version": "0.3.6" } },{}],10:[function(require,module,exports){ @@ -1796,7 +1770,7 @@ module.exports = { /** * Web3 - * + * * @module web3 */ @@ -1850,16 +1824,16 @@ var uncleCountCall = function (args) { /// @returns an array of objects describing web3.eth api methods var getBalance = new Method({ - name: 'getBalance', - call: 'eth_getBalance', + name: 'getBalance', + call: 'eth_getBalance', params: 2, inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter], outputFormatter: formatters.outputBigNumberFormatter }); var getStorageAt = new Method({ - name: 'getStorageAt', - call: 'eth_getStorageAt', + name: 'getStorageAt', + call: 'eth_getStorageAt', params: 3, inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter] }); @@ -1872,7 +1846,7 @@ var getCode = new Method({ }); var getBlock = new Method({ - name: 'getBlock', + name: 'getBlock', call: blockCall, params: 2, inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }], @@ -1997,6 +1971,11 @@ var properties = [ name: 'mining', getter: 'eth_mining' }), + new Property({ + name: 'hashrate', + getter: 'eth_hashrate', + outputFormatter: utils.toDecimal + }), new Property({ name: 'gasPrice', getter: 'eth_gasPrice', @@ -2118,7 +2097,7 @@ SolidityEvent.prototype.encode = function (indexed, options) { ['fromBlock', 'toBlock'].filter(function (f) { return options[f] !== undefined; }).forEach(function (f) { - result[f] = utils.toHex(options[f]); + result[f] = formatters.inputBlockNumberFormatter(options[f]); }); result.topics = []; @@ -2447,7 +2426,7 @@ var inputTransactionFormatter = function (options){ delete options.code; } - ['gasPrice', 'gas', 'value'].filter(function (key) { + ['gasPrice', 'gas', 'value', 'nonce'].filter(function (key) { return options[key] !== undefined; }).forEach(function(key){ options[key] = utils.fromDecimal(options[key]); @@ -2796,15 +2775,32 @@ HttpProvider.prototype.send = function (payload) { //if (request.status !== 200) { //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) { var request = new XMLHttpRequest(); request.onreadystatechange = function() { if (request.readyState === 4) { - // TODO: handle the error properly here!!! - callback(null, JSON.parse(request.responseText)); + var result = request.responseText; + var error = null; + + try { + result = JSON.parse(result); + } catch(e) { + error = errors.InvalidResponse(result); + } + + callback(error, result); } }; diff --git a/dist/web3.js.map b/dist/web3.js.map index c989052e7..4efb07df1 100644 --- a/dist/web3.js.map +++ b/dist/web3.js.map @@ -34,30 +34,30 @@ "index.js" ], "names": [], - "mappings": "AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1dA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrGA;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3nFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA", + "mappings": "AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1dA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5PA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrGA;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3nFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA", "file": "generated.js", "sourceRoot": "", "sourcesContent": [ "(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o.\n*/\n/** \n * @file abi.js\n * @author Marek Kotewicz \n * @author Gav Wood \n * @date 2014\n */\n\nvar utils = require('../utils/utils');\nvar coder = require('./coder');\nvar solUtils = require('./utils');\n\n/**\n * Formats input params to bytes\n *\n * @method formatInput\n * @param {Array} abi inputs of method\n * @param {Array} params that will be formatted to bytes\n * @returns bytes representation of input params\n */\nvar formatInput = function (inputs, params) {\n var i = inputs.map(function (input) {\n return input.type;\n });\n return coder.encodeParams(i, params);\n};\n\n/** \n * Formats output bytes back to param list\n *\n * @method formatOutput\n * @param {Array} abi outputs of method\n * @param {String} bytes represention of output\n * @returns {Array} output params\n */\nvar formatOutput = function (outs, bytes) {\n var o = outs.map(function (out) {\n return out.type;\n });\n \n return coder.decodeParams(o, bytes); \n};\n\n/**\n * Should be called to create input parser for contract with given abi\n *\n * @method inputParser\n * @param {Array} contract abi\n * @returns {Object} input parser object for given json abi\n * TODO: refactor creating the parser, do not double logic from contract\n */\nvar inputParser = function (json) {\n var parser = {};\n json.forEach(function (method) {\n var displayName = utils.extractDisplayName(method.name);\n var typeName = utils.extractTypeName(method.name);\n\n var impl = function () {\n var params = Array.prototype.slice.call(arguments);\n return formatInput(method.inputs, params);\n };\n\n if (parser[displayName] === undefined) {\n parser[displayName] = impl;\n }\n\n parser[displayName][typeName] = impl;\n });\n\n return parser;\n};\n\n/**\n * Should be called to create output parser for contract with given abi\n *\n * @method outputParser\n * @param {Array} contract abi\n * @returns {Object} output parser for given json abi\n */\nvar outputParser = function (json) {\n var parser = {};\n json.forEach(function (method) {\n\n var displayName = utils.extractDisplayName(method.name);\n var typeName = utils.extractTypeName(method.name);\n\n var impl = function (output) {\n return formatOutput(method.outputs, output);\n };\n\n if (parser[displayName] === undefined) {\n parser[displayName] = impl;\n }\n\n parser[displayName][typeName] = impl;\n });\n\n return parser;\n};\n\nvar formatConstructorParams = function (abi, params) {\n var constructor = solUtils.getConstructor(abi, params.length);\n if (!constructor) {\n if (params.length > 0) {\n console.warn(\"didn't found matching constructor, using default one\");\n }\n return '';\n }\n return formatInput(constructor.inputs, params);\n};\n\nmodule.exports = {\n inputParser: inputParser,\n outputParser: outputParser,\n formatInput: formatInput,\n formatOutput: formatOutput,\n formatConstructorParams: formatConstructorParams\n};\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file coder.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar BigNumber = require('bignumber.js');\nvar utils = require('../utils/utils');\nvar f = require('./formatters');\nvar SolidityParam = require('./param');\n\n/**\n * Should be used to check if a type is an array type\n *\n * @method isArrayType\n * @param {String} type\n * @return {Bool} true is the type is an array, otherwise false\n */\nvar isArrayType = function (type) {\n return type.slice(-2) === '[]';\n};\n\n/**\n * SolidityType prototype is used to encode/decode solidity params of certain type\n */\nvar SolidityType = function (config) {\n this._name = config.name;\n this._match = config.match;\n this._mode = config.mode;\n this._inputFormatter = config.inputFormatter;\n this._outputFormatter = config.outputFormatter;\n};\n\n/**\n * Should be used to determine if this SolidityType do match given type\n *\n * @method isType\n * @param {String} name\n * @return {Bool} true if type match this SolidityType, otherwise false\n */\nSolidityType.prototype.isType = function (name) {\n if (this._match === 'strict') {\n return this._name === name || (name.indexOf(this._name) === 0 && name.slice(this._name.length) === '[]');\n } else if (this._match === 'prefix') {\n // TODO better type detection!\n return name.indexOf(this._name) === 0;\n }\n};\n\n/**\n * Should be used to transform plain param to SolidityParam object\n *\n * @method formatInput\n * @param {Object} param - plain object, or an array of objects\n * @param {Bool} arrayType - true if a param should be encoded as an array\n * @return {SolidityParam} encoded param wrapped in SolidityParam object \n */\nSolidityType.prototype.formatInput = function (param, arrayType) {\n if (utils.isArray(param) && arrayType) { // TODO: should fail if this two are not the same\n var self = this;\n return param.map(function (p) {\n return self._inputFormatter(p);\n }).reduce(function (acc, current) {\n acc.appendArrayElement(current);\n return acc;\n }, new SolidityParam('', f.formatInputInt(param.length).value));\n } \n return this._inputFormatter(param);\n};\n\n/**\n * Should be used to transoform SolidityParam to plain param\n *\n * @method formatOutput\n * @param {SolidityParam} byteArray\n * @param {Bool} arrayType - true if a param should be decoded as an array\n * @return {Object} plain decoded param\n */\nSolidityType.prototype.formatOutput = function (param, arrayType) {\n if (arrayType) {\n // let's assume, that we solidity will never return long arrays :P \n var result = [];\n var length = new BigNumber(param.prefix, 16);\n for (var i = 0; i < length * 64; i += 64) {\n result.push(this._outputFormatter(new SolidityParam(param.suffix.slice(i, i + 64))));\n }\n return result;\n }\n return this._outputFormatter(param);\n};\n\n/**\n * Should be used to check if a type is variadic\n *\n * @method isVariadicType\n * @param {String} type\n * @returns {Bool} true if the type is variadic\n */\nSolidityType.prototype.isVariadicType = function (type) {\n return isArrayType(type) || this._mode === 'bytes';\n};\n\n/**\n * Should be used to shift param from params group\n *\n * @method shiftParam\n * @param {String} type\n * @returns {SolidityParam} shifted param\n */\nSolidityType.prototype.shiftParam = function (type, param) {\n if (this._mode === 'bytes') {\n return param.shiftBytes();\n } else if (isArrayType(type)) {\n var length = new BigNumber(param.prefix.slice(0, 64), 16);\n return param.shiftArray(length);\n }\n return param.shiftValue();\n};\n\n/**\n * SolidityCoder prototype should be used to encode/decode solidity params of any type\n */\nvar SolidityCoder = function (types) {\n this._types = types;\n};\n\n/**\n * This method should be used to transform type to SolidityType\n *\n * @method _requireType\n * @param {String} type\n * @returns {SolidityType} \n * @throws {Error} throws if no matching type is found\n */\nSolidityCoder.prototype._requireType = function (type) {\n var solidityType = this._types.filter(function (t) {\n return t.isType(type);\n })[0];\n\n if (!solidityType) {\n throw Error('invalid solidity type!: ' + type);\n }\n\n return solidityType;\n};\n\n/**\n * Should be used to transform plain bytes to SolidityParam object\n *\n * @method _bytesToParam\n * @param {Array} types of params\n * @param {String} bytes to be transformed to SolidityParam\n * @return {SolidityParam} SolidityParam for this group of params\n */\nSolidityCoder.prototype._bytesToParam = function (types, bytes) {\n var self = this;\n var prefixTypes = types.reduce(function (acc, type) {\n return self._requireType(type).isVariadicType(type) ? acc + 1 : acc;\n }, 0);\n var valueTypes = types.length - prefixTypes;\n\n var prefix = bytes.slice(0, prefixTypes * 64);\n bytes = bytes.slice(prefixTypes * 64);\n var value = bytes.slice(0, valueTypes * 64);\n var suffix = bytes.slice(valueTypes * 64);\n return new SolidityParam(value, prefix, suffix); \n};\n\n/**\n * Should be used to transform plain param of given type to SolidityParam\n *\n * @method _formatInput\n * @param {String} type of param\n * @param {Object} plain param\n * @return {SolidityParam}\n */\nSolidityCoder.prototype._formatInput = function (type, param) {\n return this._requireType(type).formatInput(param, isArrayType(type));\n};\n\n/**\n * Should be used to encode plain param\n *\n * @method encodeParam\n * @param {String} type\n * @param {Object} plain param\n * @return {String} encoded plain param\n */\nSolidityCoder.prototype.encodeParam = function (type, param) {\n return this._formatInput(type, param).encode();\n};\n\n/**\n * Should be used to encode list of params\n *\n * @method encodeParams\n * @param {Array} types\n * @param {Array} params\n * @return {String} encoded list of params\n */\nSolidityCoder.prototype.encodeParams = function (types, params) {\n var self = this;\n return types.map(function (type, index) {\n return self._formatInput(type, params[index]);\n }).reduce(function (acc, solidityParam) {\n acc.append(solidityParam);\n return acc;\n }, new SolidityParam()).encode();\n};\n\n/**\n * Should be used to transform SolidityParam to plain param\n *\n * @method _formatOutput\n * @param {String} type\n * @param {SolidityParam} param\n * @return {Object} plain param\n */\nSolidityCoder.prototype._formatOutput = function (type, param) {\n return this._requireType(type).formatOutput(param, isArrayType(type));\n};\n\n/**\n * Should be used to decode bytes to plain param\n *\n * @method decodeParam\n * @param {String} type\n * @param {String} bytes\n * @return {Object} plain param\n */\nSolidityCoder.prototype.decodeParam = function (type, bytes) {\n return this._formatOutput(type, this._bytesToParam([type], bytes));\n};\n\n/**\n * Should be used to decode list of params\n *\n * @method decodeParam\n * @param {Array} types\n * @param {String} bytes\n * @return {Array} array of plain params\n */\nSolidityCoder.prototype.decodeParams = function (types, bytes) {\n var self = this;\n var param = this._bytesToParam(types, bytes);\n return types.map(function (type) {\n var solidityType = self._requireType(type);\n var p = solidityType.shiftParam(type, param);\n return solidityType.formatOutput(p, isArrayType(type));\n });\n};\n\nvar coder = new SolidityCoder([\n new SolidityType({\n name: 'address',\n match: 'strict',\n mode: 'value',\n inputFormatter: f.formatInputInt,\n outputFormatter: f.formatOutputAddress\n }),\n new SolidityType({\n name: 'bool',\n match: 'strict',\n mode: 'value',\n inputFormatter: f.formatInputBool,\n outputFormatter: f.formatOutputBool\n }),\n new SolidityType({\n name: 'int',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputInt,\n outputFormatter: f.formatOutputInt,\n }),\n new SolidityType({\n name: 'uint',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputInt,\n outputFormatter: f.formatOutputUInt\n }),\n new SolidityType({\n name: 'bytes',\n match: 'strict',\n mode: 'bytes',\n inputFormatter: f.formatInputDynamicBytes,\n outputFormatter: f.formatOutputDynamicBytes\n }),\n new SolidityType({\n name: 'bytes',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputBytes,\n outputFormatter: f.formatOutputBytes\n }),\n new SolidityType({\n name: 'real',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputReal,\n outputFormatter: f.formatOutputReal\n }),\n new SolidityType({\n name: 'ureal',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputReal,\n outputFormatter: f.formatOutputUReal\n })\n]);\n\nmodule.exports = coder;\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file formatters.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar BigNumber = require('bignumber.js');\nvar utils = require('../utils/utils');\nvar c = require('../utils/config');\nvar SolidityParam = require('./param');\n\n\n/**\n * Formats input value to byte representation of int\n * If value is negative, return it's two's complement\n * If the value is floating point, round it down\n *\n * @method formatInputInt\n * @param {String|Number|BigNumber} value that needs to be formatted\n * @returns {SolidityParam}\n */\nvar formatInputInt = function (value) {\n var padding = c.ETH_PADDING * 2;\n BigNumber.config(c.ETH_BIGNUMBER_ROUNDING_MODE);\n var result = utils.padLeft(utils.toTwosComplement(value).round().toString(16), padding);\n return new SolidityParam(result);\n};\n\n/**\n * Formats input value to byte representation of string\n *\n * @method formatInputBytes\n * @param {String}\n * @returns {SolidityParam}\n */\nvar formatInputBytes = function (value) {\n var result = utils.fromAscii(value, c.ETH_PADDING).substr(2);\n return new SolidityParam(result);\n};\n\n/**\n * Formats input value to byte representation of string\n *\n * @method formatInputDynamicBytes\n * @param {String}\n * @returns {SolidityParam}\n */\nvar formatInputDynamicBytes = function (value) {\n var result = utils.fromAscii(value, c.ETH_PADDING).substr(2);\n return new SolidityParam('', formatInputInt(value.length).value, result);\n};\n\n/**\n * Formats input value to byte representation of bool\n *\n * @method formatInputBool\n * @param {Boolean}\n * @returns {SolidityParam}\n */\nvar formatInputBool = function (value) {\n var result = '000000000000000000000000000000000000000000000000000000000000000' + (value ? '1' : '0');\n return new SolidityParam(result);\n};\n\n/**\n * Formats input value to byte representation of real\n * Values are multiplied by 2^m and encoded as integers\n *\n * @method formatInputReal\n * @param {String|Number|BigNumber}\n * @returns {SolidityParam}\n */\nvar formatInputReal = function (value) {\n return formatInputInt(new BigNumber(value).times(new BigNumber(2).pow(128)));\n};\n\n/**\n * Check if input value is negative\n *\n * @method signedIsNegative\n * @param {String} value is hex format\n * @returns {Boolean} true if it is negative, otherwise false\n */\nvar signedIsNegative = function (value) {\n return (new BigNumber(value.substr(0, 1), 16).toString(2).substr(0, 1)) === '1';\n};\n\n/**\n * Formats right-aligned output bytes to int\n *\n * @method formatOutputInt\n * @param {SolidityParam} param\n * @returns {BigNumber} right-aligned output bytes formatted to big number\n */\nvar formatOutputInt = function (param) {\n var value = param.value || \"0\";\n\n // check if it's negative number\n // it it is, return two's complement\n if (signedIsNegative(value)) {\n return new BigNumber(value, 16).minus(new BigNumber('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16)).minus(1);\n }\n return new BigNumber(value, 16);\n};\n\n/**\n * Formats right-aligned output bytes to uint\n *\n * @method formatOutputUInt\n * @param {SolidityParam}\n * @returns {BigNumeber} right-aligned output bytes formatted to uint\n */\nvar formatOutputUInt = function (param) {\n var value = param.value || \"0\";\n return new BigNumber(value, 16);\n};\n\n/**\n * Formats right-aligned output bytes to real\n *\n * @method formatOutputReal\n * @param {SolidityParam}\n * @returns {BigNumber} input bytes formatted to real\n */\nvar formatOutputReal = function (param) {\n return formatOutputInt(param).dividedBy(new BigNumber(2).pow(128)); \n};\n\n/**\n * Formats right-aligned output bytes to ureal\n *\n * @method formatOutputUReal\n * @param {SolidityParam}\n * @returns {BigNumber} input bytes formatted to ureal\n */\nvar formatOutputUReal = function (param) {\n return formatOutputUInt(param).dividedBy(new BigNumber(2).pow(128)); \n};\n\n/**\n * Should be used to format output bool\n *\n * @method formatOutputBool\n * @param {SolidityParam}\n * @returns {Boolean} right-aligned input bytes formatted to bool\n */\nvar formatOutputBool = function (param) {\n return param.value === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false;\n};\n\n/**\n * Should be used to format output string\n *\n * @method formatOutputBytes\n * @param {SolidityParam} left-aligned hex representation of string\n * @returns {String} ascii string\n */\nvar formatOutputBytes = function (param) {\n // length might also be important!\n return utils.toAscii(param.value);\n};\n\n/**\n * Should be used to format output string\n *\n * @method formatOutputDynamicBytes\n * @param {SolidityParam} left-aligned hex representation of string\n * @returns {String} ascii string\n */\nvar formatOutputDynamicBytes = function (param) {\n // length might also be important!\n return utils.toAscii(param.suffix);\n};\n\n/**\n * Should be used to format output address\n *\n * @method formatOutputAddress\n * @param {SolidityParam} right-aligned input bytes\n * @returns {String} address\n */\nvar formatOutputAddress = function (param) {\n var value = param.value;\n return \"0x\" + value.slice(value.length - 40, value.length);\n};\n\nmodule.exports = {\n formatInputInt: formatInputInt,\n formatInputBytes: formatInputBytes,\n formatInputDynamicBytes: formatInputDynamicBytes,\n formatInputBool: formatInputBool,\n formatInputReal: formatInputReal,\n formatOutputInt: formatOutputInt,\n formatOutputUInt: formatOutputUInt,\n formatOutputReal: formatOutputReal,\n formatOutputUReal: formatOutputUReal,\n formatOutputBool: formatOutputBool,\n formatOutputBytes: formatOutputBytes,\n formatOutputDynamicBytes: formatOutputDynamicBytes,\n formatOutputAddress: formatOutputAddress\n};\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file param.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\n/**\n * SolidityParam object prototype.\n * Should be used when encoding, decoding solidity bytes\n */\nvar SolidityParam = function (value, prefix, suffix) {\n this.prefix = prefix || '';\n this.value = value || '';\n this.suffix = suffix || '';\n};\n\n/**\n * This method should be used to encode two params one after another\n *\n * @method append\n * @param {SolidityParam} param that it appended after this\n */\nSolidityParam.prototype.append = function (param) {\n this.prefix += param.prefix;\n this.value += param.value;\n this.suffix += param.suffix;\n};\n\n/**\n * This method should be used to encode next param in an array\n *\n * @method appendArrayElement\n * @param {SolidityParam} param that is appended to an array\n */\nSolidityParam.prototype.appendArrayElement = function (param) {\n this.suffix += param.value;\n this.prefix += param.prefix;\n // TODO: suffix not supported = it's required for nested arrays;\n};\n\n/**\n * This method should be used to create bytearrays from param\n *\n * @method encode\n * @return {String} encoded param(s)\n */\nSolidityParam.prototype.encode = function () {\n return this.prefix + this.value + this.suffix;\n};\n\n/**\n * This method should be used to shift first param from group of params\n *\n * @method shiftValue\n * @return {SolidityParam} first value param\n */\nSolidityParam.prototype.shiftValue = function () {\n var value = this.value.slice(0, 64);\n this.value = this.value.slice(64);\n return new SolidityParam(value);\n};\n\n/**\n * This method should be used to first bytes param from group of params\n *\n * @method shiftBytes\n * @return {SolidityParam} first bytes param\n */\nSolidityParam.prototype.shiftBytes = function () {\n return this.shiftArray(1); \n};\n\n/**\n * This method should be used to shift an array from group of params \n * \n * @method shiftArray\n * @param {Number} size of an array to shift\n * @return {SolidityParam} first array param\n */\nSolidityParam.prototype.shiftArray = function (length) {\n var prefix = this.prefix.slice(0, 64);\n this.prefix = this.value.slice(64);\n var suffix = this.suffix.slice(0, 64 * length);\n this.suffix = this.suffix.slice(64 * length);\n return new SolidityParam('', prefix, suffix);\n};\n\nmodule.exports = SolidityParam;\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/**\n * @file utils.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\n/**\n * Returns the contstructor with matching number of arguments\n *\n * @method getConstructor\n * @param {Array} abi\n * @param {Number} numberOfArgs\n * @returns {Object} constructor function abi\n */\nvar getConstructor = function (abi, numberOfArgs) {\n return abi.filter(function (f) {\n return f.type === 'constructor' && f.inputs.length === numberOfArgs;\n })[0];\n};\n\nmodule.exports = {\n getConstructor: getConstructor\n};\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file abi.js\n * @author Marek Kotewicz \n * @author Gav Wood \n * @date 2014\n */\n\nvar coder = require('./coder');\nvar utils = require('./utils');\n\nvar formatConstructorParams = function (abi, params) {\n var constructor = utils.getConstructor(abi, params.length);\n if (!constructor) {\n if (params.length > 0) {\n console.warn(\"didn't found matching constructor, using default one\");\n }\n return '';\n }\n\n return coder.encodeParams(constructor.inputs.map(function (input) {\n return input.type;\n }), params);\n};\n\nmodule.exports = {\n formatConstructorParams: formatConstructorParams\n};\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file coder.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar BigNumber = require('bignumber.js');\nvar utils = require('../utils/utils');\nvar f = require('./formatters');\nvar SolidityParam = require('./param');\n\n/**\n * Should be used to check if a type is an array type\n *\n * @method isArrayType\n * @param {String} type\n * @return {Bool} true is the type is an array, otherwise false\n */\nvar isArrayType = function (type) {\n return type.slice(-2) === '[]';\n};\n\n/**\n * SolidityType prototype is used to encode/decode solidity params of certain type\n */\nvar SolidityType = function (config) {\n this._name = config.name;\n this._match = config.match;\n this._mode = config.mode;\n this._inputFormatter = config.inputFormatter;\n this._outputFormatter = config.outputFormatter;\n};\n\n/**\n * Should be used to determine if this SolidityType do match given type\n *\n * @method isType\n * @param {String} name\n * @return {Bool} true if type match this SolidityType, otherwise false\n */\nSolidityType.prototype.isType = function (name) {\n if (this._match === 'strict') {\n return this._name === name || (name.indexOf(this._name) === 0 && name.slice(this._name.length) === '[]');\n } else if (this._match === 'prefix') {\n // TODO better type detection!\n return name.indexOf(this._name) === 0;\n }\n};\n\n/**\n * Should be used to transform plain param to SolidityParam object\n *\n * @method formatInput\n * @param {Object} param - plain object, or an array of objects\n * @param {Bool} arrayType - true if a param should be encoded as an array\n * @return {SolidityParam} encoded param wrapped in SolidityParam object \n */\nSolidityType.prototype.formatInput = function (param, arrayType) {\n if (utils.isArray(param) && arrayType) { // TODO: should fail if this two are not the same\n var self = this;\n return param.map(function (p) {\n return self._inputFormatter(p);\n }).reduce(function (acc, current) {\n return acc.combine(current);\n }, f.formatInputInt(param.length)).withOffset(32);\n } \n return this._inputFormatter(param);\n};\n\n/**\n * Should be used to transoform SolidityParam to plain param\n *\n * @method formatOutput\n * @param {SolidityParam} byteArray\n * @param {Bool} arrayType - true if a param should be decoded as an array\n * @return {Object} plain decoded param\n */\nSolidityType.prototype.formatOutput = function (param, arrayType) {\n if (arrayType) {\n // let's assume, that we solidity will never return long arrays :P \n var result = [];\n var length = new BigNumber(param.dynamicPart().slice(0, 64), 16);\n for (var i = 0; i < length * 64; i += 64) {\n result.push(this._outputFormatter(new SolidityParam(param.dynamicPart().substr(i + 64, 64))));\n }\n return result;\n }\n return this._outputFormatter(param);\n};\n\n/**\n * Should be used to slice single param from bytes\n *\n * @method sliceParam\n * @param {String} bytes\n * @param {Number} index of param to slice\n * @param {String} type\n * @returns {SolidityParam} param\n */\nSolidityType.prototype.sliceParam = function (bytes, index, type) {\n if (this._mode === 'bytes') {\n return SolidityParam.decodeBytes(bytes, index);\n } else if (isArrayType(type)) {\n return SolidityParam.decodeArray(bytes, index);\n }\n return SolidityParam.decodeParam(bytes, index);\n};\n\n/**\n * SolidityCoder prototype should be used to encode/decode solidity params of any type\n */\nvar SolidityCoder = function (types) {\n this._types = types;\n};\n\n/**\n * This method should be used to transform type to SolidityType\n *\n * @method _requireType\n * @param {String} type\n * @returns {SolidityType} \n * @throws {Error} throws if no matching type is found\n */\nSolidityCoder.prototype._requireType = function (type) {\n var solidityType = this._types.filter(function (t) {\n return t.isType(type);\n })[0];\n\n if (!solidityType) {\n throw Error('invalid solidity type!: ' + type);\n }\n\n return solidityType;\n};\n\n/**\n * Should be used to transform plain param of given type to SolidityParam\n *\n * @method _formatInput\n * @param {String} type of param\n * @param {Object} plain param\n * @return {SolidityParam}\n */\nSolidityCoder.prototype._formatInput = function (type, param) {\n return this._requireType(type).formatInput(param, isArrayType(type));\n};\n\n/**\n * Should be used to encode plain param\n *\n * @method encodeParam\n * @param {String} type\n * @param {Object} plain param\n * @return {String} encoded plain param\n */\nSolidityCoder.prototype.encodeParam = function (type, param) {\n return this._formatInput(type, param).encode();\n};\n\n/**\n * Should be used to encode list of params\n *\n * @method encodeParams\n * @param {Array} types\n * @param {Array} params\n * @return {String} encoded list of params\n */\nSolidityCoder.prototype.encodeParams = function (types, params) {\n var self = this;\n var solidityParams = types.map(function (type, index) {\n return self._formatInput(type, params[index]);\n });\n\n return SolidityParam.encodeList(solidityParams);\n};\n\n/**\n * Should be used to decode bytes to plain param\n *\n * @method decodeParam\n * @param {String} type\n * @param {String} bytes\n * @return {Object} plain param\n */\nSolidityCoder.prototype.decodeParam = function (type, bytes) {\n return this.decodeParams([type], bytes)[0];\n};\n\n/**\n * Should be used to decode list of params\n *\n * @method decodeParam\n * @param {Array} types\n * @param {String} bytes\n * @return {Array} array of plain params\n */\nSolidityCoder.prototype.decodeParams = function (types, bytes) {\n var self = this;\n return types.map(function (type, index) {\n var solidityType = self._requireType(type);\n var p = solidityType.sliceParam(bytes, index, type);\n return solidityType.formatOutput(p, isArrayType(type));\n });\n};\n\nvar coder = new SolidityCoder([\n new SolidityType({\n name: 'address',\n match: 'strict',\n mode: 'value',\n inputFormatter: f.formatInputInt,\n outputFormatter: f.formatOutputAddress\n }),\n new SolidityType({\n name: 'bool',\n match: 'strict',\n mode: 'value',\n inputFormatter: f.formatInputBool,\n outputFormatter: f.formatOutputBool\n }),\n new SolidityType({\n name: 'int',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputInt,\n outputFormatter: f.formatOutputInt,\n }),\n new SolidityType({\n name: 'uint',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputInt,\n outputFormatter: f.formatOutputUInt\n }),\n new SolidityType({\n name: 'bytes',\n match: 'strict',\n mode: 'bytes',\n inputFormatter: f.formatInputDynamicBytes,\n outputFormatter: f.formatOutputDynamicBytes\n }),\n new SolidityType({\n name: 'bytes',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputBytes,\n outputFormatter: f.formatOutputBytes\n }),\n new SolidityType({\n name: 'real',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputReal,\n outputFormatter: f.formatOutputReal\n }),\n new SolidityType({\n name: 'ureal',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputReal,\n outputFormatter: f.formatOutputUReal\n })\n]);\n\nmodule.exports = coder;\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file formatters.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar BigNumber = require('bignumber.js');\nvar utils = require('../utils/utils');\nvar c = require('../utils/config');\nvar SolidityParam = require('./param');\n\n\n/**\n * Formats input value to byte representation of int\n * If value is negative, return it's two's complement\n * If the value is floating point, round it down\n *\n * @method formatInputInt\n * @param {String|Number|BigNumber} value that needs to be formatted\n * @returns {SolidityParam}\n */\nvar formatInputInt = function (value) {\n var padding = c.ETH_PADDING * 2;\n BigNumber.config(c.ETH_BIGNUMBER_ROUNDING_MODE);\n var result = utils.padLeft(utils.toTwosComplement(value).round().toString(16), padding);\n return new SolidityParam(result);\n};\n\n/**\n * Formats input value to byte representation of string\n *\n * @method formatInputBytes\n * @param {String}\n * @returns {SolidityParam}\n */\nvar formatInputBytes = function (value) {\n var result = utils.fromAscii(value, c.ETH_PADDING).substr(2);\n return new SolidityParam(result);\n};\n\n/**\n * Formats input value to byte representation of string\n *\n * @method formatInputDynamicBytes\n * @param {String}\n * @returns {SolidityParam}\n */\nvar formatInputDynamicBytes = function (value) {\n var result = utils.fromAscii(value, c.ETH_PADDING).substr(2);\n return new SolidityParam(formatInputInt(value.length).value + result, 32);\n};\n\n/**\n * Formats input value to byte representation of bool\n *\n * @method formatInputBool\n * @param {Boolean}\n * @returns {SolidityParam}\n */\nvar formatInputBool = function (value) {\n var result = '000000000000000000000000000000000000000000000000000000000000000' + (value ? '1' : '0');\n return new SolidityParam(result);\n};\n\n/**\n * Formats input value to byte representation of real\n * Values are multiplied by 2^m and encoded as integers\n *\n * @method formatInputReal\n * @param {String|Number|BigNumber}\n * @returns {SolidityParam}\n */\nvar formatInputReal = function (value) {\n return formatInputInt(new BigNumber(value).times(new BigNumber(2).pow(128)));\n};\n\n/**\n * Check if input value is negative\n *\n * @method signedIsNegative\n * @param {String} value is hex format\n * @returns {Boolean} true if it is negative, otherwise false\n */\nvar signedIsNegative = function (value) {\n return (new BigNumber(value.substr(0, 1), 16).toString(2).substr(0, 1)) === '1';\n};\n\n/**\n * Formats right-aligned output bytes to int\n *\n * @method formatOutputInt\n * @param {SolidityParam} param\n * @returns {BigNumber} right-aligned output bytes formatted to big number\n */\nvar formatOutputInt = function (param) {\n var value = param.staticPart() || \"0\";\n\n // check if it's negative number\n // it it is, return two's complement\n if (signedIsNegative(value)) {\n return new BigNumber(value, 16).minus(new BigNumber('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16)).minus(1);\n }\n return new BigNumber(value, 16);\n};\n\n/**\n * Formats right-aligned output bytes to uint\n *\n * @method formatOutputUInt\n * @param {SolidityParam}\n * @returns {BigNumeber} right-aligned output bytes formatted to uint\n */\nvar formatOutputUInt = function (param) {\n var value = param.staticPart() || \"0\";\n return new BigNumber(value, 16);\n};\n\n/**\n * Formats right-aligned output bytes to real\n *\n * @method formatOutputReal\n * @param {SolidityParam}\n * @returns {BigNumber} input bytes formatted to real\n */\nvar formatOutputReal = function (param) {\n return formatOutputInt(param).dividedBy(new BigNumber(2).pow(128)); \n};\n\n/**\n * Formats right-aligned output bytes to ureal\n *\n * @method formatOutputUReal\n * @param {SolidityParam}\n * @returns {BigNumber} input bytes formatted to ureal\n */\nvar formatOutputUReal = function (param) {\n return formatOutputUInt(param).dividedBy(new BigNumber(2).pow(128)); \n};\n\n/**\n * Should be used to format output bool\n *\n * @method formatOutputBool\n * @param {SolidityParam}\n * @returns {Boolean} right-aligned input bytes formatted to bool\n */\nvar formatOutputBool = function (param) {\n return param.staticPart() === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false;\n};\n\n/**\n * Should be used to format output string\n *\n * @method formatOutputBytes\n * @param {SolidityParam} left-aligned hex representation of string\n * @returns {String} ascii string\n */\nvar formatOutputBytes = function (param) {\n // length might also be important!\n return utils.toAscii(param.staticPart());\n};\n\n/**\n * Should be used to format output string\n *\n * @method formatOutputDynamicBytes\n * @param {SolidityParam} left-aligned hex representation of string\n * @returns {String} ascii string\n */\nvar formatOutputDynamicBytes = function (param) {\n // length might also be important!\n return utils.toAscii(param.dynamicPart().slice(64));\n};\n\n/**\n * Should be used to format output address\n *\n * @method formatOutputAddress\n * @param {SolidityParam} right-aligned input bytes\n * @returns {String} address\n */\nvar formatOutputAddress = function (param) {\n var value = param.staticPart();\n return \"0x\" + value.slice(value.length - 40, value.length);\n};\n\nmodule.exports = {\n formatInputInt: formatInputInt,\n formatInputBytes: formatInputBytes,\n formatInputDynamicBytes: formatInputDynamicBytes,\n formatInputBool: formatInputBool,\n formatInputReal: formatInputReal,\n formatOutputInt: formatOutputInt,\n formatOutputUInt: formatOutputUInt,\n formatOutputReal: formatOutputReal,\n formatOutputUReal: formatOutputUReal,\n formatOutputBool: formatOutputBool,\n formatOutputBytes: formatOutputBytes,\n formatOutputDynamicBytes: formatOutputDynamicBytes,\n formatOutputAddress: formatOutputAddress\n};\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file param.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar utils = require('../utils/utils');\n\n/**\n * SolidityParam object prototype.\n * Should be used when encoding, decoding solidity bytes\n */\nvar SolidityParam = function (value, offset) {\n this.value = value || '';\n this.offset = offset; // offset in bytes\n};\n\n/**\n * This method should be used to get length of params's dynamic part\n * \n * @method dynamicPartLength\n * @returns {Number} length of dynamic part (in bytes)\n */\nSolidityParam.prototype.dynamicPartLength = function () {\n return this.dynamicPart().length / 2;\n};\n\n/**\n * This method should be used to create copy of solidity param with different offset\n *\n * @method withOffset\n * @param {Number} offset length in bytes\n * @returns {SolidityParam} new solidity param with applied offset\n */\nSolidityParam.prototype.withOffset = function (offset) {\n return new SolidityParam(this.value, offset);\n};\n\n/**\n * This method should be used to combine solidity params together\n * eg. when appending an array\n *\n * @method combine\n * @param {SolidityParam} param with which we should combine\n * @param {SolidityParam} result of combination\n */\nSolidityParam.prototype.combine = function (param) {\n return new SolidityParam(this.value + param.value); \n};\n\n/**\n * This method should be called to check if param has dynamic size.\n * If it has, it returns true, otherwise false\n *\n * @method isDynamic\n * @returns {Boolean}\n */\nSolidityParam.prototype.isDynamic = function () {\n return this.value.length > 64;\n};\n\n/**\n * This method should be called to transform offset to bytes\n *\n * @method offsetAsBytes\n * @returns {String} bytes representation of offset\n */\nSolidityParam.prototype.offsetAsBytes = function () {\n return !this.isDynamic() ? '' : utils.padLeft(utils.toTwosComplement(this.offset).toString(16), 64);\n};\n\n/**\n * This method should be called to get static part of param\n *\n * @method staticPart\n * @returns {String} offset if it is a dynamic param, otherwise value\n */\nSolidityParam.prototype.staticPart = function () {\n if (!this.isDynamic()) {\n return this.value; \n } \n return this.offsetAsBytes();\n};\n\n/**\n * This method should be called to get dynamic part of param\n *\n * @method dynamicPart\n * @returns {String} returns a value if it is a dynamic param, otherwise empty string\n */\nSolidityParam.prototype.dynamicPart = function () {\n return this.isDynamic() ? this.value : '';\n};\n\n/**\n * This method should be called to encode param\n *\n * @method encode\n * @returns {String}\n */\nSolidityParam.prototype.encode = function () {\n return this.staticPart() + this.dynamicPart();\n};\n\n/**\n * This method should be called to encode array of params\n *\n * @method encodeList\n * @param {Array[SolidityParam]} params\n * @returns {String}\n */\nSolidityParam.encodeList = function (params) {\n \n // updating offsets\n var totalOffset = params.length * 32;\n var offsetParams = params.map(function (param) {\n if (!param.isDynamic()) {\n return param;\n }\n var offset = totalOffset;\n totalOffset += param.dynamicPartLength();\n return param.withOffset(offset);\n });\n\n // encode everything!\n return offsetParams.reduce(function (result, param) {\n return result + param.dynamicPart();\n }, offsetParams.reduce(function (result, param) {\n return result + param.staticPart();\n }, ''));\n};\n\n/**\n * This method should be used to decode plain (static) solidity param at given index\n *\n * @method decodeParam\n * @param {String} bytes\n * @param {Number} index\n * @returns {SolidityParam}\n */\nSolidityParam.decodeParam = function (bytes, index) {\n index = index || 0;\n return new SolidityParam(bytes.substr(index * 64, 64)); \n};\n\n/**\n * This method should be called to get offset value from bytes at given index\n *\n * @method getOffset\n * @param {String} bytes\n * @param {Number} index\n * @returns {Number} offset as number\n */\nvar getOffset = function (bytes, index) {\n // we can do this cause offset is rather small\n return parseInt('0x' + bytes.substr(index * 64, 64));\n};\n\n/**\n * This method should be called to decode solidity bytes param at given index\n *\n * @method decodeBytes\n * @param {String} bytes\n * @param {Number} index\n * @returns {SolidityParam}\n */\nSolidityParam.decodeBytes = function (bytes, index) {\n index = index || 0;\n //TODO add support for strings longer than 32 bytes\n //var length = parseInt('0x' + bytes.substr(offset * 64, 64));\n\n var offset = getOffset(bytes, index);\n\n // 2 * , cause we also parse length\n return new SolidityParam(bytes.substr(offset * 2, 2 * 64));\n};\n\n/**\n * This method should be used to decode solidity array at given index\n *\n * @method decodeArray\n * @param {String} bytes\n * @param {Number} index\n * @returns {SolidityParam}\n */\nSolidityParam.decodeArray = function (bytes, index) {\n index = index || 0;\n var offset = getOffset(bytes, index);\n var length = parseInt('0x' + bytes.substr(offset * 2, 64));\n return new SolidityParam(bytes.substr(offset * 2, (length + 1) * 64));\n};\n\nmodule.exports = SolidityParam;\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/**\n * @file utils.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\n/**\n * Returns the contstructor with matching number of arguments\n *\n * @method getConstructor\n * @param {Array} abi\n * @param {Number} numberOfArgs\n * @returns {Object} constructor function abi\n */\nvar getConstructor = function (abi, numberOfArgs) {\n return abi.filter(function (f) {\n return f.type === 'constructor' && f.inputs.length === numberOfArgs;\n })[0];\n};\n\n//var getSupremeType = function (type) {\n //return type.substr(0, type.indexOf('[')) + ']';\n//};\n\n\nmodule.exports = {\n getConstructor: getConstructor\n};\n\n", "'use strict';\n\n// go env doesn't have and need XMLHttpRequest\nif (typeof XMLHttpRequest === 'undefined') {\n exports.XMLHttpRequest = {};\n} else {\n exports.XMLHttpRequest = XMLHttpRequest; // jshint ignore:line\n}\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file config.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\n/**\n * Utils\n * \n * @module utils\n */\n\n/**\n * Utility functions\n * \n * @class [utils] config\n * @constructor\n */\n\n/// required to define ETH_BIGNUMBER_ROUNDING_MODE\nvar BigNumber = require('bignumber.js');\n\nvar ETH_UNITS = [ \n 'wei', \n 'Kwei', \n 'Mwei', \n 'Gwei', \n 'szabo', \n 'finney', \n 'ether', \n 'grand', \n 'Mether', \n 'Gether', \n 'Tether', \n 'Pether', \n 'Eether', \n 'Zether', \n 'Yether', \n 'Nether', \n 'Dether', \n 'Vether', \n 'Uether' \n];\n\nmodule.exports = {\n ETH_PADDING: 32,\n ETH_SIGNATURE_LENGTH: 4,\n ETH_UNITS: ETH_UNITS,\n ETH_BIGNUMBER_ROUNDING_MODE: { ROUNDING_MODE: BigNumber.ROUND_DOWN },\n ETH_POLLING_TIMEOUT: 1000,\n defaultBlock: 'latest',\n defaultAccount: undefined\n};\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file utils.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\n/**\n * Utils\n * \n * @module utils\n */\n\n/**\n * Utility functions\n * \n * @class [utils] utils\n * @constructor\n */\n\nvar BigNumber = require('bignumber.js');\n\nvar unitMap = {\n 'wei': '1',\n 'kwei': '1000',\n 'ada': '1000',\n 'mwei': '1000000',\n 'babbage': '1000000',\n 'gwei': '1000000000',\n 'shannon': '1000000000',\n 'szabo': '1000000000000',\n 'finney': '1000000000000000',\n 'ether': '1000000000000000000',\n 'kether': '1000000000000000000000',\n 'grand': '1000000000000000000000',\n 'einstein': '1000000000000000000000',\n 'mether': '1000000000000000000000000',\n 'gether': '1000000000000000000000000000',\n 'tether': '1000000000000000000000000000000'\n};\n\n/**\n * Should be called to pad string to expected length\n *\n * @method padLeft\n * @param {String} string to be padded\n * @param {Number} characters that result string should have\n * @param {String} sign, by default 0\n * @returns {String} right aligned string\n */\nvar padLeft = function (string, chars, sign) {\n return new Array(chars - string.length + 1).join(sign ? sign : \"0\") + string;\n};\n\n/** \n * Should be called to get sting from it's hex representation\n *\n * @method toAscii\n * @param {String} string in hex\n * @returns {String} ascii string representation of hex value\n */\nvar toAscii = function(hex) {\n// Find termination\n var str = \"\";\n var i = 0, l = hex.length;\n if (hex.substring(0, 2) === '0x') {\n i = 2;\n }\n for (; i < l; i+=2) {\n var code = parseInt(hex.substr(i, 2), 16);\n if (code === 0) {\n break;\n }\n\n str += String.fromCharCode(code);\n }\n\n return str;\n};\n \n/**\n * Shold be called to get hex representation (prefixed by 0x) of ascii string \n *\n * @method toHexNative\n * @param {String} string\n * @returns {String} hex representation of input string\n */\nvar toHexNative = function(str) {\n var hex = \"\";\n for(var i = 0; i < str.length; i++) {\n var n = str.charCodeAt(i).toString(16);\n hex += n.length < 2 ? '0' + n : n;\n }\n\n return hex;\n};\n\n/**\n * Shold be called to get hex representation (prefixed by 0x) of ascii string \n *\n * @method fromAscii\n * @param {String} string\n * @param {Number} optional padding\n * @returns {String} hex representation of input string\n */\nvar fromAscii = function(str, pad) {\n pad = pad === undefined ? 0 : pad;\n var hex = toHexNative(str);\n while (hex.length < pad*2)\n hex += \"00\";\n return \"0x\" + hex;\n};\n\n/**\n * Should be used to create full function/event name from json abi\n *\n * @method transformToFullName\n * @param {Object} json-abi\n * @return {String} full fnction/event name\n */\nvar transformToFullName = function (json) {\n if (json.name.indexOf('(') !== -1) {\n return json.name;\n }\n\n var typeName = json.inputs.map(function(i){return i.type; }).join();\n return json.name + '(' + typeName + ')';\n};\n\n/**\n * Should be called to get display name of contract function\n * \n * @method extractDisplayName\n * @param {String} name of function/event\n * @returns {String} display name for function/event eg. multiply(uint256) -> multiply\n */\nvar extractDisplayName = function (name) {\n var length = name.indexOf('('); \n return length !== -1 ? name.substr(0, length) : name;\n};\n\n/// @returns overloaded part of function/event name\nvar extractTypeName = function (name) {\n /// TODO: make it invulnerable\n var length = name.indexOf('(');\n return length !== -1 ? name.substr(length + 1, name.length - 1 - (length + 1)).replace(' ', '') : \"\";\n};\n\n/**\n * Converts value to it's decimal representation in string\n *\n * @method toDecimal\n * @param {String|Number|BigNumber}\n * @return {String}\n */\nvar toDecimal = function (value) {\n return toBigNumber(value).toNumber();\n};\n\n/**\n * Converts value to it's hex representation\n *\n * @method fromDecimal\n * @param {String|Number|BigNumber}\n * @return {String}\n */\nvar fromDecimal = function (value) {\n var number = toBigNumber(value);\n var result = number.toString(16);\n\n return number.lessThan(0) ? '-0x' + result.substr(1) : '0x' + result;\n};\n\n/**\n * Auto converts any given value into it's hex representation.\n *\n * And even stringifys objects before.\n *\n * @method toHex\n * @param {String|Number|BigNumber|Object}\n * @return {String}\n */\nvar toHex = function (val) {\n /*jshint maxcomplexity:7 */\n\n if (isBoolean(val))\n return fromDecimal(+val);\n\n if (isBigNumber(val))\n return fromDecimal(val);\n\n if (isObject(val))\n return fromAscii(JSON.stringify(val));\n\n // if its a negative number, pass it through fromDecimal\n if (isString(val)) {\n if (val.indexOf('-0x') === 0)\n return fromDecimal(val);\n else if (!isFinite(val))\n return fromAscii(val);\n }\n\n return fromDecimal(val);\n};\n\n/**\n * Returns value of unit in Wei\n *\n * @method getValueOfUnit\n * @param {String} unit the unit to convert to, default ether\n * @returns {BigNumber} value of the unit (in Wei)\n * @throws error if the unit is not correct:w\n */\nvar getValueOfUnit = function (unit) {\n unit = unit ? unit.toLowerCase() : 'ether';\n var unitValue = unitMap[unit];\n if (unitValue === undefined) {\n throw new Error('This unit doesn\\'t exists, please use the one of the following units' + JSON.stringify(unitMap, null, 2));\n }\n return new BigNumber(unitValue, 10);\n};\n\n/**\n * Takes a number of wei and converts it to any other ether unit.\n *\n * Possible units are:\n * - kwei/ada\n * - mwei/babbage\n * - gwei/shannon\n * - szabo\n * - finney\n * - ether\n * - kether/grand/einstein\n * - mether\n * - gether\n * - tether\n *\n * @method fromWei\n * @param {Number|String} number can be a number, number string or a HEX of a decimal\n * @param {String} unit the unit to convert to, default ether\n * @return {String|Object} When given a BigNumber object it returns one as well, otherwise a number\n*/\nvar fromWei = function(number, unit) {\n var returnValue = toBigNumber(number).dividedBy(getValueOfUnit(unit));\n\n return isBigNumber(number) ? returnValue : returnValue.toString(10); \n};\n\n/**\n * Takes a number of a unit and converts it to wei.\n *\n * Possible units are:\n * - kwei/ada\n * - mwei/babbage\n * - gwei/shannon\n * - szabo\n * - finney\n * - ether\n * - kether/grand/einstein\n * - mether\n * - gether\n * - tether\n *\n * @method toWei\n * @param {Number|String|BigNumber} number can be a number, number string or a HEX of a decimal\n * @param {String} unit the unit to convert from, default ether\n * @return {String|Object} When given a BigNumber object it returns one as well, otherwise a number\n*/\nvar toWei = function(number, unit) {\n var returnValue = toBigNumber(number).times(getValueOfUnit(unit));\n\n return isBigNumber(number) ? returnValue : returnValue.toString(10); \n};\n\n/**\n * Takes an input and transforms it into an bignumber\n *\n * @method toBigNumber\n * @param {Number|String|BigNumber} a number, string, HEX string or BigNumber\n * @return {BigNumber} BigNumber\n*/\nvar toBigNumber = function(number) {\n /*jshint maxcomplexity:5 */\n number = number || 0;\n if (isBigNumber(number))\n return number;\n\n if (isString(number) && (number.indexOf('0x') === 0 || number.indexOf('-0x') === 0)) {\n return new BigNumber(number.replace('0x',''), 16);\n }\n \n return new BigNumber(number.toString(10), 10);\n};\n\n/**\n * Takes and input transforms it into bignumber and if it is negative value, into two's complement\n *\n * @method toTwosComplement\n * @param {Number|String|BigNumber}\n * @return {BigNumber}\n */\nvar toTwosComplement = function (number) {\n var bigNumber = toBigNumber(number);\n if (bigNumber.lessThan(0)) {\n return new BigNumber(\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\", 16).plus(bigNumber).plus(1);\n }\n return bigNumber;\n};\n\n/**\n * Checks if the given string is strictly an address\n *\n * @method isStrictAddress\n * @param {String} address the given HEX adress\n * @return {Boolean}\n*/\nvar isStrictAddress = function (address) {\n return /^0x[0-9a-f]{40}$/.test(address);\n};\n\n/**\n * Checks if the given string is an address\n *\n * @method isAddress\n * @param {String} address the given HEX adress\n * @return {Boolean}\n*/\nvar isAddress = function (address) {\n return /^(0x)?[0-9a-f]{40}$/.test(address);\n};\n\n/**\n * Transforms given string to valid 20 bytes-length addres with 0x prefix\n *\n * @method toAddress\n * @param {String} address\n * @return {String} formatted address\n */\nvar toAddress = function (address) {\n if (isStrictAddress(address)) {\n return address;\n }\n \n if (/^[0-9a-f]{40}$/.test(address)) {\n return '0x' + address;\n }\n\n return '0x' + padLeft(toHex(address).substr(2), 40);\n};\n\n/**\n * Returns true if object is BigNumber, otherwise false\n *\n * @method isBigNumber\n * @param {Object}\n * @return {Boolean} \n */\nvar isBigNumber = function (object) {\n return object instanceof BigNumber ||\n (object && object.constructor && object.constructor.name === 'BigNumber');\n};\n\n/**\n * Returns true if object is string, otherwise false\n * \n * @method isString\n * @param {Object}\n * @return {Boolean}\n */\nvar isString = function (object) {\n return typeof object === 'string' ||\n (object && object.constructor && object.constructor.name === 'String');\n};\n\n/**\n * Returns true if object is function, otherwise false\n *\n * @method isFunction\n * @param {Object}\n * @return {Boolean}\n */\nvar isFunction = function (object) {\n return typeof object === 'function';\n};\n\n/**\n * Returns true if object is Objet, otherwise false\n *\n * @method isObject\n * @param {Object}\n * @return {Boolean}\n */\nvar isObject = function (object) {\n return typeof object === 'object';\n};\n\n/**\n * Returns true if object is boolean, otherwise false\n *\n * @method isBoolean\n * @param {Object}\n * @return {Boolean}\n */\nvar isBoolean = function (object) {\n return typeof object === 'boolean';\n};\n\n/**\n * Returns true if object is array, otherwise false\n *\n * @method isArray\n * @param {Object}\n * @return {Boolean}\n */\nvar isArray = function (object) {\n return object instanceof Array; \n};\n\n/**\n * Returns true if given string is valid json object\n * \n * @method isJson\n * @param {String}\n * @return {Boolean}\n */\nvar isJson = function (str) {\n try {\n return !!JSON.parse(str);\n } catch (e) {\n return false;\n }\n};\n\nmodule.exports = {\n padLeft: padLeft,\n toHex: toHex,\n toDecimal: toDecimal,\n fromDecimal: fromDecimal,\n toAscii: toAscii,\n fromAscii: fromAscii,\n transformToFullName: transformToFullName,\n extractDisplayName: extractDisplayName,\n extractTypeName: extractTypeName,\n toWei: toWei,\n fromWei: fromWei,\n toBigNumber: toBigNumber,\n toTwosComplement: toTwosComplement,\n toAddress: toAddress,\n isBigNumber: isBigNumber,\n isStrictAddress: isStrictAddress,\n isAddress: isAddress,\n isFunction: isFunction,\n isString: isString,\n isObject: isObject,\n isBoolean: isBoolean,\n isArray: isArray,\n isJson: isJson\n};\n\n", - "module.exports={\n \"version\": \"0.3.3\"\n}\n", + "module.exports={\n \"version\": \"0.3.6\"\n}\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file web3.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * Fabian Vogelsteller \n * Gav Wood \n * @date 2014\n */\n\nvar version = require('./version.json');\nvar net = require('./web3/net');\nvar eth = require('./web3/eth');\nvar db = require('./web3/db');\nvar shh = require('./web3/shh');\nvar watches = require('./web3/watches');\nvar Filter = require('./web3/filter');\nvar utils = require('./utils/utils');\nvar formatters = require('./web3/formatters');\nvar RequestManager = require('./web3/requestmanager');\nvar c = require('./utils/config');\nvar Method = require('./web3/method');\nvar Property = require('./web3/property');\n\nvar web3Methods = [\n new Method({\n name: 'sha3',\n call: 'web3_sha3',\n params: 1\n })\n];\n\nvar web3Properties = [\n new Property({\n name: 'version.client',\n getter: 'web3_clientVersion'\n }),\n new Property({\n name: 'version.network',\n getter: 'net_version',\n inputFormatter: utils.toDecimal\n }),\n new Property({\n name: 'version.ethereum',\n getter: 'eth_protocolVersion',\n inputFormatter: utils.toDecimal\n }),\n new Property({\n name: 'version.whisper',\n getter: 'shh_version',\n inputFormatter: utils.toDecimal\n })\n];\n\n/// creates methods in a given object based on method description on input\n/// setups api calls for these methods\nvar setupMethods = function (obj, methods) {\n methods.forEach(function (method) {\n method.attachToObject(obj);\n });\n};\n\n/// creates properties in a given object based on properties description on input\n/// setups api calls for these properties\nvar setupProperties = function (obj, properties) {\n properties.forEach(function (property) {\n property.attachToObject(obj);\n });\n};\n\n/// setups web3 object, and it's in-browser executed methods\nvar web3 = {};\nweb3.providers = {};\nweb3.version = {};\nweb3.version.api = version.version;\nweb3.eth = {};\n\n/*jshint maxparams:4 */\nweb3.eth.filter = function (fil, eventParams, options, formatter) {\n\n // if its event, treat it differently\n // TODO: simplify and remove\n if (fil._isEvent) {\n return fil(eventParams, options);\n }\n\n // what outputLogFormatter? that's wrong\n //return new Filter(fil, watches.eth(), formatters.outputLogFormatter);\n return new Filter(fil, watches.eth(), formatter || formatters.outputLogFormatter);\n};\n/*jshint maxparams:3 */\n\nweb3.shh = {};\nweb3.shh.filter = function (fil) {\n return new Filter(fil, watches.shh(), formatters.outputPostFormatter);\n};\nweb3.net = {};\nweb3.db = {};\nweb3.setProvider = function (provider) {\n RequestManager.getInstance().setProvider(provider);\n};\nweb3.reset = function () {\n RequestManager.getInstance().reset();\n c.defaultBlock = 'latest';\n c.defaultAccount = undefined;\n};\nweb3.toHex = utils.toHex;\nweb3.toAscii = utils.toAscii;\nweb3.fromAscii = utils.fromAscii;\nweb3.toDecimal = utils.toDecimal;\nweb3.fromDecimal = utils.fromDecimal;\nweb3.toBigNumber = utils.toBigNumber;\nweb3.toWei = utils.toWei;\nweb3.fromWei = utils.fromWei;\nweb3.isAddress = utils.isAddress;\n\n// ADD defaultblock\nObject.defineProperty(web3.eth, 'defaultBlock', {\n get: function () {\n return c.defaultBlock;\n },\n set: function (val) {\n c.defaultBlock = val;\n return val;\n }\n});\n\nObject.defineProperty(web3.eth, 'defaultAccount', {\n get: function () {\n return c.defaultAccount;\n },\n set: function (val) {\n c.defaultAccount = val;\n return val;\n }\n});\n\n/// setups all api methods\nsetupMethods(web3, web3Methods);\nsetupProperties(web3, web3Properties);\nsetupMethods(web3.net, net.methods);\nsetupProperties(web3.net, net.properties);\nsetupMethods(web3.eth, eth.methods);\nsetupProperties(web3.eth, eth.properties);\nsetupMethods(web3.db, db.methods);\nsetupMethods(web3.shh, shh.methods);\n\nmodule.exports = web3;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file contract.js\n * @author Marek Kotewicz \n * @date 2014\n */\n\nvar web3 = require('../web3'); \nvar solAbi = require('../solidity/abi');\nvar utils = require('../utils/utils');\nvar SolidityEvent = require('./event');\nvar SolidityFunction = require('./function');\n\nvar addFunctionsToContract = function (contract, desc) {\n desc.filter(function (json) {\n return json.type === 'function';\n }).map(function (json) {\n return new SolidityFunction(json, contract.address);\n }).forEach(function (f) {\n f.attachToContract(contract);\n });\n};\n\nvar addEventsToContract = function (contract, desc) {\n desc.filter(function (json) {\n return json.type === 'event';\n }).map(function (json) {\n return new SolidityEvent(json, contract.address);\n }).forEach(function (e) {\n e.attachToContract(contract);\n });\n};\n\n/**\n * This method should be called when we want to call / transact some solidity method from javascript\n * it returns an object which has same methods available as solidity contract description\n * usage example: \n *\n * var abi = [{\n * name: 'myMethod',\n * inputs: [{ name: 'a', type: 'string' }],\n * outputs: [{name: 'd', type: 'string' }]\n * }]; // contract abi\n *\n * var MyContract = web3.eth.contract(abi); // creation of contract prototype\n *\n * var contractInstance = new MyContract('0x0123123121');\n *\n * contractInstance.myMethod('this is test string param for call'); // myMethod call (implicit, default)\n * contractInstance.call().myMethod('this is test string param for call'); // myMethod call (explicit)\n * contractInstance.sendTransaction().myMethod('this is test string param for transact'); // myMethod sendTransaction\n *\n * @param abi - abi json description of the contract, which is being created\n * @returns contract object\n */\nvar contract = function (abi) {\n\n // return prototype\n return Contract.bind(null, abi);\n};\n\nvar Contract = function (abi, options) {\n\n this.address = '';\n if (utils.isAddress(options)) {\n this.address = options;\n } else { // is an object!\n // TODO, parse the rest of the args\n options = options || {};\n var args = Array.prototype.slice.call(arguments, 2);\n var bytes = solAbi.formatConstructorParams(abi, args);\n options.data += bytes;\n this.address = web3.eth.sendTransaction(options);\n }\n\n addFunctionsToContract(this, abi);\n addEventsToContract(this, abi);\n};\n\nContract.prototype.call = function () {\n console.error('contract.call is deprecated');\n return this;\n};\n\nContract.prototype.sendTransaction = function () {\n console.error('contract.sendTransact is deprecated');\n return this;\n};\n\nmodule.exports = contract;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file db.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\nvar Method = require('./method');\n\nvar putString = new Method({\n name: 'putString',\n call: 'db_putString',\n params: 3\n});\n\n\nvar getString = new Method({\n name: 'getString',\n call: 'db_getString',\n params: 2\n});\n\nvar putHex = new Method({\n name: 'putHex',\n call: 'db_putHex',\n params: 3\n});\n\nvar getHex = new Method({\n name: 'getHex',\n call: 'db_getHex',\n params: 2\n});\n\nvar methods = [\n putString, getString, putHex, getHex\n];\n\nmodule.exports = {\n methods: methods\n};\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file errors.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nmodule.exports = {\n InvalidNumberOfParams: function () {\n return new Error('Invalid number of input parameters');\n },\n InvalidConnection: function (host){\n return new Error('CONNECTION ERROR: Couldn\\'t connect to node '+ host +', is it running?');\n },\n InvalidProvider: function () {\n return new Error('Providor not set or invalid');\n },\n InvalidResponse: function (result){\n var message = !!result && !!result.error && !!result.error.message ? result.error.message : 'Invalid JSON RPC response';\n return new Error(message);\n }\n};\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/**\n * @file eth.js\n * @author Marek Kotewicz \n * @author Fabian Vogelsteller \n * @date 2015\n */\n\n/**\n * Web3\n * \n * @module web3\n */\n\n/**\n * Eth methods and properties\n *\n * An example method object can look as follows:\n *\n * {\n * name: 'getBlock',\n * call: blockCall,\n * params: 2,\n * outputFormatter: formatters.outputBlockFormatter,\n * inputFormatter: [ // can be a formatter funciton or an array of functions. Where each item in the array will be used for one parameter\n * utils.toHex, // formats paramter 1\n * function(param){ return !!param; } // formats paramter 2\n * ]\n * },\n *\n * @class [web3] eth\n * @constructor\n */\n\n\"use strict\";\n\nvar formatters = require('./formatters');\nvar utils = require('../utils/utils');\nvar Method = require('./method');\nvar Property = require('./property');\n\nvar blockCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? \"eth_getBlockByHash\" : \"eth_getBlockByNumber\";\n};\n\nvar transactionFromBlockCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getTransactionByBlockHashAndIndex' : 'eth_getTransactionByBlockNumberAndIndex';\n};\n\nvar uncleCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleByBlockHashAndIndex' : 'eth_getUncleByBlockNumberAndIndex';\n};\n\nvar getBlockTransactionCountCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getBlockTransactionCountByHash' : 'eth_getBlockTransactionCountByNumber';\n};\n\nvar uncleCountCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleCountByBlockHash' : 'eth_getUncleCountByBlockNumber';\n};\n\n/// @returns an array of objects describing web3.eth api methods\n\nvar getBalance = new Method({\n name: 'getBalance', \n call: 'eth_getBalance', \n params: 2,\n inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter],\n outputFormatter: formatters.outputBigNumberFormatter\n});\n\nvar getStorageAt = new Method({\n name: 'getStorageAt', \n call: 'eth_getStorageAt', \n params: 3,\n inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar getCode = new Method({\n name: 'getCode',\n call: 'eth_getCode',\n params: 2,\n inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar getBlock = new Method({\n name: 'getBlock', \n call: blockCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }],\n outputFormatter: formatters.outputBlockFormatter\n});\n\nvar getUncle = new Method({\n name: 'getUncle',\n call: uncleCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex],\n outputFormatter: formatters.outputBlockFormatter,\n\n});\n\nvar getCompilers = new Method({\n name: 'getCompilers',\n call: 'eth_getCompilers',\n params: 0\n});\n\nvar getBlockTransactionCount = new Method({\n name: 'getBlockTransactionCount',\n call: getBlockTransactionCountCall,\n params: 1,\n inputFormatter: [formatters.inputBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar getBlockUncleCount = new Method({\n name: 'getBlockUncleCount',\n call: uncleCountCall,\n params: 1,\n inputFormatter: [formatters.inputBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar getTransaction = new Method({\n name: 'getTransaction',\n call: 'eth_getTransactionByHash',\n params: 1,\n outputFormatter: formatters.outputTransactionFormatter\n});\n\nvar getTransactionFromBlock = new Method({\n name: 'getTransactionFromBlock',\n call: transactionFromBlockCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex],\n outputFormatter: formatters.outputTransactionFormatter\n});\n\nvar getTransactionCount = new Method({\n name: 'getTransactionCount',\n call: 'eth_getTransactionCount',\n params: 2,\n inputFormatter: [null, formatters.inputDefaultBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar sendTransaction = new Method({\n name: 'sendTransaction',\n call: 'eth_sendTransaction',\n params: 1,\n inputFormatter: [formatters.inputTransactionFormatter]\n});\n\nvar call = new Method({\n name: 'call',\n call: 'eth_call',\n params: 2,\n inputFormatter: [formatters.inputTransactionFormatter, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar compileSolidity = new Method({\n name: 'compile.solidity',\n call: 'eth_compileSolidity',\n params: 1\n});\n\nvar compileLLL = new Method({\n name: 'compile.lll',\n call: 'eth_compileLLL',\n params: 1\n});\n\nvar compileSerpent = new Method({\n name: 'compile.serpent',\n call: 'eth_compileSerpent',\n params: 1\n});\n\nvar methods = [\n getBalance,\n getStorageAt,\n getCode,\n getBlock,\n getUncle,\n getCompilers,\n getBlockTransactionCount,\n getBlockUncleCount,\n getTransaction,\n getTransactionFromBlock,\n getTransactionCount,\n call,\n sendTransaction,\n compileSolidity,\n compileLLL,\n compileSerpent,\n];\n\n/// @returns an array of objects describing web3.eth api properties\n\n\n\nvar properties = [\n new Property({\n name: 'coinbase',\n getter: 'eth_coinbase'\n }),\n new Property({\n name: 'mining',\n getter: 'eth_mining'\n }),\n new Property({\n name: 'gasPrice',\n getter: 'eth_gasPrice',\n outputFormatter: formatters.outputBigNumberFormatter\n }),\n new Property({\n name: 'accounts',\n getter: 'eth_accounts'\n }),\n new Property({\n name: 'blockNumber',\n getter: 'eth_blockNumber',\n outputFormatter: utils.toDecimal\n })\n];\n\nmodule.exports = {\n methods: methods,\n properties: properties\n};\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file event.js\n * @author Marek Kotewicz \n * @date 2014\n */\n\nvar utils = require('../utils/utils');\nvar coder = require('../solidity/coder');\nvar web3 = require('../web3');\nvar formatters = require('./formatters');\n\n/**\n * This prototype should be used to create event filters\n */\nvar SolidityEvent = function (json, address) {\n this._params = json.inputs;\n this._name = utils.transformToFullName(json);\n this._address = address;\n this._anonymous = json.anonymous;\n};\n\n/**\n * Should be used to get filtered param types\n *\n * @method types\n * @param {Bool} decide if returned typed should be indexed\n * @return {Array} array of types\n */\nSolidityEvent.prototype.types = function (indexed) {\n return this._params.filter(function (i) {\n return i.indexed === indexed;\n }).map(function (i) {\n return i.type;\n });\n};\n\n/**\n * Should be used to get event display name\n *\n * @method displayName\n * @return {String} event display name\n */\nSolidityEvent.prototype.displayName = function () {\n return utils.extractDisplayName(this._name);\n};\n\n/**\n * Should be used to get event type name\n *\n * @method typeName\n * @return {String} event type name\n */\nSolidityEvent.prototype.typeName = function () {\n return utils.extractTypeName(this._name);\n};\n\n/**\n * Should be used to get event signature\n *\n * @method signature\n * @return {String} event signature\n */\nSolidityEvent.prototype.signature = function () {\n return web3.sha3(web3.fromAscii(this._name)).slice(2);\n};\n\n/**\n * Should be used to encode indexed params and options to one final object\n * \n * @method encode\n * @param {Object} indexed\n * @param {Object} options\n * @return {Object} everything combined together and encoded\n */\nSolidityEvent.prototype.encode = function (indexed, options) {\n indexed = indexed || {};\n options = options || {};\n var result = {};\n\n ['fromBlock', 'toBlock'].filter(function (f) {\n return options[f] !== undefined;\n }).forEach(function (f) {\n result[f] = utils.toHex(options[f]);\n });\n\n result.topics = [];\n\n if (!this._anonymous) {\n result.address = this._address;\n result.topics.push('0x' + this.signature());\n }\n\n var indexedTopics = this._params.filter(function (i) {\n return i.indexed === true;\n }).map(function (i) {\n var value = indexed[i.name];\n if (value === undefined || value === null) {\n return null;\n }\n \n if (utils.isArray(value)) {\n return value.map(function (v) {\n return '0x' + coder.encodeParam(i.type, v);\n });\n }\n return '0x' + coder.encodeParam(i.type, value);\n });\n\n result.topics = result.topics.concat(indexedTopics);\n\n return result;\n};\n\n/**\n * Should be used to decode indexed params and options\n *\n * @method decode\n * @param {Object} data\n * @return {Object} result object with decoded indexed && not indexed params\n */\nSolidityEvent.prototype.decode = function (data) {\n \n data.data = data.data || '';\n data.topics = data.topics || [];\n\n var argTopics = this._anonymous ? data.topics : data.topics.slice(1);\n var indexedData = argTopics.map(function (topics) { return topics.slice(2); }).join(\"\");\n var indexedParams = coder.decodeParams(this.types(true), indexedData); \n\n var notIndexedData = data.data.slice(2);\n var notIndexedParams = coder.decodeParams(this.types(false), notIndexedData);\n \n var result = formatters.outputLogFormatter(data);\n result.event = this.displayName();\n result.address = data.address;\n\n result.args = this._params.reduce(function (acc, current) {\n acc[current.name] = current.indexed ? indexedParams.shift() : notIndexedParams.shift();\n return acc;\n }, {});\n\n delete result.data;\n delete result.topics;\n\n return result;\n};\n\n/**\n * Should be used to create new filter object from event\n *\n * @method execute\n * @param {Object} indexed\n * @param {Object} options\n * @return {Object} filter object\n */\nSolidityEvent.prototype.execute = function (indexed, options) {\n var o = this.encode(indexed, options);\n var formatter = this.decode.bind(this);\n return web3.eth.filter(o, undefined, undefined, formatter);\n};\n\n/**\n * Should be used to attach event to contract object\n *\n * @method attachToContract\n * @param {Contract}\n */\nSolidityEvent.prototype.attachToContract = function (contract) {\n var execute = this.execute.bind(this);\n var displayName = this.displayName();\n if (!contract[displayName]) {\n contract[displayName] = execute;\n }\n contract[displayName][this.typeName()] = this.execute.bind(this, contract);\n};\n\nmodule.exports = SolidityEvent;\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/**\n * @file eth.js\n * @author Marek Kotewicz \n * @author Fabian Vogelsteller \n * @date 2015\n */\n\n/**\n * Web3\n *\n * @module web3\n */\n\n/**\n * Eth methods and properties\n *\n * An example method object can look as follows:\n *\n * {\n * name: 'getBlock',\n * call: blockCall,\n * params: 2,\n * outputFormatter: formatters.outputBlockFormatter,\n * inputFormatter: [ // can be a formatter funciton or an array of functions. Where each item in the array will be used for one parameter\n * utils.toHex, // formats paramter 1\n * function(param){ return !!param; } // formats paramter 2\n * ]\n * },\n *\n * @class [web3] eth\n * @constructor\n */\n\n\"use strict\";\n\nvar formatters = require('./formatters');\nvar utils = require('../utils/utils');\nvar Method = require('./method');\nvar Property = require('./property');\n\nvar blockCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? \"eth_getBlockByHash\" : \"eth_getBlockByNumber\";\n};\n\nvar transactionFromBlockCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getTransactionByBlockHashAndIndex' : 'eth_getTransactionByBlockNumberAndIndex';\n};\n\nvar uncleCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleByBlockHashAndIndex' : 'eth_getUncleByBlockNumberAndIndex';\n};\n\nvar getBlockTransactionCountCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getBlockTransactionCountByHash' : 'eth_getBlockTransactionCountByNumber';\n};\n\nvar uncleCountCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleCountByBlockHash' : 'eth_getUncleCountByBlockNumber';\n};\n\n/// @returns an array of objects describing web3.eth api methods\n\nvar getBalance = new Method({\n name: 'getBalance',\n call: 'eth_getBalance',\n params: 2,\n inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter],\n outputFormatter: formatters.outputBigNumberFormatter\n});\n\nvar getStorageAt = new Method({\n name: 'getStorageAt',\n call: 'eth_getStorageAt',\n params: 3,\n inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar getCode = new Method({\n name: 'getCode',\n call: 'eth_getCode',\n params: 2,\n inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar getBlock = new Method({\n name: 'getBlock',\n call: blockCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }],\n outputFormatter: formatters.outputBlockFormatter\n});\n\nvar getUncle = new Method({\n name: 'getUncle',\n call: uncleCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex],\n outputFormatter: formatters.outputBlockFormatter,\n\n});\n\nvar getCompilers = new Method({\n name: 'getCompilers',\n call: 'eth_getCompilers',\n params: 0\n});\n\nvar getBlockTransactionCount = new Method({\n name: 'getBlockTransactionCount',\n call: getBlockTransactionCountCall,\n params: 1,\n inputFormatter: [formatters.inputBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar getBlockUncleCount = new Method({\n name: 'getBlockUncleCount',\n call: uncleCountCall,\n params: 1,\n inputFormatter: [formatters.inputBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar getTransaction = new Method({\n name: 'getTransaction',\n call: 'eth_getTransactionByHash',\n params: 1,\n outputFormatter: formatters.outputTransactionFormatter\n});\n\nvar getTransactionFromBlock = new Method({\n name: 'getTransactionFromBlock',\n call: transactionFromBlockCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex],\n outputFormatter: formatters.outputTransactionFormatter\n});\n\nvar getTransactionCount = new Method({\n name: 'getTransactionCount',\n call: 'eth_getTransactionCount',\n params: 2,\n inputFormatter: [null, formatters.inputDefaultBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar sendTransaction = new Method({\n name: 'sendTransaction',\n call: 'eth_sendTransaction',\n params: 1,\n inputFormatter: [formatters.inputTransactionFormatter]\n});\n\nvar call = new Method({\n name: 'call',\n call: 'eth_call',\n params: 2,\n inputFormatter: [formatters.inputTransactionFormatter, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar compileSolidity = new Method({\n name: 'compile.solidity',\n call: 'eth_compileSolidity',\n params: 1\n});\n\nvar compileLLL = new Method({\n name: 'compile.lll',\n call: 'eth_compileLLL',\n params: 1\n});\n\nvar compileSerpent = new Method({\n name: 'compile.serpent',\n call: 'eth_compileSerpent',\n params: 1\n});\n\nvar methods = [\n getBalance,\n getStorageAt,\n getCode,\n getBlock,\n getUncle,\n getCompilers,\n getBlockTransactionCount,\n getBlockUncleCount,\n getTransaction,\n getTransactionFromBlock,\n getTransactionCount,\n call,\n sendTransaction,\n compileSolidity,\n compileLLL,\n compileSerpent,\n];\n\n/// @returns an array of objects describing web3.eth api properties\n\n\n\nvar properties = [\n new Property({\n name: 'coinbase',\n getter: 'eth_coinbase'\n }),\n new Property({\n name: 'mining',\n getter: 'eth_mining'\n }),\n new Property({\n name: 'hashrate',\n getter: 'eth_hashrate',\n outputFormatter: utils.toDecimal\n }),\n new Property({\n name: 'gasPrice',\n getter: 'eth_gasPrice',\n outputFormatter: formatters.outputBigNumberFormatter\n }),\n new Property({\n name: 'accounts',\n getter: 'eth_accounts'\n }),\n new Property({\n name: 'blockNumber',\n getter: 'eth_blockNumber',\n outputFormatter: utils.toDecimal\n })\n];\n\nmodule.exports = {\n methods: methods,\n properties: properties\n};\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file event.js\n * @author Marek Kotewicz \n * @date 2014\n */\n\nvar utils = require('../utils/utils');\nvar coder = require('../solidity/coder');\nvar web3 = require('../web3');\nvar formatters = require('./formatters');\n\n/**\n * This prototype should be used to create event filters\n */\nvar SolidityEvent = function (json, address) {\n this._params = json.inputs;\n this._name = utils.transformToFullName(json);\n this._address = address;\n this._anonymous = json.anonymous;\n};\n\n/**\n * Should be used to get filtered param types\n *\n * @method types\n * @param {Bool} decide if returned typed should be indexed\n * @return {Array} array of types\n */\nSolidityEvent.prototype.types = function (indexed) {\n return this._params.filter(function (i) {\n return i.indexed === indexed;\n }).map(function (i) {\n return i.type;\n });\n};\n\n/**\n * Should be used to get event display name\n *\n * @method displayName\n * @return {String} event display name\n */\nSolidityEvent.prototype.displayName = function () {\n return utils.extractDisplayName(this._name);\n};\n\n/**\n * Should be used to get event type name\n *\n * @method typeName\n * @return {String} event type name\n */\nSolidityEvent.prototype.typeName = function () {\n return utils.extractTypeName(this._name);\n};\n\n/**\n * Should be used to get event signature\n *\n * @method signature\n * @return {String} event signature\n */\nSolidityEvent.prototype.signature = function () {\n return web3.sha3(web3.fromAscii(this._name)).slice(2);\n};\n\n/**\n * Should be used to encode indexed params and options to one final object\n * \n * @method encode\n * @param {Object} indexed\n * @param {Object} options\n * @return {Object} everything combined together and encoded\n */\nSolidityEvent.prototype.encode = function (indexed, options) {\n indexed = indexed || {};\n options = options || {};\n var result = {};\n\n ['fromBlock', 'toBlock'].filter(function (f) {\n return options[f] !== undefined;\n }).forEach(function (f) {\n result[f] = formatters.inputBlockNumberFormatter(options[f]);\n });\n\n result.topics = [];\n\n if (!this._anonymous) {\n result.address = this._address;\n result.topics.push('0x' + this.signature());\n }\n\n var indexedTopics = this._params.filter(function (i) {\n return i.indexed === true;\n }).map(function (i) {\n var value = indexed[i.name];\n if (value === undefined || value === null) {\n return null;\n }\n \n if (utils.isArray(value)) {\n return value.map(function (v) {\n return '0x' + coder.encodeParam(i.type, v);\n });\n }\n return '0x' + coder.encodeParam(i.type, value);\n });\n\n result.topics = result.topics.concat(indexedTopics);\n\n return result;\n};\n\n/**\n * Should be used to decode indexed params and options\n *\n * @method decode\n * @param {Object} data\n * @return {Object} result object with decoded indexed && not indexed params\n */\nSolidityEvent.prototype.decode = function (data) {\n \n data.data = data.data || '';\n data.topics = data.topics || [];\n\n var argTopics = this._anonymous ? data.topics : data.topics.slice(1);\n var indexedData = argTopics.map(function (topics) { return topics.slice(2); }).join(\"\");\n var indexedParams = coder.decodeParams(this.types(true), indexedData); \n\n var notIndexedData = data.data.slice(2);\n var notIndexedParams = coder.decodeParams(this.types(false), notIndexedData);\n \n var result = formatters.outputLogFormatter(data);\n result.event = this.displayName();\n result.address = data.address;\n\n result.args = this._params.reduce(function (acc, current) {\n acc[current.name] = current.indexed ? indexedParams.shift() : notIndexedParams.shift();\n return acc;\n }, {});\n\n delete result.data;\n delete result.topics;\n\n return result;\n};\n\n/**\n * Should be used to create new filter object from event\n *\n * @method execute\n * @param {Object} indexed\n * @param {Object} options\n * @return {Object} filter object\n */\nSolidityEvent.prototype.execute = function (indexed, options) {\n var o = this.encode(indexed, options);\n var formatter = this.decode.bind(this);\n return web3.eth.filter(o, undefined, undefined, formatter);\n};\n\n/**\n * Should be used to attach event to contract object\n *\n * @method attachToContract\n * @param {Contract}\n */\nSolidityEvent.prototype.attachToContract = function (contract) {\n var execute = this.execute.bind(this);\n var displayName = this.displayName();\n if (!contract[displayName]) {\n contract[displayName] = execute;\n }\n contract[displayName][this.typeName()] = this.execute.bind(this, contract);\n};\n\nmodule.exports = SolidityEvent;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file filter.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * Fabian Vogelsteller \n * Gav Wood \n * @date 2014\n */\n\nvar RequestManager = require('./requestmanager');\nvar formatters = require('./formatters');\nvar utils = require('../utils/utils');\n\n/**\n* Converts a given topic to a hex string, but also allows null values.\n*\n* @param {Mixed} value\n* @return {String}\n*/\nvar toTopic = function(value){\n\n if(value === null || typeof value === 'undefined')\n return null;\n\n value = String(value);\n\n if(value.indexOf('0x') === 0)\n return value;\n else\n return utils.fromAscii(value);\n};\n\n/// This method should be called on options object, to verify deprecated properties && lazy load dynamic ones\n/// @param should be string or object\n/// @returns options string or object\nvar getOptions = function (options) {\n\n if (utils.isString(options)) {\n return options;\n } \n\n options = options || {};\n\n // make sure topics, get converted to hex\n options.topics = options.topics || [];\n options.topics = options.topics.map(function(topic){\n return (utils.isArray(topic)) ? topic.map(toTopic) : toTopic(topic);\n });\n\n // lazy load\n return {\n topics: options.topics,\n to: options.to,\n address: options.address,\n fromBlock: formatters.inputBlockNumberFormatter(options.fromBlock),\n toBlock: formatters.inputBlockNumberFormatter(options.toBlock) \n }; \n};\n\nvar Filter = function (options, methods, formatter) {\n var implementation = {};\n methods.forEach(function (method) {\n method.attachToObject(implementation);\n });\n this.options = getOptions(options);\n this.implementation = implementation;\n this.callbacks = [];\n this.formatter = formatter;\n this.filterId = this.implementation.newFilter(this.options);\n};\n\nFilter.prototype.watch = function (callback) {\n this.callbacks.push(callback);\n var self = this;\n\n var onMessage = function (error, messages) {\n if (error) {\n return self.callbacks.forEach(function (callback) {\n callback(error);\n });\n }\n\n messages.forEach(function (message) {\n message = self.formatter ? self.formatter(message) : message;\n self.callbacks.forEach(function (callback) {\n callback(null, message);\n });\n });\n };\n\n // call getFilterLogs on start\n if (!utils.isString(this.options)) {\n this.get(function (err, messages) {\n // don't send all the responses to all the watches again... just to this one\n if (err) {\n callback(err);\n }\n\n messages.forEach(function (message) {\n callback(null, message);\n });\n });\n }\n\n RequestManager.getInstance().startPolling({\n method: this.implementation.poll.call,\n params: [this.filterId],\n }, this.filterId, onMessage, this.stopWatching.bind(this));\n};\n\nFilter.prototype.stopWatching = function () {\n RequestManager.getInstance().stopPolling(this.filterId);\n this.implementation.uninstallFilter(this.filterId);\n this.callbacks = [];\n};\n\nFilter.prototype.get = function (callback) {\n var self = this;\n if (utils.isFunction(callback)) {\n this.implementation.getLogs(this.filterId, function(err, res){\n if (err) {\n callback(err);\n } else {\n callback(null, res.map(function (log) {\n return self.formatter ? self.formatter(log) : log;\n }));\n }\n });\n } else {\n var logs = this.implementation.getLogs(this.filterId);\n return logs.map(function (log) {\n return self.formatter ? self.formatter(log) : log;\n });\n }\n};\n\nmodule.exports = Filter;\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file formatters.js\n * @author Marek Kotewicz \n * @author Fabian Vogelsteller \n * @date 2015\n */\n\nvar utils = require('../utils/utils');\nvar config = require('../utils/config');\n\n/**\n * Should the format output to a big number\n *\n * @method outputBigNumberFormatter\n * @param {String|Number|BigNumber}\n * @returns {BigNumber} object\n */\nvar outputBigNumberFormatter = function (number) {\n return utils.toBigNumber(number);\n};\n\nvar isPredefinedBlockNumber = function (blockNumber) {\n return blockNumber === 'latest' || blockNumber === 'pending' || blockNumber === 'earliest';\n};\n\nvar inputDefaultBlockNumberFormatter = function (blockNumber) {\n if (blockNumber === undefined) {\n return config.defaultBlock;\n }\n return inputBlockNumberFormatter(blockNumber);\n};\n\nvar inputBlockNumberFormatter = function (blockNumber) {\n if (blockNumber === undefined) {\n return undefined;\n } else if (isPredefinedBlockNumber(blockNumber)) {\n return blockNumber;\n }\n return utils.toHex(blockNumber);\n};\n\n/**\n * Formats the input of a transaction and converts all values to HEX\n *\n * @method inputTransactionFormatter\n * @param {Object} transaction options\n * @returns object\n*/\nvar inputTransactionFormatter = function (options){\n\n options.from = options.from || config.defaultAccount;\n\n // make code -> data\n if (options.code) {\n options.data = options.code;\n delete options.code;\n }\n\n ['gasPrice', 'gas', 'value'].filter(function (key) {\n return options[key] !== undefined;\n }).forEach(function(key){\n options[key] = utils.fromDecimal(options[key]);\n });\n\n return options; \n};\n\n/**\n * Formats the output of a transaction to its proper values\n * \n * @method outputTransactionFormatter\n * @param {Object} transaction\n * @returns {Object} transaction\n*/\nvar outputTransactionFormatter = function (tx){\n tx.blockNumber = utils.toDecimal(tx.blockNumber);\n tx.transactionIndex = utils.toDecimal(tx.transactionIndex);\n tx.nonce = utils.toDecimal(tx.nonce);\n tx.gas = utils.toDecimal(tx.gas);\n tx.gasPrice = utils.toBigNumber(tx.gasPrice);\n tx.value = utils.toBigNumber(tx.value);\n return tx;\n};\n\n/**\n * Formats the output of a block to its proper values\n *\n * @method outputBlockFormatter\n * @param {Object} block object \n * @returns {Object} block object\n*/\nvar outputBlockFormatter = function(block) {\n\n // transform to number\n block.gasLimit = utils.toDecimal(block.gasLimit);\n block.gasUsed = utils.toDecimal(block.gasUsed);\n block.size = utils.toDecimal(block.size);\n block.timestamp = utils.toDecimal(block.timestamp);\n block.number = utils.toDecimal(block.number);\n\n block.difficulty = utils.toBigNumber(block.difficulty);\n block.totalDifficulty = utils.toBigNumber(block.totalDifficulty);\n\n if (utils.isArray(block.transactions)) {\n block.transactions.forEach(function(item){\n if(!utils.isString(item))\n return outputTransactionFormatter(item);\n });\n }\n\n return block;\n};\n\n/**\n * Formats the output of a log\n * \n * @method outputLogFormatter\n * @param {Object} log object\n * @returns {Object} log\n*/\nvar outputLogFormatter = function(log) {\n if (log === null) { // 'pending' && 'latest' filters are nulls\n return null;\n }\n\n log.blockNumber = utils.toDecimal(log.blockNumber);\n log.transactionIndex = utils.toDecimal(log.transactionIndex);\n log.logIndex = utils.toDecimal(log.logIndex);\n\n return log;\n};\n\n/**\n * Formats the input of a whisper post and converts all values to HEX\n *\n * @method inputPostFormatter\n * @param {Object} transaction object\n * @returns {Object}\n*/\nvar inputPostFormatter = function(post) {\n\n post.payload = utils.toHex(post.payload);\n post.ttl = utils.fromDecimal(post.ttl);\n post.workToProve = utils.fromDecimal(post.workToProve);\n post.priority = utils.fromDecimal(post.priority);\n\n // fallback\n if (!utils.isArray(post.topics)) {\n post.topics = post.topics ? [post.topics] : [];\n }\n\n // format the following options\n post.topics = post.topics.map(function(topic){\n return utils.fromAscii(topic);\n });\n\n return post; \n};\n\n/**\n * Formats the output of a received post message\n *\n * @method outputPostFormatter\n * @param {Object}\n * @returns {Object}\n */\nvar outputPostFormatter = function(post){\n\n post.expiry = utils.toDecimal(post.expiry);\n post.sent = utils.toDecimal(post.sent);\n post.ttl = utils.toDecimal(post.ttl);\n post.workProved = utils.toDecimal(post.workProved);\n post.payloadRaw = post.payload;\n post.payload = utils.toAscii(post.payload);\n\n if (utils.isJson(post.payload)) {\n post.payload = JSON.parse(post.payload);\n }\n\n // format the following options\n if (!post.topics) {\n post.topics = [];\n }\n post.topics = post.topics.map(function(topic){\n return utils.toAscii(topic);\n });\n\n return post;\n};\n\nmodule.exports = {\n inputDefaultBlockNumberFormatter: inputDefaultBlockNumberFormatter,\n inputBlockNumberFormatter: inputBlockNumberFormatter,\n inputTransactionFormatter: inputTransactionFormatter,\n inputPostFormatter: inputPostFormatter,\n outputBigNumberFormatter: outputBigNumberFormatter,\n outputTransactionFormatter: outputTransactionFormatter,\n outputBlockFormatter: outputBlockFormatter,\n outputLogFormatter: outputLogFormatter,\n outputPostFormatter: outputPostFormatter\n};\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file formatters.js\n * @author Marek Kotewicz \n * @author Fabian Vogelsteller \n * @date 2015\n */\n\nvar utils = require('../utils/utils');\nvar config = require('../utils/config');\n\n/**\n * Should the format output to a big number\n *\n * @method outputBigNumberFormatter\n * @param {String|Number|BigNumber}\n * @returns {BigNumber} object\n */\nvar outputBigNumberFormatter = function (number) {\n return utils.toBigNumber(number);\n};\n\nvar isPredefinedBlockNumber = function (blockNumber) {\n return blockNumber === 'latest' || blockNumber === 'pending' || blockNumber === 'earliest';\n};\n\nvar inputDefaultBlockNumberFormatter = function (blockNumber) {\n if (blockNumber === undefined) {\n return config.defaultBlock;\n }\n return inputBlockNumberFormatter(blockNumber);\n};\n\nvar inputBlockNumberFormatter = function (blockNumber) {\n if (blockNumber === undefined) {\n return undefined;\n } else if (isPredefinedBlockNumber(blockNumber)) {\n return blockNumber;\n }\n return utils.toHex(blockNumber);\n};\n\n/**\n * Formats the input of a transaction and converts all values to HEX\n *\n * @method inputTransactionFormatter\n * @param {Object} transaction options\n * @returns object\n*/\nvar inputTransactionFormatter = function (options){\n\n options.from = options.from || config.defaultAccount;\n\n // make code -> data\n if (options.code) {\n options.data = options.code;\n delete options.code;\n }\n\n ['gasPrice', 'gas', 'value', 'nonce'].filter(function (key) {\n return options[key] !== undefined;\n }).forEach(function(key){\n options[key] = utils.fromDecimal(options[key]);\n });\n\n return options; \n};\n\n/**\n * Formats the output of a transaction to its proper values\n * \n * @method outputTransactionFormatter\n * @param {Object} transaction\n * @returns {Object} transaction\n*/\nvar outputTransactionFormatter = function (tx){\n tx.blockNumber = utils.toDecimal(tx.blockNumber);\n tx.transactionIndex = utils.toDecimal(tx.transactionIndex);\n tx.nonce = utils.toDecimal(tx.nonce);\n tx.gas = utils.toDecimal(tx.gas);\n tx.gasPrice = utils.toBigNumber(tx.gasPrice);\n tx.value = utils.toBigNumber(tx.value);\n return tx;\n};\n\n/**\n * Formats the output of a block to its proper values\n *\n * @method outputBlockFormatter\n * @param {Object} block object \n * @returns {Object} block object\n*/\nvar outputBlockFormatter = function(block) {\n\n // transform to number\n block.gasLimit = utils.toDecimal(block.gasLimit);\n block.gasUsed = utils.toDecimal(block.gasUsed);\n block.size = utils.toDecimal(block.size);\n block.timestamp = utils.toDecimal(block.timestamp);\n block.number = utils.toDecimal(block.number);\n\n block.difficulty = utils.toBigNumber(block.difficulty);\n block.totalDifficulty = utils.toBigNumber(block.totalDifficulty);\n\n if (utils.isArray(block.transactions)) {\n block.transactions.forEach(function(item){\n if(!utils.isString(item))\n return outputTransactionFormatter(item);\n });\n }\n\n return block;\n};\n\n/**\n * Formats the output of a log\n * \n * @method outputLogFormatter\n * @param {Object} log object\n * @returns {Object} log\n*/\nvar outputLogFormatter = function(log) {\n if (log === null) { // 'pending' && 'latest' filters are nulls\n return null;\n }\n\n log.blockNumber = utils.toDecimal(log.blockNumber);\n log.transactionIndex = utils.toDecimal(log.transactionIndex);\n log.logIndex = utils.toDecimal(log.logIndex);\n\n return log;\n};\n\n/**\n * Formats the input of a whisper post and converts all values to HEX\n *\n * @method inputPostFormatter\n * @param {Object} transaction object\n * @returns {Object}\n*/\nvar inputPostFormatter = function(post) {\n\n post.payload = utils.toHex(post.payload);\n post.ttl = utils.fromDecimal(post.ttl);\n post.workToProve = utils.fromDecimal(post.workToProve);\n post.priority = utils.fromDecimal(post.priority);\n\n // fallback\n if (!utils.isArray(post.topics)) {\n post.topics = post.topics ? [post.topics] : [];\n }\n\n // format the following options\n post.topics = post.topics.map(function(topic){\n return utils.fromAscii(topic);\n });\n\n return post; \n};\n\n/**\n * Formats the output of a received post message\n *\n * @method outputPostFormatter\n * @param {Object}\n * @returns {Object}\n */\nvar outputPostFormatter = function(post){\n\n post.expiry = utils.toDecimal(post.expiry);\n post.sent = utils.toDecimal(post.sent);\n post.ttl = utils.toDecimal(post.ttl);\n post.workProved = utils.toDecimal(post.workProved);\n post.payloadRaw = post.payload;\n post.payload = utils.toAscii(post.payload);\n\n if (utils.isJson(post.payload)) {\n post.payload = JSON.parse(post.payload);\n }\n\n // format the following options\n if (!post.topics) {\n post.topics = [];\n }\n post.topics = post.topics.map(function(topic){\n return utils.toAscii(topic);\n });\n\n return post;\n};\n\nmodule.exports = {\n inputDefaultBlockNumberFormatter: inputDefaultBlockNumberFormatter,\n inputBlockNumberFormatter: inputBlockNumberFormatter,\n inputTransactionFormatter: inputTransactionFormatter,\n inputPostFormatter: inputPostFormatter,\n outputBigNumberFormatter: outputBigNumberFormatter,\n outputTransactionFormatter: outputTransactionFormatter,\n outputBlockFormatter: outputBlockFormatter,\n outputLogFormatter: outputLogFormatter,\n outputPostFormatter: outputPostFormatter\n};\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \n * @file function.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar web3 = require('../web3');\nvar coder = require('../solidity/coder');\nvar utils = require('../utils/utils');\n\n/**\n * This prototype should be used to call/sendTransaction to solidity functions\n */\nvar SolidityFunction = function (json, address) {\n this._inputTypes = json.inputs.map(function (i) {\n return i.type;\n });\n this._outputTypes = json.outputs.map(function (i) {\n return i.type;\n });\n this._constant = json.constant;\n this._name = utils.transformToFullName(json);\n this._address = address;\n};\n\n/**\n * Should be used to create payload from arguments\n *\n * @method toPayload\n * @param {...} solidity function params\n * @param {Object} optional payload options\n */\nSolidityFunction.prototype.toPayload = function () {\n var args = Array.prototype.slice.call(arguments);\n var options = {};\n if (args.length > this._inputTypes.length && utils.isObject(args[args.length -1])) {\n options = args.pop();\n }\n options.to = this._address;\n options.data = '0x' + this.signature() + coder.encodeParams(this._inputTypes, args);\n return options;\n};\n\n/**\n * Should be used to get function signature\n *\n * @method signature\n * @return {String} function signature\n */\nSolidityFunction.prototype.signature = function () {\n return web3.sha3(web3.fromAscii(this._name)).slice(2, 10);\n};\n\n/**\n * Should be used to call function\n * \n * @method call\n * @param {Object} options\n * @return {String} output bytes\n */\nSolidityFunction.prototype.call = function () {\n var payload = this.toPayload.apply(this, Array.prototype.slice.call(arguments));\n var output = web3.eth.call(payload);\n output = output.length >= 2 ? output.slice(2) : output;\n var result = coder.decodeParams(this._outputTypes, output);\n return result.length === 1 ? result[0] : result;\n};\n\n/**\n * Should be used to sendTransaction to solidity function\n *\n * @method sendTransaction\n * @param {Object} options\n */\nSolidityFunction.prototype.sendTransaction = function () {\n var payload = this.toPayload.apply(this, Array.prototype.slice.call(arguments));\n web3.eth.sendTransaction(payload);\n};\n\n/**\n * Should be used to get function display name\n *\n * @method displayName\n * @return {String} display name of the function\n */\nSolidityFunction.prototype.displayName = function () {\n return utils.extractDisplayName(this._name);\n};\n\n/**\n * Should be used to get function type name\n * \n * @method typeName\n * @return {String} type name of the function\n */\nSolidityFunction.prototype.typeName = function () {\n return utils.extractTypeName(this._name);\n};\n\n/**\n * Should be called to execute function\n *\n * @method execute\n */\nSolidityFunction.prototype.execute = function () {\n var transaction = !this._constant;\n \n // send transaction\n if (transaction) {\n return this.sendTransaction.apply(this, Array.prototype.slice.call(arguments));\n }\n\n // call\n return this.call.apply(this, Array.prototype.slice.call(arguments));\n};\n\n/**\n * Should be called to attach function to contract\n *\n * @method attachToContract\n * @param {Contract}\n */\nSolidityFunction.prototype.attachToContract = function (contract) {\n var execute = this.execute.bind(this);\n execute.call = this.call.bind(this);\n execute.sendTransaction = this.sendTransaction.bind(this);\n var displayName = this.displayName();\n if (!contract[displayName]) {\n contract[displayName] = execute;\n }\n contract[displayName][this.typeName()] = execute; // circular!!!!\n};\n\nmodule.exports = SolidityFunction;\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file httpprovider.js\n * @authors:\n * Marek Kotewicz \n * Marian Oancea \n * Fabian Vogelsteller \n * @date 2014\n */\n\n\"use strict\";\n\nvar XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line\nvar errors = require('./errors');\n\nvar HttpProvider = function (host) {\n this.host = host || 'http://localhost:8545';\n};\n\nHttpProvider.prototype.send = function (payload) {\n var request = new XMLHttpRequest();\n\n request.open('POST', this.host, false);\n \n try {\n request.send(JSON.stringify(payload));\n } catch(error) {\n throw errors.InvalidConnection(this.host);\n }\n\n\n // check request.status\n // TODO: throw an error here! it cannot silently fail!!!\n //if (request.status !== 200) {\n //return;\n //}\n return JSON.parse(request.responseText);\n};\n\nHttpProvider.prototype.sendAsync = function (payload, callback) {\n var request = new XMLHttpRequest();\n request.onreadystatechange = function() {\n if (request.readyState === 4) {\n // TODO: handle the error properly here!!!\n callback(null, JSON.parse(request.responseText));\n }\n };\n\n request.open('POST', this.host, true);\n\n try {\n request.send(JSON.stringify(payload));\n } catch(error) {\n callback(errors.InvalidConnection(this.host));\n }\n};\n\nmodule.exports = HttpProvider;\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file httpprovider.js\n * @authors:\n * Marek Kotewicz \n * Marian Oancea \n * Fabian Vogelsteller \n * @date 2014\n */\n\n\"use strict\";\n\nvar XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line\nvar errors = require('./errors');\n\nvar HttpProvider = function (host) {\n this.host = host || 'http://localhost:8545';\n};\n\nHttpProvider.prototype.send = function (payload) {\n var request = new XMLHttpRequest();\n\n request.open('POST', this.host, false);\n \n try {\n request.send(JSON.stringify(payload));\n } catch(error) {\n throw errors.InvalidConnection(this.host);\n }\n\n\n // check request.status\n // TODO: throw an error here! it cannot silently fail!!!\n //if (request.status !== 200) {\n //return;\n //}\n\n var result = request.responseText;\n\n try {\n result = JSON.parse(result);\n } catch(e) {\n throw errors.InvalidResponse(result); \n }\n\n return result;\n};\n\nHttpProvider.prototype.sendAsync = function (payload, callback) {\n var request = new XMLHttpRequest();\n request.onreadystatechange = function() {\n if (request.readyState === 4) {\n var result = request.responseText;\n var error = null;\n\n try {\n result = JSON.parse(result);\n } catch(e) {\n error = errors.InvalidResponse(result); \n }\n\n callback(error, result);\n }\n };\n\n request.open('POST', this.host, true);\n\n try {\n request.send(JSON.stringify(payload));\n } catch(error) {\n callback(errors.InvalidConnection(this.host));\n }\n};\n\nmodule.exports = HttpProvider;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file jsonrpc.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\nvar Jsonrpc = function () {\n // singleton pattern\n if (arguments.callee._singletonInstance) {\n return arguments.callee._singletonInstance;\n }\n arguments.callee._singletonInstance = this;\n\n this.messageId = 1;\n};\n\n/**\n * @return {Jsonrpc} singleton\n */\nJsonrpc.getInstance = function () {\n var instance = new Jsonrpc();\n return instance;\n};\n\n/**\n * Should be called to valid json create payload object\n *\n * @method toPayload\n * @param {Function} method of jsonrpc call, required\n * @param {Array} params, an array of method params, optional\n * @returns {Object} valid jsonrpc payload object\n */\nJsonrpc.prototype.toPayload = function (method, params) {\n if (!method)\n console.error('jsonrpc method should be specified!');\n\n return {\n jsonrpc: '2.0',\n method: method,\n params: params || [],\n id: this.messageId++\n };\n};\n\n/**\n * Should be called to check if jsonrpc response is valid\n *\n * @method isValidResponse\n * @param {Object}\n * @returns {Boolean} true if response is valid, otherwise false\n */\nJsonrpc.prototype.isValidResponse = function (response) {\n return !!response &&\n !response.error &&\n response.jsonrpc === '2.0' &&\n typeof response.id === 'number' &&\n response.result !== undefined; // only undefined is not valid json object\n};\n\n/**\n * Should be called to create batch payload object\n *\n * @method toBatchPayload\n * @param {Array} messages, an array of objects with method (required) and params (optional) fields\n * @returns {Array} batch payload\n */\nJsonrpc.prototype.toBatchPayload = function (messages) {\n var self = this;\n return messages.map(function (message) {\n return self.toPayload(message.method, message.params);\n });\n};\n\nmodule.exports = Jsonrpc;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/**\n * @file method.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar RequestManager = require('./requestmanager');\nvar utils = require('../utils/utils');\nvar errors = require('./errors');\n\nvar Method = function (options) {\n this.name = options.name;\n this.call = options.call;\n this.params = options.params || 0;\n this.inputFormatter = options.inputFormatter;\n this.outputFormatter = options.outputFormatter;\n};\n\n/**\n * Should be used to determine name of the jsonrpc method based on arguments\n *\n * @method getCall\n * @param {Array} arguments\n * @return {String} name of jsonrpc method\n */\nMethod.prototype.getCall = function (args) {\n return utils.isFunction(this.call) ? this.call(args) : this.call;\n};\n\n/**\n * Should be used to extract callback from array of arguments. Modifies input param\n *\n * @method extractCallback\n * @param {Array} arguments\n * @return {Function|Null} callback, if exists\n */\nMethod.prototype.extractCallback = function (args) {\n if (utils.isFunction(args[args.length - 1])) {\n return args.pop(); // modify the args array!\n }\n return null;\n};\n\n/**\n * Should be called to check if the number of arguments is correct\n * \n * @method validateArgs\n * @param {Array} arguments\n * @throws {Error} if it is not\n */\nMethod.prototype.validateArgs = function (args) {\n if (args.length !== this.params) {\n throw errors.InvalidNumberOfParams();\n }\n};\n\n/**\n * Should be called to format input args of method\n * \n * @method formatInput\n * @param {Array}\n * @return {Array}\n */\nMethod.prototype.formatInput = function (args) {\n if (!this.inputFormatter) {\n return args;\n }\n\n return this.inputFormatter.map(function (formatter, index) {\n return formatter ? formatter(args[index]) : args[index];\n });\n};\n\n/**\n * Should be called to format output(result) of method\n *\n * @method formatOutput\n * @param {Object}\n * @return {Object}\n */\nMethod.prototype.formatOutput = function (result) {\n return this.outputFormatter && result !== null ? this.outputFormatter(result) : result;\n};\n\n/**\n * Should attach function to method\n * \n * @method attachToObject\n * @param {Object}\n * @param {Function}\n */\nMethod.prototype.attachToObject = function (obj) {\n var func = this.send.bind(this);\n func.call = this.call; // that's ugly. filter.js uses it\n var name = this.name.split('.');\n if (name.length > 1) {\n obj[name[0]] = obj[name[0]] || {};\n obj[name[0]][name[1]] = func;\n } else {\n obj[name[0]] = func; \n }\n};\n\n/**\n * Should create payload from given input args\n *\n * @method toPayload\n * @param {Array} args\n * @return {Object}\n */\nMethod.prototype.toPayload = function (args) {\n var call = this.getCall(args);\n var callback = this.extractCallback(args);\n var params = this.formatInput(args);\n this.validateArgs(params);\n\n return {\n method: call,\n params: params,\n callback: callback\n };\n};\n\n/**\n * Should send request to the API\n *\n * @method send\n * @param list of params\n * @return result\n */\nMethod.prototype.send = function () {\n var payload = this.toPayload(Array.prototype.slice.call(arguments));\n if (payload.callback) {\n var self = this;\n return RequestManager.getInstance().sendAsync(payload, function (err, result) {\n payload.callback(null, self.formatOutput(result));\n });\n }\n return this.formatOutput(RequestManager.getInstance().send(payload));\n};\n\nmodule.exports = Method;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file eth.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\nvar utils = require('../utils/utils');\nvar Property = require('./property');\n\n/// @returns an array of objects describing web3.eth api methods\nvar methods = [\n];\n\n/// @returns an array of objects describing web3.eth api properties\nvar properties = [\n new Property({\n name: 'listening',\n getter: 'net_listening'\n }),\n new Property({\n name: 'peerCount',\n getter: 'net_peerCount',\n outputFormatter: utils.toDecimal\n })\n];\n\n\nmodule.exports = {\n methods: methods,\n properties: properties\n};\n\n", diff --git a/dist/web3.min.js b/dist/web3.min.js index 8523f7258..b02f1f966 100644 --- a/dist/web3.min.js +++ b/dist/web3.min.js @@ -1,2 +1,2 @@ -require=function t(e,n,r){function i(a,s){if(!n[a]){if(!e[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(o)return o(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[a]={exports:{}};e[a][0].call(l.exports,function(t){var n=e[a][1][t];return i(n?n:t)},l,l.exports,t,e,n,r)}return n[a].exports}for(var o="function"==typeof require&&require,a=0;a0&&console.warn("didn't found matching constructor, using default one"),"")};e.exports={inputParser:u,outputParser:c,formatInput:a,formatOutput:s,formatConstructorParams:l}},{"../utils/utils":8,"./coder":2,"./utils":5}],2:[function(t,e,n){var r=t("bignumber.js"),i=t("../utils/utils"),o=t("./formatters"),a=t("./param"),s=function(t){return"[]"===t.slice(-2)},u=function(t){this._name=t.name,this._match=t.match,this._mode=t.mode,this._inputFormatter=t.inputFormatter,this._outputFormatter=t.outputFormatter};u.prototype.isType=function(t){return"strict"===this._match?this._name===t||0===t.indexOf(this._name)&&"[]"===t.slice(this._name.length):"prefix"===this._match?0===t.indexOf(this._name):void 0},u.prototype.formatInput=function(t,e){if(i.isArray(t)&&e){var n=this;return t.map(function(t){return n._inputFormatter(t)}).reduce(function(t,e){return t.appendArrayElement(e),t},new a("",o.formatInputInt(t.length).value))}return this._inputFormatter(t)},u.prototype.formatOutput=function(t,e){if(e){for(var n=[],i=new r(t.prefix,16),o=0;64*i>o;o+=64)n.push(this._outputFormatter(new a(t.suffix.slice(o,o+64))));return n}return this._outputFormatter(t)},u.prototype.isVariadicType=function(t){return s(t)||"bytes"===this._mode},u.prototype.shiftParam=function(t,e){if("bytes"===this._mode)return e.shiftBytes();if(s(t)){var n=new r(e.prefix.slice(0,64),16);return e.shiftArray(n)}return e.shiftValue()};var c=function(t){this._types=t};c.prototype._requireType=function(t){var e=this._types.filter(function(e){return e.isType(t)})[0];if(!e)throw Error("invalid solidity type!: "+t);return e},c.prototype._bytesToParam=function(t,e){var n=this,r=t.reduce(function(t,e){return n._requireType(e).isVariadicType(e)?t+1:t},0),i=t.length-r,o=e.slice(0,64*r);e=e.slice(64*r);var s=e.slice(0,64*i),u=e.slice(64*i);return new a(s,o,u)},c.prototype._formatInput=function(t,e){return this._requireType(t).formatInput(e,s(t))},c.prototype.encodeParam=function(t,e){return this._formatInput(t,e).encode()},c.prototype.encodeParams=function(t,e){var n=this;return t.map(function(t,r){return n._formatInput(t,e[r])}).reduce(function(t,e){return t.append(e),t},new a).encode()},c.prototype._formatOutput=function(t,e){return this._requireType(t).formatOutput(e,s(t))},c.prototype.decodeParam=function(t,e){return this._formatOutput(t,this._bytesToParam([t],e))},c.prototype.decodeParams=function(t,e){var n=this,r=this._bytesToParam(t,e);return t.map(function(t){var e=n._requireType(t),i=e.shiftParam(t,r);return e.formatOutput(i,s(t))})};var l=new c([new u({name:"address",match:"strict",mode:"value",inputFormatter:o.formatInputInt,outputFormatter:o.formatOutputAddress}),new u({name:"bool",match:"strict",mode:"value",inputFormatter:o.formatInputBool,outputFormatter:o.formatOutputBool}),new u({name:"int",match:"prefix",mode:"value",inputFormatter:o.formatInputInt,outputFormatter:o.formatOutputInt}),new u({name:"uint",match:"prefix",mode:"value",inputFormatter:o.formatInputInt,outputFormatter:o.formatOutputUInt}),new u({name:"bytes",match:"strict",mode:"bytes",inputFormatter:o.formatInputDynamicBytes,outputFormatter:o.formatOutputDynamicBytes}),new u({name:"bytes",match:"prefix",mode:"value",inputFormatter:o.formatInputBytes,outputFormatter:o.formatOutputBytes}),new u({name:"real",match:"prefix",mode:"value",inputFormatter:o.formatInputReal,outputFormatter:o.formatOutputReal}),new u({name:"ureal",match:"prefix",mode:"value",inputFormatter:o.formatInputReal,outputFormatter:o.formatOutputUReal})]);e.exports=l},{"../utils/utils":8,"./formatters":3,"./param":4,"bignumber.js":"bignumber.js"}],3:[function(t,e,n){var r=t("bignumber.js"),i=t("../utils/utils"),o=t("../utils/config"),a=t("./param"),s=function(t){var e=2*o.ETH_PADDING;r.config(o.ETH_BIGNUMBER_ROUNDING_MODE);var n=i.padLeft(i.toTwosComplement(t).round().toString(16),e);return new a(n)},u=function(t){var e=i.fromAscii(t,o.ETH_PADDING).substr(2);return new a(e)},c=function(t){var e=i.fromAscii(t,o.ETH_PADDING).substr(2);return new a("",s(t.length).value,e)},l=function(t){var e="000000000000000000000000000000000000000000000000000000000000000"+(t?"1":"0");return new a(e)},f=function(t){return s(new r(t).times(new r(2).pow(128)))},p=function(t){return"1"===new r(t.substr(0,1),16).toString(2).substr(0,1)},m=function(t){var e=t.value||"0";return p(e)?new r(e,16).minus(new r("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16)).minus(1):new r(e,16)},h=function(t){var e=t.value||"0";return new r(e,16)},d=function(t){return m(t).dividedBy(new r(2).pow(128))},g=function(t){return h(t).dividedBy(new r(2).pow(128))},y=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t.value?!0:!1},v=function(t){return i.toAscii(t.value)},b=function(t){return i.toAscii(t.suffix)},w=function(t){var e=t.value;return"0x"+e.slice(e.length-40,e.length)};e.exports={formatInputInt:s,formatInputBytes:u,formatInputDynamicBytes:c,formatInputBool:l,formatInputReal:f,formatOutputInt:m,formatOutputUInt:h,formatOutputReal:d,formatOutputUReal:g,formatOutputBool:y,formatOutputBytes:v,formatOutputDynamicBytes:b,formatOutputAddress:w}},{"../utils/config":7,"../utils/utils":8,"./param":4,"bignumber.js":"bignumber.js"}],4:[function(t,e,n){var r=function(t,e,n){this.prefix=e||"",this.value=t||"",this.suffix=n||""};r.prototype.append=function(t){this.prefix+=t.prefix,this.value+=t.value,this.suffix+=t.suffix},r.prototype.appendArrayElement=function(t){this.suffix+=t.value,this.prefix+=t.prefix},r.prototype.encode=function(){return this.prefix+this.value+this.suffix},r.prototype.shiftValue=function(){var t=this.value.slice(0,64);return this.value=this.value.slice(64),new r(t)},r.prototype.shiftBytes=function(){return this.shiftArray(1)},r.prototype.shiftArray=function(t){var e=this.prefix.slice(0,64);this.prefix=this.value.slice(64);var n=this.suffix.slice(0,64*t);return this.suffix=this.suffix.slice(64*t),new r("",e,n)},e.exports=r},{}],5:[function(t,e,n){var r=function(t,e){return t.filter(function(t){return"constructor"===t.type&&t.inputs.length===e})[0]};e.exports={getConstructor:r}},{}],6:[function(t,e,n){"use strict";n.XMLHttpRequest="undefined"==typeof XMLHttpRequest?{}:XMLHttpRequest},{}],7:[function(t,e,n){var r=t("bignumber.js"),i=["wei","Kwei","Mwei","Gwei","szabo","finney","ether","grand","Mether","Gether","Tether","Pether","Eether","Zether","Yether","Nether","Dether","Vether","Uether"];e.exports={ETH_PADDING:32,ETH_SIGNATURE_LENGTH:4,ETH_UNITS:i,ETH_BIGNUMBER_ROUNDING_MODE:{ROUNDING_MODE:r.ROUND_DOWN},ETH_POLLING_TIMEOUT:1e3,defaultBlock:"latest",defaultAccount:void 0}},{"bignumber.js":"bignumber.js"}],8:[function(t,e,n){var r=t("bignumber.js"),i={wei:"1",kwei:"1000",ada:"1000",mwei:"1000000",babbage:"1000000",gwei:"1000000000",shannon:"1000000000",szabo:"1000000000000",finney:"1000000000000000",ether:"1000000000000000000",kether:"1000000000000000000000",grand:"1000000000000000000000",einstein:"1000000000000000000000",mether:"1000000000000000000000000",gether:"1000000000000000000000000000",tether:"1000000000000000000000000000000"},o=function(t,e,n){return new Array(e-t.length+1).join(n?n:"0")+t},a=function(t){var e="",n=0,r=t.length;for("0x"===t.substring(0,2)&&(n=2);r>n;n+=2){var i=parseInt(t.substr(n,2),16);if(0===i)break;e+=String.fromCharCode(i)}return e},s=function(t){for(var e="",n=0;nthis._inputTypes.length&&o.isObject(t[t.length-1])&&(e=t.pop()),e.to=this._address,e.data="0x"+this.signature()+i.encodeParams(this._inputTypes,t),e},a.prototype.signature=function(){return r.sha3(r.fromAscii(this._name)).slice(2,10)},a.prototype.call=function(){var t=this.toPayload.apply(this,Array.prototype.slice.call(arguments)),e=r.eth.call(t);e=e.length>=2?e.slice(2):e;var n=i.decodeParams(this._outputTypes,e);return 1===n.length?n[0]:n},a.prototype.sendTransaction=function(){var t=this.toPayload.apply(this,Array.prototype.slice.call(arguments));r.eth.sendTransaction(t)},a.prototype.displayName=function(){return o.extractDisplayName(this._name)},a.prototype.typeName=function(){return o.extractTypeName(this._name)},a.prototype.execute=function(){var t=!this._constant;return t?this.sendTransaction.apply(this,Array.prototype.slice.call(arguments)):this.call.apply(this,Array.prototype.slice.call(arguments))},a.prototype.attachToContract=function(t){var e=this.execute.bind(this);e.call=this.call.bind(this),e.sendTransaction=this.sendTransaction.bind(this);var n=this.displayName();t[n]||(t[n]=e),t[n][this.typeName()]=e},e.exports=a},{"../solidity/coder":2,"../utils/utils":8,"../web3":10}],19:[function(t,e,n){"use strict";var r=t("xmlhttprequest").XMLHttpRequest,i=t("./errors"),o=function(t){this.host=t||"http://localhost:8545"};o.prototype.send=function(t){var e=new r;e.open("POST",this.host,!1);try{e.send(JSON.stringify(t))}catch(n){throw i.InvalidConnection(this.host)}return JSON.parse(e.responseText)},o.prototype.sendAsync=function(t,e){var n=new r;n.onreadystatechange=function(){4===n.readyState&&e(null,JSON.parse(n.responseText))},n.open("POST",this.host,!0);try{n.send(JSON.stringify(t))}catch(o){e(i.InvalidConnection(this.host))}},e.exports=o},{"./errors":13,xmlhttprequest:6}],20:[function(t,e,n){var r=function(){return arguments.callee._singletonInstance?arguments.callee._singletonInstance:(arguments.callee._singletonInstance=this,void(this.messageId=1))};r.getInstance=function(){var t=new r;return t},r.prototype.toPayload=function(t,e){return t||console.error("jsonrpc method should be specified!"),{jsonrpc:"2.0",method:t,params:e||[],id:this.messageId++}},r.prototype.isValidResponse=function(t){return!!t&&!t.error&&"2.0"===t.jsonrpc&&"number"==typeof t.id&&void 0!==t.result},r.prototype.toBatchPayload=function(t){var e=this;return t.map(function(t){return e.toPayload(t.method,t.params)})},e.exports=r},{}],21:[function(t,e,n){var r=t("./requestmanager"),i=t("../utils/utils"),o=t("./errors"),a=function(t){this.name=t.name,this.call=t.call,this.params=t.params||0,this.inputFormatter=t.inputFormatter,this.outputFormatter=t.outputFormatter};a.prototype.getCall=function(t){return i.isFunction(this.call)?this.call(t):this.call},a.prototype.extractCallback=function(t){return i.isFunction(t[t.length-1])?t.pop():null},a.prototype.validateArgs=function(t){if(t.length!==this.params)throw o.InvalidNumberOfParams()},a.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter.map(function(e,n){return e?e(t[n]):t[n]}):t},a.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},a.prototype.attachToObject=function(t){var e=this.send.bind(this);e.call=this.call;var n=this.name.split(".");n.length>1?(t[n[0]]=t[n[0]]||{},t[n[0]][n[1]]=e):t[n[0]]=e},a.prototype.toPayload=function(t){var e=this.getCall(t),n=this.extractCallback(t),r=this.formatInput(t);return this.validateArgs(r),{method:e,params:r,callback:n}},a.prototype.send=function(){var t=this.toPayload(Array.prototype.slice.call(arguments));if(t.callback){var e=this;return r.getInstance().sendAsync(t,function(n,r){t.callback(null,e.formatOutput(r))})}return this.formatOutput(r.getInstance().send(t))},e.exports=a},{"../utils/utils":8,"./errors":13,"./requestmanager":25}],22:[function(t,e,n){var r=t("../utils/utils"),i=t("./property"),o=[],a=[new i({name:"listening",getter:"net_listening"}),new i({name:"peerCount",getter:"net_peerCount",outputFormatter:r.toDecimal})];e.exports={methods:o,properties:a}},{"../utils/utils":8,"./property":23}],23:[function(t,e,n){var r=t("./requestmanager"),i=function(t){this.name=t.name,this.getter=t.getter,this.setter=t.setter,this.outputFormatter=t.outputFormatter,this.inputFormatter=t.inputFormatter};i.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter(t):t},i.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},i.prototype.attachToObject=function(t){var e={get:this.get.bind(this),set:this.set.bind(this)},n=this.name.split(".");n.length>1?(t[n[0]]=t[n[0]]||{},Object.defineProperty(t[n[0]],n[1],e)):Object.defineProperty(t,n[0],e)},i.prototype.get=function(){return this.formatOutput(r.getInstance().send({method:this.getter}))},i.prototype.set=function(t){return r.getInstance().send({method:this.setter,params:[this.formatInput(t)]})},e.exports=i},{"./requestmanager":25}],24:[function(t,e,n){var r=function(){};r.prototype.send=function(t){var e=navigator.qt.callMethod(JSON.stringify(t));return JSON.parse(e)},e.exports=r},{}],25:[function(t,e,n){var r=t("./jsonrpc"),i=t("../utils/utils"),o=t("../utils/config"),a=t("./errors"),s=function(t){return arguments.callee._singletonInstance?arguments.callee._singletonInstance:(arguments.callee._singletonInstance=this,this.provider=t,this.polls=[],this.timeout=null,void this.poll())};s.getInstance=function(){var t=new s;return t},s.prototype.send=function(t){if(!this.provider)return console.error(a.InvalidProvider()),null;var e=r.getInstance().toPayload(t.method,t.params),n=this.provider.send(e);if(!r.getInstance().isValidResponse(n))throw a.InvalidResponse(n);return n.result},s.prototype.sendAsync=function(t,e){if(!this.provider)return e(a.InvalidProvider());var n=r.getInstance().toPayload(t.method,t.params);this.provider.sendAsync(n,function(t,n){return t?e(t):r.getInstance().isValidResponse(n)?void e(null,n.result):e(a.InvalidResponse(n))})},s.prototype.setProvider=function(t){this.provider=t},s.prototype.startPolling=function(t,e,n,r){this.polls.push({data:t,id:e,callback:n,uninstall:r})},s.prototype.stopPolling=function(t){for(var e=this.polls.length;e--;){var n=this.polls[e];n.id===t&&this.polls.splice(e,1)}},s.prototype.reset=function(){this.polls.forEach(function(t){t.uninstall(t.id)}),this.polls=[],this.timeout&&(clearTimeout(this.timeout),this.timeout=null),this.poll()},s.prototype.poll=function(){if(this.timeout=setTimeout(this.poll.bind(this),o.ETH_POLLING_TIMEOUT),this.polls.length){if(!this.provider)return void console.error(a.InvalidProvider());var t=r.getInstance().toBatchPayload(this.polls.map(function(t){return t.data})),e=this;this.provider.sendAsync(t,function(t,n){if(!t){if(!i.isArray(n))throw a.InvalidResponse(n);n.map(function(t,n){return t.callback=e.polls[n].callback,t}).filter(function(t){var e=r.getInstance().isValidResponse(t);return e||t.callback(a.InvalidResponse(t)),e}).filter(function(t){return i.isArray(t.result)&&t.result.length>0}).forEach(function(t){t.callback(null,t.result)})}})}},e.exports=s},{"../utils/config":7,"../utils/utils":8,"./errors":13,"./jsonrpc":20}],26:[function(t,e,n){var r=t("./method"),i=t("./formatters"),o=new r({name:"post",call:"shh_post",params:1,inputFormatter:[i.inputPostFormatter]}),a=new r({name:"newIdentity",call:"shh_newIdentity",params:0}),s=new r({name:"hasIdentity",call:"shh_hasIdentity",params:1}),u=new r({name:"newGroup",call:"shh_newGroup",params:0}),c=new r({name:"addToGroup",call:"shh_addToGroup",params:0}),l=[o,a,s,u,c];e.exports={methods:l}},{"./formatters":17,"./method":21}],27:[function(t,e,n){var r=t("./method"),i=function(){var t=function(t){return"string"==typeof t[0]?"eth_newBlockFilter":"eth_newFilter"},e=new r({name:"newFilter",call:t,params:1}),n=new r({name:"uninstallFilter",call:"eth_uninstallFilter",params:1}),i=new r({name:"getLogs",call:"eth_getFilterLogs",params:1}),o=new r({name:"poll",call:"eth_getFilterChanges",params:1 -});return[e,n,i,o]},o=function(){var t=new r({name:"newFilter",call:"shh_newFilter",params:1}),e=new r({name:"uninstallFilter",call:"shh_uninstallFilter",params:1}),n=new r({name:"getLogs",call:"shh_getMessages",params:1}),i=new r({name:"poll",call:"shh_getFilterChanges",params:1});return[t,e,n,i]};e.exports={eth:i,shh:o}},{"./method":21}],28:[function(t,e,n){},{}],"bignumber.js":[function(t,e,n){!function(n){"use strict";function r(t){function e(t,r){var i,o,a,s,u,c,l=this;if(!(l instanceof e))return V&&k(26,"constructor call without new",t),new e(t,r);if(null!=r&&J(r,2,64,R,"base")){if(r=0|r,c=t+"",10==r)return l=new e(t instanceof e?t:c),E(l,j+l.e+1,U);if((s="number"==typeof t)&&0*t!=0||!new RegExp("^-?"+(i="["+_.slice(0,r)+"]+")+"(?:\\."+i+")?$",37>r?"i":"").test(c))return d(l,c,s,r);s?(l.s=0>1/t?(c=c.slice(1),-1):1,V&&c.replace(/^0\.0*|\./,"").length>15&&k(R,x,t),s=!1):l.s=45===c.charCodeAt(0)?(c=c.slice(1),-1):1,c=n(c,10,r,l.s)}else{if(t instanceof e)return l.s=t.s,l.e=t.e,l.c=(t=t.c)?t.slice():t,void(R=0);if((s="number"==typeof t)&&0*t==0){if(l.s=0>1/t?(t=-t,-1):1,t===~~t){for(o=0,a=t;a>=10;a/=10,o++);return l.e=o,l.c=[t],void(R=0)}c=t+""}else{if(!g.test(c=t+""))return d(l,c,s);l.s=45===c.charCodeAt(0)?(c=c.slice(1),-1):1}}for((o=c.indexOf("."))>-1&&(c=c.replace(".","")),(a=c.search(/e/i))>0?(0>o&&(o=a),o+=+c.slice(a+1),c=c.substring(0,a)):0>o&&(o=c.length),a=0;48===c.charCodeAt(a);a++);for(u=c.length;48===c.charCodeAt(--u););if(c=c.slice(a,u+1))if(u=c.length,s&&V&&u>15&&k(R,x,l.s*t),o=o-a-1,o>G)l.c=l.e=null;else if(M>o)l.c=[l.e=0];else{if(l.e=o,l.c=[],a=(o+1)%N,0>o&&(a+=N),u>a){for(a&&l.c.push(+c.slice(0,a)),u-=N;u>a;)l.c.push(+c.slice(a,a+=N));c=c.slice(a),a=N-c.length}else a-=u;for(;a--;c+="0");l.c.push(+c)}else l.c=[l.e=0];R=0}function n(t,n,r,i){var a,s,u,l,p,m,h,d=t.indexOf("."),g=j,y=U;for(37>r&&(t=t.toLowerCase()),d>=0&&(u=z,z=0,t=t.replace(".",""),h=new e(r),p=h.pow(t.length-d),z=u,h.c=c(f(o(p.c),p.e),10,n),h.e=h.c.length),m=c(t,r,n),s=u=m.length;0==m[--u];m.pop());if(!m[0])return"0";if(0>d?--s:(p.c=m,p.e=s,p.s=i,p=S(p,h,g,y,n),m=p.c,l=p.r,s=p.e),a=s+g+1,d=m[a],u=n/2,l=l||0>a||null!=m[a+1],l=4>y?(null!=d||l)&&(0==y||y==(p.s<0?3:2)):d>u||d==u&&(4==y||l||6==y&&1&m[a-1]||y==(p.s<0?8:7)),1>a||!m[0])t=l?f("1",-g):"0";else{if(m.length=a,l)for(--n;++m[--a]>n;)m[a]=0,a||(++s,m.unshift(1));for(u=m.length;!m[--u];);for(d=0,t="";u>=d;t+=_.charAt(m[d++]));t=f(t,s)}return t}function m(t,n,r,i){var a,s,u,c,p;if(r=null!=r&&J(r,0,8,i,w)?0|r:U,!t.c)return t.toString();if(a=t.c[0],u=t.e,null==n)p=o(t.c),p=19==i||24==i&&H>=u?l(p,u):f(p,u);else if(t=E(new e(t),n,r),s=t.e,p=o(t.c),c=p.length,19==i||24==i&&(s>=n||H>=s)){for(;n>c;p+="0",c++);p=l(p,s)}else if(n-=u,p=f(p,s),s+1>c){if(--n>0)for(p+=".";n--;p+="0");}else if(n+=s-c,n>0)for(s+1==c&&(p+=".");n--;p+="0");return t.s<0&&a?"-"+p:p}function A(t,n){var r,i,o=0;for(u(t[0])&&(t=t[0]),r=new e(t[0]);++ot||t>n||t!=p(t))&&k(r,(i||"decimal places")+(e>t||t>n?" out of range":" not an integer"),t),!0}function P(t,e,n){for(var r=1,i=e.length;!e[--i];e.pop());for(i=e[0];i>=10;i/=10,r++);return(n=r+n*N-1)>G?t.c=t.e=null:M>n?t.c=[t.e=0]:(t.e=n,t.c=e),t}function k(t,e,n){var r=new Error(["new BigNumber","cmp","config","div","divToInt","eq","gt","gte","lt","lte","minus","mod","plus","precision","random","round","shift","times","toDigits","toExponential","toFixed","toFormat","toFraction","pow","toPrecision","toString","BigNumber"][t]+"() "+e+": "+n);throw r.name="BigNumber Error",R=0,r}function E(t,e,n,r){var i,o,a,s,u,c,l,f=t.c,p=O;if(f){t:{for(i=1,s=f[0];s>=10;s/=10,i++);if(o=e-i,0>o)o+=N,a=e,u=f[c=0],l=u/p[i-a-1]%10|0;else if(c=y((o+1)/N),c>=f.length){if(!r)break t;for(;f.length<=c;f.push(0));u=l=0,i=1,o%=N,a=o-N+1}else{for(u=s=f[c],i=1;s>=10;s/=10,i++);o%=N,a=o-N+i,l=0>a?0:u/p[i-a-1]%10|0}if(r=r||0>e||null!=f[c+1]||(0>a?u:u%p[i-a-1]),r=4>n?(l||r)&&(0==n||n==(t.s<0?3:2)):l>5||5==l&&(4==n||r||6==n&&(o>0?a>0?u/p[i-a]:0:f[c-1])%10&1||n==(t.s<0?8:7)),1>e||!f[0])return f.length=0,r?(e-=t.e+1,f[0]=p[e%N],t.e=-e||0):f[0]=t.e=0,t;if(0==o?(f.length=c,s=1,c--):(f.length=c+1,s=p[N-o],f[c]=a>0?v(u/p[i-a]%p[a])*s:0),r)for(;;){if(0==c){for(o=1,a=f[0];a>=10;a/=10,o++);for(a=f[0]+=s,s=1;a>=10;a/=10,s++);o!=s&&(t.e++,f[0]==F&&(f[0]=1));break}if(f[c]+=s,f[c]!=F)break;f[c--]=0,s=1}for(o=f.length;0===f[--o];f.pop());}t.e>G?t.c=t.e=null:t.en?null!=(t=i[n++]):void 0};return a(e="DECIMAL_PLACES")&&J(t,0,B,2,e)&&(j=0|t),r[e]=j,a(e="ROUNDING_MODE")&&J(t,0,8,2,e)&&(U=0|t),r[e]=U,a(e="EXPONENTIAL_AT")&&(u(t)?J(t[0],-B,0,2,e)&&J(t[1],0,B,2,e)&&(H=0|t[0],q=0|t[1]):J(t,-B,B,2,e)&&(H=-(q=0|(0>t?-t:t)))),r[e]=[H,q],a(e="RANGE")&&(u(t)?J(t[0],-B,-1,2,e)&&J(t[1],1,B,2,e)&&(M=0|t[0],G=0|t[1]):J(t,-B,B,2,e)&&(0|t?M=-(G=0|(0>t?-t:t)):V&&k(2,e+" cannot be zero",t))),r[e]=[M,G],a(e="ERRORS")&&(t===!!t||1===t||0===t?(R=0,J=(V=!!t)?D:s):V&&k(2,e+b,t)),r[e]=V,a(e="CRYPTO")&&(t===!!t||1===t||0===t?(W=!(!t||!h||"object"!=typeof h),t&&!W&&V&&k(2,"crypto unavailable",h)):V&&k(2,e+b,t)),r[e]=W,a(e="MODULO_MODE")&&J(t,0,9,2,e)&&($=0|t),r[e]=$,a(e="POW_PRECISION")&&J(t,0,B,2,e)&&(z=0|t),r[e]=z,a(e="FORMAT")&&("object"==typeof t?X=t:V&&k(2,e+" not an object",t)),r[e]=X,r},e.max=function(){return A(arguments,C.lt)},e.min=function(){return A(arguments,C.gt)},e.random=function(){var t=9007199254740992,n=Math.random()*t&2097151?function(){return v(Math.random()*t)}:function(){return 8388608*(1073741824*Math.random()|0)+(8388608*Math.random()|0)};return function(t){var r,i,o,a,s,u=0,c=[],l=new e(L);if(t=null!=t&&J(t,0,B,14)?0|t:j,a=y(t/N),W)if(h&&h.getRandomValues){for(r=h.getRandomValues(new Uint32Array(a*=2));a>u;)s=131072*r[u]+(r[u+1]>>>11),s>=9e15?(i=h.getRandomValues(new Uint32Array(2)),r[u]=i[0],r[u+1]=i[1]):(c.push(s%1e14),u+=2);u=a/2}else if(h&&h.randomBytes){for(r=h.randomBytes(a*=7);a>u;)s=281474976710656*(31&r[u])+1099511627776*r[u+1]+4294967296*r[u+2]+16777216*r[u+3]+(r[u+4]<<16)+(r[u+5]<<8)+r[u+6],s>=9e15?h.randomBytes(7).copy(r,u):(c.push(s%1e14),u+=7);u=a/7}else V&&k(14,"crypto unavailable",h);if(!u)for(;a>u;)s=n(),9e15>s&&(c[u++]=s%1e14);for(a=c[--u],t%=N,a&&t&&(s=O[N-t],c[u]=v(a/s)*s);0===c[u];c.pop(),u--);if(0>u)c=[o=0];else{for(o=-1;0===c[0];c.shift(),o-=N);for(u=1,s=c[0];s>=10;s/=10,u++);N>u&&(o-=N-u)}return l.e=o,l.c=c,l}}(),S=function(){function t(t,e,n){var r,i,o,a,s=0,u=t.length,c=e%T,l=e/T|0;for(t=t.slice();u--;)o=t[u]%T,a=t[u]/T|0,r=l*o+a*c,i=c*o+r%T*T+s,s=(i/n|0)+(r/T|0)+l*a,t[u]=i%n;return s&&t.unshift(s),t}function n(t,e,n,r){var i,o;if(n!=r)o=n>r?1:-1;else for(i=o=0;n>i;i++)if(t[i]!=e[i]){o=t[i]>e[i]?1:-1;break}return o}function r(t,e,n,r){for(var i=0;n--;)t[n]-=i,i=t[n]1;t.shift());}return function(o,a,s,u,c){var l,f,p,m,h,d,g,y,b,w,x,_,I,O,T,B,A,D=o.s==a.s?1:-1,P=o.c,k=a.c;if(!(P&&P[0]&&k&&k[0]))return new e(o.s&&a.s&&(P?!k||P[0]!=k[0]:k)?P&&0==P[0]||!k?0*D:D/0:0/0);for(y=new e(D),b=y.c=[],f=o.e-a.e,D=s+f+1,c||(c=F,f=i(o.e/N)-i(a.e/N),D=D/N|0),p=0;k[p]==(P[p]||0);p++);if(k[p]>(P[p]||0)&&f--,0>D)b.push(1),m=!0;else{for(O=P.length,B=k.length,p=0,D+=2,h=v(c/(k[0]+1)),h>1&&(k=t(k,h,c),P=t(P,h,c),B=k.length,O=P.length),I=B,w=P.slice(0,B),x=w.length;B>x;w[x++]=0);A=k.slice(),A.unshift(0),T=k[0],k[1]>=c/2&&T++;do{if(h=0,l=n(k,w,B,x),0>l){if(_=w[0],B!=x&&(_=_*c+(w[1]||0)),h=v(_/T),h>1)for(h>=c&&(h=c-1),d=t(k,h,c),g=d.length,x=w.length;1==n(d,w,g,x);)h--,r(d,g>B?A:k,g,c),g=d.length,l=1;else 0==h&&(l=h=1),d=k.slice(),g=d.length;if(x>g&&d.unshift(0),r(w,d,x,c),x=w.length,-1==l)for(;n(k,w,B,x)<1;)h++,r(w,x>B?A:k,x,c),x=w.length}else 0===l&&(h++,w=[0]);b[p++]=h,w[0]?w[x++]=P[I]||0:(w=[P[I]],x=1)}while((I++=10;D/=10,p++);E(y,s+(y.e=p+f*N-1)+1,u,m)}else y.e=f,y.r=+m;return y}}(),d=function(){var t=/^(-?)0([xbo])/i,n=/^([^.]+)\.$/,r=/^\.([^.]+)$/,i=/^-?(Infinity|NaN)$/,o=/^\s*\+|^\s+|\s+$/g;return function(a,s,u,c){var l,f=u?s:s.replace(o,"");if(i.test(f))a.s=isNaN(f)?null:0>f?-1:1;else{if(!u&&(f=f.replace(t,function(t,e,n){return l="x"==(n=n.toLowerCase())?16:"b"==n?2:8,c&&c!=l?t:e}),c&&(l=c,f=f.replace(n,"$1").replace(r,"0.$1")),s!=f))return new e(f,l);V&&k(R,"not a"+(c?" base "+c:"")+" number",s),a.s=null}a.c=a.e=null,R=0}}(),C.absoluteValue=C.abs=function(){var t=new e(this);return t.s<0&&(t.s=1),t},C.ceil=function(){return E(new e(this),this.e+1,2)},C.comparedTo=C.cmp=function(t,n){return R=1,a(this,new e(t,n))},C.decimalPlaces=C.dp=function(){var t,e,n=this.c;if(!n)return null;if(t=((e=n.length-1)-i(this.e/N))*N,e=n[e])for(;e%10==0;e/=10,t--);return 0>t&&(t=0),t},C.dividedBy=C.div=function(t,n){return R=3,S(this,new e(t,n),j,U)},C.dividedToIntegerBy=C.divToInt=function(t,n){return R=4,S(this,new e(t,n),0,1)},C.equals=C.eq=function(t,n){return R=5,0===a(this,new e(t,n))},C.floor=function(){return E(new e(this),this.e+1,3)},C.greaterThan=C.gt=function(t,n){return R=6,a(this,new e(t,n))>0},C.greaterThanOrEqualTo=C.gte=function(t,n){return R=7,1===(n=a(this,new e(t,n)))||0===n},C.isFinite=function(){return!!this.c},C.isInteger=C.isInt=function(){return!!this.c&&i(this.e/N)>this.c.length-2},C.isNaN=function(){return!this.s},C.isNegative=C.isNeg=function(){return this.s<0},C.isZero=function(){return!!this.c&&0==this.c[0]},C.lessThan=C.lt=function(t,n){return R=8,a(this,new e(t,n))<0},C.lessThanOrEqualTo=C.lte=function(t,n){return R=9,-1===(n=a(this,new e(t,n)))||0===n},C.minus=C.sub=function(t,n){var r,o,a,s,u=this,c=u.s;if(R=10,t=new e(t,n),n=t.s,!c||!n)return new e(0/0);if(c!=n)return t.s=-n,u.plus(t);var l=u.e/N,f=t.e/N,p=u.c,m=t.c;if(!l||!f){if(!p||!m)return p?(t.s=-n,t):new e(m?u:0/0);if(!p[0]||!m[0])return m[0]?(t.s=-n,t):new e(p[0]?u:3==U?-0:0)}if(l=i(l),f=i(f),p=p.slice(),c=l-f){for((s=0>c)?(c=-c,a=p):(f=l,a=m),a.reverse(),n=c;n--;a.push(0));a.reverse()}else for(o=(s=(c=p.length)<(n=m.length))?c:n,c=n=0;o>n;n++)if(p[n]!=m[n]){s=p[n]0)for(;n--;p[r++]=0);for(n=F-1;o>c;){if(p[--o]0?(u=s,r=l):(a=-a,r=c),r.reverse();a--;r.push(0));r.reverse()}for(a=c.length,n=l.length,0>a-n&&(r=l,l=c,c=r,n=a),a=0;n;)a=(c[--n]=c[n]+l[n]+a)/F|0,c[n]%=F;return a&&(c.unshift(a),++u),P(t,c,u)},C.precision=C.sd=function(t){var e,n,r=this,i=r.c;if(null!=t&&t!==!!t&&1!==t&&0!==t&&(V&&k(13,"argument"+b,t),t!=!!t&&(t=null)),!i)return null;if(n=i.length-1,e=n*N+1,n=i[n]){for(;n%10==0;n/=10,e--);for(n=i[0];n>=10;n/=10,e++);}return t&&r.e+1>e&&(e=r.e+1),e},C.round=function(t,n){var r=new e(this);return(null==t||J(t,0,B,15))&&E(r,~~t+this.e+1,null!=n&&J(n,0,8,15,w)?0|n:U),r},C.shift=function(t){var n=this;return J(t,-I,I,16,"argument")?n.times("1e"+p(t)):new e(n.c&&n.c[0]&&(-I>t||t>I)?n.s*(0>t?0:1/0):n)},C.squareRoot=C.sqrt=function(){var t,n,r,a,s,u=this,c=u.c,l=u.s,f=u.e,p=j+4,m=new e("0.5");if(1!==l||!c||!c[0])return new e(!l||0>l&&(!c||c[0])?0/0:c?u:1/0);if(l=Math.sqrt(+u),0==l||l==1/0?(n=o(c),(n.length+f)%2==0&&(n+="0"),l=Math.sqrt(n),f=i((f+1)/2)-(0>f||f%2),l==1/0?n="1e"+f:(n=l.toExponential(),n=n.slice(0,n.indexOf("e")+1)+f),r=new e(n)):r=new e(l+""),r.c[0])for(f=r.e,l=f+p,3>l&&(l=0);;)if(s=r,r=m.times(s.plus(S(u,s,p,1))),o(s.c).slice(0,l)===(n=o(r.c)).slice(0,l)){if(r.el&&(g=w,w=x,x=g,a=l,l=m,m=a),a=l+m,g=[];a--;g.push(0));for(y=F,v=T,a=m;--a>=0;){for(r=0,h=x[a]%v,d=x[a]/v|0,u=l,s=a+u;s>a;)f=w[--u]%v,p=w[u]/v|0,c=d*f+p*h,f=h*f+c%v*v+g[s]+r,r=(f/y|0)+(c/v|0)+d*p,g[s--]=f%y;g[s]=r}return r?++o:g.shift(),P(t,g,o)},C.toDigits=function(t,n){var r=new e(this);return t=null!=t&&J(t,1,B,18,"precision")?0|t:null,n=null!=n&&J(n,0,8,18,w)?0|n:U,t?E(r,t,n):r},C.toExponential=function(t,e){return m(this,null!=t&&J(t,0,B,19)?~~t+1:null,e,19)},C.toFixed=function(t,e){return m(this,null!=t&&J(t,0,B,20)?~~t+this.e+1:null,e,20)},C.toFormat=function(t,e){var n=m(this,null!=t&&J(t,0,B,21)?~~t+this.e+1:null,e,21);if(this.c){var r,i=n.split("."),o=+X.groupSize,a=+X.secondaryGroupSize,s=X.groupSeparator,u=i[0],c=i[1],l=this.s<0,f=l?u.slice(1):u,p=f.length;if(a&&(r=o,o=a,a=r,p-=r),o>0&&p>0){for(r=p%o||o,u=f.substr(0,r);p>r;r+=o)u+=s+f.substr(r,o);a>0&&(u+=s+f.slice(r)),l&&(u="-"+u)}n=c?u+X.decimalSeparator+((a=+X.fractionGroupSize)?c.replace(new RegExp("\\d{"+a+"}\\B","g"),"$&"+X.fractionGroupSeparator):c):u}return n},C.toFraction=function(t){var n,r,i,a,s,u,c,l,f,p=V,m=this,h=m.c,d=new e(L),g=r=new e(L),y=c=new e(L);if(null!=t&&(V=!1,u=new e(t),V=p,(!(p=u.isInt())||u.lt(L))&&(V&&k(22,"max denominator "+(p?"out of range":"not an integer"),t),t=!p&&u.c&&E(u,u.e+1,1).gte(L)?u:null)),!h)return m.toString();for(f=o(h),a=d.e=f.length-m.e-1,d.c[0]=O[(s=a%N)<0?N+s:s],t=!t||u.cmp(d)>0?a>0?d:g:u,s=G,G=1/0,u=new e(f),c.c[0]=0;l=S(u,d,0,1),i=r.plus(l.times(y)),1!=i.cmp(t);)r=y,y=i,g=c.plus(l.times(i=g)),c=i,d=u.minus(l.times(i=d)),u=i;return i=S(t.minus(r),y,0,1),c=c.plus(i.times(g)),r=r.plus(i.times(y)),c.s=g.s=m.s,a*=2,n=S(g,y,a,U).minus(m).abs().cmp(S(c,r,a,U).minus(m).abs())<1?[g.toString(),y.toString()]:[c.toString(),r.toString()],G=s,n},C.toNumber=function(){var t=this;return+t||(t.s?0*t.s:0/0)},C.toPower=C.pow=function(t){var n,r,i=v(0>t?-t:+t),o=this;if(!J(t,-I,I,23,"exponent")&&(!isFinite(t)||i>I&&(t/=0)||parseFloat(t)!=t&&!(t=0/0)))return new e(Math.pow(+o,t));for(n=z?y(z/N+2):0,r=new e(L);;){if(i%2){if(r=r.times(o),!r.c)break;n&&r.c.length>n&&(r.c.length=n)}if(i=v(i/2),!i)break;o=o.times(o),n&&o.c&&o.c.length>n&&(o.c.length=n)}return 0>t&&(r=L.div(r)),n?E(r,z,U):r},C.toPrecision=function(t,e){return m(this,null!=t&&J(t,1,B,24,"precision")?0|t:null,e,24)},C.toString=function(t){var e,r=this,i=r.s,a=r.e;return null===a?i?(e="Infinity",0>i&&(e="-"+e)):e="NaN":(e=o(r.c),e=null!=t&&J(t,2,64,25,"base")?n(f(e,a),0|t,10,i):H>=a||a>=q?l(e,a):f(e,a),0>i&&r.c[0]&&(e="-"+e)),e},C.truncated=C.trunc=function(){return E(new e(this),this.e+1,1)},C.valueOf=C.toJSON=function(){return this.toString()},null!=t&&e.config(t),e}function i(t){var e=0|t;return t>0||t===e?e:e-1}function o(t){for(var e,n,r=1,i=t.length,o=t[0]+"";i>r;){for(e=t[r++]+"",n=N-e.length;n--;e="0"+e);o+=e}for(i=o.length;48===o.charCodeAt(--i););return o.slice(0,i+1||1)}function a(t,e){var n,r,i=t.c,o=e.c,a=t.s,s=e.s,u=t.e,c=e.e;if(!a||!s)return null;if(n=i&&!i[0],r=o&&!o[0],n||r)return n?r?0:-s:a;if(a!=s)return a;if(n=0>a,r=u==c,!i||!o)return r?0:!i^n?1:-1;if(!r)return u>c^n?1:-1;for(s=(u=i.length)<(c=o.length)?u:c,a=0;s>a;a++)if(i[a]!=o[a])return i[a]>o[a]^n?1:-1;return u==c?0:u>c^n?1:-1}function s(t,e,n){return(t=p(t))>=e&&n>=t}function u(t){return"[object Array]"==Object.prototype.toString.call(t)}function c(t,e,n){for(var r,i,o=[0],a=0,s=t.length;s>a;){for(i=o.length;i--;o[i]*=e);for(o[r=0]+=_.indexOf(t.charAt(a++));rn-1&&(null==o[r+1]&&(o[r+1]=0),o[r+1]+=o[r]/n|0,o[r]%=n)}return o.reverse()}function l(t,e){return(t.length>1?t.charAt(0)+"."+t.slice(1):t)+(0>e?"e":"e+")+e}function f(t,e){var n,r;if(0>e){for(r="0.";++e;r+="0");t=r+t}else if(n=t.length,++e>n){for(r="0",e-=n;--e;r+="0");t+=r}else n>e&&(t=t.slice(0,e)+"."+t.slice(e));return t}function p(t){return t=parseFloat(t),0>t?y(t):v(t)}var m,h,d,g=/^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,y=Math.ceil,v=Math.floor,b=" not a boolean or binary digit",w="rounding mode",x="number type has more than 15 significant digits",_="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_",F=1e14,N=14,I=9007199254740991,O=[1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13],T=1e7,B=1e9;if(m=r(),"function"==typeof define&&define.amd)define(function(){return m});else if("undefined"!=typeof e&&e.exports){if(e.exports=m,!h)try{h=t("crypto")}catch(A){}}else n.BigNumber=m}(this)},{crypto:28}],web3:[function(t,e,n){var r=t("./lib/web3");r.providers.HttpProvider=t("./lib/web3/httpprovider"),r.providers.QtSyncProvider=t("./lib/web3/qtsync"),r.eth.contract=t("./lib/web3/contract"),r.abi=t("./lib/solidity/abi"),"undefined"!=typeof window&&"undefined"==typeof window.web3&&(window.web3=r),e.exports=r},{"./lib/solidity/abi":1,"./lib/web3":10,"./lib/web3/contract":11,"./lib/web3/httpprovider":19,"./lib/web3/qtsync":24}]},{},["web3"]); \ No newline at end of file +require=function t(e,n,r){function o(a,s){if(!n[a]){if(!e[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(i)return i(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[a]={exports:{}};e[a][0].call(l.exports,function(t){var n=e[a][1][t];return o(n?n:t)},l,l.exports,t,e,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;a0&&console.warn("didn't found matching constructor, using default one"),"")};e.exports={formatConstructorParams:i}},{"./coder":2,"./utils":5}],2:[function(t,e,n){var r=t("bignumber.js"),o=t("../utils/utils"),i=t("./formatters"),a=t("./param"),s=function(t){return"[]"===t.slice(-2)},u=function(t){this._name=t.name,this._match=t.match,this._mode=t.mode,this._inputFormatter=t.inputFormatter,this._outputFormatter=t.outputFormatter};u.prototype.isType=function(t){return"strict"===this._match?this._name===t||0===t.indexOf(this._name)&&"[]"===t.slice(this._name.length):"prefix"===this._match?0===t.indexOf(this._name):void 0},u.prototype.formatInput=function(t,e){if(o.isArray(t)&&e){var n=this;return t.map(function(t){return n._inputFormatter(t)}).reduce(function(t,e){return t.combine(e)},i.formatInputInt(t.length)).withOffset(32)}return this._inputFormatter(t)},u.prototype.formatOutput=function(t,e){if(e){for(var n=[],o=new r(t.dynamicPart().slice(0,64),16),i=0;64*o>i;i+=64)n.push(this._outputFormatter(new a(t.dynamicPart().substr(i+64,64))));return n}return this._outputFormatter(t)},u.prototype.sliceParam=function(t,e,n){return"bytes"===this._mode?a.decodeBytes(t,e):s(n)?a.decodeArray(t,e):a.decodeParam(t,e)};var c=function(t){this._types=t};c.prototype._requireType=function(t){var e=this._types.filter(function(e){return e.isType(t)})[0];if(!e)throw Error("invalid solidity type!: "+t);return e},c.prototype._formatInput=function(t,e){return this._requireType(t).formatInput(e,s(t))},c.prototype.encodeParam=function(t,e){return this._formatInput(t,e).encode()},c.prototype.encodeParams=function(t,e){var n=this,r=t.map(function(t,r){return n._formatInput(t,e[r])});return a.encodeList(r)},c.prototype.decodeParam=function(t,e){return this.decodeParams([t],e)[0]},c.prototype.decodeParams=function(t,e){var n=this;return t.map(function(t,r){var o=n._requireType(t),i=o.sliceParam(e,r,t);return o.formatOutput(i,s(t))})};var l=new c([new u({name:"address",match:"strict",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputAddress}),new u({name:"bool",match:"strict",mode:"value",inputFormatter:i.formatInputBool,outputFormatter:i.formatOutputBool}),new u({name:"int",match:"prefix",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputInt}),new u({name:"uint",match:"prefix",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputUInt}),new u({name:"bytes",match:"strict",mode:"bytes",inputFormatter:i.formatInputDynamicBytes,outputFormatter:i.formatOutputDynamicBytes}),new u({name:"bytes",match:"prefix",mode:"value",inputFormatter:i.formatInputBytes,outputFormatter:i.formatOutputBytes}),new u({name:"real",match:"prefix",mode:"value",inputFormatter:i.formatInputReal,outputFormatter:i.formatOutputReal}),new u({name:"ureal",match:"prefix",mode:"value",inputFormatter:i.formatInputReal,outputFormatter:i.formatOutputUReal})]);e.exports=l},{"../utils/utils":8,"./formatters":3,"./param":4,"bignumber.js":"bignumber.js"}],3:[function(t,e,n){var r=t("bignumber.js"),o=t("../utils/utils"),i=t("../utils/config"),a=t("./param"),s=function(t){var e=2*i.ETH_PADDING;r.config(i.ETH_BIGNUMBER_ROUNDING_MODE);var n=o.padLeft(o.toTwosComplement(t).round().toString(16),e);return new a(n)},u=function(t){var e=o.fromAscii(t,i.ETH_PADDING).substr(2);return new a(e)},c=function(t){var e=o.fromAscii(t,i.ETH_PADDING).substr(2);return new a(s(t.length).value+e,32)},l=function(t){var e="000000000000000000000000000000000000000000000000000000000000000"+(t?"1":"0");return new a(e)},f=function(t){return s(new r(t).times(new r(2).pow(128)))},p=function(t){return"1"===new r(t.substr(0,1),16).toString(2).substr(0,1)},m=function(t){var e=t.staticPart()||"0";return p(e)?new r(e,16).minus(new r("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16)).minus(1):new r(e,16)},h=function(t){var e=t.staticPart()||"0";return new r(e,16)},d=function(t){return m(t).dividedBy(new r(2).pow(128))},g=function(t){return h(t).dividedBy(new r(2).pow(128))},y=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t.staticPart()?!0:!1},v=function(t){return o.toAscii(t.staticPart())},b=function(t){return o.toAscii(t.dynamicPart().slice(64))},w=function(t){var e=t.staticPart();return"0x"+e.slice(e.length-40,e.length)};e.exports={formatInputInt:s,formatInputBytes:u,formatInputDynamicBytes:c,formatInputBool:l,formatInputReal:f,formatOutputInt:m,formatOutputUInt:h,formatOutputReal:d,formatOutputUReal:g,formatOutputBool:y,formatOutputBytes:v,formatOutputDynamicBytes:b,formatOutputAddress:w}},{"../utils/config":7,"../utils/utils":8,"./param":4,"bignumber.js":"bignumber.js"}],4:[function(t,e,n){var r=t("../utils/utils"),o=function(t,e){this.value=t||"",this.offset=e};o.prototype.dynamicPartLength=function(){return this.dynamicPart().length/2},o.prototype.withOffset=function(t){return new o(this.value,t)},o.prototype.combine=function(t){return new o(this.value+t.value)},o.prototype.isDynamic=function(){return this.value.length>64},o.prototype.offsetAsBytes=function(){return this.isDynamic()?r.padLeft(r.toTwosComplement(this.offset).toString(16),64):""},o.prototype.staticPart=function(){return this.isDynamic()?this.offsetAsBytes():this.value},o.prototype.dynamicPart=function(){return this.isDynamic()?this.value:""},o.prototype.encode=function(){return this.staticPart()+this.dynamicPart()},o.encodeList=function(t){var e=32*t.length,n=t.map(function(t){if(!t.isDynamic())return t;var n=e;return e+=t.dynamicPartLength(),t.withOffset(n)});return n.reduce(function(t,e){return t+e.dynamicPart()},n.reduce(function(t,e){return t+e.staticPart()},""))},o.decodeParam=function(t,e){return e=e||0,new o(t.substr(64*e,64))};var i=function(t,e){return parseInt("0x"+t.substr(64*e,64))};o.decodeBytes=function(t,e){e=e||0;var n=i(t,e);return new o(t.substr(2*n,128))},o.decodeArray=function(t,e){e=e||0;var n=i(t,e),r=parseInt("0x"+t.substr(2*n,64));return new o(t.substr(2*n,64*(r+1)))},e.exports=o},{"../utils/utils":8}],5:[function(t,e,n){var r=function(t,e){return t.filter(function(t){return"constructor"===t.type&&t.inputs.length===e})[0]};e.exports={getConstructor:r}},{}],6:[function(t,e,n){"use strict";n.XMLHttpRequest="undefined"==typeof XMLHttpRequest?{}:XMLHttpRequest},{}],7:[function(t,e,n){var r=t("bignumber.js"),o=["wei","Kwei","Mwei","Gwei","szabo","finney","ether","grand","Mether","Gether","Tether","Pether","Eether","Zether","Yether","Nether","Dether","Vether","Uether"];e.exports={ETH_PADDING:32,ETH_SIGNATURE_LENGTH:4,ETH_UNITS:o,ETH_BIGNUMBER_ROUNDING_MODE:{ROUNDING_MODE:r.ROUND_DOWN},ETH_POLLING_TIMEOUT:1e3,defaultBlock:"latest",defaultAccount:void 0}},{"bignumber.js":"bignumber.js"}],8:[function(t,e,n){var r=t("bignumber.js"),o={wei:"1",kwei:"1000",ada:"1000",mwei:"1000000",babbage:"1000000",gwei:"1000000000",shannon:"1000000000",szabo:"1000000000000",finney:"1000000000000000",ether:"1000000000000000000",kether:"1000000000000000000000",grand:"1000000000000000000000",einstein:"1000000000000000000000",mether:"1000000000000000000000000",gether:"1000000000000000000000000000",tether:"1000000000000000000000000000000"},i=function(t,e,n){return new Array(e-t.length+1).join(n?n:"0")+t},a=function(t){var e="",n=0,r=t.length;for("0x"===t.substring(0,2)&&(n=2);r>n;n+=2){var o=parseInt(t.substr(n,2),16);if(0===o)break;e+=String.fromCharCode(o)}return e},s=function(t){for(var e="",n=0;nthis._inputTypes.length&&i.isObject(t[t.length-1])&&(e=t.pop()),e.to=this._address,e.data="0x"+this.signature()+o.encodeParams(this._inputTypes,t),e},a.prototype.signature=function(){return r.sha3(r.fromAscii(this._name)).slice(2,10)},a.prototype.call=function(){var t=this.toPayload.apply(this,Array.prototype.slice.call(arguments)),e=r.eth.call(t);e=e.length>=2?e.slice(2):e;var n=o.decodeParams(this._outputTypes,e);return 1===n.length?n[0]:n},a.prototype.sendTransaction=function(){var t=this.toPayload.apply(this,Array.prototype.slice.call(arguments));r.eth.sendTransaction(t)},a.prototype.displayName=function(){return i.extractDisplayName(this._name)},a.prototype.typeName=function(){return i.extractTypeName(this._name)},a.prototype.execute=function(){var t=!this._constant;return t?this.sendTransaction.apply(this,Array.prototype.slice.call(arguments)):this.call.apply(this,Array.prototype.slice.call(arguments))},a.prototype.attachToContract=function(t){var e=this.execute.bind(this);e.call=this.call.bind(this),e.sendTransaction=this.sendTransaction.bind(this);var n=this.displayName();t[n]||(t[n]=e),t[n][this.typeName()]=e},e.exports=a},{"../solidity/coder":2,"../utils/utils":8,"../web3":10}],19:[function(t,e,n){"use strict";var r=t("xmlhttprequest").XMLHttpRequest,o=t("./errors"),i=function(t){this.host=t||"http://localhost:8545"};i.prototype.send=function(t){var e=new r;e.open("POST",this.host,!1);try{e.send(JSON.stringify(t))}catch(n){throw o.InvalidConnection(this.host)}var i=e.responseText;try{i=JSON.parse(i)}catch(a){throw o.InvalidResponse(i)}return i},i.prototype.sendAsync=function(t,e){var n=new r;n.onreadystatechange=function(){if(4===n.readyState){var t=n.responseText,r=null;try{t=JSON.parse(t)}catch(i){r=o.InvalidResponse(t)}e(r,t)}},n.open("POST",this.host,!0);try{n.send(JSON.stringify(t))}catch(i){e(o.InvalidConnection(this.host))}},e.exports=i},{"./errors":13,xmlhttprequest:6}],20:[function(t,e,n){var r=function(){return arguments.callee._singletonInstance?arguments.callee._singletonInstance:(arguments.callee._singletonInstance=this,void(this.messageId=1))};r.getInstance=function(){var t=new r;return t},r.prototype.toPayload=function(t,e){return t||console.error("jsonrpc method should be specified!"),{jsonrpc:"2.0",method:t,params:e||[],id:this.messageId++}},r.prototype.isValidResponse=function(t){return!!t&&!t.error&&"2.0"===t.jsonrpc&&"number"==typeof t.id&&void 0!==t.result},r.prototype.toBatchPayload=function(t){var e=this;return t.map(function(t){return e.toPayload(t.method,t.params)})},e.exports=r},{}],21:[function(t,e,n){var r=t("./requestmanager"),o=t("../utils/utils"),i=t("./errors"),a=function(t){this.name=t.name,this.call=t.call,this.params=t.params||0,this.inputFormatter=t.inputFormatter,this.outputFormatter=t.outputFormatter};a.prototype.getCall=function(t){return o.isFunction(this.call)?this.call(t):this.call},a.prototype.extractCallback=function(t){return o.isFunction(t[t.length-1])?t.pop():null},a.prototype.validateArgs=function(t){if(t.length!==this.params)throw i.InvalidNumberOfParams()},a.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter.map(function(e,n){return e?e(t[n]):t[n]}):t},a.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},a.prototype.attachToObject=function(t){var e=this.send.bind(this);e.call=this.call;var n=this.name.split(".");n.length>1?(t[n[0]]=t[n[0]]||{},t[n[0]][n[1]]=e):t[n[0]]=e},a.prototype.toPayload=function(t){var e=this.getCall(t),n=this.extractCallback(t),r=this.formatInput(t);return this.validateArgs(r),{method:e,params:r,callback:n}},a.prototype.send=function(){var t=this.toPayload(Array.prototype.slice.call(arguments));if(t.callback){var e=this;return r.getInstance().sendAsync(t,function(n,r){t.callback(null,e.formatOutput(r))})}return this.formatOutput(r.getInstance().send(t))},e.exports=a},{"../utils/utils":8,"./errors":13,"./requestmanager":25}],22:[function(t,e,n){var r=t("../utils/utils"),o=t("./property"),i=[],a=[new o({name:"listening",getter:"net_listening"}),new o({name:"peerCount",getter:"net_peerCount",outputFormatter:r.toDecimal})];e.exports={methods:i,properties:a}},{"../utils/utils":8,"./property":23}],23:[function(t,e,n){var r=t("./requestmanager"),o=function(t){this.name=t.name,this.getter=t.getter,this.setter=t.setter,this.outputFormatter=t.outputFormatter,this.inputFormatter=t.inputFormatter};o.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter(t):t},o.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},o.prototype.attachToObject=function(t){var e={get:this.get.bind(this),set:this.set.bind(this)},n=this.name.split(".");n.length>1?(t[n[0]]=t[n[0]]||{},Object.defineProperty(t[n[0]],n[1],e)):Object.defineProperty(t,n[0],e)},o.prototype.get=function(){return this.formatOutput(r.getInstance().send({method:this.getter}))},o.prototype.set=function(t){return r.getInstance().send({method:this.setter,params:[this.formatInput(t)]})},e.exports=o},{"./requestmanager":25}],24:[function(t,e,n){var r=function(){};r.prototype.send=function(t){var e=navigator.qt.callMethod(JSON.stringify(t));return JSON.parse(e)},e.exports=r},{}],25:[function(t,e,n){var r=t("./jsonrpc"),o=t("../utils/utils"),i=t("../utils/config"),a=t("./errors"),s=function(t){return arguments.callee._singletonInstance?arguments.callee._singletonInstance:(arguments.callee._singletonInstance=this,this.provider=t,this.polls=[],this.timeout=null,void this.poll())};s.getInstance=function(){var t=new s;return t},s.prototype.send=function(t){if(!this.provider)return console.error(a.InvalidProvider()),null;var e=r.getInstance().toPayload(t.method,t.params),n=this.provider.send(e);if(!r.getInstance().isValidResponse(n))throw a.InvalidResponse(n);return n.result},s.prototype.sendAsync=function(t,e){if(!this.provider)return e(a.InvalidProvider());var n=r.getInstance().toPayload(t.method,t.params);this.provider.sendAsync(n,function(t,n){return t?e(t):r.getInstance().isValidResponse(n)?void e(null,n.result):e(a.InvalidResponse(n))})},s.prototype.setProvider=function(t){this.provider=t},s.prototype.startPolling=function(t,e,n,r){this.polls.push({data:t,id:e,callback:n,uninstall:r})},s.prototype.stopPolling=function(t){for(var e=this.polls.length;e--;){var n=this.polls[e];n.id===t&&this.polls.splice(e,1)}},s.prototype.reset=function(){this.polls.forEach(function(t){t.uninstall(t.id)}),this.polls=[],this.timeout&&(clearTimeout(this.timeout),this.timeout=null),this.poll()},s.prototype.poll=function(){if(this.timeout=setTimeout(this.poll.bind(this),i.ETH_POLLING_TIMEOUT),this.polls.length){if(!this.provider)return void console.error(a.InvalidProvider());var t=r.getInstance().toBatchPayload(this.polls.map(function(t){return t.data})),e=this;this.provider.sendAsync(t,function(t,n){if(!t){if(!o.isArray(n))throw a.InvalidResponse(n);n.map(function(t,n){return t.callback=e.polls[n].callback,t}).filter(function(t){var e=r.getInstance().isValidResponse(t);return e||t.callback(a.InvalidResponse(t)),e}).filter(function(t){return o.isArray(t.result)&&t.result.length>0}).forEach(function(t){t.callback(null,t.result)})}})}},e.exports=s},{"../utils/config":7,"../utils/utils":8,"./errors":13,"./jsonrpc":20}],26:[function(t,e,n){var r=t("./method"),o=t("./formatters"),i=new r({name:"post",call:"shh_post",params:1,inputFormatter:[o.inputPostFormatter]}),a=new r({name:"newIdentity",call:"shh_newIdentity",params:0}),s=new r({name:"hasIdentity",call:"shh_hasIdentity",params:1}),u=new r({name:"newGroup",call:"shh_newGroup",params:0}),c=new r({name:"addToGroup",call:"shh_addToGroup",params:0}),l=[i,a,s,u,c];e.exports={methods:l}},{"./formatters":17,"./method":21}],27:[function(t,e,n){var r=t("./method"),o=function(){var t=function(t){return"string"==typeof t[0]?"eth_newBlockFilter":"eth_newFilter"},e=new r({name:"newFilter",call:t,params:1}),n=new r({name:"uninstallFilter",call:"eth_uninstallFilter",params:1}),o=new r({name:"getLogs",call:"eth_getFilterLogs",params:1}),i=new r({name:"poll",call:"eth_getFilterChanges",params:1});return[e,n,o,i]},i=function(){var t=new r({name:"newFilter",call:"shh_newFilter",params:1}),e=new r({name:"uninstallFilter",call:"shh_uninstallFilter",params:1}),n=new r({name:"getLogs",call:"shh_getMessages",params:1}),o=new r({name:"poll",call:"shh_getFilterChanges",params:1 +});return[t,e,n,o]};e.exports={eth:o,shh:i}},{"./method":21}],28:[function(t,e,n){},{}],"bignumber.js":[function(t,e,n){!function(n){"use strict";function r(t){function e(t,r){var o,i,a,s,u,c,l=this;if(!(l instanceof e))return J&&k(26,"constructor call without new",t),new e(t,r);if(null!=r&&V(r,2,64,R,"base")){if(r=0|r,c=t+"",10==r)return l=new e(t instanceof e?t:c),S(l,j+l.e+1,U);if((s="number"==typeof t)&&0*t!=0||!new RegExp("^-?"+(o="["+F.slice(0,r)+"]+")+"(?:\\."+o+")?$",37>r?"i":"").test(c))return d(l,c,s,r);s?(l.s=0>1/t?(c=c.slice(1),-1):1,J&&c.replace(/^0\.0*|\./,"").length>15&&k(R,_,t),s=!1):l.s=45===c.charCodeAt(0)?(c=c.slice(1),-1):1,c=n(c,10,r,l.s)}else{if(t instanceof e)return l.s=t.s,l.e=t.e,l.c=(t=t.c)?t.slice():t,void(R=0);if((s="number"==typeof t)&&0*t==0){if(l.s=0>1/t?(t=-t,-1):1,t===~~t){for(i=0,a=t;a>=10;a/=10,i++);return l.e=i,l.c=[t],void(R=0)}c=t+""}else{if(!g.test(c=t+""))return d(l,c,s);l.s=45===c.charCodeAt(0)?(c=c.slice(1),-1):1}}for((i=c.indexOf("."))>-1&&(c=c.replace(".","")),(a=c.search(/e/i))>0?(0>i&&(i=a),i+=+c.slice(a+1),c=c.substring(0,a)):0>i&&(i=c.length),a=0;48===c.charCodeAt(a);a++);for(u=c.length;48===c.charCodeAt(--u););if(c=c.slice(a,u+1))if(u=c.length,s&&J&&u>15&&k(R,_,l.s*t),i=i-a-1,i>G)l.c=l.e=null;else if(M>i)l.c=[l.e=0];else{if(l.e=i,l.c=[],a=(i+1)%I,0>i&&(a+=I),u>a){for(a&&l.c.push(+c.slice(0,a)),u-=I;u>a;)l.c.push(+c.slice(a,a+=I));c=c.slice(a),a=I-c.length}else a-=u;for(;a--;c+="0");l.c.push(+c)}else l.c=[l.e=0];R=0}function n(t,n,r,o){var a,s,u,l,p,m,h,d=t.indexOf("."),g=j,y=U;for(37>r&&(t=t.toLowerCase()),d>=0&&(u=z,z=0,t=t.replace(".",""),h=new e(r),p=h.pow(t.length-d),z=u,h.c=c(f(i(p.c),p.e),10,n),h.e=h.c.length),m=c(t,r,n),s=u=m.length;0==m[--u];m.pop());if(!m[0])return"0";if(0>d?--s:(p.c=m,p.e=s,p.s=o,p=E(p,h,g,y,n),m=p.c,l=p.r,s=p.e),a=s+g+1,d=m[a],u=n/2,l=l||0>a||null!=m[a+1],l=4>y?(null!=d||l)&&(0==y||y==(p.s<0?3:2)):d>u||d==u&&(4==y||l||6==y&&1&m[a-1]||y==(p.s<0?8:7)),1>a||!m[0])t=l?f("1",-g):"0";else{if(m.length=a,l)for(--n;++m[--a]>n;)m[a]=0,a||(++s,m.unshift(1));for(u=m.length;!m[--u];);for(d=0,t="";u>=d;t+=F.charAt(m[d++]));t=f(t,s)}return t}function m(t,n,r,o){var a,s,u,c,p;if(r=null!=r&&V(r,0,8,o,w)?0|r:U,!t.c)return t.toString();if(a=t.c[0],u=t.e,null==n)p=i(t.c),p=19==o||24==o&&H>=u?l(p,u):f(p,u);else if(t=S(new e(t),n,r),s=t.e,p=i(t.c),c=p.length,19==o||24==o&&(s>=n||H>=s)){for(;n>c;p+="0",c++);p=l(p,s)}else if(n-=u,p=f(p,s),s+1>c){if(--n>0)for(p+=".";n--;p+="0");}else if(n+=s-c,n>0)for(s+1==c&&(p+=".");n--;p+="0");return t.s<0&&a?"-"+p:p}function T(t,n){var r,o,i=0;for(u(t[0])&&(t=t[0]),r=new e(t[0]);++it||t>n||t!=p(t))&&k(r,(o||"decimal places")+(e>t||t>n?" out of range":" not an integer"),t),!0}function D(t,e,n){for(var r=1,o=e.length;!e[--o];e.pop());for(o=e[0];o>=10;o/=10,r++);return(n=r+n*I-1)>G?t.c=t.e=null:M>n?t.c=[t.e=0]:(t.e=n,t.c=e),t}function k(t,e,n){var r=new Error(["new BigNumber","cmp","config","div","divToInt","eq","gt","gte","lt","lte","minus","mod","plus","precision","random","round","shift","times","toDigits","toExponential","toFixed","toFormat","toFraction","pow","toPrecision","toString","BigNumber"][t]+"() "+e+": "+n);throw r.name="BigNumber Error",R=0,r}function S(t,e,n,r){var o,i,a,s,u,c,l,f=t.c,p=O;if(f){t:{for(o=1,s=f[0];s>=10;s/=10,o++);if(i=e-o,0>i)i+=I,a=e,u=f[c=0],l=u/p[o-a-1]%10|0;else if(c=y((i+1)/I),c>=f.length){if(!r)break t;for(;f.length<=c;f.push(0));u=l=0,o=1,i%=I,a=i-I+1}else{for(u=s=f[c],o=1;s>=10;s/=10,o++);i%=I,a=i-I+o,l=0>a?0:u/p[o-a-1]%10|0}if(r=r||0>e||null!=f[c+1]||(0>a?u:u%p[o-a-1]),r=4>n?(l||r)&&(0==n||n==(t.s<0?3:2)):l>5||5==l&&(4==n||r||6==n&&(i>0?a>0?u/p[o-a]:0:f[c-1])%10&1||n==(t.s<0?8:7)),1>e||!f[0])return f.length=0,r?(e-=t.e+1,f[0]=p[e%I],t.e=-e||0):f[0]=t.e=0,t;if(0==i?(f.length=c,s=1,c--):(f.length=c+1,s=p[I-i],f[c]=a>0?v(u/p[o-a]%p[a])*s:0),r)for(;;){if(0==c){for(i=1,a=f[0];a>=10;a/=10,i++);for(a=f[0]+=s,s=1;a>=10;a/=10,s++);i!=s&&(t.e++,f[0]==x&&(f[0]=1));break}if(f[c]+=s,f[c]!=x)break;f[c--]=0,s=1}for(i=f.length;0===f[--i];f.pop());}t.e>G?t.c=t.e=null:t.en?null!=(t=o[n++]):void 0};return a(e="DECIMAL_PLACES")&&V(t,0,P,2,e)&&(j=0|t),r[e]=j,a(e="ROUNDING_MODE")&&V(t,0,8,2,e)&&(U=0|t),r[e]=U,a(e="EXPONENTIAL_AT")&&(u(t)?V(t[0],-P,0,2,e)&&V(t[1],0,P,2,e)&&(H=0|t[0],q=0|t[1]):V(t,-P,P,2,e)&&(H=-(q=0|(0>t?-t:t)))),r[e]=[H,q],a(e="RANGE")&&(u(t)?V(t[0],-P,-1,2,e)&&V(t[1],1,P,2,e)&&(M=0|t[0],G=0|t[1]):V(t,-P,P,2,e)&&(0|t?M=-(G=0|(0>t?-t:t)):J&&k(2,e+" cannot be zero",t))),r[e]=[M,G],a(e="ERRORS")&&(t===!!t||1===t||0===t?(R=0,V=(J=!!t)?A:s):J&&k(2,e+b,t)),r[e]=J,a(e="CRYPTO")&&(t===!!t||1===t||0===t?(W=!(!t||!h||"object"!=typeof h),t&&!W&&J&&k(2,"crypto unavailable",h)):J&&k(2,e+b,t)),r[e]=W,a(e="MODULO_MODE")&&V(t,0,9,2,e)&&($=0|t),r[e]=$,a(e="POW_PRECISION")&&V(t,0,P,2,e)&&(z=0|t),r[e]=z,a(e="FORMAT")&&("object"==typeof t?X=t:J&&k(2,e+" not an object",t)),r[e]=X,r},e.max=function(){return T(arguments,C.lt)},e.min=function(){return T(arguments,C.gt)},e.random=function(){var t=9007199254740992,n=Math.random()*t&2097151?function(){return v(Math.random()*t)}:function(){return 8388608*(1073741824*Math.random()|0)+(8388608*Math.random()|0)};return function(t){var r,o,i,a,s,u=0,c=[],l=new e(L);if(t=null!=t&&V(t,0,P,14)?0|t:j,a=y(t/I),W)if(h&&h.getRandomValues){for(r=h.getRandomValues(new Uint32Array(a*=2));a>u;)s=131072*r[u]+(r[u+1]>>>11),s>=9e15?(o=h.getRandomValues(new Uint32Array(2)),r[u]=o[0],r[u+1]=o[1]):(c.push(s%1e14),u+=2);u=a/2}else if(h&&h.randomBytes){for(r=h.randomBytes(a*=7);a>u;)s=281474976710656*(31&r[u])+1099511627776*r[u+1]+4294967296*r[u+2]+16777216*r[u+3]+(r[u+4]<<16)+(r[u+5]<<8)+r[u+6],s>=9e15?h.randomBytes(7).copy(r,u):(c.push(s%1e14),u+=7);u=a/7}else J&&k(14,"crypto unavailable",h);if(!u)for(;a>u;)s=n(),9e15>s&&(c[u++]=s%1e14);for(a=c[--u],t%=I,a&&t&&(s=O[I-t],c[u]=v(a/s)*s);0===c[u];c.pop(),u--);if(0>u)c=[i=0];else{for(i=-1;0===c[0];c.shift(),i-=I);for(u=1,s=c[0];s>=10;s/=10,u++);I>u&&(i-=I-u)}return l.e=i,l.c=c,l}}(),E=function(){function t(t,e,n){var r,o,i,a,s=0,u=t.length,c=e%B,l=e/B|0;for(t=t.slice();u--;)i=t[u]%B,a=t[u]/B|0,r=l*i+a*c,o=c*i+r%B*B+s,s=(o/n|0)+(r/B|0)+l*a,t[u]=o%n;return s&&t.unshift(s),t}function n(t,e,n,r){var o,i;if(n!=r)i=n>r?1:-1;else for(o=i=0;n>o;o++)if(t[o]!=e[o]){i=t[o]>e[o]?1:-1;break}return i}function r(t,e,n,r){for(var o=0;n--;)t[n]-=o,o=t[n]1;t.shift());}return function(i,a,s,u,c){var l,f,p,m,h,d,g,y,b,w,_,F,N,O,B,P,T,A=i.s==a.s?1:-1,D=i.c,k=a.c;if(!(D&&D[0]&&k&&k[0]))return new e(i.s&&a.s&&(D?!k||D[0]!=k[0]:k)?D&&0==D[0]||!k?0*A:A/0:0/0);for(y=new e(A),b=y.c=[],f=i.e-a.e,A=s+f+1,c||(c=x,f=o(i.e/I)-o(a.e/I),A=A/I|0),p=0;k[p]==(D[p]||0);p++);if(k[p]>(D[p]||0)&&f--,0>A)b.push(1),m=!0;else{for(O=D.length,P=k.length,p=0,A+=2,h=v(c/(k[0]+1)),h>1&&(k=t(k,h,c),D=t(D,h,c),P=k.length,O=D.length),N=P,w=D.slice(0,P),_=w.length;P>_;w[_++]=0);T=k.slice(),T.unshift(0),B=k[0],k[1]>=c/2&&B++;do{if(h=0,l=n(k,w,P,_),0>l){if(F=w[0],P!=_&&(F=F*c+(w[1]||0)),h=v(F/B),h>1)for(h>=c&&(h=c-1),d=t(k,h,c),g=d.length,_=w.length;1==n(d,w,g,_);)h--,r(d,g>P?T:k,g,c),g=d.length,l=1;else 0==h&&(l=h=1),d=k.slice(),g=d.length;if(_>g&&d.unshift(0),r(w,d,_,c),_=w.length,-1==l)for(;n(k,w,P,_)<1;)h++,r(w,_>P?T:k,_,c),_=w.length}else 0===l&&(h++,w=[0]);b[p++]=h,w[0]?w[_++]=D[N]||0:(w=[D[N]],_=1)}while((N++=10;A/=10,p++);S(y,s+(y.e=p+f*I-1)+1,u,m)}else y.e=f,y.r=+m;return y}}(),d=function(){var t=/^(-?)0([xbo])/i,n=/^([^.]+)\.$/,r=/^\.([^.]+)$/,o=/^-?(Infinity|NaN)$/,i=/^\s*\+|^\s+|\s+$/g;return function(a,s,u,c){var l,f=u?s:s.replace(i,"");if(o.test(f))a.s=isNaN(f)?null:0>f?-1:1;else{if(!u&&(f=f.replace(t,function(t,e,n){return l="x"==(n=n.toLowerCase())?16:"b"==n?2:8,c&&c!=l?t:e}),c&&(l=c,f=f.replace(n,"$1").replace(r,"0.$1")),s!=f))return new e(f,l);J&&k(R,"not a"+(c?" base "+c:"")+" number",s),a.s=null}a.c=a.e=null,R=0}}(),C.absoluteValue=C.abs=function(){var t=new e(this);return t.s<0&&(t.s=1),t},C.ceil=function(){return S(new e(this),this.e+1,2)},C.comparedTo=C.cmp=function(t,n){return R=1,a(this,new e(t,n))},C.decimalPlaces=C.dp=function(){var t,e,n=this.c;if(!n)return null;if(t=((e=n.length-1)-o(this.e/I))*I,e=n[e])for(;e%10==0;e/=10,t--);return 0>t&&(t=0),t},C.dividedBy=C.div=function(t,n){return R=3,E(this,new e(t,n),j,U)},C.dividedToIntegerBy=C.divToInt=function(t,n){return R=4,E(this,new e(t,n),0,1)},C.equals=C.eq=function(t,n){return R=5,0===a(this,new e(t,n))},C.floor=function(){return S(new e(this),this.e+1,3)},C.greaterThan=C.gt=function(t,n){return R=6,a(this,new e(t,n))>0},C.greaterThanOrEqualTo=C.gte=function(t,n){return R=7,1===(n=a(this,new e(t,n)))||0===n},C.isFinite=function(){return!!this.c},C.isInteger=C.isInt=function(){return!!this.c&&o(this.e/I)>this.c.length-2},C.isNaN=function(){return!this.s},C.isNegative=C.isNeg=function(){return this.s<0},C.isZero=function(){return!!this.c&&0==this.c[0]},C.lessThan=C.lt=function(t,n){return R=8,a(this,new e(t,n))<0},C.lessThanOrEqualTo=C.lte=function(t,n){return R=9,-1===(n=a(this,new e(t,n)))||0===n},C.minus=C.sub=function(t,n){var r,i,a,s,u=this,c=u.s;if(R=10,t=new e(t,n),n=t.s,!c||!n)return new e(0/0);if(c!=n)return t.s=-n,u.plus(t);var l=u.e/I,f=t.e/I,p=u.c,m=t.c;if(!l||!f){if(!p||!m)return p?(t.s=-n,t):new e(m?u:0/0);if(!p[0]||!m[0])return m[0]?(t.s=-n,t):new e(p[0]?u:3==U?-0:0)}if(l=o(l),f=o(f),p=p.slice(),c=l-f){for((s=0>c)?(c=-c,a=p):(f=l,a=m),a.reverse(),n=c;n--;a.push(0));a.reverse()}else for(i=(s=(c=p.length)<(n=m.length))?c:n,c=n=0;i>n;n++)if(p[n]!=m[n]){s=p[n]0)for(;n--;p[r++]=0);for(n=x-1;i>c;){if(p[--i]0?(u=s,r=l):(a=-a,r=c),r.reverse();a--;r.push(0));r.reverse()}for(a=c.length,n=l.length,0>a-n&&(r=l,l=c,c=r,n=a),a=0;n;)a=(c[--n]=c[n]+l[n]+a)/x|0,c[n]%=x;return a&&(c.unshift(a),++u),D(t,c,u)},C.precision=C.sd=function(t){var e,n,r=this,o=r.c;if(null!=t&&t!==!!t&&1!==t&&0!==t&&(J&&k(13,"argument"+b,t),t!=!!t&&(t=null)),!o)return null;if(n=o.length-1,e=n*I+1,n=o[n]){for(;n%10==0;n/=10,e--);for(n=o[0];n>=10;n/=10,e++);}return t&&r.e+1>e&&(e=r.e+1),e},C.round=function(t,n){var r=new e(this);return(null==t||V(t,0,P,15))&&S(r,~~t+this.e+1,null!=n&&V(n,0,8,15,w)?0|n:U),r},C.shift=function(t){var n=this;return V(t,-N,N,16,"argument")?n.times("1e"+p(t)):new e(n.c&&n.c[0]&&(-N>t||t>N)?n.s*(0>t?0:1/0):n)},C.squareRoot=C.sqrt=function(){var t,n,r,a,s,u=this,c=u.c,l=u.s,f=u.e,p=j+4,m=new e("0.5");if(1!==l||!c||!c[0])return new e(!l||0>l&&(!c||c[0])?0/0:c?u:1/0);if(l=Math.sqrt(+u),0==l||l==1/0?(n=i(c),(n.length+f)%2==0&&(n+="0"),l=Math.sqrt(n),f=o((f+1)/2)-(0>f||f%2),l==1/0?n="1e"+f:(n=l.toExponential(),n=n.slice(0,n.indexOf("e")+1)+f),r=new e(n)):r=new e(l+""),r.c[0])for(f=r.e,l=f+p,3>l&&(l=0);;)if(s=r,r=m.times(s.plus(E(u,s,p,1))),i(s.c).slice(0,l)===(n=i(r.c)).slice(0,l)){if(r.el&&(g=w,w=_,_=g,a=l,l=m,m=a),a=l+m,g=[];a--;g.push(0));for(y=x,v=B,a=m;--a>=0;){for(r=0,h=_[a]%v,d=_[a]/v|0,u=l,s=a+u;s>a;)f=w[--u]%v,p=w[u]/v|0,c=d*f+p*h,f=h*f+c%v*v+g[s]+r,r=(f/y|0)+(c/v|0)+d*p,g[s--]=f%y;g[s]=r}return r?++i:g.shift(),D(t,g,i)},C.toDigits=function(t,n){var r=new e(this);return t=null!=t&&V(t,1,P,18,"precision")?0|t:null,n=null!=n&&V(n,0,8,18,w)?0|n:U,t?S(r,t,n):r},C.toExponential=function(t,e){return m(this,null!=t&&V(t,0,P,19)?~~t+1:null,e,19)},C.toFixed=function(t,e){return m(this,null!=t&&V(t,0,P,20)?~~t+this.e+1:null,e,20)},C.toFormat=function(t,e){var n=m(this,null!=t&&V(t,0,P,21)?~~t+this.e+1:null,e,21);if(this.c){var r,o=n.split("."),i=+X.groupSize,a=+X.secondaryGroupSize,s=X.groupSeparator,u=o[0],c=o[1],l=this.s<0,f=l?u.slice(1):u,p=f.length;if(a&&(r=i,i=a,a=r,p-=r),i>0&&p>0){for(r=p%i||i,u=f.substr(0,r);p>r;r+=i)u+=s+f.substr(r,i);a>0&&(u+=s+f.slice(r)),l&&(u="-"+u)}n=c?u+X.decimalSeparator+((a=+X.fractionGroupSize)?c.replace(new RegExp("\\d{"+a+"}\\B","g"),"$&"+X.fractionGroupSeparator):c):u}return n},C.toFraction=function(t){var n,r,o,a,s,u,c,l,f,p=J,m=this,h=m.c,d=new e(L),g=r=new e(L),y=c=new e(L);if(null!=t&&(J=!1,u=new e(t),J=p,(!(p=u.isInt())||u.lt(L))&&(J&&k(22,"max denominator "+(p?"out of range":"not an integer"),t),t=!p&&u.c&&S(u,u.e+1,1).gte(L)?u:null)),!h)return m.toString();for(f=i(h),a=d.e=f.length-m.e-1,d.c[0]=O[(s=a%I)<0?I+s:s],t=!t||u.cmp(d)>0?a>0?d:g:u,s=G,G=1/0,u=new e(f),c.c[0]=0;l=E(u,d,0,1),o=r.plus(l.times(y)),1!=o.cmp(t);)r=y,y=o,g=c.plus(l.times(o=g)),c=o,d=u.minus(l.times(o=d)),u=o;return o=E(t.minus(r),y,0,1),c=c.plus(o.times(g)),r=r.plus(o.times(y)),c.s=g.s=m.s,a*=2,n=E(g,y,a,U).minus(m).abs().cmp(E(c,r,a,U).minus(m).abs())<1?[g.toString(),y.toString()]:[c.toString(),r.toString()],G=s,n},C.toNumber=function(){var t=this;return+t||(t.s?0*t.s:0/0)},C.toPower=C.pow=function(t){var n,r,o=v(0>t?-t:+t),i=this;if(!V(t,-N,N,23,"exponent")&&(!isFinite(t)||o>N&&(t/=0)||parseFloat(t)!=t&&!(t=0/0)))return new e(Math.pow(+i,t));for(n=z?y(z/I+2):0,r=new e(L);;){if(o%2){if(r=r.times(i),!r.c)break;n&&r.c.length>n&&(r.c.length=n)}if(o=v(o/2),!o)break;i=i.times(i),n&&i.c&&i.c.length>n&&(i.c.length=n)}return 0>t&&(r=L.div(r)),n?S(r,z,U):r},C.toPrecision=function(t,e){return m(this,null!=t&&V(t,1,P,24,"precision")?0|t:null,e,24)},C.toString=function(t){var e,r=this,o=r.s,a=r.e;return null===a?o?(e="Infinity",0>o&&(e="-"+e)):e="NaN":(e=i(r.c),e=null!=t&&V(t,2,64,25,"base")?n(f(e,a),0|t,10,o):H>=a||a>=q?l(e,a):f(e,a),0>o&&r.c[0]&&(e="-"+e)),e},C.truncated=C.trunc=function(){return S(new e(this),this.e+1,1)},C.valueOf=C.toJSON=function(){return this.toString()},null!=t&&e.config(t),e}function o(t){var e=0|t;return t>0||t===e?e:e-1}function i(t){for(var e,n,r=1,o=t.length,i=t[0]+"";o>r;){for(e=t[r++]+"",n=I-e.length;n--;e="0"+e);i+=e}for(o=i.length;48===i.charCodeAt(--o););return i.slice(0,o+1||1)}function a(t,e){var n,r,o=t.c,i=e.c,a=t.s,s=e.s,u=t.e,c=e.e;if(!a||!s)return null;if(n=o&&!o[0],r=i&&!i[0],n||r)return n?r?0:-s:a;if(a!=s)return a;if(n=0>a,r=u==c,!o||!i)return r?0:!o^n?1:-1;if(!r)return u>c^n?1:-1;for(s=(u=o.length)<(c=i.length)?u:c,a=0;s>a;a++)if(o[a]!=i[a])return o[a]>i[a]^n?1:-1;return u==c?0:u>c^n?1:-1}function s(t,e,n){return(t=p(t))>=e&&n>=t}function u(t){return"[object Array]"==Object.prototype.toString.call(t)}function c(t,e,n){for(var r,o,i=[0],a=0,s=t.length;s>a;){for(o=i.length;o--;i[o]*=e);for(i[r=0]+=F.indexOf(t.charAt(a++));rn-1&&(null==i[r+1]&&(i[r+1]=0),i[r+1]+=i[r]/n|0,i[r]%=n)}return i.reverse()}function l(t,e){return(t.length>1?t.charAt(0)+"."+t.slice(1):t)+(0>e?"e":"e+")+e}function f(t,e){var n,r;if(0>e){for(r="0.";++e;r+="0");t=r+t}else if(n=t.length,++e>n){for(r="0",e-=n;--e;r+="0");t+=r}else n>e&&(t=t.slice(0,e)+"."+t.slice(e));return t}function p(t){return t=parseFloat(t),0>t?y(t):v(t)}var m,h,d,g=/^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,y=Math.ceil,v=Math.floor,b=" not a boolean or binary digit",w="rounding mode",_="number type has more than 15 significant digits",F="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_",x=1e14,I=14,N=9007199254740991,O=[1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13],B=1e7,P=1e9;if(m=r(),"function"==typeof define&&define.amd)define(function(){return m});else if("undefined"!=typeof e&&e.exports){if(e.exports=m,!h)try{h=t("crypto")}catch(T){}}else n.BigNumber=m}(this)},{crypto:28}],web3:[function(t,e,n){var r=t("./lib/web3");r.providers.HttpProvider=t("./lib/web3/httpprovider"),r.providers.QtSyncProvider=t("./lib/web3/qtsync"),r.eth.contract=t("./lib/web3/contract"),r.abi=t("./lib/solidity/abi"),"undefined"!=typeof window&&"undefined"==typeof window.web3&&(window.web3=r),e.exports=r},{"./lib/solidity/abi":1,"./lib/web3":10,"./lib/web3/contract":11,"./lib/web3/httpprovider":19,"./lib/web3/qtsync":24}]},{},["web3"]); \ No newline at end of file diff --git a/example/event_inc.html b/example/event_inc.html index 74bcb9c4b..ac12c6447 100644 --- a/example/event_inc.html +++ b/example/event_inc.html @@ -45,7 +45,7 @@ var contract; 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 () { diff --git a/lib/solidity/abi.js b/lib/solidity/abi.js index e9299c386..feb139ed4 100644 --- a/lib/solidity/abi.js +++ b/lib/solidity/abi.js @@ -21,113 +21,24 @@ * @date 2014 */ -var utils = require('../utils/utils'); var coder = require('./coder'); -var solUtils = 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 utils = require('./utils'); var formatConstructorParams = function (abi, params) { - var constructor = solUtils.getConstructor(abi, params.length); + var constructor = utils.getConstructor(abi, params.length); if (!constructor) { if (params.length > 0) { console.warn("didn't found matching constructor, using default one"); } return ''; } - return formatInput(constructor.inputs, params); + + return coder.encodeParams(constructor.inputs.map(function (input) { + return input.type; + }), params); }; module.exports = { - inputParser: inputParser, - outputParser: outputParser, - formatInput: formatInput, - formatOutput: formatOutput, formatConstructorParams: formatConstructorParams }; + diff --git a/lib/solidity/coder.js b/lib/solidity/coder.js index 76de8d426..b46a38b0b 100644 --- a/lib/solidity/coder.js +++ b/lib/solidity/coder.js @@ -77,9 +77,8 @@ SolidityType.prototype.formatInput = function (param, arrayType) { return param.map(function (p) { return self._inputFormatter(p); }).reduce(function (acc, current) { - acc.appendArrayElement(current); - return acc; - }, new SolidityParam('', f.formatInputInt(param.length).value)); + return acc.combine(current); + }, f.formatInputInt(param.length)).withOffset(32); } return this._inputFormatter(param); }; @@ -96,9 +95,9 @@ SolidityType.prototype.formatOutput = function (param, arrayType) { if (arrayType) { // let's assume, that we solidity will never return long arrays :P 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) { - 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; } @@ -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 - * @param {String} type - * @returns {Bool} true if the type is variadic - */ -SolidityType.prototype.isVariadicType = function (type) { - return isArrayType(type) || this._mode === 'bytes'; -}; - -/** - * Should be used to shift param from params group - * - * @method shiftParam + * @method sliceParam + * @param {String} bytes + * @param {Number} index of param to slice * @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') { - return param.shiftBytes(); + return SolidityParam.decodeBytes(bytes, index); } else if (isArrayType(type)) { - var length = new BigNumber(param.prefix.slice(0, 64), 16); - return param.shiftArray(length); + return SolidityParam.decodeArray(bytes, index); } - return param.shiftValue(); + return SolidityParam.decodeParam(bytes, index); }; /** @@ -160,28 +149,6 @@ SolidityCoder.prototype._requireType = function (type) { 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 * @@ -216,24 +183,11 @@ SolidityCoder.prototype.encodeParam = function (type, param) { */ SolidityCoder.prototype.encodeParams = function (types, params) { var self = this; - return types.map(function (type, index) { + var solidityParams = types.map(function (type, index) { return self._formatInput(type, params[index]); - }).reduce(function (acc, solidityParam) { - acc.append(solidityParam); - return acc; - }, new SolidityParam()).encode(); -}; + }); -/** - * 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)); + return SolidityParam.encodeList(solidityParams); }; /** @@ -245,7 +199,7 @@ SolidityCoder.prototype._formatOutput = function (type, param) { * @return {Object} plain param */ 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) { var self = this; - var param = this._bytesToParam(types, bytes); - return types.map(function (type) { + return types.map(function (type, index) { var solidityType = self._requireType(type); - var p = solidityType.shiftParam(type, param); + var p = solidityType.sliceParam(bytes, index, type); return solidityType.formatOutput(p, isArrayType(type)); }); }; diff --git a/lib/solidity/formatters.js b/lib/solidity/formatters.js index a4ff3406c..3db936528 100644 --- a/lib/solidity/formatters.js +++ b/lib/solidity/formatters.js @@ -63,7 +63,7 @@ var formatInputBytes = function (value) { */ var formatInputDynamicBytes = function (value) { 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 */ var formatOutputInt = function (param) { - var value = param.value || "0"; + var value = param.staticPart() || "0"; // check if it's negative number // it it is, return two's complement @@ -127,7 +127,7 @@ var formatOutputInt = function (param) { * @returns {BigNumeber} right-aligned output bytes formatted to uint */ var formatOutputUInt = function (param) { - var value = param.value || "0"; + var value = param.staticPart() || "0"; return new BigNumber(value, 16); }; @@ -161,7 +161,7 @@ var formatOutputUReal = function (param) { * @returns {Boolean} right-aligned input bytes formatted to bool */ 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) { // 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) { // 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 */ var formatOutputAddress = function (param) { - var value = param.value; + var value = param.staticPart(); return "0x" + value.slice(value.length - 40, value.length); }; diff --git a/lib/solidity/param.js b/lib/solidity/param.js index 15ba0c61f..7c3254659 100644 --- a/lib/solidity/param.js +++ b/lib/solidity/param.js @@ -20,85 +20,190 @@ * @date 2015 */ +var utils = require('../utils/utils'); + /** * SolidityParam object prototype. * Should be used when encoding, decoding solidity bytes */ -var SolidityParam = function (value, prefix, suffix) { - this.prefix = prefix || ''; +var SolidityParam = function (value, offset) { 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 - * @param {SolidityParam} param that it appended after this + * @method offsetAsBytes + * @returns {String} bytes representation of offset */ -SolidityParam.prototype.append = function (param) { - this.prefix += param.prefix; - this.value += param.value; - this.suffix += param.suffix; +SolidityParam.prototype.offsetAsBytes = function () { + return !this.isDynamic() ? '' : utils.padLeft(utils.toTwosComplement(this.offset).toString(16), 64); }; /** - * 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 - * @param {SolidityParam} param that is appended to an array + * @method staticPart + * @returns {String} offset if it is a dynamic param, otherwise value */ -SolidityParam.prototype.appendArrayElement = function (param) { - this.suffix += param.value; - this.prefix += param.prefix; - // TODO: suffix not supported = it's required for nested arrays; +SolidityParam.prototype.staticPart = function () { + if (!this.isDynamic()) { + return this.value; + } + 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 - * @return {String} encoded param(s) + * @returns {String} */ 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 - * @return {SolidityParam} first value param + * @method encodeList + * @param {Array[SolidityParam]} params + * @returns {String} */ -SolidityParam.prototype.shiftValue = function () { - var value = this.value.slice(0, 64); - this.value = this.value.slice(64); - return new SolidityParam(value); +SolidityParam.encodeList = function (params) { + + // updating offsets + 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 - * @return {SolidityParam} first bytes param + * @method decodeParam + * @param {String} bytes + * @param {Number} index + * @returns {SolidityParam} */ -SolidityParam.prototype.shiftBytes = function () { - return this.shiftArray(1); +SolidityParam.decodeParam = function (bytes, index) { + index = index || 0; + return new SolidityParam(bytes.substr(index * 64, 64)); }; /** - * This method should be used to shift an array from group of params - * - * @method shiftArray - * @param {Number} size of an array to shift - * @return {SolidityParam} first array param + * This method should be called to get offset value from bytes at given index + * + * @method getOffset + * @param {String} bytes + * @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) { - var prefix = this.prefix.slice(0, 64); - this.prefix = this.value.slice(64); - var suffix = this.suffix.slice(0, 64 * length); - this.suffix = this.suffix.slice(64 * length); - return new SolidityParam('', prefix, suffix); +SolidityParam.decodeArray = function (bytes, index) { + index = index || 0; + var offset = getOffset(bytes, index); + var length = parseInt('0x' + bytes.substr(offset * 2, 64)); + return new SolidityParam(bytes.substr(offset * 2, (length + 1) * 64)); }; module.exports = SolidityParam; diff --git a/lib/solidity/utils.js b/lib/solidity/utils.js index 9ea416d8b..23566f74a 100644 --- a/lib/solidity/utils.js +++ b/lib/solidity/utils.js @@ -34,6 +34,11 @@ var getConstructor = function (abi, numberOfArgs) { })[0]; }; +//var getSupremeType = function (type) { + //return type.substr(0, type.indexOf('[')) + ']'; +//}; + + module.exports = { getConstructor: getConstructor }; diff --git a/lib/version.json b/lib/version.json index 536695767..e5c97ebab 100644 --- a/lib/version.json +++ b/lib/version.json @@ -1,3 +1,3 @@ { - "version": "0.3.3" + "version": "0.3.6" } diff --git a/lib/web3/eth.js b/lib/web3/eth.js index 625f5c02d..b955a45ac 100644 --- a/lib/web3/eth.js +++ b/lib/web3/eth.js @@ -23,7 +23,7 @@ /** * Web3 - * + * * @module web3 */ @@ -77,16 +77,16 @@ var uncleCountCall = function (args) { /// @returns an array of objects describing web3.eth api methods var getBalance = new Method({ - name: 'getBalance', - call: 'eth_getBalance', + name: 'getBalance', + call: 'eth_getBalance', params: 2, inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter], outputFormatter: formatters.outputBigNumberFormatter }); var getStorageAt = new Method({ - name: 'getStorageAt', - call: 'eth_getStorageAt', + name: 'getStorageAt', + call: 'eth_getStorageAt', params: 3, inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter] }); @@ -99,7 +99,7 @@ var getCode = new Method({ }); var getBlock = new Method({ - name: 'getBlock', + name: 'getBlock', call: blockCall, params: 2, inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }], @@ -224,6 +224,11 @@ var properties = [ name: 'mining', getter: 'eth_mining' }), + new Property({ + name: 'hashrate', + getter: 'eth_hashrate', + outputFormatter: utils.toDecimal + }), new Property({ name: 'gasPrice', getter: 'eth_gasPrice', diff --git a/lib/web3/event.js b/lib/web3/event.js index eeffa0cdd..f9305f8b8 100644 --- a/lib/web3/event.js +++ b/lib/web3/event.js @@ -96,7 +96,7 @@ SolidityEvent.prototype.encode = function (indexed, options) { ['fromBlock', 'toBlock'].filter(function (f) { return options[f] !== undefined; }).forEach(function (f) { - result[f] = utils.toHex(options[f]); + result[f] = formatters.inputBlockNumberFormatter(options[f]); }); result.topics = []; diff --git a/lib/web3/formatters.js b/lib/web3/formatters.js index 73fd907da..d45353649 100644 --- a/lib/web3/formatters.js +++ b/lib/web3/formatters.js @@ -72,7 +72,7 @@ var inputTransactionFormatter = function (options){ delete options.code; } - ['gasPrice', 'gas', 'value'].filter(function (key) { + ['gasPrice', 'gas', 'value', 'nonce'].filter(function (key) { return options[key] !== undefined; }).forEach(function(key){ options[key] = utils.fromDecimal(options[key]); diff --git a/lib/web3/httpprovider.js b/lib/web3/httpprovider.js index 83ab4bb5d..fd972c05a 100644 --- a/lib/web3/httpprovider.js +++ b/lib/web3/httpprovider.js @@ -48,15 +48,32 @@ HttpProvider.prototype.send = function (payload) { //if (request.status !== 200) { //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) { var request = new XMLHttpRequest(); request.onreadystatechange = function() { if (request.readyState === 4) { - // TODO: handle the error properly here!!! - callback(null, JSON.parse(request.responseText)); + var result = request.responseText; + var error = null; + + try { + result = JSON.parse(result); + } catch(e) { + error = errors.InvalidResponse(result); + } + + callback(error, result); } }; diff --git a/package.js b/package.js index 40b274bd7..bfb8d0556 100644 --- a/package.js +++ b/package.js @@ -1,7 +1,7 @@ /* jshint ignore:start */ Package.describe({ name: 'ethereum:web3', - version: '0.3.3', + version: '0.3.6', summary: 'Ethereum JavaScript API, middleware to talk to a ethreum node over RPC', git: 'https://github.com/ethereum/ethereum.js', // By default, Meteor will default to using README.md for documentation. diff --git a/package.json b/package.json index f6756cab1..4c7c81445 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "web3", "namespace": "ethereum", - "version": "0.3.3", + "version": "0.3.6", "description": "Ethereum JavaScript API, middleware to talk to a ethereum node over RPC", "main": "./index.js", "directories": { diff --git a/test/abi.inputParser.js b/test/abi.inputParser.js deleted file mode 100644 index 6700acd72..000000000 --- a/test/abi.inputParser.js +++ /dev/null @@ -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); - - }); - - }); -}); diff --git a/test/abi.outputParser.js b/test/abi.outputParser.js deleted file mode 100644 index 5fe23e28a..000000000 --- a/test/abi.outputParser.js +++ /dev/null @@ -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); - - }); - - }); -}); - diff --git a/test/coder.decodeParam.js b/test/coder.decodeParam.js index 3eea9dd6f..23b0228eb 100644 --- a/test/coder.decodeParam.js +++ b/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(-1), value: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); test({ type: 'bytes32', expected: 'gavofyork', value: '6761766f66796f726b0000000000000000000000000000000000000000000000'}); - test({ type: 'bytes', expected: 'gavofyork', value: '0000000000000000000000000000000000000000000000000000000000000009' + + test({ type: 'bytes', expected: 'gavofyork', value: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000009' + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); - test({ type: 'int[]', expected: [new bn(3)], value: '0000000000000000000000000000000000000000000000000000000000000001' + + test({ type: 'int[]', expected: [new bn(3)], value: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000003'}); - test({ type: 'int256[]', expected: [new bn(3)], value: '0000000000000000000000000000000000000000000000000000000000000001' + + test({ type: 'int256[]', expected: [new bn(3)], value: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000003'}); test({ type: 'int[]', expected: [new bn(1), new bn(2), new bn(3)], - value: '0000000000000000000000000000000000000000000000000000000000000003' + + value: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000003' + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000002' + '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'}); 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)]], - values: '0000000000000000000000000000000000000000000000000000000000000009' + - '0000000000000000000000000000000000000000000000000000000000000003' + - '0000000000000000000000000000000000000000000000000000000000000001' + - '0000000000000000000000000000000000000000000000000000000000000002' + - '0000000000000000000000000000000000000000000000000000000000000003' + - '0000000000000000000000000000000000000000000000000000000000000004' + - '6761766f66796f726b0000000000000000000000000000000000000000000000' + - '0000000000000000000000000000000000000000000000000000000000000005' + - '0000000000000000000000000000000000000000000000000000000000000006' + - '0000000000000000000000000000000000000000000000000000000000000007'}); + values: '0000000000000000000000000000000000000000000000000000000000000001' + + '00000000000000000000000000000000000000000000000000000000000000c0' + + '0000000000000000000000000000000000000000000000000000000000000002' + + '0000000000000000000000000000000000000000000000000000000000000003' + + '0000000000000000000000000000000000000000000000000000000000000004' + + '0000000000000000000000000000000000000000000000000000000000000100' + + '0000000000000000000000000000000000000000000000000000000000000009' + + '6761766f66796f726b0000000000000000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000003' + + '0000000000000000000000000000000000000000000000000000000000000005' + + '0000000000000000000000000000000000000000000000000000000000000006' + + '0000000000000000000000000000000000000000000000000000000000000007'}); }); }); diff --git a/test/coder.encodeParam.js b/test/coder.encodeParam.js index a9e11ab9e..60d1c618e 100644 --- a/test/coder.encodeParam.js +++ b/test/coder.encodeParam.js @@ -15,20 +15,37 @@ describe('lib/solidity/coder', function () { test({ type: 'int', value: 1, expected: '0000000000000000000000000000000000000000000000000000000000000001'}); test({ type: 'int', value: 16, expected: '0000000000000000000000000000000000000000000000000000000000000010'}); 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: 16, expected: '0000000000000000000000000000000000000000000000000000000000000010'}); test({ type: 'int256', value: -1, expected: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); test({ type: 'bytes32', value: 'gavofyork', expected: '6761766f66796f726b0000000000000000000000000000000000000000000000'}); - test({ type: 'bytes', value: 'gavofyork', expected: '0000000000000000000000000000000000000000000000000000000000000009' + + test({ type: 'bytes', value: 'gavofyork', expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000009' + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); - test({ type: 'int[]', value: [3], expected: '0000000000000000000000000000000000000000000000000000000000000001' + + test({ type: 'int[]', value: [3], expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000003'}); - test({ type: 'int256[]', value: [3], expected: '0000000000000000000000000000000000000000000000000000000000000001' + + test({ type: 'int256[]', value: [3], expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000003'}); - test({ type: 'int[]', value: [1,2,3], expected: '0000000000000000000000000000000000000000000000000000000000000003' + + test({ type: 'int[]', value: [1,2,3], expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000003' + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000002' + '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: [-1], expected: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); test({ types: ['bytes32'], values: ['gavofyork'], expected: '6761766f66796f726b0000000000000000000000000000000000000000000000'}); - test({ types: ['bytes'], values: ['gavofyork'], expected: '0000000000000000000000000000000000000000000000000000000000000009' + + test({ types: ['bytes'], values: ['gavofyork'], expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000009' + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); - test({ types: ['int[]'], values: [[3]], expected: '0000000000000000000000000000000000000000000000000000000000000001' + + test({ types: ['int[]'], values: [[3]], expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000003'}); - test({ types: ['int256[]'], values: [[3]], expected: '0000000000000000000000000000000000000000000000000000000000000001' + + test({ types: ['int256[]'], values: [[3]], expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000003'}); - test({ types: ['int256[]'], values: [[1,2,3]], expected: '0000000000000000000000000000000000000000000000000000000000000003' + + test({ types: ['int256[]'], values: [[1,2,3]], expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000003' + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000002' + '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], expected: '6761766f66796f726b0000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000000000005'}); @@ -66,25 +96,47 @@ describe('lib/solidity/coder', function () { expected: '0000000000000000000000000000000000000000000000000000000000000005' + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); test({ types: ['bytes', 'int'], values: ['gavofyork', 5], - expected: '0000000000000000000000000000000000000000000000000000000000000009' + + expected: '0000000000000000000000000000000000000000000000000000000000000040' + '0000000000000000000000000000000000000000000000000000000000000005' + + '0000000000000000000000000000000000000000000000000000000000000009' + '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'], - expected: '0000000000000000000000000000000000000000000000000000000000000009' + - '0000000000000000000000000000000000000000000000000000000000000005' + + expected: '0000000000000000000000000000000000000000000000000000000000000005' + + '0000000000000000000000000000000000000000000000000000000000000040' + + '0000000000000000000000000000000000000000000000000000000000000009' + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); test({ types: ['int', 'bytes', 'int', 'int', 'int', 'int[]'], values: [1, 'gavofyork', 2, 3, 4, [5, 6, 7]], - expected: '0000000000000000000000000000000000000000000000000000000000000009' + - '0000000000000000000000000000000000000000000000000000000000000003' + - '0000000000000000000000000000000000000000000000000000000000000001' + + expected: '0000000000000000000000000000000000000000000000000000000000000001' + + '00000000000000000000000000000000000000000000000000000000000000c0' + '0000000000000000000000000000000000000000000000000000000000000002' + '0000000000000000000000000000000000000000000000000000000000000003' + '0000000000000000000000000000000000000000000000000000000000000004' + + '0000000000000000000000000000000000000000000000000000000000000100' + + '0000000000000000000000000000000000000000000000000000000000000009' + '6761766f66796f726b0000000000000000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000003' + '0000000000000000000000000000000000000000000000000000000000000005' + '0000000000000000000000000000000000000000000000000000000000000006' + '0000000000000000000000000000000000000000000000000000000000000007'}); - }); }); diff --git a/test/contract.js b/test/contract.js index 8a2ea109d..0dcaa1003 100644 --- a/test/contract.js +++ b/test/contract.js @@ -345,6 +345,7 @@ describe('web3.eth.contract', function () { assert.equal(payload.method, 'eth_call'); assert.deepEqual(payload.params, [{ data: sha3.slice(0, 10) + + '0000000000000000000000000000000000000000000000000000000000000020' + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000003', to: address diff --git a/test/event.encode.js b/test/event.encode.js index c28588c2e..6d9850c00 100644 --- a/test/event.encode.js +++ b/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: { name: 'event1', inputs: [{ diff --git a/test/formatters.inputTransactionFormatter.js b/test/formatters.inputTransactionFormatter.js index 2f7f8c2e5..44c3534d3 100644 --- a/test/formatters.inputTransactionFormatter.js +++ b/test/formatters.inputTransactionFormatter.js @@ -3,24 +3,62 @@ var assert = chai.assert; var formatters = require('../lib/web3/formatters.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('inputTransactionFormatter', function () { - it('should return the correct value', function () { - - assert.deepEqual(formatters.inputTransactionFormatter({ - 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' + tests.forEach(function(test){ + it('should return the correct value', function () { + assert.deepEqual(formatters.inputTransactionFormatter(test.input), test.result); }); }); }); diff --git a/test/web3.eth.filter.js b/test/web3.eth.filter.js index d8b37311a..7a355b50c 100644 --- a/test/web3.eth.filter.js +++ b/test/web3.eth.filter.js @@ -21,6 +21,21 @@ var tests = [{ result: '0xf', formattedResult: '0xf', 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'], formattedArgs: ['pending'], diff --git a/test/web3.eth.hashRate.js b/test/web3.eth.hashRate.js new file mode 100644 index 000000000..ec01bfad1 --- /dev/null +++ b/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); + }); + }); + }); +}); + From 9b80352a7c4549c123dbac621e8a6609b0f31961 Mon Sep 17 00:00:00 2001 From: arkpar Date: Mon, 11 May 2015 07:45:05 +0200 Subject: [PATCH 06/30] made _secret parameter optional --- mix/MixClient.cpp | 16 ++++++++-------- mix/MixClient.h | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index 09fed6fc6..cac208ba4 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -98,7 +98,7 @@ void MixClient::resetState(std::unordered_map const& _accounts m_executions.clear(); } -Transaction MixClient::replaceGas(Transaction const& _t, Secret const& _secret, u256 const& _gas) +Transaction MixClient::replaceGas(Transaction const& _t, u256 const& _gas, Secret const& _secret) { Transaction ret; if (_secret) @@ -119,9 +119,9 @@ Transaction MixClient::replaceGas(Transaction const& _t, Secret const& _secret, return ret; } -void MixClient::executeTransaction(Transaction const& _t, Secret const& _secret, State& _state, bool _call, bool _gasAuto) +void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _call, bool _gasAuto, Secret const& _secret) { - Transaction t = _gasAuto ? replaceGas(_t, Secret(), m_state.gasLimitRemaining()) : _t; + Transaction t = _gasAuto ? replaceGas(_t, m_state.gasLimitRemaining()) : _t; // do debugging run first LastHashes lastHashes(256); lastHashes[0] = bc().numberHash(bc().number()); @@ -230,7 +230,7 @@ void MixClient::executeTransaction(Transaction const& _t, Secret const& _secret, // execute on a state if (!_call) { - t = _gasAuto ? replaceGas(_t, _secret, d.gasUsed) : _t; + t = _gasAuto ? replaceGas(_t, d.gasUsed, _secret) : _t; er =_state.execute(lastHashes, t); if (t.isCreation() && _state.code(d.contractAddress).empty()) BOOST_THROW_EXCEPTION(OutOfGas() << errinfo_comment("Not enough gas for contract deployment")); @@ -293,7 +293,7 @@ void MixClient::submitTransaction(Secret _secret, u256 _value, Address _dest, by WriteGuard l(x_state); u256 n = m_state.transactionsFrom(toAddress(_secret)); Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); - executeTransaction(t, _secret, m_state, false, _gasAuto); + executeTransaction(t, m_state, false, _gasAuto, _secret); } Address MixClient::submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice, bool _gasAuto) @@ -301,7 +301,7 @@ Address MixClient::submitTransaction(Secret _secret, u256 _endowment, bytes cons WriteGuard l(x_state); u256 n = m_state.transactionsFrom(toAddress(_secret)); eth::Transaction t(_endowment, _gasPrice, _gas, _init, n, _secret); - executeTransaction(t, _secret, m_state, false, _gasAuto); + executeTransaction(t, m_state, false, _gasAuto, _secret); Address address = right160(sha3(rlpList(t.sender(), t.nonce()))); return address; } @@ -316,7 +316,7 @@ dev::eth::ExecutionResult MixClient::call(Address const& _from, u256 _value, Add if (_ff == FudgeFactor::Lenient) temp.addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value())); WriteGuard lw(x_state); //TODO: lock is required only for last execution state - executeTransaction(t, Secret(), temp, true, _gasAuto); + executeTransaction(t, temp, true, _gasAuto); return lastExecution().result; } @@ -350,7 +350,7 @@ dev::eth::ExecutionResult MixClient::create(Address const& _from, u256 _value, b if (_ff == FudgeFactor::Lenient) temp.addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value())); WriteGuard lw(x_state); //TODO: lock is required only for last execution state - executeTransaction(t, Secret(), temp, true, false); + executeTransaction(t, temp, true, false); return lastExecution().result; } diff --git a/mix/MixClient.h b/mix/MixClient.h index 5988286d0..2c6734234 100644 --- a/mix/MixClient.h +++ b/mix/MixClient.h @@ -87,9 +87,9 @@ protected: virtual void prepareForTransaction() override {} private: - void executeTransaction(dev::eth::Transaction const& _t, dev::Secret const& _secret, eth::State& _state, bool _call, bool _gasAuto); + void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state, bool _call, bool _gasAuto, dev::Secret const& _secret = dev::Secret()); void noteChanged(h256Set const& _filters); - dev::eth::Transaction replaceGas(dev::eth::Transaction const& _t, dev::Secret const& _secret, dev::u256 const& _gas); + dev::eth::Transaction replaceGas(dev::eth::Transaction const& _t, dev::u256 const& _gas, dev::Secret const& _secret = dev::Secret()); eth::State m_state; eth::State m_startState; From 7ca3e392988e0521ad131729505bfab002ba1113 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 11 May 2015 09:42:32 +0200 Subject: [PATCH 07/30] fix BlockGasLimit verification --- libethcore/BlockInfo.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libethcore/BlockInfo.cpp b/libethcore/BlockInfo.cpp index e20e88a91..083ade9a4 100644 --- a/libethcore/BlockInfo.cpp +++ b/libethcore/BlockInfo.cpp @@ -246,9 +246,9 @@ void BlockInfo::verifyParent(BlockInfo const& _parent) const BOOST_THROW_EXCEPTION(InvalidDifficulty() << RequirementError((bigint)calculateDifficulty(_parent), (bigint)difficulty)); if (gasLimit < c_minGasLimit || - gasLimit < _parent.gasLimit * (c_gasLimitBoundDivisor - 1) / c_gasLimitBoundDivisor || - gasLimit > _parent.gasLimit * (c_gasLimitBoundDivisor + 1) / c_gasLimitBoundDivisor) - BOOST_THROW_EXCEPTION(InvalidGasLimit() << errinfo_min((bigint)_parent.gasLimit * (c_gasLimitBoundDivisor - 1) / c_gasLimitBoundDivisor) << errinfo_got((bigint)gasLimit) << errinfo_max((bigint)_parent.gasLimit * (c_gasLimitBoundDivisor + 1) / c_gasLimitBoundDivisor)); + gasLimit < _parent.gasLimit - _parent.gasLimit / c_gasLimitBoundDivisor || + gasLimit > _parent.gasLimit + _parent.gasLimit / c_gasLimitBoundDivisor) + BOOST_THROW_EXCEPTION(InvalidGasLimit() << errinfo_min((bigint)_parent.gasLimit - _parent.gasLimit / c_gasLimitBoundDivisor) << errinfo_got((bigint)gasLimit) << errinfo_max((bigint)_parent.gasLimit + _parent.gasLimit / c_gasLimitBoundDivisor)); // Check timestamp is after previous timestamp. if (parentHash) From de64afac2bd46d1a48484472fc46f2320fb2a90e Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 11 May 2015 09:48:53 +0200 Subject: [PATCH 08/30] fix --- libethcore/BlockInfo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libethcore/BlockInfo.cpp b/libethcore/BlockInfo.cpp index 083ade9a4..f6ecb5472 100644 --- a/libethcore/BlockInfo.cpp +++ b/libethcore/BlockInfo.cpp @@ -246,8 +246,8 @@ void BlockInfo::verifyParent(BlockInfo const& _parent) const BOOST_THROW_EXCEPTION(InvalidDifficulty() << RequirementError((bigint)calculateDifficulty(_parent), (bigint)difficulty)); if (gasLimit < c_minGasLimit || - gasLimit < _parent.gasLimit - _parent.gasLimit / c_gasLimitBoundDivisor || - gasLimit > _parent.gasLimit + _parent.gasLimit / c_gasLimitBoundDivisor) + gasLimit <= _parent.gasLimit - _parent.gasLimit / c_gasLimitBoundDivisor || + gasLimit >= _parent.gasLimit + _parent.gasLimit / c_gasLimitBoundDivisor) BOOST_THROW_EXCEPTION(InvalidGasLimit() << errinfo_min((bigint)_parent.gasLimit - _parent.gasLimit / c_gasLimitBoundDivisor) << errinfo_got((bigint)gasLimit) << errinfo_max((bigint)_parent.gasLimit + _parent.gasLimit / c_gasLimitBoundDivisor)); // Check timestamp is after previous timestamp. From 4b3fd578f818d5b502299f103f1e44c7d5715bf5 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 11 May 2015 09:58:00 +0200 Subject: [PATCH 09/30] fix selecting gasLimit --- libethcore/BlockInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethcore/BlockInfo.cpp b/libethcore/BlockInfo.cpp index f6ecb5472..eb64593af 100644 --- a/libethcore/BlockInfo.cpp +++ b/libethcore/BlockInfo.cpp @@ -228,7 +228,7 @@ u256 BlockInfo::selectGasLimit(BlockInfo const& _parent) const return c_genesisGasLimit; else // target minimum of 3141592 - return max(max(c_minGasLimit, 3141592), (_parent.gasLimit * (c_gasLimitBoundDivisor - 1) + (_parent.gasUsed * 6 / 5)) / c_gasLimitBoundDivisor); + return max(max(c_minGasLimit, 3141592), _parent.gasLimit - _parent.gasLimit / c_gasLimitBoundDivisor + 1 + (_parent.gasUsed * 6 / 5) / c_gasLimitBoundDivisor); } u256 BlockInfo::calculateDifficulty(BlockInfo const& _parent) const From 0470ff66497753220c74ccdda7d7075ff402ac1a Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 11 May 2015 12:30:47 +0200 Subject: [PATCH 10/30] cmake target for building osx .dmg file --- CMakeLists.txt | 16 +++++++++++++++- appdmg.json.in | 13 +++++++++++++ bg.png | Bin 0 -> 175517 bytes cmake/EthDependencies.cmake | 5 +++++ cmake/scripts/appdmg.cmake | 17 +++++++++++++++++ 5 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 appdmg.json.in create mode 100644 bg.png create mode 100644 cmake/scripts/appdmg.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ba214cce..1f2877c10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -396,8 +396,22 @@ if (GUI) endif() +if (APPLE) -#unset(TARGET_PLATFORM CACHE) + add_custom_target(appdmg + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMAND ${CMAKE_COMMAND} + -DAPP_DMG_EXE=${ETH_APP_DMG} + -DAPP_DMG_FILE=appdmg.json.in + -DAPP_DMG_ICON="alethzero/alethzero.icns" + -DAPP_DMG_BACKGROUND="bg.png" + -DETH_BUILD_DIR="${CMAKE_BINARY_DIR}" + -DETH_MIX_APP="$" + -DETH_ALETHZERO_APP="$" + -P "${ETH_SCRIPTS_DIR}/appdmg.cmake" + ) + +endif () if (WIN32) # packaging stuff diff --git a/appdmg.json.in b/appdmg.json.in new file mode 100644 index 000000000..4fb9a6e33 --- /dev/null +++ b/appdmg.json.in @@ -0,0 +1,13 @@ +{ + "title": "Ethereum", + "icon": "appdmg_icon.icns", + "background": "appdmg_background.png", + "icon-size": 80, + "contents": [ + { "x": 600, "y": 170, "type": "link", "path": "/Applications" }, + { "x": 150, "y": 90, "type": "file", "path": "${ETH_ALETHZERO_APP}" }, + { "x": 150, "y": 260, "type": "file", "path": "${ETH_MIX_APP}" } + ] +} + + diff --git a/bg.png b/bg.png new file mode 100644 index 0000000000000000000000000000000000000000..869290c2b861dd148e1ae500770f3bc47879761e GIT binary patch literal 175517 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
-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�I*sMH@QHEDf(ql`);jlqV0D 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 Date: Mon, 11 May 2015 14:26:27 +0200 Subject: [PATCH 11/30] reorganize inout Limits tests --- test/libevm/vm.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/test/libevm/vm.cpp b/test/libevm/vm.cpp index 8b5a7c5d3..4c666dbba 100644 --- a/test/libevm/vm.cpp +++ b/test/libevm/vm.cpp @@ -492,16 +492,10 @@ BOOST_AUTO_TEST_CASE(vmPerformanceTest) dev::test::executeTests("vmPerformanceTest", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests); } -BOOST_AUTO_TEST_CASE(vmInputLimitsTest1) +BOOST_AUTO_TEST_CASE(vmInputLimitsTest) { if (test::Options::get().inputLimits) - dev::test::executeTests("vmInputLimits1", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests); -} - -BOOST_AUTO_TEST_CASE(vmInputLimitsTest2) -{ - if (test::Options::get().inputLimits) - dev::test::executeTests("vmInputLimits2", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests); + dev::test::executeTests("vmInputLimits", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests); } BOOST_AUTO_TEST_CASE(vmInputLimitsLightTest) From ef6c1588059900fb536948ff6a8276610e7b39b3 Mon Sep 17 00:00:00 2001 From: Liana Husikyan Date: Mon, 11 May 2015 13:47:21 +0200 Subject: [PATCH 12/30] bug in abi. fixed external type for return parameters --- libsolidity/InterfaceHandler.cpp | 10 ++-- test/libsolidity/SolidityABIJSON.cpp | 48 ++++++++++++++++++- .../SolidityNameAndTypeResolution.cpp | 22 +++++++++ 3 files changed, 74 insertions(+), 6 deletions(-) diff --git a/libsolidity/InterfaceHandler.cpp b/libsolidity/InterfaceHandler.cpp index d4958475b..e266f8d61 100644 --- a/libsolidity/InterfaceHandler.cpp +++ b/libsolidity/InterfaceHandler.cpp @@ -55,15 +55,15 @@ std::unique_ptr InterfaceHandler::getABIInterface(ContractDefinitio for (auto it: _contractDef.getInterfaceFunctions()) { - + auto externalFunctionType = it.second->externalFunctionType(); Json::Value method; method["type"] = "function"; method["name"] = it.second->getDeclaration().getName(); method["constant"] = it.second->isConstant(); - method["inputs"] = populateParameters(it.second->getParameterNames(), - it.second->getParameterTypeNames()); - method["outputs"] = populateParameters(it.second->getReturnParameterNames(), - it.second->getReturnParameterTypeNames()); + method["inputs"] = populateParameters(externalFunctionType->getParameterNames(), + externalFunctionType->getParameterTypeNames()); + method["outputs"] = populateParameters(externalFunctionType->getReturnParameterNames(), + externalFunctionType->getReturnParameterTypeNames()); abi.append(method); } if (_contractDef.getConstructor()) diff --git a/test/libsolidity/SolidityABIJSON.cpp b/test/libsolidity/SolidityABIJSON.cpp index 26d0110b8..6c1025d6a 100644 --- a/test/libsolidity/SolidityABIJSON.cpp +++ b/test/libsolidity/SolidityABIJSON.cpp @@ -499,7 +499,8 @@ BOOST_AUTO_TEST_CASE(constructor_abi) { char const* sourceCode = R"( contract test { - function test(uint param1, test param2, bool param3) {} + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function test(uint param1, test param2, bool param3, ActionChoices param4) {} } )"; @@ -517,6 +518,51 @@ BOOST_AUTO_TEST_CASE(constructor_abi) { "name": "param3", "type": "bool" + }, + { + "name": "param4", + "type": "uint8" + } + ], + "type": "constructor" + } + ])"; + checkInterface(sourceCode, interface); +} + + +BOOST_AUTO_TEST_CASE(return_param_in_abi) +{ + // bug #1801 + char const* sourceCode = R"( + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function test(ActionChoices param) {} + function ret() returns(ActionChoices){ + ActionChoices action = ActionChoices.GoLeft; + return action; + } + } + )"; + + char const* interface = R"([ + { + "constant" : false, + "inputs" : [], + "name" : "ret", + "outputs" : [ + { + "name" : "", + "type" : "uint8" + } + ], + "type" : "function" + }, + { + "inputs": [ + { + "name": "param", + "type": "uint8" } ], "type": "constructor" diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index c317dad97..c59c1f56f 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -508,6 +508,28 @@ BOOST_AUTO_TEST_CASE(function_external_types) } } +BOOST_AUTO_TEST_CASE(enum_external_type) +{ + // bug #1801 + ASTPointer sourceUnit; + char const* text = R"( + contract Test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function boo(ActionChoices enumArg) external returns (uint ret) { + ret = 5; + } + })"; + ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseTextAndResolveNames(text), "Parsing and name Resolving failed"); + for (ASTPointer const& node: sourceUnit->getNodes()) + if (ContractDefinition* contract = dynamic_cast(node.get())) + { + auto functions = contract->getDefinedFunctions(); + if (functions.empty()) + continue; + BOOST_CHECK_EQUAL("boo(uint8)", functions[0]->externalSignature()); + } +} + BOOST_AUTO_TEST_CASE(function_external_call_allowed_conversion) { char const* text = R"( From 6cc7bb915a217d359c2091fb8875880071371a37 Mon Sep 17 00:00:00 2001 From: Liana Husikyan Date: Mon, 11 May 2015 16:24:04 +0200 Subject: [PATCH 13/30] updated unit test --- libsolidity/InterfaceHandler.cpp | 12 ++-- test/libsolidity/SolidityABIJSON.cpp | 55 +++++++++---------- .../SolidityNameAndTypeResolution.cpp | 2 +- 3 files changed, 35 insertions(+), 34 deletions(-) diff --git a/libsolidity/InterfaceHandler.cpp b/libsolidity/InterfaceHandler.cpp index e266f8d61..a49c4dc3f 100644 --- a/libsolidity/InterfaceHandler.cpp +++ b/libsolidity/InterfaceHandler.cpp @@ -60,10 +60,14 @@ std::unique_ptr InterfaceHandler::getABIInterface(ContractDefinitio method["type"] = "function"; method["name"] = it.second->getDeclaration().getName(); method["constant"] = it.second->isConstant(); - method["inputs"] = populateParameters(externalFunctionType->getParameterNames(), - externalFunctionType->getParameterTypeNames()); - method["outputs"] = populateParameters(externalFunctionType->getReturnParameterNames(), - externalFunctionType->getReturnParameterTypeNames()); + method["inputs"] = populateParameters( + externalFunctionType->getParameterNames(), + externalFunctionType->getParameterTypeNames() + ); + method["outputs"] = populateParameters( + externalFunctionType->getReturnParameterNames(), + externalFunctionType->getReturnParameterTypeNames() + ); abi.append(method); } if (_contractDef.getConstructor()) diff --git a/test/libsolidity/SolidityABIJSON.cpp b/test/libsolidity/SolidityABIJSON.cpp index 6c1025d6a..fe8b791c5 100644 --- a/test/libsolidity/SolidityABIJSON.cpp +++ b/test/libsolidity/SolidityABIJSON.cpp @@ -499,8 +499,7 @@ BOOST_AUTO_TEST_CASE(constructor_abi) { char const* sourceCode = R"( contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } - function test(uint param1, test param2, bool param3, ActionChoices param4) {} + function test(uint param1, test param2, bool param3) {} } )"; @@ -518,10 +517,6 @@ BOOST_AUTO_TEST_CASE(constructor_abi) { "name": "param3", "type": "bool" - }, - { - "name": "param4", - "type": "uint8" } ], "type": "constructor" @@ -545,29 +540,31 @@ BOOST_AUTO_TEST_CASE(return_param_in_abi) } )"; - char const* interface = R"([ - { - "constant" : false, - "inputs" : [], - "name" : "ret", - "outputs" : [ - { - "name" : "", - "type" : "uint8" - } - ], - "type" : "function" - }, - { - "inputs": [ - { - "name": "param", - "type": "uint8" - } - ], - "type": "constructor" - } - ])"; + char const* interface = R"( + [ + { + "constant" : false, + "inputs" : [], + "name" : "ret", + "outputs" : [ + { + "name" : "", + "type" : "uint8" + } + ], + "type" : "function" + }, + { + "inputs": [ + { + "name": "param", + "type": "uint8" + } + ], + "type": "constructor" + } + ] + )"; checkInterface(sourceCode, interface); } diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index c59c1f56f..4ec7b8bda 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -516,7 +516,7 @@ BOOST_AUTO_TEST_CASE(enum_external_type) contract Test { enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } function boo(ActionChoices enumArg) external returns (uint ret) { - ret = 5; + ret = 5; } })"; ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseTextAndResolveNames(text), "Parsing and name Resolving failed"); From d3e0b74f0c605a940ebb3bdc5542f9558c090850 Mon Sep 17 00:00:00 2001 From: Liana Husikyan Date: Mon, 11 May 2015 17:17:50 +0200 Subject: [PATCH 14/30] Update SolidityABIJSON.cpp --- test/libsolidity/SolidityABIJSON.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/libsolidity/SolidityABIJSON.cpp b/test/libsolidity/SolidityABIJSON.cpp index fe8b791c5..f9bf78d0a 100644 --- a/test/libsolidity/SolidityABIJSON.cpp +++ b/test/libsolidity/SolidityABIJSON.cpp @@ -546,7 +546,7 @@ BOOST_AUTO_TEST_CASE(return_param_in_abi) "constant" : false, "inputs" : [], "name" : "ret", - "outputs" : [ + "outputs" : [ { "name" : "", "type" : "uint8" From fda1fe5d37af63827c51d0374b183ee4cbb99b50 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 10 May 2015 18:22:33 +0300 Subject: [PATCH 15/30] Threading fixes & cleanup. --- libp2p/NodeTable.cpp | 78 +++++++++++++++++++++++--------------------- libp2p/NodeTable.h | 4 ++- 2 files changed, 44 insertions(+), 38 deletions(-) diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index e926356b7..fe2940b30 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -127,20 +127,19 @@ void NodeTable::discover() list NodeTable::nodes() const { list nodes; - Guard l(x_nodes); - for (auto& i: m_nodes) - nodes.push_back(i.second->id); + DEV_GUARDED(x_nodes) + for (auto& i: m_nodes) + nodes.push_back(i.second->id); return move(nodes); } list NodeTable::snapshot() const { list ret; - Guard l(x_state); - for (auto s: m_state) - for (auto np: s.nodes) - if (auto n = np.lock()) - if (!!n) + DEV_GUARDED(x_state) + for (auto const& s: m_state) + for (auto const& np: s.nodes) + if (auto n = np.lock()) ret.push_back(*n); return move(ret); } @@ -151,8 +150,7 @@ Node NodeTable::node(NodeId const& _id) if (m_nodes.count(_id)) { auto entry = m_nodes[_id]; - Node n(_id, entry->endpoint, entry->required); - return move(n); + return Node(_id, entry->endpoint, entry->required); } return UnspecifiedNode; } @@ -173,7 +171,7 @@ void NodeTable::discover(NodeId _node, unsigned _round, shared_ptr>()); @@ -228,7 +226,7 @@ vector> NodeTable::nearestNodeEntries(NodeId _target) while (head != tail && head < s_bins && count < s_bucketSize) { Guard l(x_state); - for (auto n: m_state[head].nodes) + for (auto const& n: m_state[head].nodes) if (auto p = n.lock()) { if (count < s_bucketSize) @@ -238,7 +236,7 @@ vector> NodeTable::nearestNodeEntries(NodeId _target) } if (count < s_bucketSize && tail) - for (auto n: m_state[tail].nodes) + for (auto const& n: m_state[tail].nodes) if (auto p = n.lock()) { if (count < s_bucketSize) @@ -255,7 +253,7 @@ vector> NodeTable::nearestNodeEntries(NodeId _target) while (head < s_bins && count < s_bucketSize) { Guard l(x_state); - for (auto n: m_state[head].nodes) + for (auto const& n: m_state[head].nodes) if (auto p = n.lock()) { if (count < s_bucketSize) @@ -269,7 +267,7 @@ vector> NodeTable::nearestNodeEntries(NodeId _target) while (tail > 0 && count < s_bucketSize) { Guard l(x_state); - for (auto n: m_state[tail].nodes) + for (auto const& n: m_state[tail].nodes) if (auto p = n.lock()) { if (count < s_bucketSize) @@ -282,7 +280,7 @@ vector> NodeTable::nearestNodeEntries(NodeId _target) vector> ret; for (auto& nodes: found) - for (auto n: nodes.second) + for (auto const& n: nodes.second) if (ret.size() < s_bucketSize && !!n->endpoint && n->endpoint.isAllowed()) ret.push_back(n); return move(ret); @@ -306,12 +304,15 @@ void NodeTable::evict(shared_ptr _leastSeen, shared_ptr _n if (!m_socketPointer->isOpen()) return; + unsigned ec; + DEV_GUARDED(x_evictions) { - Guard l(x_evictions); m_evictions.push_back(EvictionTimeout(make_pair(_leastSeen->id,chrono::steady_clock::now()), _new->id)); - if (m_evictions.size() == 1) - doCheckEvictions(boost::system::error_code()); + ec = m_evictions.size(); } + + if (ec == 1) + doCheckEvictions(boost::system::error_code()); ping(_leastSeen.get()); } @@ -428,24 +429,27 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes Pong in = Pong::fromBytesConstRef(_from, rlpBytes); // whenever a pong is received, check if it's in m_evictions - Guard le(x_evictions); - bool evictionEntry = false; - for (auto it = m_evictions.begin(); it != m_evictions.end(); it++) - if (it->first.first == nodeid && it->first.second > std::chrono::steady_clock::now()) - { - evictionEntry = true; - if (auto n = nodeEntry(it->second)) - dropNode(n); - - if (auto n = nodeEntry(it->first.first)) - n->pending = false; - - it = m_evictions.erase(it); - } - - // if not, check if it's known/pending or a pubk discovery ping - if (!evictionEntry) + bool found = false; + EvictionTimeout evictionEntry; + DEV_GUARDED(x_evictions) + for (auto it = m_evictions.begin(); it != m_evictions.end();) + if (it->first.first == nodeid && it->first.second > std::chrono::steady_clock::now()) + { + found = true; + evictionEntry = *it; + m_evictions.erase(it); + break; + } + if (found) + { + if (auto n = nodeEntry(evictionEntry.second)) + dropNode(n); + if (auto n = nodeEntry(evictionEntry.first.first)) + n->pending = false; + } + else { + // if not, check if it's known/pending or a pubk discovery ping if (auto n = nodeEntry(nodeid)) n->pending = false; else @@ -584,7 +588,7 @@ void NodeTable::doCheckEvictions(boost::system::error_code const& _ec) if (chrono::steady_clock::now() - e.first.second > c_reqTimeout) if (m_nodes.count(e.second)) drop.push_back(m_nodes[e.second]); - evictionsRemain = m_evictions.size() - drop.size() > 0; + evictionsRemain = (m_evictions.size() - drop.size() > 0); } drop.unique(); diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 92bf17f79..2e10dd891 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -45,10 +45,12 @@ struct NodeEntry: public Node bool pending = true; ///< Node will be ignored until Pong is received }; -enum NodeTableEventType { +enum NodeTableEventType +{ NodeEntryAdded, NodeEntryDropped }; + class NodeTable; class NodeTableEventHandler { From 68714c59f8ca491be57f6b0077ef0cf793588c92 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 10 May 2015 18:22:45 +0300 Subject: [PATCH 16/30] Integrate KeyManager. --- alethzero/MainWin.cpp | 39 +++++++++-- alethzero/MainWin.h | 4 ++ alethzero/OurWebThreeStubServer.cpp | 69 +++++++++++++----- alethzero/OurWebThreeStubServer.h | 43 +++++++++--- eth/main.cpp | 56 +++++++++++++-- exp/main.cpp | 2 +- libdevcore/Common.cpp | 2 + libdevcore/Common.h | 2 + libdevcore/FixedHash.h | 1 + libdevcrypto/SecretStore.h | 5 +- libethcore/Common.h | 11 +++ libethcore/CommonJS.cpp | 2 - libethcore/CommonJS.h | 14 ---- libethereum/ClientBase.h | 1 + libethereum/Interface.h | 4 ++ libethereum/KeyManager.cpp | 14 +++- libethereum/KeyManager.h | 15 ++-- libtestutils/FixedWebThreeServer.cpp | 5 ++ libtestutils/FixedWebThreeServer.h | 6 +- libweb3jsonrpc/AccountHolder.cpp | 51 +++++++++----- libweb3jsonrpc/AccountHolder.h | 85 +++++++++++++++++++---- libweb3jsonrpc/WebThreeStubServer.cpp | 4 +- libweb3jsonrpc/WebThreeStubServer.h | 2 +- libweb3jsonrpc/WebThreeStubServerBase.cpp | 43 +++--------- libweb3jsonrpc/WebThreeStubServerBase.h | 10 +-- mix/ClientModel.cpp | 5 +- mix/ClientModel.h | 3 +- mix/Web3Server.cpp | 5 +- mix/Web3Server.h | 3 +- test/libweb3jsonrpc/AccountHolder.cpp | 28 ++++---- 30 files changed, 373 insertions(+), 161 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 437e75576..06f5f5283 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -143,6 +143,38 @@ Main::Main(QWidget *parent) : // ui->log->addItem(QString::fromStdString(s)); }; + // Open Key Store + bool opened = false; + if (m_keyManager.exists()) + while (!opened) + { + QString s = QInputDialog::getText(nullptr, "Master password", "Enter your MASTER account password.", QLineEdit::Password, QString()); + if (m_keyManager.load(s.toStdString())) + opened = true; + else if (QMessageBox::question( + nullptr, + "Invalid password entered", + "The password you entered is incorrect. If you have forgotten your password, and you wish to start afresh, manually remove the file: " + QString::fromStdString(getDataDir("ethereum")) + "/keys.info", + QMessageBox::Retry, + QMessageBox::Abort) + == QMessageBox::Abort) + exit(0); + } + if (!opened) + { + QString password; + while (true) + { + password = QInputDialog::getText(nullptr, "Master password", "Enter a MASTER password for your key store. Make it strong. You probably want to write it down somewhere and keep it safe and secure; your identity will rely on this - you never want to lose it.", QLineEdit::Password, QString()); + QString confirm = QInputDialog::getText(nullptr, "Master password", "Confirm this password by typing it again", QLineEdit::Password, QString()); + if (password == confirm) + break; + QMessageBox::warning(nullptr, "Try again", "You entered two different passwords - please enter the same password twice.", QMessageBox::Ok); + } + m_keyManager.create(password.toStdString()); + m_keyManager.import(Secret::random(), "{\"name\":\"Default identity\"}"); + } + #if ETH_DEBUG m_servers.append("127.0.0.1:30300"); #endif @@ -176,7 +208,7 @@ Main::Main(QWidget *parent) : m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir(), WithExisting::Trust, {"eth", "shh"}, p2p::NetworkPreferences(), network)); m_httpConnector.reset(new jsonrpc::HttpServer(SensibleHttpPort, "", "", dev::SensibleHttpThreads)); - m_server.reset(new OurWebThreeStubServer(*m_httpConnector, *web3(), keysAsVector(m_myKeys), this)); + m_server.reset(new OurWebThreeStubServer(*m_httpConnector, *web3(), this)); connect(&*m_server, SIGNAL(onNewId(QString)), SLOT(addNewId(QString))); m_server->setIdentities(keysAsVector(owned())); m_server->StartListening(); @@ -690,7 +722,6 @@ void Main::readSettings(bool _skipGeometry) } } ethereum()->setAddress(m_myKeys.back().address()); - m_server->setAccounts(keysAsVector(m_myKeys)); } { @@ -1397,9 +1428,6 @@ void Main::ourAccountsRowsMoved() myKeys.push_back(i); } m_myKeys = myKeys; - - if (m_server.get()) - m_server->setAccounts(keysAsVector(m_myKeys)); } void Main::on_inject_triggered() @@ -1837,7 +1865,6 @@ void Main::on_mine_triggered() void Main::keysChanged() { onBalancesChange(); - m_server->setAccounts(keysAsVector(m_myKeys)); } bool beginsWith(Address _a, bytes const& _b) diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 127b174c6..6b2ede715 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include "Context.h" @@ -90,6 +91,8 @@ public: dev::u256 gasPrice() const { return 10 * dev::eth::szabo; } + dev::eth::KeyManager& keyManager() { return m_keyManager; } + public slots: void load(QString _file); void note(QString _entry); @@ -249,6 +252,7 @@ private: QStringList m_servers; QList m_myKeys; QList m_myIdentities; + dev::eth::KeyManager m_keyManager; QString m_privateChain; dev::Address m_nameReg; diff --git a/alethzero/OurWebThreeStubServer.cpp b/alethzero/OurWebThreeStubServer.cpp index 161bb4926..da645766a 100644 --- a/alethzero/OurWebThreeStubServer.cpp +++ b/alethzero/OurWebThreeStubServer.cpp @@ -20,23 +20,23 @@ */ #include "OurWebThreeStubServer.h" - #include #include #include #include - #include "MainWin.h" - using namespace std; using namespace dev; using namespace dev::eth; -OurWebThreeStubServer::OurWebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, WebThreeDirect& _web3, - vector const& _accounts, Main* _main): - WebThreeStubServer(_conn, _web3, _accounts), m_web3(&_web3), m_main(_main) +OurWebThreeStubServer::OurWebThreeStubServer( + jsonrpc::AbstractServerConnector& _conn, + WebThreeDirect& _web3, + Main* _main +): + WebThreeStubServer(_conn, _web3, make_shared(_web3, _main), _main->owned().toVector().toStdVector()), + m_main(_main) { - connect(_main, SIGNAL(poll()), this, SLOT(doValidations())); } string OurWebThreeStubServer::shh_newIdentity() @@ -46,7 +46,18 @@ string OurWebThreeStubServer::shh_newIdentity() return toJS(kp.pub()); } -bool OurWebThreeStubServer::showAuthenticationPopup(string const& _title, string const& _text) +OurAccountHolder::OurAccountHolder( + WebThreeDirect& _web3, + Main* _main +): + AccountHolder([=](){ return m_web3->ethereum(); }), + m_web3(&_web3), + m_main(_main) +{ + connect(_main, SIGNAL(poll()), this, SLOT(doValidations())); +} + +bool OurAccountHolder::showAuthenticationPopup(string const& _title, string const& _text) { if (!m_main->confirm()) { @@ -66,18 +77,18 @@ bool OurWebThreeStubServer::showAuthenticationPopup(string const& _title, string //return button == QMessageBox::Ok; } -bool OurWebThreeStubServer::showCreationNotice(TransactionSkeleton const& _t, bool _toProxy) +bool OurAccountHolder::showCreationNotice(TransactionSkeleton const& _t, bool _toProxy) { return showAuthenticationPopup("Contract Creation Transaction", string("ÐApp is attemping to create a contract; ") + (_toProxy ? "(this transaction is not executed directly, but forwarded to another ÐApp) " : "") + "to be endowed with " + formatBalance(_t.value) + ", with additional network fees of up to " + formatBalance(_t.gas * _t.gasPrice) + ".\n\nMaximum total cost is " + formatBalance(_t.value + _t.gas * _t.gasPrice) + "."); } -bool OurWebThreeStubServer::showSendNotice(TransactionSkeleton const& _t, bool _toProxy) +bool OurAccountHolder::showSendNotice(TransactionSkeleton const& _t, bool _toProxy) { return showAuthenticationPopup("Fund Transfer Transaction", "ÐApp is attempting to send " + formatBalance(_t.value) + " to a recipient " + m_main->pretty(_t.to) + (_toProxy ? " (this transaction is not executed directly, but forwarded to another ÐApp)" : "") + ", with additional network fees of up to " + formatBalance(_t.gas * _t.gasPrice) + ".\n\nMaximum total cost is " + formatBalance(_t.value + _t.gas * _t.gasPrice) + "."); } -bool OurWebThreeStubServer::showUnknownCallNotice(TransactionSkeleton const& _t, bool _toProxy) +bool OurAccountHolder::showUnknownCallNotice(TransactionSkeleton const& _t, bool _toProxy) { return showAuthenticationPopup("DANGEROUS! Unknown Contract Transaction!", "ÐApp is attempting to call into an unknown contract at address " + @@ -93,25 +104,47 @@ bool OurWebThreeStubServer::showUnknownCallNotice(TransactionSkeleton const& _t, "REJECT UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!"); } -void OurWebThreeStubServer::authenticate(TransactionSkeleton const& _t, bool _toProxy) +void OurAccountHolder::authenticate(TransactionSkeleton const& _t) { Guard l(x_queued); - m_queued.push(make_pair(_t, _toProxy)); + m_queued.push(_t); } -void OurWebThreeStubServer::doValidations() +void OurAccountHolder::doValidations() { Guard l(x_queued); while (!m_queued.empty()) { - auto q = m_queued.front(); + auto t = m_queued.front(); m_queued.pop(); - if (validateTransaction(q.first, q.second)) - WebThreeStubServerBase::authenticate(q.first, q.second); + + bool proxy = isProxyAccount(t.from); + if (!proxy && !isRealAccount(t.from)) + { + cwarn << "Trying to send from non-existant account" << t.from; + return; + } + + // TODO: determine gas price. + + if (!validateTransaction(t, proxy)) + return; + + if (proxy) + queueTransaction(t); + else + // sign and submit. + if (Secret s = m_main->keyManager().secret(t.from)) + m_web3->ethereum()->submitTransaction(s, t); } } -bool OurWebThreeStubServer::validateTransaction(TransactionSkeleton const& _t, bool _toProxy) +AddressHash OurAccountHolder::realAccounts() const +{ + return m_main->keyManager().accounts(); +} + +bool OurAccountHolder::validateTransaction(TransactionSkeleton const& _t, bool _toProxy) { if (_t.creation) { diff --git a/alethzero/OurWebThreeStubServer.h b/alethzero/OurWebThreeStubServer.h index 95cf70438..a07188b2d 100644 --- a/alethzero/OurWebThreeStubServer.h +++ b/alethzero/OurWebThreeStubServer.h @@ -25,26 +25,29 @@ #include #include #include +#include class Main; -class OurWebThreeStubServer: public QObject, public WebThreeStubServer +class OurAccountHolder: public QObject, public dev::eth::AccountHolder { Q_OBJECT public: - OurWebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, dev::WebThreeDirect& _web3, - std::vector const& _accounts, Main* main); - - virtual std::string shh_newIdentity() override; - virtual void authenticate(dev::eth::TransactionSkeleton const& _t, bool _toProxy); - -signals: - void onNewId(QString _s); + OurAccountHolder( + dev::WebThreeDirect& _web3, + Main* _main + ); public slots: void doValidations(); +protected: + // easiest to return keyManager.addresses(); + virtual dev::AddressHash realAccounts() const override; + // use web3 to submit a signed transaction to accept + virtual void authenticate(dev::eth::TransactionSkeleton const& _t) override; + private: bool showAuthenticationPopup(std::string const& _title, std::string const& _text); bool showCreationNotice(dev::eth::TransactionSkeleton const& _t, bool _toProxy); @@ -53,9 +56,29 @@ private: bool validateTransaction(dev::eth::TransactionSkeleton const& _t, bool _toProxy); - std::queue> m_queued; + std::queue m_queued; dev::Mutex x_queued; dev::WebThreeDirect* m_web3; Main* m_main; }; + +class OurWebThreeStubServer: public QObject, public WebThreeStubServer +{ + Q_OBJECT + +public: + OurWebThreeStubServer( + jsonrpc::AbstractServerConnector& _conn, + dev::WebThreeDirect& _web3, + Main* main + ); + + virtual std::string shh_newIdentity() override; + +signals: + void onNewId(QString _s); + +private: + Main* m_main; +}; diff --git a/eth/main.cpp b/eth/main.cpp index a5db1eecb..04ac5bc7e 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #if ETH_JSCONSOLE || !ETH_TRUE #include @@ -46,6 +47,7 @@ #include #endif #if ETH_JSONRPC || !ETH_TRUE +#include #include #include #include @@ -1086,13 +1088,53 @@ int main(int argc, char** argv) if (remoteHost.size()) web3.addNode(p2p::NodeId(), remoteHost + ":" + toString(remotePort)); -#if ETH_JSONRPC + KeyManager keyManager; + if (keyManager.exists()) + { + while (masterPassword.empty()) + { + cout << "Please enter your MASTER password:" << flush; + getline(cin, masterPassword); + if (!keyManager.load(masterPassword)) + { + cout << "Password invalid. Try again." << endl; + masterPassword.clear(); + } + } + } + else + { + while (masterPassword.empty()) + { + cout << "Please enter a MASTER password to protect your key store. Make it strong." << flush; + getline(cin, masterPassword); + string confirm; + cout << "Please confirm the password by entering it again." << flush; + getline(cin, confirm); + if (masterPassword != confirm) + { + cout << "Passwords were different. Try again." << endl; + masterPassword.clear(); + } + } + keyManager.create(masterPassword); + } + + string logbuf; + bool silence = false; + std::string additional; + g_logPost = [&](std::string const& a, char const*) { if (silence) logbuf += a + "\n"; else cout << "\r \r" << a << endl << additional << flush; }; + + // TODO: give hints &c. + auto getPassword = [&](Address const& a){ auto s = silence; silence = true; string ret; cout << endl << "Enter password for address " << a.abridged() << ": " << flush; std::getline(cin, ret); silence = s; return ret; }; + +#if ETH_JSONRPC || !ETH_TRUE shared_ptr jsonrpcServer; unique_ptr jsonrpcConnector; if (jsonrpc > -1) { jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads)); - jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector({sigKey}))); + jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){return web3.ethereum();}, getPassword, keyManager), vector({sigKey}))); jsonrpcServer->StartListening(); } #endif @@ -1103,15 +1145,15 @@ int main(int argc, char** argv) if (interactive) { - string logbuf; + additional = "Press Enter"; string l; while (!g_exit) { - g_logPost = [](std::string const& a, char const*) { cout << "\r \r" << a << endl << "Press Enter" << flush; }; + silence = false; cout << logbuf << "Press Enter" << flush; std::getline(cin, l); logbuf.clear(); - g_logPost = [&](std::string const& a, char const*) { logbuf += a + "\n"; }; + silence = true; #if ETH_READLINE if (l.size()) @@ -1224,7 +1266,7 @@ int main(int argc, char** argv) iss >> g_logVerbosity; cout << "Verbosity: " << g_logVerbosity << endl; } -#if ETH_JSONRPC +#if ETH_JSONRPC || !ETH_TRUE else if (cmd == "jsonport") { if (iss.peek() != -1) @@ -1236,7 +1278,7 @@ int main(int argc, char** argv) if (jsonrpc < 0) jsonrpc = SensibleHttpPort; jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads)); - jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector({sigKey}))); + jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){return web3.ethereum();}, getPassword, keyManager), vector({sigKey}))); jsonrpcServer->StartListening(); } else if (cmd == "jsonstop") diff --git a/exp/main.cpp b/exp/main.cpp index 5fee5cbee..2bd0a741e 100644 --- a/exp/main.cpp +++ b/exp/main.cpp @@ -81,7 +81,7 @@ int main() // cdebug << toString(a2); Address a2("19c486071651b2650449ba3c6a807f316a73e8fe"); - cdebug << keyman.keys(); + cdebug << keyman.accountDetails(); cdebug << "Secret key for " << a << "is" << keyman.secret(a, [](){ return "bar"; }); cdebug << "Secret key for " << a2 << "is" << keyman.secret(a2); diff --git a/libdevcore/Common.cpp b/libdevcore/Common.cpp index 5f3658030..5f15902e2 100644 --- a/libdevcore/Common.cpp +++ b/libdevcore/Common.cpp @@ -30,6 +30,8 @@ namespace dev char const* Version = "0.9.17"; +const u256 UndefinedU256 = ~(u256)0; + void HasInvariants::checkInvariants() const { if (!invariants()) diff --git a/libdevcore/Common.h b/libdevcore/Common.h index 36e57c44f..41f1b1d49 100644 --- a/libdevcore/Common.h +++ b/libdevcore/Common.h @@ -82,6 +82,8 @@ using u160s = std::vector; using u256Set = std::set; using u160Set = std::set; +extern const u256 UndefinedU256; + // Map types. using StringMap = std::map; using u256Map = std::map; diff --git a/libdevcore/FixedHash.h b/libdevcore/FixedHash.h index 14bc500e6..9b25837af 100644 --- a/libdevcore/FixedHash.h +++ b/libdevcore/FixedHash.h @@ -282,6 +282,7 @@ namespace std { /// Forward std::hash to dev::FixedHash::hash. template<> struct hash: dev::h64::hash {}; + template<> struct hash: dev::h128::hash {}; template<> struct hash: dev::h160::hash {}; template<> struct hash: dev::h256::hash {}; template<> struct hash: dev::h512::hash {}; diff --git a/libdevcrypto/SecretStore.h b/libdevcrypto/SecretStore.h index 7f4ae08f1..1fb6adf4a 100644 --- a/libdevcrypto/SecretStore.h +++ b/libdevcrypto/SecretStore.h @@ -23,6 +23,7 @@ #include #include +#include #include "Common.h" #include "FileSystem.h" @@ -48,8 +49,8 @@ private: static std::string encrypt(bytes const& _v, std::string const& _pass); static bytes decrypt(std::string const& _v, std::string const& _pass); - mutable std::map m_cached; - std::map> m_keys; + mutable std::unordered_map m_cached; + std::unordered_map> m_keys; }; } diff --git a/libethcore/Common.h b/libethcore/Common.h index 84459c6bf..8855bc3a7 100644 --- a/libethcore/Common.h +++ b/libethcore/Common.h @@ -136,5 +136,16 @@ private: using Handler = std::shared_ptr; +struct TransactionSkeleton +{ + bool creation = false; + Address from; + Address to; + u256 value; + bytes data; + u256 gas = UndefinedU256; + u256 gasPrice = UndefinedU256; +}; + } } diff --git a/libethcore/CommonJS.cpp b/libethcore/CommonJS.cpp index 286641bc3..167879db3 100644 --- a/libethcore/CommonJS.cpp +++ b/libethcore/CommonJS.cpp @@ -26,8 +26,6 @@ namespace dev { -const u256 UndefinedU256 = ~(u256)0; - Address toAddress(std::string const& _sn) { if (_sn.size() == 40) diff --git a/libethcore/CommonJS.h b/libethcore/CommonJS.h index 72625122d..0ff21afdf 100644 --- a/libethcore/CommonJS.h +++ b/libethcore/CommonJS.h @@ -48,8 +48,6 @@ inline Address jsToAddress(std::string const& _s) { return jsToFixed using namespace std; using namespace dev; +using namespace eth; namespace fs = boost::filesystem; KeyManager::KeyManager(std::string const& _keysFile): @@ -151,9 +152,18 @@ void KeyManager::kill(Address const& _a) m_store.kill(id); } -std::map> KeyManager::keys() const +AddressHash KeyManager::accounts() const { - std::map> ret; + AddressHash ret; + for (auto const& i: m_addrLookup) + if (m_keyInfo.count(i.second) > 0) + ret.insert(i.first); + return ret; +} + +std::unordered_map> KeyManager::accountDetails() const +{ + std::unordered_map> ret; for (auto const& i: m_addrLookup) if (m_keyInfo.count(i.second) > 0) ret[i.first] = make_pair(m_keyInfo.at(i.second).info, m_passwordInfo.at(m_keyInfo.at(i.second).passHash)); diff --git a/libethereum/KeyManager.h b/libethereum/KeyManager.h index 9cb22e5b3..391121b1c 100644 --- a/libethereum/KeyManager.h +++ b/libethereum/KeyManager.h @@ -28,7 +28,8 @@ namespace dev { - +namespace eth +{ class UnknownPassword: public Exception {}; struct KeyInfo @@ -65,7 +66,8 @@ public: bool load(std::string const& _pass); void save(std::string const& _pass) const { write(_pass, m_keysFile); } - std::map> keys() const; + AddressHash accounts() const; + std::unordered_map> accountDetails() const; h128 uuid(Address const& _a) const; Address address(h128 const& _uuid) const; @@ -92,12 +94,12 @@ private: void write(h128 const& _key, std::string const& _keysFile) const; // Ethereum keys. - std::map m_addrLookup; - std::map m_keyInfo; - std::map m_passwordInfo; + std::unordered_map m_addrLookup; + std::unordered_map m_keyInfo; + std::unordered_map m_passwordInfo; // Passwords that we're storing. - mutable std::map m_cachedPasswords; + mutable std::unordered_map m_cachedPasswords; // The default password for keys in the keystore - protected by the master password. std::string m_password; @@ -108,3 +110,4 @@ private: }; } +} diff --git a/libtestutils/FixedWebThreeServer.cpp b/libtestutils/FixedWebThreeServer.cpp index c72a106c6..0be34cc93 100644 --- a/libtestutils/FixedWebThreeServer.cpp +++ b/libtestutils/FixedWebThreeServer.cpp @@ -16,7 +16,12 @@ */ /** @file FixedWebThreeStubServer.cpp * @author Marek Kotewicz + * @author Gav Wood * @date 2015 */ #include "FixedWebThreeServer.h" +#include +using namespace std; +using namespace dev; +using namespace eth; diff --git a/libtestutils/FixedWebThreeServer.h b/libtestutils/FixedWebThreeServer.h index 33ccbf71e..bcaacecd8 100644 --- a/libtestutils/FixedWebThreeServer.h +++ b/libtestutils/FixedWebThreeServer.h @@ -23,6 +23,7 @@ #include #include +#include /** * @brief dummy JSON-RPC api implementation @@ -33,7 +34,10 @@ class FixedWebThreeServer: public dev::WebThreeStubServerBase, public dev::WebThreeStubDatabaseFace { public: - FixedWebThreeServer(jsonrpc::AbstractServerConnector& _conn, std::vector const& _accounts, dev::eth::Interface* _client): WebThreeStubServerBase(_conn, _accounts), m_client(_client) {}; + FixedWebThreeServer(jsonrpc::AbstractServerConnector& _conn, std::vector const& _allAccounts, dev::eth::Interface* _client): + WebThreeStubServerBase(_conn, std::make_shared([=](){return _client;}, _allAccounts), _allAccounts), + m_client(_client) + {} private: dev::eth::Interface* client() override { return m_client; } diff --git a/libweb3jsonrpc/AccountHolder.cpp b/libweb3jsonrpc/AccountHolder.cpp index b88397953..a73f20680 100644 --- a/libweb3jsonrpc/AccountHolder.cpp +++ b/libweb3jsonrpc/AccountHolder.cpp @@ -26,6 +26,7 @@ #include #include #include +#include using namespace std; using namespace dev; @@ -35,31 +36,23 @@ vector g_emptyQueue; static std::mt19937 g_randomNumberGenerator(time(0)); static Mutex x_rngMutex; -void AccountHolder::setAccounts(vector const& _accounts) +vector
AccountHolder::allAccounts() const { - m_accounts.clear(); - for (auto const& keyPair: _accounts) - { - m_accounts.push_back(keyPair.address()); - m_keyPairs[keyPair.address()] = keyPair; - } -} - -vector
AccountHolder::getAllAccounts() const -{ - vector
accounts = m_accounts; + vector
accounts; + accounts += realAccounts(); for (auto const& pair: m_proxyAccounts) if (!isRealAccount(pair.first)) accounts.push_back(pair.first); return accounts; } -Address const& AccountHolder::getDefaultTransactAccount() const +Address const& AccountHolder::defaultTransactAccount() const { - if (m_accounts.empty()) + auto accounts = realAccounts(); + if (accounts.empty()) return ZeroAddress; - Address const* bestMatch = &m_accounts.front(); - for (auto const& account: m_accounts) + Address const* bestMatch = &*accounts.begin(); + for (auto const& account: accounts) if (m_client()->balanceAt(account) > m_client()->balanceAt(*bestMatch)) bestMatch = &account; return *bestMatch; @@ -94,7 +87,7 @@ void AccountHolder::queueTransaction(TransactionSkeleton const& _transaction) m_transactionQueues[id].second.push_back(_transaction); } -vector const& AccountHolder::getQueuedTransactions(int _id) const +vector const& AccountHolder::queuedTransactions(int _id) const { if (!m_transactionQueues.count(_id)) return g_emptyQueue; @@ -106,3 +99,27 @@ void AccountHolder::clearQueue(int _id) if (m_transactionQueues.count(_id)) m_transactionQueues.at(_id).second.clear(); } + +AddressHash SimpleAccountHolder::realAccounts() const +{ + return m_keyManager.accounts(); +} + +void SimpleAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t) +{ + if (isRealAccount(_t.from)) + m_client()->submitTransaction(m_keyManager.secret(_t.from, [&](){ return m_getPassword(_t.from); }), _t); + else if (isProxyAccount(_t.from)) + queueTransaction(_t); +} + +void FixedAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t) +{ + if (isRealAccount(_t.from)) + m_client()->submitTransaction(m_accounts[_t.from], _t); + else if (isProxyAccount(_t.from)) + queueTransaction(_t); +} + + + diff --git a/libweb3jsonrpc/AccountHolder.h b/libweb3jsonrpc/AccountHolder.h index 52005b51f..10b036226 100644 --- a/libweb3jsonrpc/AccountHolder.h +++ b/libweb3jsonrpc/AccountHolder.h @@ -24,17 +24,20 @@ #pragma once #include +#include #include #include #include #include +#include namespace dev { namespace eth { + +class KeyManager; class Interface; -} /** * Manages real accounts (where we know the secret key) and proxy accounts (where transactions @@ -43,32 +46,84 @@ class Interface; class AccountHolder { public: - explicit AccountHolder(std::function const& _client): m_client(_client) {} + explicit AccountHolder(std::function const& _client): m_client(_client) {} + + // easiest to return keyManager.addresses(); + virtual AddressHash realAccounts() const = 0; + // use m_web3's submitTransaction + // or use AccountHolder::queueTransaction(_t) to accept + virtual void authenticate(dev::eth::TransactionSkeleton const& _t) = 0; - /// Sets or resets the list of real accounts. - void setAccounts(std::vector const& _accounts); - std::vector
const& getRealAccounts() const { return m_accounts; } - bool isRealAccount(Address const& _account) const { return m_keyPairs.count(_account) > 0; } + Addresses allAccounts() const; + bool isRealAccount(Address const& _account) const { return realAccounts().count(_account) > 0; } bool isProxyAccount(Address const& _account) const { return m_proxyAccounts.count(_account) > 0; } - Secret const& secretKey(Address const& _account) const { return m_keyPairs.at(_account).secret(); } - std::vector
getAllAccounts() const; - Address const& getDefaultTransactAccount() const; + Address const& defaultTransactAccount() const; int addProxyAccount(Address const& _account); bool removeProxyAccount(unsigned _id); void queueTransaction(eth::TransactionSkeleton const& _transaction); - std::vector const& getQueuedTransactions(int _id) const; + std::vector const& queuedTransactions(int _id) const; void clearQueue(int _id); +protected: + std::function m_client; + private: using TransactionQueue = std::vector; - std::map m_keyPairs; - std::vector
m_accounts; - std::map m_proxyAccounts; - std::map> m_transactionQueues; - std::function m_client; + std::unordered_map m_proxyAccounts; + std::unordered_map> m_transactionQueues; +}; + +class SimpleAccountHolder: public AccountHolder +{ +public: + SimpleAccountHolder(std::function const& _client, std::function const& _getPassword, KeyManager& _keyman): + AccountHolder(_client), + m_getPassword(_getPassword), + m_keyManager(_keyman) + {} + + AddressHash realAccounts() const override; + void authenticate(dev::eth::TransactionSkeleton const& _t) override; + +private: + std::function m_getPassword; + KeyManager& m_keyManager; +}; + +class FixedAccountHolder: public AccountHolder +{ +public: + FixedAccountHolder(std::function const& _client, std::vector const& _accounts): + AccountHolder(_client) + { + setAccounts(_accounts); + } + + void setAccounts(std::vector const& _accounts) + { + for (auto const& i: _accounts) + m_accounts[i.address()] = i.secret(); + } + + dev::AddressHash realAccounts() const override + { + dev::AddressHash ret; + for (auto const& i: m_accounts) + ret.insert(i.first); + return ret; + } + + // use m_web3's submitTransaction + // or use AccountHolder::queueTransaction(_t) to accept + void authenticate(dev::eth::TransactionSkeleton const& _t) override; + +private: + std::unordered_map m_accounts; }; + +} } diff --git a/libweb3jsonrpc/WebThreeStubServer.cpp b/libweb3jsonrpc/WebThreeStubServer.cpp index 30a634b3d..5235b0c4f 100644 --- a/libweb3jsonrpc/WebThreeStubServer.cpp +++ b/libweb3jsonrpc/WebThreeStubServer.cpp @@ -33,8 +33,8 @@ using namespace std; using namespace dev; using namespace dev::eth; -WebThreeStubServer::WebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, WebThreeDirect& _web3, std::vector const& _accounts): - WebThreeStubServerBase(_conn, _accounts), +WebThreeStubServer::WebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, WebThreeDirect& _web3, shared_ptr const& _ethAccounts, std::vector const& _shhAccounts): + WebThreeStubServerBase(_conn, _ethAccounts, _shhAccounts), m_web3(_web3) { auto path = getDataDir() + "/.web3"; diff --git a/libweb3jsonrpc/WebThreeStubServer.h b/libweb3jsonrpc/WebThreeStubServer.h index 08991d2f5..35c35c3f0 100644 --- a/libweb3jsonrpc/WebThreeStubServer.h +++ b/libweb3jsonrpc/WebThreeStubServer.h @@ -41,7 +41,7 @@ class WebThreeDirect; class WebThreeStubServer: public dev::WebThreeStubServerBase, public dev::WebThreeStubDatabaseFace { public: - WebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, dev::WebThreeDirect& _web3, std::vector const& _accounts); + WebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, dev::WebThreeDirect& _web3, std::shared_ptr const& _ethAccounts, std::vector const& _shhAccounts); virtual std::string web3_clientVersion(); diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 12486d529..cac634a61 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -297,10 +297,11 @@ static Json::Value toJson(h256 const& _h, shh::Envelope const& _e, shh::Message return res; } -WebThreeStubServerBase::WebThreeStubServerBase(AbstractServerConnector& _conn, vector const& _accounts): - AbstractWebThreeStubServer(_conn), m_ethAccounts(make_shared(bind(&WebThreeStubServerBase::client, this))) +WebThreeStubServerBase::WebThreeStubServerBase(AbstractServerConnector& _conn, std::shared_ptr const& _ethAccounts, vector const& _sshAccounts): + AbstractWebThreeStubServer(_conn), + m_ethAccounts(_ethAccounts) { - m_ethAccounts->setAccounts(_accounts); + setIdentities(_sshAccounts); } void WebThreeStubServerBase::setIdentities(vector const& _ids) @@ -353,7 +354,7 @@ string WebThreeStubServerBase::eth_gasPrice() Json::Value WebThreeStubServerBase::eth_accounts() { Json::Value ret(Json::arrayValue); - for (auto const& i: m_ethAccounts->getAllAccounts()) + for (auto const& i: m_ethAccounts->allAccounts()) ret.append(toJS(i)); return ret; } @@ -499,7 +500,7 @@ string WebThreeStubServerBase::eth_sendTransaction(Json::Value const& _json) TransactionSkeleton t = toTransaction(_json); if (!t.from) - t.from = m_ethAccounts->getDefaultTransactAccount(); + t.from = m_ethAccounts->defaultTransactAccount(); if (t.creation) ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from)))));; if (t.gasPrice == UndefinedU256) @@ -507,10 +508,7 @@ string WebThreeStubServerBase::eth_sendTransaction(Json::Value const& _json) if (t.gas == UndefinedU256) t.gas = min(client()->gasLimitRemaining() / 5, client()->balanceAt(t.from) / t.gasPrice); - if (m_ethAccounts->isRealAccount(t.from)) - authenticate(t, false); - else if (m_ethAccounts->isProxyAccount(t.from)) - authenticate(t, true); + m_ethAccounts->authenticate(t); return ret; } @@ -528,7 +526,7 @@ string WebThreeStubServerBase::eth_signTransaction(Json::Value const& _json) TransactionSkeleton t = toTransaction(_json); if (!t.from) - t.from = m_ethAccounts->getDefaultTransactAccount(); + t.from = m_ethAccounts->defaultTransactAccount(); if (t.creation) ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from)))));; if (t.gasPrice == UndefinedU256) @@ -536,10 +534,7 @@ string WebThreeStubServerBase::eth_signTransaction(Json::Value const& _json) if (t.gas == UndefinedU256) t.gas = min(client()->gasLimitRemaining() / 5, client()->balanceAt(t.from) / t.gasPrice); - if (m_ethAccounts->isRealAccount(t.from)) - authenticate(t, false); - else if (m_ethAccounts->isProxyAccount(t.from)) - authenticate(t, true); + m_ethAccounts->authenticate(t); return toJS((t.creation ? Transaction(t.value, t.gasPrice, t.gas, t.data) : Transaction(t.value, t.gasPrice, t.gas, t.to, t.data)).sha3(WithoutSignature)); } @@ -579,7 +574,7 @@ string WebThreeStubServerBase::eth_call(Json::Value const& _json, string const& { TransactionSkeleton t = toTransaction(_json); if (!t.from) - t.from = m_ethAccounts->getDefaultTransactAccount(); + t.from = m_ethAccounts->defaultTransactAccount(); // if (!m_accounts->isRealAccount(t.from)) // return ret; if (t.gasPrice == UndefinedU256) @@ -593,7 +588,6 @@ string WebThreeStubServerBase::eth_call(Json::Value const& _json, string const& { BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); } - } bool WebThreeStubServerBase::eth_flush() @@ -906,7 +900,7 @@ Json::Value WebThreeStubServerBase::eth_fetchQueuedTransactions(string const& _a auto id = jsToInt(_accountId); Json::Value ret(Json::arrayValue); // TODO: throw an error on no account with given id - for (TransactionSkeleton const& t: m_ethAccounts->getQueuedTransactions(id)) + for (TransactionSkeleton const& t: m_ethAccounts->queuedTransactions(id)) ret.append(toJson(t)); m_ethAccounts->clearQueue(id); return ret; @@ -1077,18 +1071,3 @@ Json::Value WebThreeStubServerBase::shh_getMessages(string const& _filterId) BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); } } - -void WebThreeStubServerBase::authenticate(TransactionSkeleton const& _t, bool _toProxy) -{ - if (_toProxy) - m_ethAccounts->queueTransaction(_t); - else if (_t.to) - client()->submitTransaction(m_ethAccounts->secretKey(_t.from), _t.value, _t.to, _t.data, _t.gas, _t.gasPrice); - else - client()->submitTransaction(m_ethAccounts->secretKey(_t.from), _t.value, _t.data, _t.gas, _t.gasPrice); -} - -void WebThreeStubServerBase::setAccounts(const vector& _accounts) -{ - m_ethAccounts->setAccounts(_accounts); -} diff --git a/libweb3jsonrpc/WebThreeStubServerBase.h b/libweb3jsonrpc/WebThreeStubServerBase.h index 425e6567e..f3f7edfe7 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.h +++ b/libweb3jsonrpc/WebThreeStubServerBase.h @@ -36,10 +36,10 @@ namespace dev { class WebThreeNetworkFace; -class AccountHolder; class KeyPair; namespace eth { +class AccountHolder; struct TransactionSkeleton; class Interface; } @@ -68,7 +68,7 @@ public: class WebThreeStubServerBase: public AbstractWebThreeStubServer { public: - WebThreeStubServerBase(jsonrpc::AbstractServerConnector& _conn, std::vector const& _accounts); + WebThreeStubServerBase(jsonrpc::AbstractServerConnector& _conn, std::shared_ptr const& _ethAccounts, std::vector const& _sshAccounts); virtual std::string web3_sha3(std::string const& _param1); virtual std::string web3_clientVersion() { return "C++ (ethereum-cpp)"; } @@ -134,20 +134,16 @@ public: virtual Json::Value shh_getFilterChanges(std::string const& _filterId); virtual Json::Value shh_getMessages(std::string const& _filterId); - void setAccounts(std::vector const& _accounts); void setIdentities(std::vector const& _ids); std::map const& ids() const { return m_shhIds; } -protected: - virtual void authenticate(dev::eth::TransactionSkeleton const& _t, bool _toProxy); - protected: virtual dev::eth::Interface* client() = 0; virtual std::shared_ptr face() = 0; virtual dev::WebThreeNetworkFace* network() = 0; virtual dev::WebThreeStubDatabaseFace* db() = 0; - std::shared_ptr m_ethAccounts; + std::shared_ptr m_ethAccounts; std::map m_shhIds; std::map m_shhWatches; diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index c558c71f3..b355c336f 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -85,7 +85,8 @@ ClientModel::ClientModel(): connect(this, &ClientModel::runComplete, this, &ClientModel::showDebugger, Qt::QueuedConnection); m_client.reset(new MixClient(QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString())); - m_web3Server.reset(new Web3Server(*m_rpcConnector.get(), std::vector(), m_client.get())); + m_ethAccounts = make_shared([=](){return m_client.get();}, std::vector()); + m_web3Server.reset(new Web3Server(*m_rpcConnector.get(), m_ethAccounts, std::vector(), m_client.get())); connect(m_web3Server.get(), &Web3Server::newTransaction, this, &ClientModel::onNewTransaction, Qt::DirectConnection); } @@ -280,7 +281,7 @@ void ClientModel::setupState(QVariantMap _state) transactionSequence.push_back(transactionSettings); } } - m_web3Server->setAccounts(userAccounts); + m_ethAccounts->setAccounts(userAccounts); executeSequence(transactionSequence, accounts, Secret(_state.value("miner").toMap().value("secret").toString().toStdString())); } diff --git a/mix/ClientModel.h b/mix/ClientModel.h index b88ae8511..910c0ed01 100644 --- a/mix/ClientModel.h +++ b/mix/ClientModel.h @@ -35,7 +35,7 @@ namespace dev { -namespace eth { class Account; } +namespace eth { class Account; class FixedAccountHolder; } namespace mix { @@ -235,6 +235,7 @@ private: std::unique_ptr m_client; std::unique_ptr m_rpcConnector; std::unique_ptr m_web3Server; + std::shared_ptr m_ethAccounts; QList m_gasCosts; std::map m_contractAddresses; std::map m_contractNames; diff --git a/mix/Web3Server.cpp b/mix/Web3Server.cpp index 7edc73060..855f33ca5 100644 --- a/mix/Web3Server.cpp +++ b/mix/Web3Server.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "Web3Server.h" using namespace dev::mix; @@ -108,8 +109,8 @@ class EmptyNetwork : public dev::WebThreeNetworkFace } -Web3Server::Web3Server(jsonrpc::AbstractServerConnector& _conn, std::vector const& _accounts, dev::eth::Interface* _client): - WebThreeStubServerBase(_conn, _accounts), +Web3Server::Web3Server(jsonrpc::AbstractServerConnector& _conn, std::shared_ptr const& _ethAccounts, std::vector const& _shhAccounts, dev::eth::Interface* _client): + WebThreeStubServerBase(_conn, _ethAccounts, _shhAccounts), m_client(_client), m_network(new EmptyNetwork()) { diff --git a/mix/Web3Server.h b/mix/Web3Server.h index b8a059295..2383a0a3c 100644 --- a/mix/Web3Server.h +++ b/mix/Web3Server.h @@ -25,6 +25,7 @@ #include #include #include +#include #include namespace dev @@ -38,7 +39,7 @@ class Web3Server: public QObject, public dev::WebThreeStubServerBase, public dev Q_OBJECT public: - Web3Server(jsonrpc::AbstractServerConnector& _conn, std::vector const& _accounts, dev::eth::Interface* _client); + Web3Server(jsonrpc::AbstractServerConnector& _conn, std::shared_ptr const& _ethAccounts, std::vector const& _shhAccounts, dev::eth::Interface* _client); virtual ~Web3Server(); signals: diff --git a/test/libweb3jsonrpc/AccountHolder.cpp b/test/libweb3jsonrpc/AccountHolder.cpp index e8e42ff18..c9500a6ef 100644 --- a/test/libweb3jsonrpc/AccountHolder.cpp +++ b/test/libweb3jsonrpc/AccountHolder.cpp @@ -22,6 +22,9 @@ #include #include +using namespace std; +using namespace dev; +using namespace eth; namespace dev { @@ -32,16 +35,17 @@ BOOST_AUTO_TEST_SUITE(AccountHolderTest) BOOST_AUTO_TEST_CASE(ProxyAccountUseCase) { - AccountHolder h = AccountHolder(std::function()); - BOOST_CHECK(h.getAllAccounts().empty()); - BOOST_CHECK(h.getRealAccounts().empty()); + FixedAccountHolder h = FixedAccountHolder(function(), vector()); + + BOOST_CHECK(h.allAccounts().empty()); + BOOST_CHECK(h.realAccounts().empty()); Address addr("abababababababababababababababababababab"); Address addr2("abababababababababababababababababababab"); int id = h.addProxyAccount(addr); - BOOST_CHECK(h.getQueuedTransactions(id).empty()); + BOOST_CHECK(h.queuedTransactions(id).empty()); // register it again int secondID = h.addProxyAccount(addr); - BOOST_CHECK(h.getQueuedTransactions(secondID).empty()); + BOOST_CHECK(h.queuedTransactions(secondID).empty()); eth::TransactionSkeleton t1; eth::TransactionSkeleton t2; @@ -49,20 +53,20 @@ BOOST_AUTO_TEST_CASE(ProxyAccountUseCase) t1.data = fromHex("12345678"); t2.from = addr; t2.data = fromHex("abcdef"); - BOOST_CHECK(h.getQueuedTransactions(id).empty()); + BOOST_CHECK(h.queuedTransactions(id).empty()); h.queueTransaction(t1); - BOOST_CHECK_EQUAL(1, h.getQueuedTransactions(id).size()); + BOOST_CHECK_EQUAL(1, h.queuedTransactions(id).size()); h.queueTransaction(t2); - BOOST_REQUIRE_EQUAL(2, h.getQueuedTransactions(id).size()); + BOOST_REQUIRE_EQUAL(2, h.queuedTransactions(id).size()); // second proxy should not see transactions - BOOST_CHECK(h.getQueuedTransactions(secondID).empty()); + BOOST_CHECK(h.queuedTransactions(secondID).empty()); - BOOST_CHECK(h.getQueuedTransactions(id)[0].data == t1.data); - BOOST_CHECK(h.getQueuedTransactions(id)[1].data == t2.data); + BOOST_CHECK(h.queuedTransactions(id)[0].data == t1.data); + BOOST_CHECK(h.queuedTransactions(id)[1].data == t2.data); h.clearQueue(id); - BOOST_CHECK(h.getQueuedTransactions(id).empty()); + BOOST_CHECK(h.queuedTransactions(id).empty()); // removing fails because it never existed BOOST_CHECK(!h.removeProxyAccount(secondID)); BOOST_CHECK(h.removeProxyAccount(id)); From 69328f1dbf9abeaa3c161bccee796915f18215b4 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 11 May 2015 16:36:33 +0300 Subject: [PATCH 17/30] Compiles and tested basically ok. --- alethzero/Context.h | 2 + alethzero/MainWin.cpp | 166 +++++++++++++++++----------- alethzero/MainWin.h | 13 ++- alethzero/OurWebThreeStubServer.cpp | 2 +- alethzero/Transact.cpp | 23 ++-- alethzero/Transact.h | 4 +- 6 files changed, 130 insertions(+), 80 deletions(-) diff --git a/alethzero/Context.h b/alethzero/Context.h index 20c9696f9..3ed7cf7b3 100644 --- a/alethzero/Context.h +++ b/alethzero/Context.h @@ -64,5 +64,7 @@ public: virtual std::pair fromString(std::string const& _a) const = 0; virtual std::string renderDiff(dev::eth::StateDiff const& _d) const = 0; virtual std::string render(dev::Address const& _a) const = 0; + virtual dev::Secret retrieveSecret(dev::Address const& _a) const = 0; + }; diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 06f5f5283..8a2fca714 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -200,8 +201,6 @@ Main::Main(QWidget *parent) : ui->blockCount->setText(QString("PV%1.%2 D%3 %4-%5 v%6").arg(eth::c_protocolVersion).arg(eth::c_minorProtocolVersion).arg(c_databaseVersion).arg(QString::fromStdString(ProofOfWork::name())).arg(ProofOfWork::revision()).arg(dev::Version)); - connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved())); - QSettings s("ethereum", "alethzero"); m_networkConfig = s.value("peers").toByteArray(); bytesConstRef network((byte*)m_networkConfig.data(), m_networkConfig.size()); @@ -230,6 +229,7 @@ Main::Main(QWidget *parent) : // ui->webView->page()->settings()->setAttribute(QWebEngineSettings::DeveloperExtrasEnabled, true); // QWebEngineInspector* inspector = new QWebEngineInspector(); // inspector->setPage(page); + setBeneficiary(*m_keyManager.accounts().begin()); readSettings(); #if !ETH_FATDB removeDockWidget(ui->dockWidget_accounts); @@ -390,9 +390,9 @@ void Main::installBalancesWatch() // TODO: Update for new currencies reg. for (unsigned i = 0; i < ethereum()->stateAt(coinsAddr, PendingBlock); ++i) altCoins.push_back(right160(ethereum()->stateAt(coinsAddr, i + 1))); - for (auto i: m_myKeys) + for (auto const& i: m_keyManager.accounts()) for (auto c: altCoins) - tf.address(c).topic(0, h256(i.address(), h256::AlignRight)); + tf.address(c).topic(0, h256(i, h256::AlignRight)); uninstallWatch(m_balancesFilter); m_balancesFilter = installWatch(tf, [=](LocalisedLogEntries const&){ onBalancesChange(); }); @@ -461,7 +461,7 @@ void Main::load(QString _s) void Main::on_newTransaction_triggered() { - m_transact.setEnvironment(m_myKeys, ethereum(), &m_natSpecDB); + m_transact.setEnvironment(m_keyManager.accounts(), ethereum(), &m_natSpecDB); m_transact.exec(); } @@ -648,17 +648,7 @@ void Main::on_paranoia_triggered() void Main::writeSettings() { QSettings s("ethereum", "alethzero"); - { - QByteArray b; - b.resize(sizeof(Secret) * m_myKeys.size()); - auto p = b.data(); - for (auto i: m_myKeys) - { - memcpy(p, &(i.secret()), sizeof(Secret)); - p += sizeof(Secret); - } - s.setValue("address", b); - } + s.remove("address"); { QByteArray b; b.resize(sizeof(Secret) * m_myIdentities.size()); @@ -698,6 +688,20 @@ void Main::writeSettings() s.setValue("windowState", saveState()); } +Secret Main::retrieveSecret(Address const& _a) const +{ + auto info = m_keyManager.accountDetails()[_a]; + while (true) + { + if (Secret s = m_keyManager.secret(_a, [&](){ + return QInputDialog::getText(const_cast(this), "Import Account Key", QString("Enter the password for the account %2 (%1). The hint is:\n%3").arg(QString::fromStdString(_a.abridged())).arg(QString::fromStdString(info.first)).arg(QString::fromStdString(info.second)), QLineEdit::Password).toStdString(); + })) + return s; + else if (QMessageBox::warning(const_cast(this), "Incorrect Password", "The password you gave is incorrect for this key.", QMessageBox::Retry, QMessageBox::Cancel) == QMessageBox::Cancel) + return Secret(); + } +} + void Main::readSettings(bool _skipGeometry) { QSettings s("ethereum", "alethzero"); @@ -707,21 +711,17 @@ void Main::readSettings(bool _skipGeometry) restoreState(s.value("windowState").toByteArray()); { - m_myKeys.clear(); QByteArray b = s.value("address").toByteArray(); - if (b.isEmpty()) - m_myKeys.append(KeyPair::create()); - else + if (!b.isEmpty()) { h256 k; for (unsigned i = 0; i < b.size() / sizeof(Secret); ++i) { memcpy(&k, b.data() + i * sizeof(Secret), sizeof(Secret)); - if (!count(m_myKeys.begin(), m_myKeys.end(), KeyPair(k))) - m_myKeys.append(KeyPair(k)); + if (!m_keyManager.accounts().count(KeyPair(k).address())) + m_keyManager.import(k, "Imported (UNSAFE) key."); } } - ethereum()->setAddress(m_myKeys.back().address()); } { @@ -766,16 +766,38 @@ void Main::readSettings(bool _skipGeometry) on_urlEdit_returnPressed(); } +std::string Main::getPassword(std::string const& _title, std::string const& _for) +{ + QString password; + while (true) + { + password = QInputDialog::getText(nullptr, QString::fromStdString(_title), QString::fromStdString(_for), QLineEdit::Password, QString()); + QString confirm = QInputDialog::getText(nullptr, QString::fromStdString(_title), "Confirm this password by typing it again", QLineEdit::Password, QString()); + if (password == confirm) + break; + QMessageBox::warning(nullptr, QString::fromStdString(_title), "You entered two different passwords - please enter the same password twice.", QMessageBox::Ok); + } + return password.toStdString(); +} + void Main::on_importKey_triggered() { - QString s = QInputDialog::getText(this, "Import Account Key", "Enter account's secret key"); + QString s = QInputDialog::getText(this, "Import Account Key", "Enter account's secret key", QLineEdit::Password); bytes b = fromHex(s.toStdString()); if (b.size() == 32) { auto k = KeyPair(h256(b)); - if (std::find(m_myKeys.begin(), m_myKeys.end(), k) == m_myKeys.end()) + if (!m_keyManager.accounts().count(k.address())) { - m_myKeys.append(k); + QString s = QInputDialog::getText(this, "Import Account Key", "Enter this account's name"); + if (QMessageBox::question(this, "Additional Security?", "Would you like to use additional security for this key? This lets you protect it with a different password to other keys, but also means you must re-enter the key's password every time you wish to use the account.", QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) + { + std::string password = getPassword("Import Account Key", "Enter the password you would like to use for this key. Don't forget it!"); + std::string hint = QInputDialog::getText(this, "Import Account Key", "Enter a hint to help you remember this password.").toStdString(); + m_keyManager.import(k.secret(), s.toStdString(), password, hint); + } + else + m_keyManager.import(k.secret(), s.toStdString()); keysChanged(); } else @@ -816,15 +838,8 @@ void Main::on_importKeyFile_triggered() } cnote << k.address(); - if (std::find(m_myKeys.begin(), m_myKeys.end(), k) == m_myKeys.end()) - { - if (m_myKeys.empty()) - { - m_myKeys.push_back(KeyPair::create()); - keysChanged(); - } - ethereum()->submitTransaction(k.sec(), ethereum()->balanceAt(k.address()) - gasPrice() * c_txGas, m_myKeys.back().address(), {}, c_txGas, gasPrice()); - } + if (!m_keyManager.accounts().count(k.address())) + ethereum()->submitTransaction(k.sec(), ethereum()->balanceAt(k.address()) - gasPrice() * c_txGas, m_beneficiary, {}, c_txGas, gasPrice()); else QMessageBox::warning(this, "Already Have Key", "Could not import the secret key: we already own this account."); } @@ -843,10 +858,12 @@ void Main::on_importKeyFile_triggered() void Main::on_exportKey_triggered() { - if (ui->ourAccounts->currentRow() >= 0 && ui->ourAccounts->currentRow() < m_myKeys.size()) + if (ui->ourAccounts->currentRow() >= 0) { - auto k = m_myKeys[ui->ourAccounts->currentRow()]; - QMessageBox::information(this, "Export Account Key", "Secret key to account " + QString::fromStdString(render(k.address()) + " is:\n" + toHex(k.sec().ref()))); + auto hba = ui->ourAccounts->currentItem()->data(Qt::UserRole).toByteArray(); + Address h((byte const*)hba.data(), Address::ConstructFromPointer); + Secret s = retrieveSecret(h); + QMessageBox::information(this, "Export Account Key", "Secret key to account " + QString::fromStdString(render(h) + " is:\n" + s.hex())); } } @@ -944,6 +961,24 @@ void Main::refreshMining() */ } +void Main::setBeneficiary(Address const& _b) +{ + for (int i = 0; i < ui->ourAccounts->count(); ++i) + { + auto hba = ui->ourAccounts->item(i)->data(Qt::UserRole).toByteArray(); + auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer); + ui->ourAccounts->item(i)->setCheckState(h == _b ? Qt::Checked : Qt::Unchecked); + } + m_beneficiary = _b; + ethereum()->setAddress(_b); +} + +void Main::on_ourAccounts_itemClicked(QListWidgetItem* _i) +{ + auto hba = _i->data(Qt::UserRole).toByteArray(); + setBeneficiary(Address((byte const*)hba.data(), Address::ConstructFromPointer)); +} + void Main::refreshBalances() { cwatch << "refreshBalances()"; @@ -962,11 +997,13 @@ void Main::refreshBalances() // cdebug << n << addr << denom << sha3(h256(n).asBytes()); altCoins[addr] = make_tuple(fromRaw(n), 0, denom); }*/ - for (auto i: m_myKeys) + for (pair> const& i: m_keyManager.accountDetails()) { - u256 b = ethereum()->balanceAt(i.address()); - (new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(b).c_str()).arg(QString::fromStdString(render(i.address()))).arg((unsigned)ethereum()->countAt(i.address())), ui->ourAccounts)) - ->setData(Qt::UserRole, QByteArray((char const*)i.address().data(), Address::size)); + u256 b = ethereum()->balanceAt(i.first); + QListWidgetItem* li = new QListWidgetItem(QString("%4 %2: %1 [%3]").arg(formatBalance(b).c_str()).arg(QString::fromStdString(render(i.first))).arg((unsigned)ethereum()->countAt(i.first)).arg(QString::fromStdString(i.second.first)), ui->ourAccounts); + li->setData(Qt::UserRole, QByteArray((char const*)i.first.data(), Address::size)); + li->setFlags(Qt::ItemIsUserCheckable); + li->setCheckState(m_beneficiary == i.first ? Qt::Checked : Qt::Unchecked); totalBalance += b; // for (auto& c: altCoins) @@ -1416,20 +1453,6 @@ void Main::on_transactionQueue_currentItemChanged() ui->pendingInfo->moveCursor(QTextCursor::Start); } -void Main::ourAccountsRowsMoved() -{ - QList myKeys; - for (int i = 0; i < ui->ourAccounts->count(); ++i) - { - auto hba = ui->ourAccounts->item(i)->data(Qt::UserRole).toByteArray(); - auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer); - for (auto i: m_myKeys) - if (i.address() == h) - myKeys.push_back(i); - } - m_myKeys = myKeys; -} - void Main::on_inject_triggered() { QString s = QInputDialog::getText(this, "Inject Transaction", "Enter transaction dump in hex"); @@ -1855,7 +1878,7 @@ void Main::on_mine_triggered() { if (ui->mine->isChecked()) { - ethereum()->setAddress(m_myKeys.last().address()); + ethereum()->setAddress(m_beneficiary); ethereum()->startMining(); } else @@ -1928,24 +1951,39 @@ void Main::on_newAccount_triggered() t->join(); delete t; } - m_myKeys.append(p); + + QString s = QInputDialog::getText(this, "Create Account", "Enter this account's name"); + if (QMessageBox::question(this, "Create Account", "Would you like to use additional security for this key? This lets you protect it with a different password to other keys, but also means you must re-enter the key's password every time you wish to use the account.", QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) + { + std::string password = getPassword("Create Account", "Enter the password you would like to use for this key. Don't forget it!"); + std::string hint = QInputDialog::getText(this, "Create Account", "Enter a hint to help you remember this password.").toStdString(); + m_keyManager.import(p.secret(), s.toStdString(), password, hint); + } + else + m_keyManager.import(p.secret(), s.toStdString()); keysChanged(); } void Main::on_killAccount_triggered() { - if (ui->ourAccounts->currentRow() >= 0 && ui->ourAccounts->currentRow() < m_myKeys.size()) + if (ui->ourAccounts->currentRow() >= 0) { - auto k = m_myKeys[ui->ourAccounts->currentRow()]; + auto hba = ui->accounts->currentItem()->data(Qt::UserRole).toByteArray(); + Address h((byte const*)hba.data(), Address::ConstructFromPointer); + auto k = m_keyManager.accountDetails()[h]; if ( - ethereum()->balanceAt(k.address()) != 0 && - QMessageBox::critical(this, "Kill Account?!", - QString::fromStdString("Account " + render(k.address()) + " has " + formatBalance(ethereum()->balanceAt(k.address())) + " in it. It, and any contract that this account can access, will be lost forever if you continue. Do NOT continue unless you know what you are doing.\n" + ethereum()->balanceAt(h) != 0 && + QMessageBox::critical(this, QString::fromStdString("Kill Account " + k.first + "?!"), + QString::fromStdString("Account " + k.first + " (" + render(h) + ") has " + formatBalance(ethereum()->balanceAt(h)) + " in it. It, and any contract that this account can access, will be lost forever if you continue. Do NOT continue unless you know what you are doing.\n" "Are you sure you want to continue?"), QMessageBox::Yes, QMessageBox::No) == QMessageBox::No) return; - m_myKeys.erase(m_myKeys.begin() + ui->ourAccounts->currentRow()); + m_keyManager.kill(h); + if (m_keyManager.accounts().empty()) + m_keyManager.import(Secret::random(), "Default account"); keysChanged(); + if (m_beneficiary == h) + setBeneficiary(*m_keyManager.accounts().begin()); } } diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 6b2ede715..0d5f9808c 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -43,6 +43,8 @@ #include "NatspecHandler.h" #include "Connect.h" +class QListWidgetItem; + namespace Ui { class Main; } @@ -87,12 +89,14 @@ public: std::pair fromString(std::string const& _a) const override; std::string renderDiff(dev::eth::StateDiff const& _d) const override; - QList owned() const { return m_myIdentities + m_myKeys; } + QList owned() const { return m_myIdentities; } dev::u256 gasPrice() const { return 10 * dev::eth::szabo; } dev::eth::KeyManager& keyManager() { return m_keyManager; } + dev::Secret retrieveSecret(dev::Address const& _a) const override; + public slots: void load(QString _file); void note(QString _entry); @@ -147,7 +151,7 @@ private slots: void on_exportState_triggered(); // Stuff concerning the blocks/transactions/accounts panels - void ourAccountsRowsMoved(); + void on_ourAccounts_itemClicked(QListWidgetItem* _i); void on_ourAccounts_doubleClicked(); void on_accounts_doubleClicked(); void on_accounts_currentItemChanged(); @@ -239,6 +243,9 @@ private: void refreshBlockCount(); void refreshBalances(); + void setBeneficiary(dev::Address const& _b); + std::string getPassword(std::string const& _title, std::string const& _for); + std::unique_ptr ui; std::unique_ptr m_webThree; @@ -250,11 +257,11 @@ private: QByteArray m_networkConfig; QStringList m_servers; - QList m_myKeys; QList m_myIdentities; dev::eth::KeyManager m_keyManager; QString m_privateChain; dev::Address m_nameReg; + dev::Address m_beneficiary; QList> m_consoleHistory; QMutex m_logLock; diff --git a/alethzero/OurWebThreeStubServer.cpp b/alethzero/OurWebThreeStubServer.cpp index da645766a..d3ee4f41b 100644 --- a/alethzero/OurWebThreeStubServer.cpp +++ b/alethzero/OurWebThreeStubServer.cpp @@ -134,7 +134,7 @@ void OurAccountHolder::doValidations() queueTransaction(t); else // sign and submit. - if (Secret s = m_main->keyManager().secret(t.from)) + if (Secret s = m_main->retrieveSecret(t.from)) m_web3->ethereum()->submitTransaction(s, t); } } diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp index 2041bf39d..5e4493431 100644 --- a/alethzero/Transact.cpp +++ b/alethzero/Transact.cpp @@ -69,9 +69,9 @@ Transact::~Transact() delete ui; } -void Transact::setEnvironment(QList _myKeys, dev::eth::Client* _eth, NatSpecFace* _natSpecDB) +void Transact::setEnvironment(AddressHash const& _accounts, dev::eth::Client* _eth, NatSpecFace* _natSpecDB) { - m_myKeys = _myKeys; + m_accounts = _accounts; m_ethereum = _eth; m_natSpecDB = _natSpecDB; } @@ -126,8 +126,8 @@ void Transact::updateFee() ui->total->setText(QString("Total: %1").arg(formatBalance(totalReq).c_str())); bool ok = false; - for (auto i: m_myKeys) - if (ethereum()->balanceAt(i.address()) >= totalReq) + for (auto const& i: m_accounts) + if (ethereum()->balanceAt(i) >= totalReq) { ok = true; break; @@ -388,17 +388,20 @@ Secret Transact::findSecret(u256 _totalReq) const if (!ethereum()) return Secret(); - Secret best; + Address best; u256 bestBalance = 0; - for (auto const& i: m_myKeys) + for (auto const& i: m_accounts) { - auto b = ethereum()->balanceAt(i.address(), PendingBlock); + auto b = ethereum()->balanceAt(i, PendingBlock); if (b >= _totalReq) - return i.secret(); + { + best = i; + break; + } if (b > bestBalance) - bestBalance = b, best = i.secret(); + bestBalance = b, best = i; } - return best; + return m_context->retrieveSecret(best); } void Transact::on_send_clicked() diff --git a/alethzero/Transact.h b/alethzero/Transact.h index 71bc393b2..d49fea72c 100644 --- a/alethzero/Transact.h +++ b/alethzero/Transact.h @@ -41,7 +41,7 @@ public: explicit Transact(Context* _context, QWidget* _parent = 0); ~Transact(); - void setEnvironment(QList _myKeys, dev::eth::Client* _eth, NatSpecFace* _natSpecDB); + void setEnvironment(dev::AddressHash const& _accounts, dev::eth::Client* _eth, NatSpecFace* _natSpecDB); private slots: void on_destination_currentTextChanged(QString); @@ -76,7 +76,7 @@ private: unsigned m_backupGas = 0; dev::bytes m_data; - QList m_myKeys; + dev::AddressHash m_accounts; dev::eth::Client* m_ethereum = nullptr; Context* m_context = nullptr; NatSpecFace* m_natSpecDB = nullptr; From f64164e88e51b9648b93094657909370aa31b2d6 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 11 May 2015 17:19:24 +0300 Subject: [PATCH 18/30] Selectable from account in transact dialog. Fixes. --- alethzero/Context.h | 3 +- alethzero/Main.ui | 7 +- alethzero/MainWin.cpp | 2 +- alethzero/MainWin.h | 2 +- alethzero/Transact.cpp | 32 ++++- alethzero/Transact.h | 1 + alethzero/Transact.ui | 261 +++++++++++++++++++++-------------------- 7 files changed, 173 insertions(+), 135 deletions(-) diff --git a/alethzero/Context.h b/alethzero/Context.h index 3ed7cf7b3..4a52366db 100644 --- a/alethzero/Context.h +++ b/alethzero/Context.h @@ -29,7 +29,7 @@ class QComboBox; -namespace dev { namespace eth { struct StateDiff; } } +namespace dev { namespace eth { struct StateDiff; class KeyManager; } } #define Small "font-size: small; " #define Mono "font-family: Ubuntu Mono, Monospace, Lucida Console, Courier New; font-weight: bold; " @@ -65,6 +65,7 @@ public: virtual std::string renderDiff(dev::eth::StateDiff const& _d) const = 0; virtual std::string render(dev::Address const& _a) const = 0; virtual dev::Secret retrieveSecret(dev::Address const& _a) const = 0; + virtual dev::eth::KeyManager& keyManager() = 0; }; diff --git a/alethzero/Main.ui b/alethzero/Main.ui index 736af8684..5b0ad7582 100644 --- a/alethzero/Main.ui +++ b/alethzero/Main.ui @@ -548,12 +548,15 @@ QFrame::NoFrame - - QAbstractItemView::InternalMove + + false true + + true + diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 8a2fca714..925a04cae 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1002,7 +1002,7 @@ void Main::refreshBalances() u256 b = ethereum()->balanceAt(i.first); QListWidgetItem* li = new QListWidgetItem(QString("%4 %2: %1 [%3]").arg(formatBalance(b).c_str()).arg(QString::fromStdString(render(i.first))).arg((unsigned)ethereum()->countAt(i.first)).arg(QString::fromStdString(i.second.first)), ui->ourAccounts); li->setData(Qt::UserRole, QByteArray((char const*)i.first.data(), Address::size)); - li->setFlags(Qt::ItemIsUserCheckable); + li->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); li->setCheckState(m_beneficiary == i.first ? Qt::Checked : Qt::Unchecked); totalBalance += b; diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 0d5f9808c..51d4cc8f4 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -93,7 +93,7 @@ public: dev::u256 gasPrice() const { return 10 * dev::eth::szabo; } - dev::eth::KeyManager& keyManager() { return m_keyManager; } + dev::eth::KeyManager& keyManager() override { return m_keyManager; } dev::Secret retrieveSecret(dev::Address const& _a) const override; diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp index 5e4493431..bc37db8ef 100644 --- a/alethzero/Transact.cpp +++ b/alethzero/Transact.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #if ETH_SERPENT #include #include @@ -74,6 +75,15 @@ void Transact::setEnvironment(AddressHash const& _accounts, dev::eth::Client* _e m_accounts = _accounts; m_ethereum = _eth; m_natSpecDB = _natSpecDB; + + ui->from->clear(); + for (auto const& i: m_accounts) + { + auto d = m_context->keyManager().accountDetails()[i]; + u256 b = ethereum()->balanceAt(i, PendingBlock); + QString s = QString("%4 %2: %1").arg(formatBalance(b).c_str()).arg(QString::fromStdString(m_context->render(i))).arg(QString::fromStdString(d.first)); + ui->from->addItem(s); + } } bool Transact::isCreation() const @@ -404,9 +414,17 @@ Secret Transact::findSecret(u256 _totalReq) const return m_context->retrieveSecret(best); } +Address Transact::fromAccount() +{ + auto it = m_accounts.begin(); + std::advance(it, ui->from->currentIndex()); + return *it; +} + void Transact::on_send_clicked() { - Secret s = findSecret(value() + fee()); +// Secret s = findSecret(value() + fee()); + Secret s = m_context->retrieveSecret(fromAccount()); auto b = ethereum()->balanceAt(KeyPair(s).address(), PendingBlock); if (!s || b < value() + fee()) { @@ -443,9 +461,10 @@ void Transact::on_send_clicked() void Transact::on_debug_clicked() { - Secret s = findSecret(value() + fee()); - auto b = ethereum()->balanceAt(KeyPair(s).address(), PendingBlock); - if (!s || b < value() + fee()) +// Secret s = findSecret(value() + fee()); + Address from = fromAccount(); + auto b = ethereum()->balanceAt(from, PendingBlock); + if (!from || b < value() + fee()) { QMessageBox::critical(this, "Transaction Failed", "Couldn't make transaction: no single account contains at least the required amount."); return; @@ -455,8 +474,9 @@ void Transact::on_debug_clicked() { State st(ethereum()->postState()); Transaction t = isCreation() ? - Transaction(value(), gasPrice(), ui->gas->value(), m_data, st.transactionsFrom(dev::toAddress(s)), s) : - Transaction(value(), gasPrice(), ui->gas->value(), m_context->fromString(ui->destination->currentText().toStdString()).first, m_data, st.transactionsFrom(dev::toAddress(s)), s); + Transaction(value(), gasPrice(), ui->gas->value(), m_data, st.transactionsFrom(from)) : + Transaction(value(), gasPrice(), ui->gas->value(), m_context->fromString(ui->destination->currentText().toStdString()).first, m_data, st.transactionsFrom(from)); + t.forceSender(from); Debugger dw(m_context, this); Executive e(st, ethereum()->blockChain(), 0); dw.populate(e, t); diff --git a/alethzero/Transact.h b/alethzero/Transact.h index d49fea72c..cd62c0e20 100644 --- a/alethzero/Transact.h +++ b/alethzero/Transact.h @@ -60,6 +60,7 @@ private: dev::eth::Client* ethereum() const { return m_ethereum; } void rejigData(); + dev::Address fromAccount(); void updateDestination(); void updateFee(); bool isCreation() const; diff --git a/alethzero/Transact.ui b/alethzero/Transact.ui index 75af9ba98..f7a5e7c0e 100644 --- a/alethzero/Transact.ui +++ b/alethzero/Transact.ui @@ -14,91 +14,69 @@ Transact - - - - + + + + + 0 + 0 + - - 430000000 + + D&ata - - 0 + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + data - - + + - &Amount + &Optimise - - value + + true - - - - false + + + + gas - - true + + 1 - - + + 430000000 + + + 10000 - - - - Qt::Vertical + + + + &Cancel + + + Esc - - - QFrame::NoFrame - - - 0 - - - - - Qt::ClickFocus - - - QFrame::NoFrame - - - 0 - - - true - - - - - - - - - - 0 - 0 - - + + - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + &Debug - + @@ -114,53 +92,68 @@ - - - - - + + + + + 0 + 0 + + - &Debug + - - - - &Execute + + + + - - false + + 430000000 + + + 0 + + + - + - &Gas + &Amount - gas + value - - - - gas - - - 1 + + + + &Execute - - 430000000 + + false - - 10000 + + + + + + true + + + (Create Contract) + + - + @ @@ -173,49 +166,63 @@ - - - - &Optimise - - - true + + + + Qt::Vertical + + + QFrame::NoFrame + + + 0 + + + + + Qt::ClickFocus + + + QFrame::NoFrame + + + 0 + + + true + + - - - - 0 - 0 - - + - D&ata - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + &Gas - data + gas - - - + + + + false + + true - - - (Create Contract) - - + + + - - + + + + + 0 @@ -225,18 +232,24 @@ + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + - - + + - &Cancel + &From - - Esc + + from + + + From 4011d4de7123b9cf392537939c66728d7b2915ba Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 11 May 2015 17:46:28 +0300 Subject: [PATCH 19/30] Don't echo passwords. --- eth/main.cpp | 11 ++++------- libdevcore/CommonIO.cpp | 14 +++++++++++++- libdevcore/CommonIO.h | 2 ++ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/eth/main.cpp b/eth/main.cpp index 04ac5bc7e..2514a2a1b 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -1093,8 +1093,7 @@ int main(int argc, char** argv) { while (masterPassword.empty()) { - cout << "Please enter your MASTER password:" << flush; - getline(cin, masterPassword); + masterPassword = getPassword("Please enter your MASTER password: "); if (!keyManager.load(masterPassword)) { cout << "Password invalid. Try again." << endl; @@ -1106,10 +1105,8 @@ int main(int argc, char** argv) { while (masterPassword.empty()) { - cout << "Please enter a MASTER password to protect your key store. Make it strong." << flush; - getline(cin, masterPassword); - string confirm; - cout << "Please confirm the password by entering it again." << flush; + masterPassword = getPassword("Please enter a MASTER password to protect your key store (make it strong!): "); + string confirm = getPassword("Please confirm the password by entering it again: "); getline(cin, confirm); if (masterPassword != confirm) { @@ -1126,7 +1123,7 @@ int main(int argc, char** argv) g_logPost = [&](std::string const& a, char const*) { if (silence) logbuf += a + "\n"; else cout << "\r \r" << a << endl << additional << flush; }; // TODO: give hints &c. - auto getPassword = [&](Address const& a){ auto s = silence; silence = true; string ret; cout << endl << "Enter password for address " << a.abridged() << ": " << flush; std::getline(cin, ret); silence = s; return ret; }; + auto getPassword = [&](Address const& a){ auto s = silence; silence = true; cout << endl; string ret = dev::getPassword("Enter password for address " + a.abridged() + ": "); silence = s; return ret; }; #if ETH_JSONRPC || !ETH_TRUE shared_ptr jsonrpcServer; diff --git a/libdevcore/CommonIO.cpp b/libdevcore/CommonIO.cpp index a1a1056cb..80ad7ecf9 100644 --- a/libdevcore/CommonIO.cpp +++ b/libdevcore/CommonIO.cpp @@ -20,7 +20,8 @@ */ #include "CommonIO.h" - +#include +#include #include #include "Exceptions.h" using namespace std; @@ -117,3 +118,14 @@ void dev::writeFile(std::string const& _file, bytesConstRef _data) ofstream(_file, ios::trunc|ios::binary).write((char const*)_data.data(), _data.size()); } +std::string dev::getPassword(std::string const& _prompt) +{ +#if WIN32 + cout << _prompt << flush; + std::string ret; + std::getline(cin, ret); + return ret; +#else + return getpass(_prompt.c_str()); +#endif +} diff --git a/libdevcore/CommonIO.h b/libdevcore/CommonIO.h index 80334fa31..46a8b80bc 100644 --- a/libdevcore/CommonIO.h +++ b/libdevcore/CommonIO.h @@ -42,6 +42,8 @@ namespace dev { +std::string getPassword(std::string const& _prompt); + /// Retrieve and returns the contents of the given file. If the file doesn't exist or isn't readable, returns an empty bytes. bytes contents(std::string const& _file); std::string contentsString(std::string const& _file); From b3f85187169bb7761c1aaac0ff486b76b3e29f1c Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 11 May 2015 21:17:23 +0300 Subject: [PATCH 20/30] Structured logger can output to a file. Better support of imports/keys and key manager integration for eth. --- eth/main.cpp | 148 ++++++++++++++++++++++---------- libdevcore/StructuredLogger.cpp | 13 ++- libdevcore/StructuredLogger.h | 14 +-- libethereum/BlockChain.cpp | 39 ++++++--- libethereum/KeyManager.h | 2 + libethereum/State.cpp | 1 + libethereum/State.h | 2 +- 7 files changed, 153 insertions(+), 66 deletions(-) diff --git a/eth/main.cpp b/eth/main.cpp index 2514a2a1b..ba44b15a8 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -91,10 +91,8 @@ void interactiveHelp() << " minestart Starts mining." << endl << " minestop Stops mining." << endl << " mineforce Forces mining, even when there are no transactions." << endl - << " address Gives the current address." << endl - << " secret Gives the current secret" << endl << " block Gives the current block height." << endl - << " balance Gives the current balance." << endl + << " accounts Gives information on all owned accounts (balances, mining beneficiary and default signer)." << endl << " transact Execute a given transaction." << endl << " send Execute a given transaction with current secret." << endl << " contract Create a new contract with current secret." << endl @@ -103,7 +101,7 @@ void interactiveHelp() << " listaccounts List the accounts on the network." << endl << " listcontracts List the contracts on the network." << endl #endif - << " setsecret Set the secret to the hex secret key." << endl + << " setsigningkey Set the address with which to sign transactions." << endl << " setaddress Set the coinbase (mining payout) address." << endl << " exportconfig Export the config (.RLP) to the path provided." << endl << " importconfig Import the config (.RLP) from the path provided." << endl @@ -127,13 +125,18 @@ void help() #endif << " -K,--kill First kill the blockchain." << endl << " -R,--rebuild Rebuild the blockchain from the existing database." << endl - << " -s,--secret Set the secret key for use with send command (default: auto)." << endl - << " -S,--session-secret Set the secret key for use with send command, for this session only." << endl + << " -s,--import-secret Import a secret key into the key store and use as the default." << endl + << " -S,--import-session-secret Import a secret key into the key store and use as the default for this session only." << endl + << " --sign-key
Sign all transactions with the key of the given address." << endl + << " --session-sign-key
Sign all transactions with the key of the given address for this session only." << endl << " --master Give the master password for the key store." << endl + << " --password Give a password for a private key." << endl + << endl << "Client transacting:" << endl << " -B,--block-fees Set the block fee profit in the reference unit e.g. ¢ (default: 15)." << endl << " -e,--ether-price Set the ether price in the reference unit e.g. ¢ (default: 30.679)." << endl << " -P,--priority <0 - 100> Default % priority of a transaction (default: 50)." << endl + << endl << "Client mining:" << endl << " -a,--address Set the coinbase (mining payout) address to addr (default: auto)." << endl << " -m,--mining Enable mining, optionally for a specified number of blocks (default: off)" << endl @@ -143,6 +146,7 @@ void help() << " --opencl-platform When mining using -G/--opencl use OpenCL platform n (default: 0)." << endl << " --opencl-device When mining using -G/--opencl use OpenCL device n (default: 0)." << endl << " -t, --mining-threads Limit number of CPU/GPU miners to n (default: use everything available on selected platform)" << endl + << endl << "Client networking:" << endl << " --client-name Add a name to your client's version string (default: blank)." << endl << " -b,--bootstrap Connect to the default Ethereum peerserver." << endl @@ -155,12 +159,15 @@ void help() << " --network-id Only connect to other hosts with this network id (default:0)." << endl << " --upnp Use UPnP for NAT (default: on)." << endl #if ETH_JSONRPC || !ETH_TRUE + << endl << "Work farming mode:" << endl << " -F,--farm Put into mining farm mode with the work server at URL. Use with -G/--opencl." << endl << " --farm-recheck Leave n ms between checks for changed work (default: 500)." << endl #endif + << endl << "Ethash verify mode:" << endl << " -w,--check-pow Check PoW credentials for validity." << endl + << endl << "Benchmarking mode:" << endl << " -M,--benchmark Benchmark for mining and exit; use with --cpu and --opencl." << endl << " --benchmark-warmup Set the duration of warmup for the benchmark tests (default: 3)." << endl @@ -169,14 +176,17 @@ void help() #if ETH_JSONRPC || !ETH_TRUE << " --phone-home When benchmarking, publish results (default: on)" << endl #endif + << endl << "DAG creation mode:" << endl << " -D,--create-dag Create the DAG in preparation for mining on given block and exit." << endl + << endl << "Import/export modes:" << endl << " -I,--import Import file as a concatenated series of blocks and exit." << endl << " -E,--export Export file as a concatenated series of blocks and exit." << endl << " --from Export only from block n; n may be a decimal, a '0x' prefixed hash, or 'latest'." << endl << " --to Export only to block n (inclusive); n may be a decimal, a '0x' prefixed hash, or 'latest'." << endl << " --only Equivalent to --export-from n --export-to n." << endl + << endl << "General Options:" << endl << " -d,--db-path Load database from path (default: " << getDataDir() << ")" << endl #if ETH_EVMJIT || !ETH_TRUE @@ -539,13 +549,14 @@ int main(int argc, char** argv) /// Mining params unsigned mining = 0; bool forceMining = false; - KeyPair sigKey = KeyPair::create(); - Secret sessionSecret; - Address coinbase = sigKey.address(); + Address signingKey; + Address sessionKey; + Address beneficiary = signingKey; /// Structured logging params bool structuredLogging = false; string structuredLoggingFormat = "%Y-%m-%dT%H:%M:%S"; + string structuredLoggingURL; /// Transaction params TransactionPriority priority = TransactionPriority::Medium; @@ -570,11 +581,20 @@ int main(int argc, char** argv) string configFile = getDataDir() + "/config.rlp"; bytes b = contents(configFile); + + strings passwordsToNote; + Secrets toImport; if (b.size()) { RLP config(b); - sigKey = KeyPair(config[0].toHash()); - coinbase = config[1].toHash
(); + if (config[0].size() == 32) // secret key - import and forget. + { + Secret s = config[0].toHash(); + toImport.push_back(s); + } + else // new format - just use it as an address. + signingKey = config[0].toHash
(); + beneficiary = config[1].toHash
(); } for (int i = 1; i < argc; ++i) @@ -602,6 +622,8 @@ int main(int argc, char** argv) cerr << "-p is DEPRECATED. It will be removed for the Frontier. Use --port instead (or place directly as host:port)." << endl; remotePort = (short)atoi(argv[++i]); } + else if (arg == "--password" && i + 1 < argc) + passwordsToNote.push_back(argv[++i]); else if (arg == "--master" && i + 1 < argc) masterPassword = argv[++i]; else if ((arg == "-I" || arg == "--import") && i + 1 < argc) @@ -744,7 +766,7 @@ int main(int argc, char** argv) } else if ((arg == "-a" || arg == "--address" || arg == "--coinbase-address") && i + 1 < argc) try { - coinbase = h160(fromHex(argv[++i], WhenError::Throw)); + beneficiary = h160(fromHex(argv[++i], WhenError::Throw)); } catch (BadHexCharacter&) { @@ -760,14 +782,32 @@ int main(int argc, char** argv) minerType = MinerType::CPU; else if (arg == "-G" || arg == "--opencl") minerType = MinerType::GPU; - else if ((arg == "-s" || arg == "--secret") && i + 1 < argc) - sigKey = KeyPair(h256(fromHex(argv[++i]))); - else if ((arg == "-S" || arg == "--session-secret") && i + 1 < argc) - sessionSecret = h256(fromHex(argv[++i])); + /*<< " -s,--import-secret Import a secret key into the key store and use as the default." << endl + << " -S,--import-session-secret Import a secret key into the key store and use as the default for this session only." << endl + << " --sign-key
Sign all transactions with the key of the given address." << endl + << " --session-sign-key
Sign all transactions with the key of the given address for this session only." << endl*/ + else if ((arg == "-s" || arg == "--import-secret") && i + 1 < argc) + { + Secret s(fromHex(argv[++i])); + toImport.push_back(s); + signingKey = toAddress(s); + } + else if ((arg == "-S" || arg == "--import-session-secret") && i + 1 < argc) + { + Secret s(fromHex(argv[++i])); + toImport.push_back(s); + sessionKey = toAddress(s); + } + else if ((arg == "--sign-key") && i + 1 < argc) + sessionKey = Address(fromHex(argv[++i])); + else if ((arg == "--session-sign-key") && i + 1 < argc) + sessionKey = Address(fromHex(argv[++i])); else if (arg == "--structured-logging-format" && i + 1 < argc) structuredLoggingFormat = string(argv[++i]); else if (arg == "--structured-logging") structuredLogging = true; + else if (arg == "--structured-logging-destination" && i + 1 < argc) + structuredLoggingURL = argv[++i]; else if ((arg == "-d" || arg == "--path" || arg == "--db-path") && i + 1 < argc) dbPath = argv[++i]; else if ((arg == "-D" || arg == "--create-dag") && i + 1 < argc) @@ -951,16 +991,24 @@ int main(int argc, char** argv) } } + KeyManager keyManager; + for (auto const& s: passwordsToNote) + keyManager.notePassword(s); + for (auto const& s: toImport) + { + keyManager.import(s, "Imported key"); + if (!signingKey) + signingKey = toAddress(s); + } + { RLPStream config(2); - config << sigKey.secret() << coinbase; + config << signingKey << beneficiary; writeFile(configFile, config.out()); } - if (sessionSecret) - sigKey = KeyPair(sessionSecret); - - + if (sessionKey) + signingKey = sessionKey; if (minerType == MinerType::CPU) ProofOfWork::CPUMiner::setNumInstances(miningThreads); @@ -985,7 +1033,7 @@ int main(int argc, char** argv) if (!clientName.empty()) clientName += "/"; - StructuredLogger::get().initialize(structuredLogging, structuredLoggingFormat); + StructuredLogger::get().initialize(structuredLogging, structuredLoggingFormat, structuredLoggingURL); VMFactory::setKind(jit ? VMKind::JIT : VMKind::Interpreter); auto netPrefs = publicIP.empty() ? NetworkPreferences(listenIP ,listenPort, upnp) : NetworkPreferences(publicIP, listenIP ,listenPort, upnp); auto nodesState = contents((dbPath.size() ? dbPath : getDataDir()) + "/network.rlp"); @@ -1074,12 +1122,12 @@ int main(int argc, char** argv) c->setGasPricer(gasPricer); c->setForceMining(forceMining); c->setTurboMining(minerType == MinerType::GPU); - c->setAddress(coinbase); + c->setAddress(beneficiary); c->setNetworkId(networkId); } - cout << "Transaction Signer: " << sigKey.address() << endl; - cout << "Mining Benefactor: " << coinbase << endl; + cout << "Transaction Signer: " << signingKey << endl; + cout << "Mining Benefactor: " << beneficiary << endl; web3.startNetwork(); cout << "Node ID: " << web3.enode() << endl; @@ -1088,9 +1136,7 @@ int main(int argc, char** argv) if (remoteHost.size()) web3.addNode(p2p::NodeId(), remoteHost + ":" + toString(remotePort)); - KeyManager keyManager; if (keyManager.exists()) - { while (masterPassword.empty()) { masterPassword = getPassword("Please enter your MASTER password: "); @@ -1100,14 +1146,12 @@ int main(int argc, char** argv) masterPassword.clear(); } } - } else { while (masterPassword.empty()) { masterPassword = getPassword("Please enter a MASTER password to protect your key store (make it strong!): "); string confirm = getPassword("Please confirm the password by entering it again: "); - getline(cin, confirm); if (masterPassword != confirm) { cout << "Passwords were different. Try again." << endl; @@ -1123,7 +1167,14 @@ int main(int argc, char** argv) g_logPost = [&](std::string const& a, char const*) { if (silence) logbuf += a + "\n"; else cout << "\r \r" << a << endl << additional << flush; }; // TODO: give hints &c. - auto getPassword = [&](Address const& a){ auto s = silence; silence = true; cout << endl; string ret = dev::getPassword("Enter password for address " + a.abridged() + ": "); silence = s; return ret; }; + auto getPassword = [&](Address const& a){ + auto s = silence; + silence = true; + cout << endl; + string ret = dev::getPassword("Enter password for address " + keyManager.accountDetails()[a].first + " (" + a.abridged() + "; hint:" + keyManager.accountDetails()[a].second + "): "); + silence = s; + return ret; + }; #if ETH_JSONRPC || !ETH_TRUE shared_ptr jsonrpcServer; @@ -1131,7 +1182,7 @@ int main(int argc, char** argv) if (jsonrpc > -1) { jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads)); - jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){return web3.ethereum();}, getPassword, keyManager), vector({sigKey}))); + jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){return web3.ethereum();}, getPassword, keyManager), vector())); jsonrpcServer->StartListening(); } #endif @@ -1275,7 +1326,7 @@ int main(int argc, char** argv) if (jsonrpc < 0) jsonrpc = SensibleHttpPort; jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads)); - jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){return web3.ethereum();}, getPassword, keyManager), vector({sigKey}))); + jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){return web3.ethereum();}, getPassword, keyManager), vector())); jsonrpcServer->StartListening(); } else if (cmd == "jsonstop") @@ -1287,11 +1338,8 @@ int main(int argc, char** argv) #endif else if (cmd == "address") { - cout << "Current address:" << endl << sigKey.address() << endl; - } - else if (cmd == "secret") - { - cout << "Secret Key: " << sigKey.secret() << endl; + cout << "Current mining beneficiary:" << endl << beneficiary << endl; + cout << "Current signing account:" << endl << signingKey << endl; } else if (c && cmd == "block") { @@ -1306,7 +1354,15 @@ int main(int argc, char** argv) } else if (c && cmd == "balance") { - cout << "Current balance: " << formatBalance( c->balanceAt(sigKey.address())) << " = " <balanceAt(sigKey.address()) << " wei" << endl; + cout << "Current balance:" << endl; + u256 total = 0; + for (auto const& i: keyManager.accountDetails()) + { + auto b = c->balanceAt(i.first); + cout << ((i.first == signingKey) ? "SIGNING " : " ") << ((i.first == beneficiary) ? "COINBASE " : " ") << i.second.first << " (" << i.first << "): " << formatBalance(b) << " = " << b << " wei" << endl; + total += b; + } + cout << "Total: " << formatBalance(total) << " = " << total << " wei" << endl; } else if (c && cmd == "transact") { @@ -1422,7 +1478,7 @@ int main(int argc, char** argv) try { Address dest = h160(fromHex(hexAddr, WhenError::Throw)); - c->submitTransaction(sigKey.secret(), amount, dest, bytes(), minGas); + c->submitTransaction(keyManager.secret(signingKey, [&](){ return getPassword(signingKey); }), amount, dest, bytes(), minGas); } catch (BadHexCharacter& _e) { @@ -1491,7 +1547,7 @@ int main(int argc, char** argv) else if (gas < minGas) cwarn << "Minimum gas amount is" << minGas; else - c->submitTransaction(sigKey.secret(), endowment, init, gas, gasPrice); + c->submitTransaction(keyManager.secret(signingKey, [&](){ return getPassword(signingKey); }), endowment, init, gas, gasPrice); } else cwarn << "Require parameters: contract ENDOWMENT GASPRICE GAS CODEHEX"; @@ -1602,13 +1658,13 @@ int main(int argc, char** argv) } } } - else if (cmd == "setsecret") + else if (cmd == "setsigningkey") { if (iss.peek() != -1) { string hexSec; iss >> hexSec; - sigKey = KeyPair(h256(fromHex(hexSec))); + signingKey = Address(fromHex(hexSec)); } else cwarn << "Require parameter: setSecret HEXSECRETKEY"; @@ -1625,7 +1681,7 @@ int main(int argc, char** argv) { try { - coinbase = h160(fromHex(hexAddr, WhenError::Throw)); + beneficiary = h160(fromHex(hexAddr, WhenError::Throw)); } catch (BadHexCharacter& _e) { @@ -1648,7 +1704,7 @@ int main(int argc, char** argv) string path; iss >> path; RLPStream config(2); - config << sigKey.secret() << coinbase; + config << signingKey << beneficiary; writeFile(path, config.out()); } else @@ -1664,8 +1720,8 @@ int main(int argc, char** argv) if (b.size()) { RLP config(b); - sigKey = KeyPair(config[0].toHash()); - coinbase = config[1].toHash
(); + signingKey = config[0].toHash
(); + beneficiary = config[1].toHash
(); } else cwarn << path << "has no content!"; diff --git a/libdevcore/StructuredLogger.cpp b/libdevcore/StructuredLogger.cpp index f51ed310a..7d8a17722 100644 --- a/libdevcore/StructuredLogger.cpp +++ b/libdevcore/StructuredLogger.cpp @@ -34,6 +34,15 @@ using namespace std; namespace dev { +void StructuredLogger::initialize(bool _enabled, std::string const& _timeFormat, std::string const& _destinationURL) +{ + m_enabled = _enabled; + m_timeFormat = _timeFormat; + if (_destinationURL.size() > 7 && _destinationURL.substr(0, 7) == "file://") + m_out.open(_destinationURL.substr(7)); + // TODO: support tcp:// +} + void StructuredLogger::outputJson(Json::Value const& _value, std::string const& _name) const { Json::Value event; @@ -41,7 +50,7 @@ void StructuredLogger::outputJson(Json::Value const& _value, std::string const& Json::FastWriter fastWriter; Guard l(s_lock); event[_name] = _value; - cout << fastWriter.write(event) << endl; + (m_out.is_open() ? m_out : cout) << fastWriter.write(event) << endl; } void StructuredLogger::starting(string const& _clientImpl, const char* _ethVersion) @@ -51,6 +60,7 @@ void StructuredLogger::starting(string const& _clientImpl, const char* _ethVersi Json::Value event; event["client_impl"] = _clientImpl; event["eth_version"] = std::string(_ethVersion); + // TODO net_version event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str()); get().outputJson(event, "starting"); @@ -64,6 +74,7 @@ void StructuredLogger::stopping(string const& _clientImpl, const char* _ethVersi Json::Value event; event["client_impl"] = _clientImpl; event["eth_version"] = std::string(_ethVersion); + // TODO net_version event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str()); get().outputJson(event, "stopping"); diff --git a/libdevcore/StructuredLogger.h b/libdevcore/StructuredLogger.h index 2c30541e4..107598706 100644 --- a/libdevcore/StructuredLogger.h +++ b/libdevcore/StructuredLogger.h @@ -25,6 +25,7 @@ #pragma once +#include #include #include @@ -46,11 +47,7 @@ public: * http://en.cppreference.com/w/cpp/chrono/c/strftime * with which to display timestamps */ - void initialize(bool _enabled, std::string const& _timeFormat) - { - m_enabled = _enabled; - m_timeFormat = _timeFormat; - } + void initialize(bool _enabled, std::string const& _timeFormat, std::string const& _destinationURL); static StructuredLogger& get() { @@ -92,6 +89,11 @@ public: std::string const& _prevHash ); static void transactionReceived(std::string const& _hash, std::string const& _remoteId); + // TODO: static void pendingQueueChanged(std::vector const& _hashes); + // TODO: static void miningStarted(); + // TODO: static void stillMining(unsigned _hashrate); + // TODO: static void miningStopped(); + private: // Singleton class. Private default ctor and no copying StructuredLogger() = default; @@ -102,6 +104,8 @@ private: bool m_enabled = false; std::string m_timeFormat = "%Y-%m-%dT%H:%M:%S"; + + mutable std::ofstream m_out; }; } diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 607fc586c..f13f83588 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -456,7 +456,7 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import { // Check transactions are valid and that they result in a state equivalent to our state_root. // Get total difficulty increase and update state, checking it. - State s(_db); //, bi.coinbaseAddress + State s(_db); auto tdIncrease = s.enactOn(&_block, bi, *this, _ir); BlockLogBlooms blb; @@ -467,6 +467,7 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import br.receipts.push_back(s.receipt(i)); } s.cleanup(true); + td = pd.totalDifficulty + tdIncrease; #if ETH_TIMED_IMPORTS @@ -603,7 +604,6 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import { newLastBlockHash = bi.hash(); newLastBlockNumber = (unsigned)bi.number; - extrasBatch.Put(ldb::Slice("best"), ldb::Slice((char const*)&(bi.hash()), 32)); } clog(BlockChainNote) << " Imported and best" << td << " (#" << bi.number << "). Has" << (details(bi.parentHash).children.size() - 1) << "siblings. Route:" << route; @@ -623,12 +623,33 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import m_blocksDB->Write(m_writeOptions, &blocksBatch); m_extrasDB->Write(m_writeOptions, &extrasBatch); - DEV_WRITE_GUARDED(x_lastBlockHash) + if (isKnown(bi.hash()) && !details(bi.hash())) { - m_lastBlockHash = newLastBlockHash; - m_lastBlockNumber = newLastBlockNumber; + clog(BlockChainDebug) << "Known block just inserted has no details."; + clog(BlockChainDebug) << "Block:" << bi; + clog(BlockChainDebug) << "DATABASE CORRUPTION: CRITICAL FAILURE"; + exit(-1); } + try { + State canary(_db, *this, bi.hash()); + } + catch (...) + { + clog(BlockChainDebug) << "Failed to initialise State object form imported block."; + clog(BlockChainDebug) << "Block:" << bi; + clog(BlockChainDebug) << "DATABASE CORRUPTION: CRITICAL FAILURE"; + exit(-1); + } + + if (m_lastBlockHash != newLastBlockHash) + DEV_WRITE_GUARDED(x_lastBlockHash) + { + m_lastBlockHash = newLastBlockHash; + m_lastBlockNumber = newLastBlockNumber; + m_extrasDB->Put(m_writeOptions, ldb::Slice("best"), ldb::Slice((char const*)&m_lastBlockHash, 32)); + } + #if ETH_PARANOIA || !ETH_TRUE checkConsistency(); #endif @@ -646,14 +667,6 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import if (!route.empty()) noteCanonChanged(); - if (isKnown(bi.hash()) && !details(bi.hash())) - { - clog(BlockChainDebug) << "Known block just inserted has no details."; - clog(BlockChainDebug) << "Block:" << bi; - clog(BlockChainDebug) << "DATABASE CORRUPTION: CRITICAL FAILURE"; - exit(-1); - } - h256s fresh; h256s dead; bool isOld = true; diff --git a/libethereum/KeyManager.h b/libethereum/KeyManager.h index 391121b1c..38e8d8853 100644 --- a/libethereum/KeyManager.h +++ b/libethereum/KeyManager.h @@ -66,6 +66,8 @@ public: bool load(std::string const& _pass); void save(std::string const& _pass) const { write(_pass, m_keysFile); } + void notePassword(std::string const& _pass) { m_cachedPasswords[hashPassword(_pass)] = _pass; } + AddressHash accounts() const; std::unordered_map> accountDetails() const; diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 2e4fe5749..50e4b26ab 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -707,6 +707,7 @@ void State::cleanup(bool _fullCommit) { if (_fullCommit) { + paranoia("immediately before database commit", true); // Commit the new trie to disk. diff --git a/libethereum/State.h b/libethereum/State.h index 74d75685c..a11812c6f 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -49,7 +49,7 @@ class BlockChain; class State; struct StateChat: public LogChannel { static const char* name(); static const int verbosity = 4; }; -struct StateTrace: public LogChannel { static const char* name(); static const int verbosity = 7; }; +struct StateTrace: public LogChannel { static const char* name(); static const int verbosity = 5; }; struct StateDetail: public LogChannel { static const char* name(); static const int verbosity = 14; }; struct StateSafeExceptions: public LogChannel { static const char* name(); static const int verbosity = 21; }; From 488cfae8cbfb90a6868973d078233557dea10a64 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 11 May 2015 21:32:56 +0300 Subject: [PATCH 21/30] Version bump. --- libdevcore/Common.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libdevcore/Common.cpp b/libdevcore/Common.cpp index 5f15902e2..06950cbee 100644 --- a/libdevcore/Common.cpp +++ b/libdevcore/Common.cpp @@ -28,7 +28,7 @@ using namespace dev; namespace dev { -char const* Version = "0.9.17"; +char const* Version = "0.9.18"; const u256 UndefinedU256 = ~(u256)0; From 34bc96bbdca06b4f24f603802b2dfd1f0a04e199 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 11 May 2015 21:49:24 +0300 Subject: [PATCH 22/30] Quick fix for web3 keys dir. --- libdevcrypto/SecretStore.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libdevcrypto/SecretStore.cpp b/libdevcrypto/SecretStore.cpp index 858f2a09f..9be0b89e8 100644 --- a/libdevcrypto/SecretStore.cpp +++ b/libdevcrypto/SecretStore.cpp @@ -104,6 +104,7 @@ void SecretStore::save(std::string const& _keysPath) void SecretStore::load(std::string const& _keysPath) { fs::path p(_keysPath); + boost::filesystem::create_directories(p); js::mValue v; for (fs::directory_iterator it(p); it != fs::directory_iterator(); ++it) if (is_regular_file(it->path())) From 0f496a04bc46d29f9ba5504f89e2d4646ff3de6b Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 11 May 2015 21:56:42 +0300 Subject: [PATCH 23/30] Default srgument to structured logger to fix build. --- libdevcore/StructuredLogger.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libdevcore/StructuredLogger.h b/libdevcore/StructuredLogger.h index 107598706..913d7b9b2 100644 --- a/libdevcore/StructuredLogger.h +++ b/libdevcore/StructuredLogger.h @@ -47,7 +47,7 @@ public: * http://en.cppreference.com/w/cpp/chrono/c/strftime * with which to display timestamps */ - void initialize(bool _enabled, std::string const& _timeFormat, std::string const& _destinationURL); + void initialize(bool _enabled, std::string const& _timeFormat, std::string const& _destinationURL = ""); static StructuredLogger& get() { From 4ef410eee032cda9931988d40168ffa2cb1383e1 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 11 May 2015 22:37:16 +0300 Subject: [PATCH 24/30] Use Go bootnodes. --- alethzero/MainWin.cpp | 5 +++-- eth/main.cpp | 3 ++- libp2p/Host.cpp | 10 ++++++++++ libp2p/Host.h | 2 ++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 925a04cae..87c9c2dc9 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -173,7 +173,7 @@ Main::Main(QWidget *parent) : QMessageBox::warning(nullptr, "Try again", "You entered two different passwords - please enter the same password twice.", QMessageBox::Ok); } m_keyManager.create(password.toStdString()); - m_keyManager.import(Secret::random(), "{\"name\":\"Default identity\"}"); + m_keyManager.import(Secret::random(), "Default identity"); } #if ETH_DEBUG @@ -1994,7 +1994,8 @@ void Main::on_go_triggered() ui->net->setChecked(true); on_net_triggered(); } - web3()->addNode(p2p::NodeId(), Host::pocHost()); + for (auto const& i: Host::pocHosts()) + web3()->requirePeer(i.first, i.second); } std::string Main::prettyU256(dev::u256 const& _n) const diff --git a/eth/main.cpp b/eth/main.cpp index ba44b15a8..60d454287 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -1132,7 +1132,8 @@ int main(int argc, char** argv) cout << "Node ID: " << web3.enode() << endl; if (bootstrap) - web3.addNode(p2p::NodeId(), Host::pocHost()); + for (auto const& i: Host::pocHosts()) + web3.requirePeer(i.first, i.second); if (remoteHost.size()) web3.addNode(p2p::NodeId(), remoteHost + ":" + toString(remotePort)); diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 4560c1564..9b5a6dca7 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -389,6 +389,16 @@ string Host::pocHost() return "poc-" + strs[1] + ".ethdev.com"; } +std::unordered_map const& Host::pocHosts() +{ + static const std::unordered_map c_ret = { +// { Public(""), "poc-9.ethdev.com:30303" }, + { Public("a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c"), "52.16.188.185:30303" }, + { Public("7f25d3eab333a6b98a8b5ed68d962bb22c876ffcd5561fca54e3c2ef27f754df6f7fd7c9b74cc919067abac154fb8e1f8385505954f161ae440abc355855e034"), "54.207.93.166:30303" } + }; + return c_ret; +} + void Host::addNode(NodeId const& _node, NodeIPEndpoint const& _endpoint) { // return if network is stopped while waiting on Host::run() or nodeTable to start diff --git a/libp2p/Host.h b/libp2p/Host.h index b9af0e8b0..4cfca7718 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -95,6 +95,8 @@ public: /// Default host for current version of client. static std::string pocHost(); + static std::unordered_map const& pocHosts(); + /// Register a peer-capability; all new peer connections will have this capability. template std::shared_ptr registerCapability(T* _t) { _t->m_host = this; std::shared_ptr ret(_t); m_capabilities[std::make_pair(T::staticName(), T::staticVersion())] = ret; return ret; } From da25ad8b9f6178248a593f843dad2593503f467a Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 11 May 2015 22:44:01 +0300 Subject: [PATCH 25/30] Fix iteration in evictions. --- libp2p/NodeTable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index fe2940b30..35cfda64b 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -432,7 +432,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes bool found = false; EvictionTimeout evictionEntry; DEV_GUARDED(x_evictions) - for (auto it = m_evictions.begin(); it != m_evictions.end();) + for (auto it = m_evictions.begin(); it != m_evictions.end(); ++it) if (it->first.first == nodeid && it->first.second > std::chrono::steady_clock::now()) { found = true; From b3dd2eaceca518486d4c4a3c6347ad92e4d37cb3 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 11 May 2015 23:59:44 +0300 Subject: [PATCH 26/30] Disable neth from build until new API is refactored into it. --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f2877c10..a675e8655 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -377,7 +377,8 @@ if (TOOLS) endif() if (NCURSES) - add_subdirectory(neth) + # Commented out until caktux refactors with the new wallet API. +# add_subdirectory(neth) endif () if (GUI) From cbe32996aca0331a8b5f875b5f8c81be3825be9d Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 11 May 2015 23:06:30 +0200 Subject: [PATCH 27/30] fix for building osx package --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f2877c10..7eeab79d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -396,7 +396,7 @@ if (GUI) endif() -if (APPLE) +if (APPLE AND GUI) add_custom_target(appdmg WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} From 5e22df8f4cfc5bc33da553faca7d1e57d124f7dc Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 12 May 2015 00:20:10 +0300 Subject: [PATCH 28/30] compatibility options HEADLESS should build solidity by default. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a675e8655..879ca88bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,7 +155,7 @@ set (ETH_HAVE_WEBENGINE 1) # Backwards compatibility if (HEADLESS) message("*** WARNING: -DHEADLESS=1 option is DEPRECATED! Use -DBUNDLE=minimal or -DGUI=0") - set(BUNDLE "minimal") + set(GUI OFF) endif () # TODO: Abstract into something sensible and move into a function. From 4b49df14ebedeb205cfeaf780b93f424f5c2b198 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 12 May 2015 01:10:10 +0300 Subject: [PATCH 29/30] Start at a random nonce, not just 0. --- libethash-cl/ethash_cl_miner.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libethash-cl/ethash_cl_miner.cpp b/libethash-cl/ethash_cl_miner.cpp index 42098e09d..ea9fdd3e9 100644 --- a/libethash-cl/ethash_cl_miner.cpp +++ b/libethash-cl/ethash_cl_miner.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -341,7 +342,9 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook unsigned buf = 0; - for (uint64_t start_nonce = 0; ; start_nonce += c_search_batch_size) + std::random_device engine; + uint64_t start_nonce = std::uniform_int_distribution()(engine); + for (; ; start_nonce += c_search_batch_size) { // supply output buffer to kernel m_search_kernel.setArg(0, m_search_buf[buf]); From 96803503d629dd8a7dc7010f84c5bd52ff7e2cec Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 12 May 2015 01:28:23 +0300 Subject: [PATCH 30/30] Build fix for neth. --- CMakeLists.txt | 3 +-- libethash-cl/ethash_cl_miner.cpp | 8 -------- neth/main.cpp | 9 +++++---- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 222c191fa..289cecad8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -377,8 +377,7 @@ if (TOOLS) endif() if (NCURSES) - # Commented out until caktux refactors with the new wallet API. -# add_subdirectory(neth) + add_subdirectory(neth) endif () if (GUI) diff --git a/libethash-cl/ethash_cl_miner.cpp b/libethash-cl/ethash_cl_miner.cpp index ea9fdd3e9..cc35d6215 100644 --- a/libethash-cl/ethash_cl_miner.cpp +++ b/libethash-cl/ethash_cl_miner.cpp @@ -307,21 +307,15 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook // update header constant buffer m_queue.enqueueWriteBuffer(m_header, false, 0, 32, header); for (unsigned i = 0; i != c_num_buffers; ++i) - { m_queue.enqueueWriteBuffer(m_search_buf[i], false, 0, 4, &c_zero); - } #if CL_VERSION_1_2 && 0 cl::Event pre_return_event; if (!m_opencl_1_1) - { m_queue.enqueueBarrierWithWaitList(NULL, &pre_return_event); - } else #endif - { m_queue.finish(); - } /* __kernel void ethash_combined_search( @@ -389,9 +383,7 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook // not safe to return until this is ready #if CL_VERSION_1_2 && 0 if (!m_opencl_1_1) - { pre_return_event.wait(); - } #endif } diff --git a/neth/main.cpp b/neth/main.cpp index 066177b2f..7ce64cba5 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -36,8 +36,9 @@ #include #include #include -#if ETH_JSONRPC +#if ETH_JSONRPC || !ETH_TRUE #include +#include #include #endif #include "BuildInfo.h" @@ -573,13 +574,13 @@ int main(int argc, char** argv) if (c && mining) c->startMining(); -#if ETH_JSONRPC +#if ETH_JSONRPC || !ETH_TRUE shared_ptr jsonrpcServer; unique_ptr jsonrpcConnector; if (jsonrpc > -1) { jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads)); - jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector({us}))); + jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){ return web3.ethereum(); }, vector({us})), vector({us}))); jsonrpcServer->setIdentities({us}); jsonrpcServer->StartListening(); } @@ -793,7 +794,7 @@ int main(int argc, char** argv) #else jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 4)); #endif - jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector({us}))); + jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){ return web3.ethereum(); }, vector({us})), vector({us}))); jsonrpcServer->setIdentities({us}); jsonrpcServer->StartListening(); }