Browse Source

Merge branch 'develop' into UI

cl-refactor
Alexandre Van de Sande 10 years ago
parent
commit
37db7b06ee
  1. 6
      alethzero/Main.ui
  2. 6
      alethzero/MainWin.cpp
  3. 2
      alethzero/Transact.cpp
  4. 59
      eth/main.cpp
  5. 2
      libdevcore/Common.cpp
  6. 28
      libdevcore/CommonData.h
  7. 6
      libdevcrypto/TrieDB.h
  8. 30
      libethcore/BlockInfo.cpp
  9. 4
      libethcore/BlockInfo.h
  10. 17
      libethcore/CommonJS.cpp
  11. 3
      libethcore/CommonJS.h
  12. 1
      libethcore/Exceptions.h
  13. 77
      libethereum/BlockChain.cpp
  14. 26
      libethereum/BlockChain.h
  15. 8
      libethereum/BlockQueue.cpp
  16. 6
      libethereum/Client.cpp
  17. 25
      libethereum/ClientBase.cpp
  18. 5
      libethereum/ClientBase.h
  19. 5
      libethereum/EthereumHost.cpp
  20. 4
      libethereum/EthereumPeer.cpp
  21. 13
      libethereum/Executive.cpp
  22. 2
      libethereum/Executive.h
  23. 19
      libethereum/Interface.h
  24. 41
      libethereum/State.cpp
  25. 5
      libethereum/State.h
  26. 16
      libethereum/Transaction.cpp
  27. 48
      libethereum/Transaction.h
  28. 8
      libethereum/TransactionQueue.cpp
  29. 3
      libethereum/TransactionQueue.h
  30. 4
      libjsqrc/ethereumjs/.bowerrc
  31. 1
      libjsqrc/ethereumjs/.gitignore
  32. 1
      libjsqrc/ethereumjs/.travis.yml
  33. 8
      libjsqrc/ethereumjs/README.md
  34. 4
      libjsqrc/ethereumjs/bower.json
  35. 57
      libjsqrc/ethereumjs/dist/ethereum.js.map
  36. 1
      libjsqrc/ethereumjs/dist/ethereum.min.js
  37. 1891
      libjsqrc/ethereumjs/dist/web3-light.js
  38. 69
      libjsqrc/ethereumjs/dist/web3-light.js.map
  39. 1
      libjsqrc/ethereumjs/dist/web3-light.min.js
  40. 5548
      libjsqrc/ethereumjs/dist/web3.js
  41. 69
      libjsqrc/ethereumjs/dist/web3.js.map
  42. 2
      libjsqrc/ethereumjs/dist/web3.min.js
  43. 4
      libjsqrc/ethereumjs/example/balance.html
  44. 153
      libjsqrc/ethereumjs/example/coin.html
  45. 3
      libjsqrc/ethereumjs/example/contract.html
  46. 3
      libjsqrc/ethereumjs/example/contract_with_array.html
  47. 3
      libjsqrc/ethereumjs/example/event.html
  48. 3
      libjsqrc/ethereumjs/example/event_inc.html
  49. 3
      libjsqrc/ethereumjs/example/natspec_contract.html
  50. 34
      libjsqrc/ethereumjs/gulpfile.js
  51. 9
      libjsqrc/ethereumjs/index.js
  52. 3
      libjsqrc/ethereumjs/karma.conf.js
  53. 20
      libjsqrc/ethereumjs/lib/solidity/formatters.js
  54. 4
      libjsqrc/ethereumjs/lib/utils/browser-bn.js
  55. 9
      libjsqrc/ethereumjs/lib/utils/browser-xhr.js
  56. 4
      libjsqrc/ethereumjs/lib/utils/config.js
  57. 68
      libjsqrc/ethereumjs/lib/utils/utils.js
  58. 3
      libjsqrc/ethereumjs/lib/version.json
  59. 288
      libjsqrc/ethereumjs/lib/web3.js
  60. 47
      libjsqrc/ethereumjs/lib/web3/contract.js
  61. 38
      libjsqrc/ethereumjs/lib/web3/db.js
  62. 38
      libjsqrc/ethereumjs/lib/web3/errors.js
  63. 242
      libjsqrc/ethereumjs/lib/web3/eth.js
  64. 4
      libjsqrc/ethereumjs/lib/web3/event.js
  65. 171
      libjsqrc/ethereumjs/lib/web3/filter.js
  66. 96
      libjsqrc/ethereumjs/lib/web3/formatters.js
  67. 56
      libjsqrc/ethereumjs/lib/web3/httpprovider.js
  68. 70
      libjsqrc/ethereumjs/lib/web3/jsonrpc.js
  69. 159
      libjsqrc/ethereumjs/lib/web3/method.js
  70. 13
      libjsqrc/ethereumjs/lib/web3/net.js
  71. 104
      libjsqrc/ethereumjs/lib/web3/property.js
  72. 300
      libjsqrc/ethereumjs/lib/web3/requestmanager.js
  73. 52
      libjsqrc/ethereumjs/lib/web3/shh.js
  74. 66
      libjsqrc/ethereumjs/lib/web3/watches.js
  75. 3
      libjsqrc/ethereumjs/package-init.js
  76. 8
      libjsqrc/ethereumjs/package.js
  77. 30
      libjsqrc/ethereumjs/package.json
  78. 2
      libjsqrc/ethereumjs/test/abi.inputParser.js
  79. 2
      libjsqrc/ethereumjs/test/abi.outputParser.js
  80. 229
      libjsqrc/ethereumjs/test/contract.js
  81. 26
      libjsqrc/ethereumjs/test/event.inputParser.js
  82. 6
      libjsqrc/ethereumjs/test/event.outputParser.js
  83. 24
      libjsqrc/ethereumjs/test/filter.methods.js
  84. 24
      libjsqrc/ethereumjs/test/formatters.inputDefaultBlockFormatter.js
  85. 3
      libjsqrc/ethereumjs/test/formatters.inputPostFormatter.js
  86. 11
      libjsqrc/ethereumjs/test/formatters.inputTransactionFormatter.js
  87. 8
      libjsqrc/ethereumjs/test/formatters.outputTransactionFormatter.js
  88. 68
      libjsqrc/ethereumjs/test/helpers/FakeHttpProvider.js
  89. 11
      libjsqrc/ethereumjs/test/helpers/FakeQtNavigator.js
  90. 31
      libjsqrc/ethereumjs/test/helpers/FakeXMLHttpRequest.js
  91. 68
      libjsqrc/ethereumjs/test/helpers/test.method.js
  92. 9
      libjsqrc/ethereumjs/test/helpers/test.utils.js
  93. 33
      libjsqrc/ethereumjs/test/httpprovider.js
  94. 23
      libjsqrc/ethereumjs/test/jsonrpc.id.js
  95. 1
      libjsqrc/ethereumjs/test/jsonrpc.isValidResponse.js
  96. 1
      libjsqrc/ethereumjs/test/jsonrpc.toBatchPayload.js
  97. 4
      libjsqrc/ethereumjs/test/jsonrpc.toPayload.js
  98. 44
      libjsqrc/ethereumjs/test/method.attachToObject.js
  99. 52
      libjsqrc/ethereumjs/test/method.extractCallback.js
  100. 41
      libjsqrc/ethereumjs/test/method.formatInput.js

6
alethzero/Main.ui

@ -570,7 +570,7 @@
<item>
<widget class="QListWidget" name="ourAccounts">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
<enum>Qt::WheelFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
@ -637,7 +637,7 @@
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
<enum>Qt::WheelFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
@ -715,7 +715,7 @@
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
<enum>Qt::WheelFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>

6
alethzero/MainWin.cpp

@ -1156,7 +1156,7 @@ void Main::refreshBlockChain()
auto b = bc.block(h);
for (auto const& i: RLP(b)[1])
{
Transaction t(i.data(), CheckSignature::Sender);
Transaction t(i.data(), CheckTransaction::Everything);
QString s = t.receiveAddress() ?
QString(" %2 %5> %3: %1 [%4]")
.arg(formatBalance(t.value()).c_str())
@ -1536,7 +1536,7 @@ void Main::on_blocks_currentItemChanged()
else
{
unsigned txi = item->data(Qt::UserRole + 1).toInt();
Transaction tx(block[1][txi].data(), CheckSignature::Sender);
Transaction tx(block[1][txi].data(), CheckTransaction::Everything);
auto ss = tx.safeSender();
h256 th = sha3(rlpList(ss, tx.nonce()));
TransactionReceipt receipt = ethereum()->blockChain().receipts(h).receipts[txi];
@ -1597,7 +1597,7 @@ void Main::on_debugCurrent_triggered()
State s(ethereum()->state(txi, h));
Executive e(s, ethereum()->blockChain());
Debugger dw(this, this);
dw.populate(e, Transaction(t, CheckSignature::Sender));
dw.populate(e, Transaction(t, CheckTransaction::Everything));
dw.exec();
}
}

2
alethzero/Transact.cpp

@ -306,7 +306,7 @@ void Transact::rejigData()
htmlInfo += "<h4>Hex</h4>" + QString(Div(Mono)) + QString::fromStdString(toHex(m_data)) + "</div>";
// Determine the minimum amount of gas we need to play...
qint64 baseGas = (qint64)Interface::txGas(m_data, 0);
qint64 baseGas = (qint64)Transaction::gasRequired(m_data, 0);
qint64 gasNeeded = 0;
if (b < value() + baseGas * gasPrice())

59
eth/main.cpp

@ -113,7 +113,7 @@ void help()
<< " -c,--client-name <name> Add a name to your client's version string (default: blank)." << endl
<< " -d,--db-path <path> Load database from path (default: ~/.ethereum " << endl
<< " <APPDATA>/Etherum or Library/Application Support/Ethereum)." << endl
<< " -D,--initdag Initialize DAG for mining and exit." << endl
<< " -D,--create-dag <this/next/number> Create the DAG in preparation for mining on given block and exit." << endl
<< " -e,--ether-price <n> Set the ether price in the reference unit e.g. ¢ (Default: 30.679)." << endl
<< " -f,--force-mining Mine even when there are no transaction to mine (Default: off)" << endl
<< " -h,--help Show this help message and exit." << endl
@ -200,9 +200,20 @@ enum class NodeMode
Full
};
void doInitDAG(unsigned _n)
{
BlockInfo bi;
bi.number = _n;
cout << "Initializing DAG for epoch beginning #" << (bi.number / 30000 * 30000) << " (seedhash " << bi.seedHash().abridged() << "). This will take a while." << endl;
Ethasher::get()->full(bi);
exit(0);
}
static const unsigned NoDAGInit = (unsigned)-3;
int main(int argc, char** argv)
{
bool initDAG = false;
unsigned initDAG = NoDAGInit;
string listenIP;
unsigned short listenPort = 30303;
string publicIP;
@ -307,8 +318,24 @@ int main(int argc, char** argv)
structuredLogging = true;
else if ((arg == "-d" || arg == "--path" || arg == "--db-path") && i + 1 < argc)
dbPath = argv[++i];
else if (arg == "-D" || arg == "--initdag")
initDAG = true;
else if ((arg == "-D" || arg == "--create-dag") && i + 1 < argc)
{
string m = boost::to_lower_copy(string(argv[++i]));
if (m == "next")
initDAG = PendingBlock;
else if (m == "this")
initDAG = LatestBlock;
else
try
{
initDAG = stol(m);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << m << endl;
return -1;
}
}
else if ((arg == "-B" || arg == "--block-fees") && i + 1 < argc)
{
try
@ -317,7 +344,7 @@ int main(int argc, char** argv)
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[++i] << endl;
cerr << "Bad " << arg << " option: " << argv[i] << endl;
return -1;
}
}
@ -329,7 +356,7 @@ int main(int argc, char** argv)
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[++i] << endl;
cerr << "Bad " << arg << " option: " << argv[i] << endl;
return -1;
}
}
@ -422,6 +449,12 @@ int main(int argc, char** argv)
}
}
// Two codepaths is necessary since named block require database, but numbered
// blocks are superuseful to have when database is already open in another process.
if (initDAG < NoDAGInit)
doInitDAG(initDAG);
if (!clientName.empty())
clientName += "/";
@ -442,12 +475,8 @@ int main(int argc, char** argv)
miners
);
if (initDAG)
{
cout << "Initializing DAG. (This will take awhile)" << endl;
Ethasher::get()->full(web3.ethereum()->blockChain().info());
return 0;
}
if (initDAG == LatestBlock || initDAG == PendingBlock)
doInitDAG(web3.ethereum()->blockChain().number() + (initDAG == PendingBlock ? 30000 : 0));
web3.setIdealPeerCount(peers);
std::shared_ptr<eth::BasicGasPricer> gasPricer = make_shared<eth::BasicGasPricer>(u256(double(ether / 1000) / etherPrice), u256(blockFees * 1000));
@ -667,7 +696,7 @@ int main(int argc, char** argv)
cnote << ssbd.str();
int ssize = sechex.length();
int size = hexAddr.length();
u256 minGas = (u256)Client::txGas(data, 0);
u256 minGas = (u256)Transaction::gasRequired(data, 0);
if (size < 40)
{
if (size > 0)
@ -746,7 +775,7 @@ int main(int argc, char** argv)
auto h = bc.currentHash();
auto blockData = bc.block(h);
BlockInfo info(blockData);
u256 minGas = (u256)Client::txGas(bytes(), 0);
u256 minGas = (u256)Transaction::gasRequired(bytes(), 0);
try
{
Address dest = h160(fromHex(hexAddr, WhenError::Throw));
@ -811,7 +840,7 @@ int main(int argc, char** argv)
cnote << "Init:";
cnote << ssc.str();
}
u256 minGas = (u256)Client::txGas(init, 0);
u256 minGas = (u256)Transaction::gasRequired(init, 0);
if (!init.size())
cwarn << "Contract creation aborted, no init code.";
else if (endowment < 0)

2
libdevcore/Common.cpp

@ -27,7 +27,7 @@ using namespace dev;
namespace dev
{
char const* Version = "0.9.5";
char const* Version = "0.9.6";
}

28
libdevcore/CommonData.h

@ -236,6 +236,34 @@ inline std::vector<_T>& operator+=(std::vector<typename std::enable_if<!std::is_
return _a;
}
/// Insert the contents of a container into a set
template <class T, class U> std::set<T>& operator+=(std::set<T>& _a, U const& _b)
{
for (auto const& i: _b)
_a.insert(i);
return _a;
}
/// Concatenate the contents of a container onto a vector
template <class T, class U> std::vector<T>& operator+=(std::vector<T>& _a, U const& _b)
{
for (auto const& i: _b)
_a.push_back(i);
return _a;
}
/// Insert the contents of a container into a set
template <class T, class U> std::set<T> operator+(std::set<T> _a, U const& _b)
{
return _a += _b;
}
/// Concatenate the contents of a container onto a vector
template <class T, class U> std::vector<T> operator+(std::vector<T> _a, U const& _b)
{
return _a += _b;
}
/// Concatenate two vectors of elements.
template <class _T>
inline std::vector<_T> operator+(std::vector<_T> const& _a, std::vector<_T> const& _b)

6
libdevcrypto/TrieDB.h

@ -161,9 +161,15 @@ public:
}
}
std::string at(bytes const& _key) const { return at(&_key); }
std::string at(bytesConstRef _key) const;
void insert(bytes const& _key, bytes const& _value) { insert(&_key, &_value); }
void insert(bytesConstRef _key, bytes const& _value) { insert(_key, &_value); }
void insert(bytes const& _key, bytesConstRef _value) { insert(&_key, _value); }
void insert(bytesConstRef _key, bytesConstRef _value);
void remove(bytes const& _key) { remove(&_key); }
void remove(bytesConstRef _key);
bool contains(bytes const& _key) { return contains(&_key); }
bool contains(bytesConstRef _key) { return !at(_key).empty(); }
class iterator

30
libethcore/BlockInfo.cpp

@ -40,7 +40,7 @@ BlockInfo::BlockInfo(bytesConstRef _block, Strictness _s, h256 const& _h)
populate(_block, _s, _h);
}
void BlockInfo::setEmpty()
void BlockInfo::clear()
{
parentHash = h256();
sha3Uncles = EmptyListSHA3;
@ -105,8 +105,9 @@ h256 BlockInfo::headerHash(bytesConstRef _block)
void BlockInfo::populateFromHeader(RLP const& _header, Strictness _s, h256 const& _h)
{
// m_hash = dev::sha3(_header.data());
m_hash = _h;
if (_h)
assert(_h == dev::sha3(_header.data()));
m_seedHash = h256();
int field = 0;
@ -172,13 +173,21 @@ void BlockInfo::populate(bytesConstRef _block, Strictness _s, h256 const& _h)
BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("block uncles need to be a list") << BadFieldError(2, root[2].data().toString()));
}
template <class T, class U> h256 trieRootOver(unsigned _itemCount, T const& _getKey, U const& _getValue)
{
MemoryDB db;
GenericTrieDB<MemoryDB> t(&db);
t.init();
for (unsigned i = 0; i < _itemCount; ++i)
t.insert(_getKey(i), _getValue(i));
return t.root();
}
void BlockInfo::verifyInternals(bytesConstRef _block) const
{
RLP root(_block);
u256 mgp = (u256)-1;
OverlayDB db;
/*OverlayDB db;
GenericTrieDB<OverlayDB> t(&db);
t.init();
unsigned i = 0;
@ -186,12 +195,13 @@ void BlockInfo::verifyInternals(bytesConstRef _block) const
{
bytes k = rlp(i);
t.insert(&k, tr.data());
u256 gasprice = tr[1].toInt<u256>();
mgp = min(mgp, gasprice); // the minimum gas price is not used for anything //TODO delete?
++i;
}
if (transactionsRoot != t.root())
BOOST_THROW_EXCEPTION(InvalidTransactionsHash() << HashMismatchError(t.root(), transactionsRoot));
if (transactionsRoot != t.root())*/
auto txList = root[1];
auto expectedRoot = trieRootOver(txList.itemCount(), [&](unsigned i){ return rlp(i); }, [&](unsigned i){ return txList[i].data(); });
if (transactionsRoot != expectedRoot)
BOOST_THROW_EXCEPTION(InvalidTransactionsHash() << HashMismatchError(expectedRoot, transactionsRoot));
if (sha3Uncles != sha3(root[2].data()))
BOOST_THROW_EXCEPTION(InvalidUnclesHash());
@ -199,7 +209,7 @@ void BlockInfo::verifyInternals(bytesConstRef _block) const
void BlockInfo::populateFromParent(BlockInfo const& _parent)
{
m_hash = m_seedHash = h256();
noteDirty();
stateRoot = _parent.stateRoot;
parentHash = _parent.hash();
number = _parent.number + 1;

4
libethcore/BlockInfo.h

@ -116,9 +116,9 @@ public:
}
bool operator!=(BlockInfo const& _cmp) const { return !operator==(_cmp); }
void setEmpty();
void clear();
void noteDirty() const { m_hash = m_seedHash= h256(); }
void noteDirty() const { m_hash = m_seedHash = h256(); }
void populateFromHeader(RLP const& _header, Strictness _s = IgnoreNonce, h256 const& _h = h256());
void populate(bytesConstRef _block, Strictness _s = IgnoreNonce, h256 const& _h = h256());

17
libethcore/CommonJS.cpp

@ -65,5 +65,22 @@ std::string prettyU256(u256 _n, bool _abridged)
return s.str();
}
namespace eth
{
BlockNumber jsToBlockNumber(std::string const& _js)
{
if (_js == "latest")
return LatestBlock;
else if (_js == "earliest")
return 0;
else if (_js == "pending")
return PendingBlock;
else
return (unsigned)jsToInt(_js);
}
}
}

3
libethcore/CommonJS.h

@ -67,5 +67,8 @@ struct TransactionSkeleton
u256 gasPrice;
};
/// Convert to a block number, a bit like jsToInt, except that it correctly recognises "pending" and "latest".
BlockNumber jsToBlockNumber(std::string const& _js);
}
}

1
libethcore/Exceptions.h

@ -38,6 +38,7 @@ using errinfo_difficulty = boost::error_info<struct tag_difficulty, u256>;
using BadFieldError = boost::tuple<errinfo_field, errinfo_data>;
struct DatabaseAlreadyOpen: virtual dev::Exception {};
struct OutOfGasBase: virtual dev::Exception {};
struct NotEnoughAvailableSpace: virtual dev::Exception {};
struct NotEnoughCash: virtual dev::Exception {};
struct GasPriceTooLow: virtual dev::Exception {};

77
libethereum/BlockChain.cpp

@ -68,20 +68,6 @@ std::ostream& dev::eth::operator<<(std::ostream& _out, BlockChain const& _bc)
return _out;
}
ldb::Slice dev::eth::oldToSlice(h256 const& _h, unsigned _sub)
{
#if ALL_COMPILERS_ARE_CPP11_COMPLIANT
static thread_local h256 h = _h ^ sha3(h256(u256(_sub)));
return ldb::Slice((char const*)&h, 32);
#else
static boost::thread_specific_ptr<h256> t_h;
if (!t_h.get())
t_h.reset(new h256);
*t_h = _h ^ sha3(h256(u256(_sub)));
return ldb::Slice((char const*)t_h.get(), 32);
#endif
}
ldb::Slice dev::eth::toSlice(h256 const& _h, unsigned _sub)
{
#if ALL_COMPILERS_ARE_CPP11_COMPLIANT
@ -398,19 +384,18 @@ pair<h256s, h256> BlockChain::import(bytes const& _block, OverlayDB const& _db,
throw;
}
#endif
auto newHash = BlockInfo::headerHash(_block);
// Check block doesn't already exist first!
if (isKnown(newHash) && !_force)
if (isKnown(bi.hash()) && !_force)
{
clog(BlockChainNote) << newHash << ": Not new.";
clog(BlockChainNote) << bi.hash() << ": Not new.";
BOOST_THROW_EXCEPTION(AlreadyHaveBlock());
}
// Work out its number as the parent's number + 1
if (!isKnown(bi.parentHash))
{
clog(BlockChainNote) << newHash << ": Unknown parent " << bi.parentHash;
clog(BlockChainNote) << bi.hash() << ": Unknown parent " << bi.parentHash;
// We don't know the parent (yet) - discard for now. It'll get resent to us if we find out about its ancestry later on.
BOOST_THROW_EXCEPTION(UnknownParent());
}
@ -427,12 +412,12 @@ pair<h256s, h256> BlockChain::import(bytes const& _block, OverlayDB const& _db,
// Check it's not crazy
if (bi.timestamp > (u256)time(0))
{
clog(BlockChainNote) << newHash << ": Future time " << bi.timestamp << " (now at " << time(0) << ")";
clog(BlockChainNote) << bi.hash() << ": Future time " << bi.timestamp << " (now at " << time(0) << ")";
// Block has a timestamp in the future. This is no good.
BOOST_THROW_EXCEPTION(FutureTime());
}
clog(BlockChainNote) << "Attempting import of " << newHash.abridged() << "...";
clog(BlockChainNote) << "Attempting import of " << bi.hash().abridged() << "...";
#if ETH_TIMED_IMPORTS
preliminaryChecks = t.elapsed();
@ -477,16 +462,16 @@ pair<h256s, h256> BlockChain::import(bytes const& _block, OverlayDB const& _db,
details(bi.parentHash);
WriteGuard l(x_details);
m_details[newHash] = BlockDetails((unsigned)pd.number + 1, td, bi.parentHash, {});
m_details[bi.parentHash].children.push_back(newHash);
m_details[bi.hash()] = BlockDetails((unsigned)pd.number + 1, td, bi.parentHash, {});
m_details[bi.parentHash].children.push_back(bi.hash());
}
{
WriteGuard l(x_logBlooms);
m_logBlooms[newHash] = blb;
m_logBlooms[bi.hash()] = blb;
}
{
WriteGuard l(x_receipts);
m_receipts[newHash] = br;
m_receipts[bi.hash()] = br;
}
#if ETH_TIMED_IMPORTS
@ -498,11 +483,11 @@ pair<h256s, h256> BlockChain::import(bytes const& _block, OverlayDB const& _db,
ReadGuard l2(x_details);
ReadGuard l4(x_receipts);
ReadGuard l5(x_logBlooms);
m_blocksDB->Put(m_writeOptions, toSlice(newHash), (ldb::Slice)ref(_block));
m_extrasDB->Put(m_writeOptions, toSlice(newHash, ExtraDetails), (ldb::Slice)dev::ref(m_details[newHash].rlp()));
m_blocksDB->Put(m_writeOptions, toSlice(bi.hash()), (ldb::Slice)ref(_block));
m_extrasDB->Put(m_writeOptions, toSlice(bi.hash(), ExtraDetails), (ldb::Slice)dev::ref(m_details[bi.hash()].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(bi.parentHash, ExtraDetails), (ldb::Slice)dev::ref(m_details[bi.parentHash].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(newHash, ExtraLogBlooms), (ldb::Slice)dev::ref(m_logBlooms[newHash].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(newHash, ExtraReceipts), (ldb::Slice)dev::ref(m_receipts[newHash].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(bi.hash(), ExtraLogBlooms), (ldb::Slice)dev::ref(m_logBlooms[bi.hash()].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(bi.hash(), ExtraReceipts), (ldb::Slice)dev::ref(m_receipts[bi.hash()].rlp()));
}
#if ETH_TIMED_IMPORTS
@ -549,13 +534,13 @@ pair<h256s, h256> BlockChain::import(bytes const& _block, OverlayDB const& _db,
if (td > details(last).totalDifficulty)
{
unsigned commonIndex;
tie(route, common, commonIndex) = treeRoute(last, newHash);
tie(route, common, commonIndex) = treeRoute(last, bi.hash());
{
WriteGuard l(x_lastBlockHash);
m_lastBlockHash = newHash;
m_lastBlockHash = bi.hash();
}
m_extrasDB->Put(m_writeOptions, ldb::Slice("best"), ldb::Slice((char const*)&newHash, 32));
m_extrasDB->Put(m_writeOptions, ldb::Slice("best"), ldb::Slice((char const*)&(bi.hash()), 32));
// Most of the time these two will be equal - only when we're doing a chain revert will they not be
if (common != last)
@ -988,41 +973,11 @@ bytes BlockChain::block(h256 const& _hash) const
return bytes();
}
WriteGuard l(x_blocks);
m_blocks[_hash].resize(d.size());
memcpy(m_blocks[_hash].data(), d.data(), d.size());
noteUsed(_hash);
return m_blocks[_hash];
}
bytes BlockChain::oldBlock(h256 const& _hash) const
{
if (_hash == m_genesisHash)
return m_genesisBlock;
{
ReadGuard l(x_blocks);
auto it = m_blocks.find(_hash);
if (it != m_blocks.end())
return it->second;
}
string d;
m_blocksDB->Get(m_readOptions, oldToSlice(_hash), &d);
if (!d.size())
{
cwarn << "Couldn't find requested block:" << _hash.abridged();
return bytes();
}
WriteGuard l(x_blocks);
m_blocks[_hash].resize(d.size());
memcpy(m_blocks[_hash].data(), d.data(), d.size());
noteUsed(_hash);
return m_blocks[_hash];
}

26
libethereum/BlockChain.h

@ -64,7 +64,6 @@ struct BlockChainWarn: public LogChannel { static const char* name() { return "=
std::map<Address, Account> const& genesisState();
ldb::Slice toSlice(h256 const& _h, unsigned _sub = 0);
ldb::Slice oldToSlice(h256 const& _h, unsigned _sub = 0);
using BlocksHash = std::map<h256, bytes>;
using TransactionHashes = h256s;
@ -84,7 +83,6 @@ using ProgressCallback = std::function<void(unsigned, unsigned)>;
/**
* @brief Implements the blockchain database. All data this gives is disk-backed.
* @threadsafe
* @todo Make not memory hog (should actually act as a cache and deallocate old entries).
*/
class BlockChain
{
@ -274,30 +272,6 @@ private:
return ret.first->second;
}
template<class T, unsigned N> T oldQueryExtras(h256 const& _h, std::map<h256, T>& _m, boost::shared_mutex& _x, T const& _n, ldb::DB* _extrasDB = nullptr) const
{
{
ReadGuard l(_x);
auto it = _m.find(_h);
if (it != _m.end())
return it->second;
}
std::string s;
(_extrasDB ? _extrasDB : m_extrasDB)->Get(m_readOptions, oldToSlice(_h, N), &s);
if (s.empty())
{
// cout << "Not found in DB: " << _h << endl;
return _n;
}
noteUsed(_h, N);
WriteGuard l(_x);
auto ret = _m.insert(std::make_pair(_h, T(RLP(s))));
return ret.first->second;
}
void checkConsistency();
/// The caches of the disk DB and their locks.

8
libethereum/BlockQueue.cpp

@ -107,14 +107,6 @@ ImportResult BlockQueue::import(bytesConstRef _block, BlockChain const& _bc)
}
}
namespace dev {
template <class T, class U> std::set<T>& operator+=(std::set<T>& _a, U const& _b)
{
for (auto const& i: _b)
_a.insert(i);
return _a;
} }
bool BlockQueue::doneDrain(h256s const& _bad)
{
WriteGuard l(m_lock);

6
libethereum/Client.cpp

@ -94,7 +94,7 @@ void BasicGasPricer::update(BlockChain const& _bc)
for (unsigned i = 0; i < r[1].size(); ++i)
{
auto gu = brs.receipts[i].gasUsed();
dist[Transaction(r[1][i].data(), CheckSignature::None).gasPrice()] += (unsigned)brs.receipts[i].gasUsed();
dist[Transaction(r[1][i].data(), CheckTransaction::None).gasPrice()] += (unsigned)brs.receipts[i].gasUsed();
total += (unsigned)gu;
}
}
@ -511,7 +511,7 @@ void Client::doWork()
clog(ClientNote) << "Dead block:" << h.abridged();
for (auto const& t: m_bc.transactions(h))
{
clog(ClientNote) << "Resubmitting transaction " << Transaction(t, CheckSignature::None);
clog(ClientNote) << "Resubmitting transaction " << Transaction(t, CheckTransaction::None);
m_tq.import(t);
}
}
@ -519,7 +519,7 @@ void Client::doWork()
// remove transactions from m_tq nicely rather than relying on out of date nonce later on.
for (auto const& h: fresh)
{
clog(ClientChat) << "Mined block:" << h.abridged();
clog(ClientChat) << "Live block:" << h.abridged();
for (auto const& th: m_bc.transactionHashes(h))
{
clog(ClientNote) << "Safely dropping transaction " << th;

25
libethereum/ClientBase.cpp

@ -285,11 +285,6 @@ LocalisedLogEntries ClientBase::checkWatch(unsigned _watchId)
return ret;
}
h256 ClientBase::hashFromNumber(unsigned _number) const
{
return bc().numberHash(_number);
}
BlockInfo ClientBase::blockInfo(h256 _hash) const
{
return BlockInfo(bc().block(_hash));
@ -302,7 +297,7 @@ BlockDetails ClientBase::blockDetails(h256 _hash) const
Transaction ClientBase::transaction(h256 _transactionHash) const
{
return Transaction(bc().transaction(_transactionHash), CheckSignature::Range);
return Transaction(bc().transaction(_transactionHash), CheckTransaction::Cheap);
}
Transaction ClientBase::transaction(h256 _blockHash, unsigned _i) const
@ -310,7 +305,7 @@ Transaction ClientBase::transaction(h256 _blockHash, unsigned _i) const
auto bl = bc().block(_blockHash);
RLP b(bl);
if (_i < b[1].itemCount())
return Transaction(b[1][_i].data(), CheckSignature::Range);
return Transaction(b[1][_i].data(), CheckTransaction::Cheap);
else
return Transaction();
}
@ -321,7 +316,7 @@ Transactions ClientBase::transactions(h256 _blockHash) const
RLP b(bl);
Transactions res;
for (unsigned i = 0; i < b[1].itemCount(); i++)
res.emplace_back(b[1][i].data(), CheckSignature::Range);
res.emplace_back(b[1][i].data(), CheckTransaction::Cheap);
return res;
}
@ -369,6 +364,11 @@ Transactions ClientBase::pending() const
return postMine().pending();
}
h256s ClientBase::pendingHashes() const
{
return h256s() + postMine().pendingHashes();
}
StateDiff ClientBase::diff(unsigned _txi, h256 _block) const
{
@ -399,3 +399,12 @@ Address ClientBase::address() const
{
return preMine().address();
}
h256 ClientBase::hashFromNumber(BlockNumber _number) const
{
if (_number == PendingBlock)
return h256();
if (_number == LatestBlock)
return bc().currentHash();
return bc().numberHash(_number);
}

5
libethereum/ClientBase.h

@ -63,7 +63,7 @@ struct WatchChannel: public LogChannel { static const char* name() { return "(o)
#define cwatch dev::LogOutputStream<dev::eth::WatchChannel, true>()
struct WorkInChannel: public LogChannel { static const char* name() { return ">W>"; } static const int verbosity = 16; };
struct WorkOutChannel: public LogChannel { static const char* name() { return "<W<"; } static const int verbosity = 16; };
struct WorkChannel: public LogChannel { static const char* name() { return "-W-"; } static const int verbosity = 16; };
struct WorkChannel: public LogChannel { static const char* name() { return "-W-"; } static const int verbosity = 21; };
#define cwork dev::LogOutputStream<dev::eth::WorkChannel, true>()
#define cworkin dev::LogOutputStream<dev::eth::WorkInChannel, true>()
#define cworkout dev::LogOutputStream<dev::eth::WorkOutChannel, true>()
@ -109,7 +109,7 @@ public:
virtual LocalisedLogEntries checkWatch(unsigned _watchId) override;
// TODO: switch all the _blockHash arguments to also accept _blockNumber
virtual h256 hashFromNumber(unsigned _number) const override;
virtual h256 hashFromNumber(BlockNumber _number) const override;
virtual eth::BlockInfo blockInfo(h256 _hash) const override;
virtual eth::BlockDetails blockDetails(h256 _hash) const override;
virtual eth::Transaction transaction(h256 _transactionHash) const override;
@ -122,6 +122,7 @@ public:
virtual unsigned uncleCount(h256 _blockHash) const override;
virtual unsigned number() const override;
virtual eth::Transactions pending() const override;
virtual h256s pendingHashes() const override;
using Interface::diff;
virtual StateDiff diff(unsigned _txi, h256 _block) const override;

5
libethereum/EthereumHost.cpp

@ -191,6 +191,8 @@ void EthereumHost::maintainTransactions()
for (auto const& p: randomSelection(25, [&](EthereumPeer* p) { return p->m_requireTransactions || (unsent && !p->m_knownTransactions.count(i.first)); }))
peerTransactions[p].push_back(i.first);
}
for (auto const& t: ts)
m_transactionsSent.insert(t.first);
for (auto p: peerSessions())
if (auto ep = p.first->cap<EthereumPeer>())
{
@ -198,11 +200,10 @@ void EthereumHost::maintainTransactions()
unsigned n = 0;
for (auto const& h: peerTransactions[ep])
{
ep->m_knownTransactions.insert(h);
b += ts[h].rlp();
++n;
}
for (auto const& t: ts)
m_transactionsSent.insert(t.first);
ep->clearKnownTransactions();

4
libethereum/EthereumPeer.cpp

@ -334,7 +334,7 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r)
case GetTransactionsPacket: break; // DEPRECATED.
case TransactionsPacket:
{
clogS(NetMessageSummary) << "Transactions (" << dec << _r.itemCount() << "entries)";
clogS(NetAllDetail) << "Transactions (" << dec << _r.itemCount() << "entries)";
Guard l(x_knownTransactions);
for (unsigned i = 0; i < _r.itemCount(); ++i)
{
@ -348,11 +348,11 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r)
break;
case ImportResult::AlreadyKnown:
// if we already had the transaction, then don't bother sending it on.
host()->m_transactionsSent.insert(h);
addRating(0);
break;
case ImportResult::Success:
addRating(100);
host()->m_transactionsSent.insert(h);
break;
default:;
}

13
libethereum/Executive.cpp

@ -31,8 +31,6 @@ using namespace std;
using namespace dev;
using namespace dev::eth;
#define ETH_VMTRACE 1
Executive::Executive(State& _s, BlockChain const& _bc, unsigned _level):
m_s(_s),
m_lastHashes(_bc.lastHashes((unsigned)_s.info().number - 1)),
@ -69,12 +67,11 @@ void Executive::initialize(Transaction const& _transaction)
}
// Check gas cost is enough.
m_gasRequired = Interface::txGas(m_t.data());
if (m_t.gas() < m_gasRequired)
if (!m_t.checkPayment())
{
clog(StateDetail) << "Not enough gas to pay for the transaction: Require >" << m_gasRequired << " Got" << m_t.gas();
clog(StateDetail) << "Not enough gas to pay for the transaction: Require >" << m_t.gasRequired() << " Got" << m_t.gas();
m_excepted = TransactionException::OutOfGas;
BOOST_THROW_EXCEPTION(OutOfGas() << RequirementError((bigint)m_gasRequired, (bigint)m_t.gas()));
BOOST_THROW_EXCEPTION(OutOfGasBase() << RequirementError(m_t.gasRequired(), (bigint)m_t.gas()));
}
// Avoid invalid transactions.
@ -119,9 +116,9 @@ bool Executive::execute()
m_s.subBalance(m_t.sender(), m_gasCost);
if (m_t.isCreation())
return create(m_t.sender(), m_t.value(), m_t.gasPrice(), m_t.gas() - (u256)m_gasRequired, &m_t.data(), m_t.sender());
return create(m_t.sender(), m_t.value(), m_t.gasPrice(), m_t.gas() - (u256)m_t.gasRequired(), &m_t.data(), m_t.sender());
else
return call(m_t.receiveAddress(), m_t.receiveAddress(), m_t.sender(), m_t.value(), m_t.gasPrice(), bytesConstRef(&m_t.data()), m_t.gas() - (u256)m_gasRequired, m_t.sender());
return call(m_t.receiveAddress(), m_t.receiveAddress(), m_t.sender(), m_t.value(), m_t.gasPrice(), bytesConstRef(&m_t.data()), m_t.gas() - (u256)m_t.gasRequired(), m_t.sender());
}
bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256 _gas, Address _originAddress)

2
libethereum/Executive.h

@ -71,7 +71,7 @@ public:
void operator=(Executive) = delete;
/// Initializes the executive for evaluating a transaction. You must call finalize() at some point following this.
void initialize(bytesConstRef _transaction) { initialize(Transaction(_transaction, CheckSignature::None)); }
void initialize(bytesConstRef _transaction) { initialize(Transaction(_transaction, CheckTransaction::None)); }
void initialize(Transaction const& _transaction);
/// Finalise a transaction previously set up with initialize().
/// @warning Only valid after initialize() and execute(), and possibly go().

19
libethereum/Interface.h

@ -112,10 +112,11 @@ public:
// [BLOCK QUERY API]
virtual h256 hashFromNumber(unsigned _number) const = 0;
virtual Transaction transaction(h256 _transactionHash) const = 0;
virtual h256 hashFromNumber(BlockNumber _number) const = 0;
virtual BlockInfo blockInfo(h256 _hash) const = 0;
virtual BlockDetails blockDetails(h256 _hash) const = 0;
virtual Transaction transaction(h256 _transactionHash) const = 0;
virtual Transaction transaction(h256 _blockHash, unsigned _i) const = 0;
virtual BlockInfo uncle(h256 _blockHash, unsigned _i) const = 0;
virtual UncleHashes uncleHashes(h256 _blockHash) const = 0;
@ -124,6 +125,16 @@ public:
virtual Transactions transactions(h256 _blockHash) const = 0;
virtual TransactionHashes transactionHashes(h256 _blockHash) const = 0;
BlockInfo blockInfo(BlockNumber _block) const { return blockInfo(hashFromNumber(_block)); }
BlockDetails blockDetails(BlockNumber _block) const { return blockDetails(hashFromNumber(_block)); }
Transaction transaction(BlockNumber _block, unsigned _i) const { if (_block == PendingBlock) { auto p = pending(); return _i < p.size() ? p[_i] : Transaction(); } return transaction(hashFromNumber(_block)); }
unsigned transactionCount(BlockNumber _block) const { if (_block == PendingBlock) { auto p = pending(); return p.size(); } return transactionCount(hashFromNumber(_block)); }
Transactions transactions(BlockNumber _block) const { if (_block == PendingBlock) return pending(); return transactions(hashFromNumber(_block)); }
TransactionHashes transactionHashes(BlockNumber _block) const { if (_block == PendingBlock) return pendingHashes(); return transactionHashes(hashFromNumber(_block)); }
BlockInfo uncle(BlockNumber _block, unsigned _i) const { return uncle(hashFromNumber(_block), _i); }
UncleHashes uncleHashes(BlockNumber _block) const { return uncleHashes(hashFromNumber(_block)); }
unsigned uncleCount(BlockNumber _block) const { return uncleCount(hashFromNumber(_block)); }
// [EXTRA API]:
/// @returns The height of the chain.
@ -132,6 +143,7 @@ public:
/// Get a map containing each of the pending transactions.
/// @TODO: Remove in favour of transactions().
virtual Transactions pending() const = 0;
virtual h256s pendingHashes() const = 0;
/// Differences between transactions.
StateDiff diff(unsigned _txi) const { return diff(_txi, m_default); }
@ -143,9 +155,6 @@ public:
virtual Addresses addresses() const { return addresses(m_default); }
virtual Addresses addresses(BlockNumber _block) const = 0;
/// Get the fee associated for a transaction with the given data.
template <class T> static bigint txGas(T const& _data, u256 _gas = 0) { bigint ret = c_txGas + _gas; for (auto i: _data) ret += i ? c_txDataNonZeroGas : c_txDataZeroGas; return ret; }
/// Get the remaining gas limit in this block.
virtual u256 gasLimitRemaining() const = 0;

41
libethereum/State.cpp

@ -99,7 +99,7 @@ State::State(OverlayDB const& _db, BaseState _bs, Address _coinbaseAddress):
m_previousBlock = CanonBlockChain::genesis();
}
else
m_previousBlock.setEmpty();
m_previousBlock.clear();
resetCurrent();
@ -190,6 +190,8 @@ State& State::operator=(State const& _s)
m_blockReward = _s.m_blockReward;
m_lastTx = _s.m_lastTx;
paranoia("after state cloning (assignment op)", true);
m_committedToMine = false;
return *this;
}
@ -276,8 +278,8 @@ bool State::sync(BlockChain const& _bc, h256 _block, BlockInfo const& _bi)
{
bool ret = false;
// BLOCK
BlockInfo bi = _bi;
if (!bi)
BlockInfo bi = _bi ? _bi : _bc.info(_block);
/* if (!bi)
while (1)
{
try
@ -299,7 +301,7 @@ bool State::sync(BlockChain const& _bc, h256 _block, BlockInfo const& _bi)
cerr << "ERROR: Corrupt block-chain! Delete your block-chain DB and restart." << endl;
cerr << _e.what() << endl;
}
}
}*/
if (bi == m_currentBlock)
{
// We mined the last block.
@ -364,7 +366,7 @@ u256 State::enactOn(bytesConstRef _block, BlockInfo const& _bi, BlockChain const
#endif
// Check family:
BlockInfo biParent(_bc.block(_bi.parentHash));
BlockInfo biParent = _bc.info(_bi.parentHash);
_bi.verifyParent(biParent);
#if ETH_TIMED_ENACTMENTS
@ -374,7 +376,7 @@ u256 State::enactOn(bytesConstRef _block, BlockInfo const& _bi, BlockChain const
BlockInfo biGrandParent;
if (biParent.number)
biGrandParent.populate(_bc.block(biParent.parentHash));
biGrandParent = _bc.info(biParent.parentHash);
#if ETH_TIMED_ENACTMENTS
populateGrand = t.elapsed();
@ -434,6 +436,8 @@ void State::resetCurrent()
m_lastTx = m_db;
m_state.setRoot(m_previousBlock.stateRoot);
m_committedToMine = false;
paranoia("begin resetCurrent", true);
}
@ -539,6 +543,9 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, bool _checkNonce)
// m_currentBlock is assumed to be prepopulated and reset.
BlockInfo bi(_block, _checkNonce ? CheckEverything : IgnoreNonce);
cdebug << "enacting" << BlockInfo::headerHash(_block).abridged() << "==" << bi.hash().abridged() << "on" << m_previousBlock.hash().abridged();
cdebug << m_currentBlock;
#if !ETH_RELEASE
assert(m_previousBlock.hash() == bi.parentHash);
assert(m_currentBlock.parentHash == bi.parentHash);
@ -551,6 +558,10 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, bool _checkNonce)
// Populate m_currentBlock with the correct values.
m_currentBlock = bi;
m_currentBlock.verifyInternals(_block);
m_currentBlock.noteDirty();
cdebug << "populated and verified. incoming block hash is" << m_currentBlock.hash().abridged();
cdebug << m_currentBlock;
// cnote << "playback begins:" << m_state.root();
// cnote << m_state;
@ -574,7 +585,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, bool _checkNonce)
k << i;
transactionsTrie.insert(&k.out(), tr.data());
execute(lh, Transaction(tr.data(), CheckSignature::Sender));
execute(lh, Transaction(tr.data(), CheckTransaction::Everything));
RLPStream receiptrlp;
m_receipts.back().streamRLP(receiptrlp);
@ -620,6 +631,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, bool _checkNonce)
// Initialise total difficulty calculation.
u256 tdIncrease = m_currentBlock.difficulty;
// Check uncles & apply their rewards to state.
if (rlp[2].itemCount() > 2)
BOOST_THROW_EXCEPTION(TooManyUncles());
@ -646,6 +658,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, bool _checkNonce)
tdIncrease += uncle.difficulty;
rewarded.push_back(uncle);
}
applyRewards(rewarded);
// Commit all cached state changes to the state trie.
@ -673,6 +686,11 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, bool _checkNonce)
BOOST_THROW_EXCEPTION(InvalidGasUsed() << RequirementError(bigint(gasUsed()), bigint(m_currentBlock.gasUsed)));
}
cdebug << m_currentBlock;
auto hh = m_currentBlock.hash();
m_currentBlock.noteDirty();
cdebug << "done enacting. new stateroot is" << m_currentBlock.stateRoot.abridged() << ", hash is" << m_currentBlock.hash().abridged() << " = " << hh;
return tdIncrease;
}
@ -687,6 +705,9 @@ void State::cleanup(bool _fullCommit)
paranoia("immediately after database commit", true);
m_previousBlock = m_currentBlock;
m_currentBlock.populateFromParent(m_previousBlock);
cdebug << "finalising enactment. current -> previous, hash is" << m_previousBlock.hash().abridged();
}
else
m_db.rollback();
@ -696,7 +717,7 @@ void State::cleanup(bool _fullCommit)
void State::uncommitToMine()
{
if (m_currentBlock.sha3Uncles)
if (m_committedToMine)
{
m_cache.clear();
if (!m_transactions.size())
@ -705,7 +726,7 @@ void State::uncommitToMine()
m_state.setRoot(m_receipts.back().stateRoot());
m_db = m_lastTx;
paranoia("Uncommited to mine", true);
m_currentBlock.sha3Uncles = h256();
m_committedToMine = false;
}
}
@ -842,6 +863,8 @@ void State::commitToMine(BlockChain const& _bc)
m_currentBlock.gasUsed = gasUsed();
m_currentBlock.stateRoot = m_state.root();
m_currentBlock.parentHash = m_previousBlock.hash();
m_committedToMine = true;
}
MineInfo State::mine(unsigned _msTimeout, bool _turbo)

5
libethereum/State.h

@ -138,6 +138,7 @@ public:
static OverlayDB openDB(std::string _path, WithExisting _we = WithExisting::Trust);
static OverlayDB openDB(WithExisting _we = WithExisting::Trust) { return openDB(std::string(), _we); }
OverlayDB const& db() const { return m_db; }
OverlayDB& db() { return m_db; }
/// @returns the set containing all addresses currently in use in Ethereum.
/// @throws InterfaceNotSupported if compiled without ETH_FATDB.
@ -274,6 +275,9 @@ public:
/// Get the list of pending transactions.
Transactions const& pending() const { return m_transactions; }
/// Get the list of hashes of pending transactions.
h256Set const& pendingHashes() const { return m_transactionSet; }
/// Get the transaction receipt for the transaction of the given index.
TransactionReceipt const& receipt(unsigned _i) const { return m_receipts[_i]; }
@ -360,6 +364,7 @@ private:
BlockInfo m_previousBlock; ///< The previous block's information.
BlockInfo m_currentBlock; ///< The current block's information.
bytes m_currentBytes; ///< The current block.
bool m_committedToMine = false; ///< Have we committed to mine on the present m_currentBlock?
bytes m_currentTxs; ///< The RLP-encoded block of transactions.
bytes m_currentUncles; ///< The RLP-encoded block of uncles.

16
libethereum/Transaction.cpp

@ -25,6 +25,7 @@
#include <libdevcrypto/Common.h>
#include <libethcore/Exceptions.h>
#include <libevm/VMFace.h>
#include "Interface.h"
#include "Transaction.h"
using namespace std;
using namespace dev;
@ -53,7 +54,7 @@ TransactionException dev::eth::toTransactionException(VMException const& _e)
return TransactionException::Unknown;
}
Transaction::Transaction(bytesConstRef _rlpData, CheckSignature _checkSig)
Transaction::Transaction(bytesConstRef _rlpData, CheckTransaction _checkSig)
{
int field = 0;
RLP rlp(_rlpData);
@ -81,9 +82,9 @@ Transaction::Transaction(bytesConstRef _rlpData, CheckSignature _checkSig)
BOOST_THROW_EXCEPTION(BadRLP() << errinfo_comment("to many fields in the transaction RLP"));
m_vrs = SignatureStruct{ r, s, v };
if (_checkSig >= CheckSignature::Range && !m_vrs.isValid())
if (_checkSig >= CheckTransaction::Cheap && !m_vrs.isValid())
BOOST_THROW_EXCEPTION(InvalidSignature());
if (_checkSig == CheckSignature::Sender)
if (_checkSig == CheckTransaction::Everything)
m_sender = sender();
}
catch (Exception& _e)
@ -91,6 +92,8 @@ Transaction::Transaction(bytesConstRef _rlpData, CheckSignature _checkSig)
_e << errinfo_name("invalid transaction format") << BadFieldError(field, toHex(rlp[field].data().toBytes()));
throw;
}
if (_checkSig >= CheckTransaction::Cheap && !checkPayment())
BOOST_THROW_EXCEPTION(OutOfGasBase() << RequirementError(gasRequired(), (bigint)gas()));
}
Address const& Transaction::safeSender() const noexcept
@ -118,6 +121,13 @@ Address const& Transaction::sender() const
return m_sender;
}
bigint Transaction::gasRequired() const
{
if (!m_gasRequired)
m_gasRequired = Transaction::gasRequired(m_data);
return m_gasRequired;
}
void Transaction::sign(Secret _priv)
{
auto sig = dev::sign(_priv, sha3(WithoutSignature));

48
libethereum/Transaction.h

@ -24,7 +24,7 @@
#include <libdevcore/RLP.h>
#include <libdevcrypto/SHA3.h>
#include <libethcore/Common.h>
#include <libethcore/Params.h>
namespace dev
{
namespace eth
@ -37,11 +37,11 @@ enum IncludeSignature
WithSignature = 1, ///< Do include a signature.
};
enum class CheckSignature
enum class CheckTransaction
{
None,
Range,
Sender
Cheap,
Everything
};
enum class TransactionException
@ -119,10 +119,10 @@ public:
Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data): m_type(ContractCreation), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {}
/// Constructs a transaction from the given RLP.
explicit Transaction(bytesConstRef _rlp, CheckSignature _checkSig);
explicit Transaction(bytesConstRef _rlp, CheckTransaction _checkSig);
/// Constructs a transaction from the given RLP.
explicit Transaction(bytes const& _rlp, CheckSignature _checkSig): Transaction(&_rlp, _checkSig) {}
explicit Transaction(bytes const& _rlp, CheckTransaction _checkSig): Transaction(&_rlp, _checkSig) {}
/// Checks equality of transactions.
@ -178,27 +178,37 @@ public:
/// @returns the signature of the transaction. Encodes the sender.
SignatureStruct const& signature() const { return m_vrs; }
/// @returns true if the transaction contains enough gas for the basic payment.
bool checkPayment() const { return m_gas >= gasRequired(); }
/// @returns the gas required to run this transaction.
bigint gasRequired() const;
/// Get the fee associated for a transaction with the given data.
template <class T> static bigint gasRequired(T const& _data, u256 _gas = 0) { bigint ret = c_txGas + _gas; for (auto i: _data) ret += i ? c_txDataNonZeroGas : c_txDataZeroGas; return ret; }
private:
/// Type of transaction.
enum Type
{
NullTransaction, ///< Null transaction.
ContractCreation, ///< Transaction to create contracts - receiveAddress() is ignored.
MessageCall ///< Transaction to invoke a message call - receiveAddress() is used.
NullTransaction, ///< Null transaction.
ContractCreation, ///< Transaction to create contracts - receiveAddress() is ignored.
MessageCall ///< Transaction to invoke a message call - receiveAddress() is used.
};
void sign(Secret _priv); ///< Sign the transaction.
void sign(Secret _priv); ///< Sign the transaction.
Type m_type = NullTransaction; ///< Is this a contract-creation transaction or a message-call transaction?
u256 m_nonce; ///< The transaction-count of the sender.
u256 m_value; ///< The amount of ETH to be transferred by this transaction. Called 'endowment' for contract-creation transactions.
Address m_receiveAddress; ///< The receiving address of the transaction.
u256 m_gasPrice; ///< The base fee and thus the implied exchange rate of ETH to GAS.
u256 m_gas; ///< The total gas to convert, paid for from sender's account. Any unused gas gets refunded once the contract is ended.
bytes m_data; ///< The data associated with the transaction, or the initialiser if it's a creation transaction.
SignatureStruct m_vrs; ///< The signature of the transaction. Encodes the sender.
Type m_type = NullTransaction; ///< Is this a contract-creation transaction or a message-call transaction?
u256 m_nonce; ///< The transaction-count of the sender.
u256 m_value; ///< The amount of ETH to be transferred by this transaction. Called 'endowment' for contract-creation transactions.
Address m_receiveAddress; ///< The receiving address of the transaction.
u256 m_gasPrice; ///< The base fee and thus the implied exchange rate of ETH to GAS.
u256 m_gas; ///< The total gas to convert, paid for from sender's account. Any unused gas gets refunded once the contract is ended.
bytes m_data; ///< The data associated with the transaction, or the initialiser if it's a creation transaction.
SignatureStruct m_vrs; ///< The signature of the transaction. Encodes the sender.
mutable Address m_sender; ///< Cached sender, determined from signature.
mutable Address m_sender; ///< Cached sender, determined from signature.
mutable bigint m_gasRequired = 0; ///< Memoised amount required for the transaction to run.
};
/// Nice name for vector of Transaction.

8
libethereum/TransactionQueue.cpp

@ -44,21 +44,23 @@ ImportResult TransactionQueue::import(bytesConstRef _transactionRLP)
// Check validity of _transactionRLP as a transaction. To do this we just deserialise and attempt to determine the sender.
// If it doesn't work, the signature is bad.
// The transaction's nonce may yet be invalid (or, it could be "valid" but we may be missing a marginally older transaction).
Transaction t(_transactionRLP, CheckSignature::Sender);
Transaction t(_transactionRLP, CheckTransaction::Everything);
UpgradeGuard ul(l);
// If valid, append to blocks.
m_current[h] = t;
m_known.insert(h);
ctxq << "Queued vaguely legit-looking transaction" << h.abridged();
}
catch (Exception const& _e)
{
cwarn << "Ignoring invalid transaction: " << diagnostic_information(_e);
ctxq << "Ignoring invalid transaction: " << diagnostic_information(_e);
return ImportResult::Malformed;
}
catch (std::exception const& _e)
{
cwarn << "Ignoring invalid transaction: " << _e.what();
ctxq << "Ignoring invalid transaction: " << _e.what();
return ImportResult::Malformed;
}

3
libethereum/TransactionQueue.h

@ -24,6 +24,7 @@
#include <boost/thread.hpp>
#include <libdevcore/Common.h>
#include <libdevcore/Guards.h>
#include <libdevcore/Log.h>
#include "libethcore/Common.h"
#include "Transaction.h"
@ -34,6 +35,8 @@ namespace eth
class BlockChain;
struct TransactionQueueChannel: public LogChannel { static const char* name() { return "->Q"; } static const int verbosity = 4; };
#define ctxq dev::LogOutputStream<dev::eth::TransactionQueueChannel, true>()
/**
* @brief A queue of Transactions, each stored as RLP.

4
libjsqrc/ethereumjs/.bowerrc

@ -1,5 +1,5 @@
{
"directory": "example/js/",
"directory": "bower",
"cwd": "./",
"analytics": false
}
}

1
libjsqrc/ethereumjs/.gitignore

@ -17,3 +17,4 @@ example/js
node_modules
bower_components
npm-debug.log
/bower

1
libjsqrc/ethereumjs/.travis.yml

@ -14,4 +14,5 @@ after_script:
- npm run-script build
- npm run-script karma
- npm run-script test-coveralls
- cd test/node && npm install && node app.js

8
libjsqrc/ethereumjs/README.md

@ -1,9 +1,11 @@
# Ethereum JavaScript API
[![Join the chat at https://gitter.im/ethereum/ethereum.js](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ethereum/ethereum.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
This is the Ethereum compatible [JavaScript API](https://github.com/ethereum/wiki/wiki/JavaScript-API)
which implements the [Generic JSON RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC) spec. It's available on npm as a node module, for bower and component as an embeddable js and as a meteor.js package.
[![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![dependency status][dep-image]][dep-url] [![dev dependency status][dep-dev-image]][dep-dev-url][![Coverage Status][coveralls-image]][coveralls-url]
[![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![dependency status][dep-image]][dep-url] [![dev dependency status][dep-dev-image]][dep-dev-url][![Coverage Status][coveralls-image]][coveralls-url][![Stories in Ready][waffle-image]][waffle-url]
<!-- [![browser support](https://ci.testling.com/ethereum/ethereum.js.png)](https://ci.testling.com/ethereum/ethereum.js) -->
@ -36,7 +38,7 @@ Component
## Usage
Require the library (not required for the meteor package):
var web3 = require('web3');
var web3 = require('ethereum.js');
Set a provider (QtSyncProvider, HttpProvider)
@ -110,4 +112,6 @@ eth -j
[dep-dev-url]: https://david-dm.org/ethereum/ethereum.js#info=devDependencies
[coveralls-image]: https://coveralls.io/repos/ethereum/ethereum.js/badge.svg?branch=master
[coveralls-url]: https://coveralls.io/r/ethereum/ethereum.js?branch=master
[waffle-image]: https://badge.waffle.io/ethereum/ethereum.js.svg?label=ready&title=Ready
[waffle-url]: http://waffle.io/ethereum/ethereum.js

4
libjsqrc/ethereumjs/bower.json

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

57
libjsqrc/ethereumjs/dist/ethereum.js.map

File diff suppressed because one or more lines are too long

1
libjsqrc/ethereumjs/dist/ethereum.min.js

File diff suppressed because one or more lines are too long

1891
libjsqrc/ethereumjs/dist/ethereum.js → libjsqrc/ethereumjs/dist/web3-light.js

File diff suppressed because it is too large

69
libjsqrc/ethereumjs/dist/web3-light.js.map

File diff suppressed because one or more lines are too long

1
libjsqrc/ethereumjs/dist/web3-light.min.js

File diff suppressed because one or more lines are too long

5548
libjsqrc/ethereumjs/dist/web3.js

File diff suppressed because it is too large

69
libjsqrc/ethereumjs/dist/web3.js.map

File diff suppressed because one or more lines are too long

2
libjsqrc/ethereumjs/dist/web3.min.js

File diff suppressed because one or more lines are too long

4
libjsqrc/ethereumjs/example/balance.html

@ -2,8 +2,8 @@
<html>
<head>
<script type="text/javascript" src="js/bignumber.js/bignumber.min.js"></script>
<script type="text/javascript" src="../dist/ethereum.js"></script>
<script type="text/javascript" src="../node_modules/bignumber.js/bignumber.min.js"></script>
<script type="text/javascript" src="../dist/web3-light.js"></script>
<script type="text/javascript">
var web3 = require('web3');

153
libjsqrc/ethereumjs/example/coin.html

@ -0,0 +1,153 @@
<!doctype>
<html>
<title>JevCoin</title>
<head>
<script type="text/javascript" src="../dist/web3.js"></script>
</head>
<body>
<h1>JevCoin <code id="contract_addr"></code></h1>
<div>
<strong>Balance</strong>
<span id="balance"></strong>
</div>
<div>
<span>Address:</span>
<input type="text" id="address" style="width:200px">
<span>Amount:</span>
<input type="text" id="amount" style="width:200px">
<button onclick="transact()">Send</button>
<span id="message"></span>
</div>
<hr>
<table width="100%" id="table">
<tr><td style="width:40%;">Address</td><td>Balance</td></tr>
<tbody id="table_body"></tbody>
</table>
</body>
<script type="text/javascript">
var web3 = require('web3');
var eth = web3.eth;
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8080'));
var desc = [{
"name": "balance(address)",
"type": "function",
"inputs": [{
"name": "who",
"type": "address"
}],
"constant": true,
"outputs": [{
"name": "value",
"type": "uint256"
}]
}, {
"name": "send(address,uint256)",
"type": "function",
"inputs": [{
"name": "to",
"type": "address"
}, {
"name": "value",
"type": "uint256"
}],
"outputs": []
}, {
"name":"Changed",
"type":"event",
"inputs": [
{"name":"from","type":"address","indexed":true},
{"name":"amount","type":"uint256","indexed":true},
],
}];
var address = localStorage.getItem("address");
// deploy if not exist
if(address === null) {
var code = "0x60056013565b61014f8061003a6000396000f35b620f42406000600033600160a060020a0316815260200190815260200160002081905550560060e060020a600035048063d0679d3414610020578063e3d670d71461003457005b61002e600435602435610049565b60006000f35b61003f600435610129565b8060005260206000f35b806000600033600160a060020a03168152602001908152602001600020541061007157610076565b610125565b806000600033600160a060020a03168152602001908152602001600020908154039081905550806000600084600160a060020a031681526020019081526020016000209081540190819055508033600160a060020a03167fb52dda022b6c1a1f40905a85f257f689aa5d69d850e49cf939d688fbe5af594660006000a38082600160a060020a03167fb52dda022b6c1a1f40905a85f257f689aa5d69d850e49cf939d688fbe5af594660006000a35b5050565b60006000600083600160a060020a0316815260200190815260200160002054905091905056";
address = web3.eth.transact({from: eth.coinbase, data: code, gas: "1000000"});
localStorage.setItem("address", address);
}
document.querySelector("#contract_addr").innerHTML = address;
var Contract = web3.eth.contract(desc);
contract = new Contract(address);
contract.Changed({from: eth.accounts[0]}).changed(function() {
refresh();
});
function refresh() {
document.querySelector("#balance").innerHTML = contract.balance(eth.coinbase);
var table = document.querySelector("#table_body");
table.innerHTML = ""; // clear
/*var storage = eth.getStorage(address);*/
/*table.innerHTML = "";*/
/*for( var item in storage ) {*/
/*table.innerHTML += "<tr><td>"+item+"</td><td>"+web3.toDecimal(storage[item])+"</td></tr>";*/
/*}*/
}
function transact() {
var to = document.querySelector("#address");
if( to.value.length == 0 ) {
to = "0x4205b06c2cfa0e30359edcab94543266cb6fa1d3";
} else {
if (to.value.substr(0,2) != "0x")
to.value = "0x"+to.value;
}
var value = document.querySelector("#amount");
var amount = parseInt( value.value );
console.log("transact: ", to.value, " => ", amount)
contract.sendTransaction({from: eth.accounts[0]}).send( to.value, amount );
to.value = "";
value.value = "";
var message = document.querySelector("#message")
message.innerHTML = "Submitted";
setTimeout(function() {
message.innerHTML = "";
}, 1000);
}
refresh();
</script>
</html>
<!--
contract JevCoin {
function JevCoin()
{
balances[msg.sender] = 1000000;
}
event Changed(address indexed from, uint indexed amount);
function send(address to, uint value)
{
if( balances[msg.sender] < value ) return;
balances[msg.sender] -= value;
balances[to] += value;
Changed(msg.sender, value);
Changed(to, value);
}
function balance(address who) constant returns(uint t)
{
t = balances[who];
}
mapping(address => uint256) balances;
}
-!>

3
libjsqrc/ethereumjs/example/contract.html

@ -2,8 +2,7 @@
<html>
<head>
<script type="text/javascript" src="js/bignumber.js/bignumber.min.js"></script>
<script type="text/javascript" src="../dist/ethereum.js"></script>
<script type="text/javascript" src="../dist/web3"></script>
<script type="text/javascript">
var web3 = require('web3');

3
libjsqrc/ethereumjs/example/contract_with_array.html

@ -2,8 +2,7 @@
<html>
<head>
<script type="text/javascript" src="js/bignumber.js/bignumber.min.js"></script>
<script type="text/javascript" src="../dist/ethereum.js"></script>
<script type="text/javascript" src="../dist/web3.js"></script>
<script type="text/javascript">
var web3 = require('web3');

3
libjsqrc/ethereumjs/example/event.html

@ -1,8 +1,7 @@
<!doctype>
<html>
<head>
<script type="text/javascript" src="js/bignumber.js/bignumber.min.js"></script>
<script type="text/javascript" src="../dist/ethereum.js"></script>
<script type="text/javascript" src="../dist/web3.js"></script>
<script type="text/javascript">
var web3 = require('web3');
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8080'));

3
libjsqrc/ethereumjs/example/event_inc.html

@ -1,8 +1,7 @@
<!doctype>
<html>
<head>
<script type="text/javascript" src="js/bignumber.js/bignumber.min.js"></script>
<script type="text/javascript" src="../dist/ethereum.js"></script>
<script type="text/javascript" src="../dist/web3.js"></script>
<script type="text/javascript">
var web3 = require('web3');
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8080'));

3
libjsqrc/ethereumjs/example/natspec_contract.html

@ -2,8 +2,7 @@
<html>
<head>
<script type="text/javascript" src="js/bignumber.js/bignumber.min.js"></script>
<script type="text/javascript" src="../dist/ethereum.js"></script>
<script type="text/javascript" src="../dist/web3.js"></script>
<script type="text/javascript">
var web3 = require('web3');

34
libjsqrc/ethereumjs/gulpfile.js

@ -2,7 +2,7 @@
'use strict';
var version = require('./version.json');
var version = require('./lib/version.json');
var path = require('path');
var del = require('del');
@ -19,19 +19,23 @@ var replace = require('gulp-replace');
var DEST = './dist/';
var src = 'index';
var dst = 'ethereum';
var dst = 'web3';
var lightDst = 'web3-light';
var browserifyOptions = {
debug: true,
insert_global_vars: false, // jshint ignore:line
detectGlobals: false,
bundleExternal: false
bundleExternal: true
};
gulp.task('versionReplace', function(){
gulp.src(['./package.json'])
.pipe(replace(/\"version\"\: \"(.{5})\"/, '"version": "'+ version.version + '"'))
.pipe(gulp.dest('./'));
gulp.src(['./bower.json'])
.pipe(replace(/\"version\"\: \"(.{5})\"/, '"version": "'+ version.version + '"'))
.pipe(gulp.dest('./'));
gulp.src(['./package.js'])
.pipe(replace(/version\: \'(.{5})\'/, "version: '"+ version.version + "'"))
.pipe(gulp.dest('./'));
@ -54,10 +58,27 @@ gulp.task('lint', function(){
.pipe(jshint.reporter('default'));
});
gulp.task('build', ['clean'], function () {
gulp.task('buildLight', ['clean'], function () {
return browserify(browserifyOptions)
.require('./' + src + '.js', {expose: 'web3'})
.ignore('bignumber.js')
.require('./lib/utils/browser-bn.js', {expose: 'bignumber.js'}) // fake bignumber.js
.add('./' + src + '.js')
.bundle()
.pipe(exorcist(path.join( DEST, lightDst + '.js.map')))
.pipe(source(lightDst + '.js'))
.pipe(gulp.dest( DEST ))
.pipe(streamify(uglify()))
.pipe(rename(lightDst + '.min.js'))
.pipe(gulp.dest( DEST ));
});
gulp.task('buildStandalone', ['clean'], function () {
return browserify(browserifyOptions)
.require('./' + src + '.js', {expose: 'web3'})
.require('bignumber.js') // expose it to dapp users
.add('./' + src + '.js')
.ignore('crypto')
.bundle()
.pipe(exorcist(path.join( DEST, dst + '.js.map')))
.pipe(source(dst + '.js'))
@ -71,8 +92,9 @@ gulp.task('watch', function() {
gulp.watch(['./lib/*.js'], ['lint', 'build']);
});
gulp.task('dev', ['versionReplace','bower', 'lint', 'build']);
gulp.task('default', ['dev']);
gulp.task('light', ['versionReplace','bower', 'lint', 'buildLight']);
gulp.task('standalone', ['versionReplace','bower', 'lint', 'buildStandalone']);
gulp.task('default', ['light', 'standalone']);
gulp.task('version', ['versionReplace']);

9
libjsqrc/ethereumjs/index.js

@ -1,7 +1,14 @@
var web3 = require('./lib/web3');
// dont override global variable
if (typeof web3 !== 'undefined') {
var web3;
}
web3 = require('./lib/web3');
web3.providers.HttpProvider = require('./lib/web3/httpprovider');
web3.providers.QtSyncProvider = require('./lib/web3/qtsync');
web3.eth.contract = require('./lib/web3/contract');
web3.abi = require('./lib/solidity/abi');
module.exports = web3;

3
libjsqrc/ethereumjs/karma.conf.js

@ -22,8 +22,7 @@ module.exports = function (config) {
// list of files / patterns to load in the browser
files: [
'node_modules/bignumber.js/bignumber.js',
'test/*.js',
'test/*.js'
],

20
libjsqrc/ethereumjs/lib/solidity/formatters.js

@ -20,26 +20,10 @@
* @date 2015
*/
if (process.env.NODE_ENV !== 'build') {
var BigNumber = require('bignumber.js'); // jshint ignore:line
}
var BigNumber = require('bignumber.js');
var utils = require('../utils/utils');
var c = require('../utils/config');
/**
* Should be called to pad string to expected length
*
* @method padLeft
* @param {String} string to be padded
* @param {Number} characters that result string should have
* @param {String} sign, by default 0
* @returns {String} right aligned string
*/
var padLeft = function (string, chars, sign) {
return new Array(chars - string.length + 1).join(sign ? sign : "0") + string;
};
/**
* Formats input value to byte representation of int
* If value is negative, return it's two's complement
@ -52,7 +36,7 @@ var padLeft = function (string, chars, sign) {
var formatInputInt = function (value) {
var padding = c.ETH_PADDING * 2;
BigNumber.config(c.ETH_BIGNUMBER_ROUNDING_MODE);
return padLeft(utils.toTwosComplement(value).round().toString(16), padding);
return utils.padLeft(utils.toTwosComplement(value).round().toString(16), padding);
};
/**

4
libjsqrc/ethereumjs/lib/utils/browser-bn.js

@ -0,0 +1,4 @@
'use strict';
module.exports = BigNumber; // jshint ignore:line

9
libjsqrc/ethereumjs/lib/utils/browser-xhr.js

@ -0,0 +1,9 @@
'use strict';
// go env doesn't have and need XMLHttpRequest
if (typeof XMLHttpRequest === 'undefined') {
exports.XMLHttpRequest = {};
} else {
exports.XMLHttpRequest = XMLHttpRequest; // jshint ignore:line
}

4
libjsqrc/ethereumjs/lib/utils/config.js

@ -34,9 +34,7 @@
*/
/// required to define ETH_BIGNUMBER_ROUNDING_MODE
if (process.env.NODE_ENV !== 'build') {
var BigNumber = require('bignumber.js'); // jshint ignore:line
}
var BigNumber = require('bignumber.js');
var ETH_UNITS = [
'wei',

68
libjsqrc/ethereumjs/lib/utils/utils.js

@ -33,9 +33,7 @@
* @constructor
*/
if (process.env.NODE_ENV !== 'build') {
var BigNumber = require('bignumber.js'); // jshint ignore:line
}
var BigNumber = require('bignumber.js');
var unitMap = {
'wei': '1',
@ -56,6 +54,18 @@ var unitMap = {
'tether': '1000000000000000000000000000000'
};
/**
* Should be called to pad string to expected length
*
* @method padLeft
* @param {String} string to be padded
* @param {Number} characters that result string should have
* @param {String} sign, by default 0
* @returns {String} right aligned string
*/
var padLeft = function (string, chars, sign) {
return new Array(chars - string.length + 1).join(sign ? sign : "0") + string;
};
/** Finds first index of array element matching pattern
*
@ -214,13 +224,13 @@ var fromDecimal = function (value) {
var toHex = function (val) {
/*jshint maxcomplexity:7 */
if(isBoolean(val))
return val;
if (isBoolean(val))
return fromDecimal(+val);
if(isBigNumber(val))
if (isBigNumber(val))
return fromDecimal(val);
if(isObject(val))
if (isObject(val))
return fromAscii(JSON.stringify(val));
// if its a negative number, pass it through fromDecimal
@ -345,13 +355,27 @@ var toTwosComplement = function (number) {
* @param {String} address the given HEX adress
* @return {Boolean}
*/
var isAddress = function(address) {
if (!isString(address)) {
return false;
var isAddress = function (address) {
return /^0x[0-9a-f]{40}$/.test(address);
};
/**
* Transforms given string to valid 20 bytes-length addres with 0x prefix
*
* @method toAddress
* @param {String} address
* @return {String} formatted address
*/
var toAddress = function (address) {
if (isAddress(address)) {
return address;
}
if (/^[0-9a-f]{40}$/.test(address)) {
return '0x' + address;
}
return ((address.indexOf('0x') === 0 && address.length === 42) ||
(address.indexOf('0x') === -1 && address.length === 40));
return '0x' + padLeft(toHex(address).substr(2), 40);
};
/**
@ -422,7 +446,23 @@ var isArray = function (object) {
return object instanceof Array;
};
/**
* Returns true if given string is valid json object
*
* @method isJson
* @param {String}
* @return {Boolean}
*/
var isJson = function (str) {
try {
return !!JSON.parse(str);
} catch (e) {
return false;
}
};
module.exports = {
padLeft: padLeft,
findIndex: findIndex,
toHex: toHex,
toDecimal: toDecimal,
@ -437,12 +477,14 @@ module.exports = {
fromWei: fromWei,
toBigNumber: toBigNumber,
toTwosComplement: toTwosComplement,
toAddress: toAddress,
isBigNumber: isBigNumber,
isAddress: isAddress,
isFunction: isFunction,
isString: isString,
isObject: isObject,
isBoolean: isBoolean,
isArray: isArray
isArray: isArray,
isJson: isJson
};

3
libjsqrc/ethereumjs/lib/version.json

@ -0,0 +1,3 @@
{
"version": "0.2.5"
}

288
libjsqrc/ethereumjs/lib/web3.js

@ -24,79 +24,55 @@
* @date 2014
*/
var version = require('../version.json');
var version = require('./version.json');
var net = require('./web3/net');
var eth = require('./web3/eth');
var db = require('./web3/db');
var shh = require('./web3/shh');
var watches = require('./web3/watches');
var filter = require('./web3/filter');
var Filter = require('./web3/filter');
var utils = require('./utils/utils');
var formatters = require('./solidity/formatters');
var requestManager = require('./web3/requestmanager');
var formatters = require('./web3/formatters');
var RequestManager = require('./web3/requestmanager');
var c = require('./utils/config');
var Method = require('./web3/method');
var Property = require('./web3/property');
/// @returns an array of objects describing web3 api methods
var web3Methods = [
{ name: 'sha3', call: 'web3_sha3', inputFormatter: utils.toHex },
new Method({
name: 'sha3',
call: 'web3_sha3',
params: 1
})
];
var web3Properties = [
{ name: 'version.client', getter: 'web3_clientVersion' },
{ name: 'version.network', getter: 'net_version' }
new Property({
name: 'version.client',
getter: 'web3_clientVersion'
}),
new Property({
name: 'version.network',
getter: 'net_version',
inputFormatter: utils.toDecimal
}),
new Property({
name: 'version.ethereum',
getter: 'eth_version',
inputFormatter: utils.toDecimal
}),
new Property({
name: 'version.whisper',
getter: 'shh_version',
inputFormatter: utils.toDecimal
})
];
/// creates methods in a given object based on method description on input
/// setups api calls for these methods
var setupMethods = function (obj, methods) {
methods.forEach(function (method) {
// allow for object methods 'myObject.method'
var objectMethods = method.name.split('.'),
callFunction = function () {
/*jshint maxcomplexity:8 */
var callback = null,
args = Array.prototype.slice.call(arguments),
call = typeof method.call === 'function' ? method.call(args) : method.call;
// get the callback if one is available
if(typeof args[args.length-1] === 'function'){
callback = args[args.length-1];
Array.prototype.pop.call(args);
}
// add the defaultBlock if not given
if(method.addDefaultblock) {
if(args.length !== method.addDefaultblock)
Array.prototype.push.call(args, (isFinite(c.ETH_DEFAULTBLOCK) ? utils.fromDecimal(c.ETH_DEFAULTBLOCK) : c.ETH_DEFAULTBLOCK));
else
args[args.length-1] = isFinite(args[args.length-1]) ? utils.fromDecimal(args[args.length-1]) : args[args.length-1];
}
// show deprecated warning
if(method.newMethod)
console.warn('This method is deprecated please use web3.'+ method.newMethod +'() instead.');
return web3.manager.send({
method: call,
params: args,
outputFormatter: method.outputFormatter,
inputFormatter: method.inputFormatter,
addDefaultblock: method.addDefaultblock
}, callback);
};
if(objectMethods.length > 1) {
if(!obj[objectMethods[0]])
obj[objectMethods[0]] = {};
obj[objectMethods[0]][objectMethods[1]] = callFunction;
} else {
obj[objectMethods[0]] = callFunction;
}
method.attachToObject(obj);
});
};
@ -104,173 +80,53 @@ var setupMethods = function (obj, methods) {
/// setups api calls for these properties
var setupProperties = function (obj, properties) {
properties.forEach(function (property) {
var objectProperties = property.name.split('.'),
proto = {};
proto.get = function () {
// show deprecated warning
if(property.newProperty)
console.warn('This property is deprecated please use web3.'+ property.newProperty +' instead.');
return web3.manager.send({
method: property.getter,
outputFormatter: property.outputFormatter
});
};
if (property.setter) {
proto.set = function (val) {
// show deprecated warning
if(property.newProperty)
console.warn('This property is deprecated please use web3.'+ property.newProperty +' instead.');
return web3.manager.send({
method: property.setter,
params: [val],
inputFormatter: property.inputFormatter
});
};
}
proto.enumerable = !property.newProperty;
if(objectProperties.length > 1) {
if(!obj[objectProperties[0]])
obj[objectProperties[0]] = {};
Object.defineProperty(obj[objectProperties[0]], objectProperties[1], proto);
} else
Object.defineProperty(obj, property.name, proto);
property.attachToObject(obj);
});
};
/// setups web3 object, and it's in-browser executed methods
var web3 = {};
web3.providers = {};
web3.version = {};
web3.version.api = version.version;
web3.eth = {};
/*jshint maxparams:4 */
var startPolling = function (method, id, callback, uninstall) {
web3.manager.startPolling({
method: method,
params: [id]
}, id, callback, uninstall);
};
/*jshint maxparams:3 */
web3.eth.filter = function (fil, eventParams, options, formatter) {
var stopPolling = function (id) {
web3.manager.stopPolling(id);
};
// if its event, treat it differently
// TODO: simplify and remove
if (fil._isEvent) {
return fil(eventParams, options);
}
var ethWatch = {
startPolling: startPolling.bind(null, 'eth_getFilterChanges'),
stopPolling: stopPolling
// what outputLogFormatter? that's wrong
//return new Filter(fil, watches.eth(), formatters.outputLogFormatter);
return new Filter(fil, watches.eth(), formatter || formatters.outputLogFormatter);
};
/*jshint maxparams:3 */
var shhWatch = {
startPolling: startPolling.bind(null, 'shh_getFilterChanges'),
stopPolling: stopPolling
web3.shh = {};
web3.shh.filter = function (fil) {
return new Filter(fil, watches.shh(), formatters.outputPostFormatter);
};
/// setups web3 object, and it's in-browser executed methods
var web3 = {
version: {
api: version.version
},
manager: requestManager(),
providers: {},
setProvider: function (provider) {
web3.manager.setProvider(provider);
},
/// Should be called to reset state of web3 object
/// Resets everything except manager
reset: function () {
web3.manager.reset();
},
/// @returns hex string of the input
toHex: utils.toHex,
/// @returns ascii string representation of hex value prefixed with 0x
toAscii: utils.toAscii,
/// @returns hex representation (prefixed by 0x) of ascii string
fromAscii: utils.fromAscii,
/// @returns decimal representaton of hex value prefixed by 0x
toDecimal: utils.toDecimal,
/// @returns hex representation (prefixed by 0x) of decimal value
fromDecimal: utils.fromDecimal,
/// @returns a BigNumber object
toBigNumber: utils.toBigNumber,
toWei: utils.toWei,
fromWei: utils.fromWei,
isAddress: utils.isAddress,
// provide network information
net: {
// peerCount:
},
/// eth object prototype
eth: {
// DEPRECATED
contractFromAbi: function (abi) {
console.warn('Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead.');
return function(addr) {
// Default to address of Config. TODO: rremove prior to genesis.
addr = addr || '0xc6d9d2cd449a754c494264e1809c50e34d64562b';
var ret = web3.eth.contract(addr, abi);
ret.address = addr;
return ret;
};
},
/// @param filter may be a string, object or event
/// @param eventParams is optional, this is an object with optional event eventParams params
/// @param options is optional, this is an object with optional event options ('max'...)
/*jshint maxparams:4 */
filter: function (fil, eventParams, options) {
// if its event, treat it differently
if (fil._isEvent)
return fil(eventParams, options);
return filter(fil, ethWatch, formatters.outputLogFormatter);
},
// DEPRECATED
watch: function (fil, eventParams, options) {
console.warn('eth.watch() is deprecated please use eth.filter() instead.');
return this.filter(fil, eventParams, options);
}
/*jshint maxparams:3 */
},
/// db object prototype
db: {},
/// shh object prototype
shh: {
/// @param filter may be a string, object or event
filter: function (fil) {
return filter(fil, shhWatch, formatters.outputPostFormatter);
},
// DEPRECATED
watch: function (fil) {
console.warn('shh.watch() is deprecated please use shh.filter() instead.');
return this.filter(fil);
}
}
web3.net = {};
web3.db = {};
web3.setProvider = function (provider) {
RequestManager.getInstance().setProvider(provider);
};
web3.reset = function () {
RequestManager.getInstance().reset();
};
web3.toHex = utils.toHex;
web3.toAscii = utils.toAscii;
web3.fromAscii = utils.fromAscii;
web3.toDecimal = utils.toDecimal;
web3.fromDecimal = utils.fromDecimal;
web3.toBigNumber = utils.toBigNumber;
web3.toWei = utils.toWei;
web3.fromWei = utils.fromWei;
web3.isAddress = utils.isAddress;
// ADD defaultblock
Object.defineProperty(web3.eth, 'defaultBlock', {
@ -291,10 +147,8 @@ setupMethods(web3.net, net.methods);
setupProperties(web3.net, net.properties);
setupMethods(web3.eth, eth.methods);
setupProperties(web3.eth, eth.properties);
setupMethods(web3.db, db.methods());
setupMethods(web3.shh, shh.methods());
setupMethods(ethWatch, watches.eth());
setupMethods(shhWatch, watches.shh());
setupMethods(web3.db, db.methods);
setupMethods(web3.shh, shh.methods);
module.exports = web3;

47
libjsqrc/ethereumjs/lib/web3/contract.js

@ -26,15 +26,6 @@ var utils = require('../utils/utils');
var eventImpl = require('./event');
var signature = require('./signature');
var exportNatspecGlobals = function (vars) {
// it's used byt natspec.js
// TODO: figure out better way to solve this
web3._currentContractAbi = vars.abi;
web3._currentContractAddress = vars.address;
web3._currentContractMethodName = vars.method;
web3._currentContractMethodParams = vars.params;
};
var addFunctionRelatedPropertiesToContract = function (contract) {
contract.call = function (options) {
@ -43,28 +34,11 @@ var addFunctionRelatedPropertiesToContract = function (contract) {
return contract;
};
contract.sendTransaction = function (options) {
contract._isTransaction = true;
contract._options = options;
return contract;
};
// DEPRECATED
contract.transact = function (options) {
console.warn('myContract.transact() is deprecated please use myContract.sendTransaction() instead.');
return contract.sendTransaction(options);
};
contract._options = {};
['gas', 'gasPrice', 'value', 'from'].forEach(function(p) {
contract[p] = function (v) {
contract._options[p] = v;
return contract;
};
});
};
var addFunctionsToContract = function (contract, desc, address) {
@ -96,13 +70,6 @@ var addFunctionsToContract = function (contract, desc, address) {
if (isTransaction) {
exportNatspecGlobals({
abi: desc,
address: address,
method: method.name,
params: params
});
// transactions do not have any output, cause we do not know, when they will be processed
web3.eth.sendTransaction(options);
return;
@ -159,7 +126,7 @@ var addEventsToContract = function (contract, desc, address) {
var parser = eventImpl.outputParser(e);
return parser(data);
};
return web3.eth.filter(o, undefined, undefined, outputFormatter);
return web3.eth.filter(o, undefined, undefined, outputFormatter);
};
// this property should be used by eth.filter to check if object is an event
@ -203,17 +170,7 @@ var addEventsToContract = function (contract, desc, address) {
var contract = function (abi) {
// return prototype
if(abi instanceof Array && arguments.length === 1) {
return Contract.bind(null, abi);
// deprecated: auto initiate contract
} else {
console.warn('Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead.');
return new Contract(arguments[1], arguments[0]);
}
return Contract.bind(null, abi);
};
function Contract(abi, address) {

38
libjsqrc/ethereumjs/lib/web3/db.js

@ -20,16 +20,36 @@
* @date 2015
*/
var Method = require('./method');
/// @returns an array of objects describing web3.db api methods
var methods = function () {
return [
{ name: 'putString', call: 'db_putString'},
{ name: 'getString', call: 'db_getString'},
{ name: 'putHex', call: 'db_putHex'},
{ name: 'getHex', call: 'db_getHex'}
];
};
var putString = new Method({
name: 'putString',
call: 'db_putString',
params: 3
});
var getString = new Method({
name: 'getString',
call: 'db_getString',
params: 2
});
var putHex = new Method({
name: 'putHex',
call: 'db_putHex',
params: 3
});
var getHex = new Method({
name: 'getHex',
call: 'db_getHex',
params: 2
});
var methods = [
putString, getString, putHex, getHex
];
module.exports = {
methods: methods

38
libjsqrc/ethereumjs/lib/web3/errors.js

@ -0,0 +1,38 @@
/*
This file is part of ethereum.js.
ethereum.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethereum.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file errors.js
* @author Marek Kotewicz <marek@ethdev.com>
* @date 2015
*/
var utils = require('../utils/utils');
module.exports = {
InvalidNumberOfParams: new Error('Invalid number of input parameters'),
InvalidProvider: new Error('Providor not set or invalid'),
InvalidResponse: function(result){
var message = 'Invalid JSON RPC response';
if(utils.isObject(result) && result.error && result.error.message) {
message = result.error.message;
}
return new Error(message);
}
};

242
libjsqrc/ethereumjs/lib/web3/eth.js

@ -14,10 +14,10 @@
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file eth.js
* @authors:
* Marek Kotewicz <marek@ethdev.com>
* Fabian Vogelsteller <fabian@ethdev.com>
/**
* @file eth.js
* @author Marek Kotewicz <marek@ethdev.com>
* @author Fabian Vogelsteller <fabian@ethdev.com>
* @date 2015
*/
@ -35,10 +35,11 @@
* {
* name: 'getBlock',
* call: blockCall,
* params: 2,
* outputFormatter: formatters.outputBlockFormatter,
* inputFormatter: [ // can be a formatter funciton or an array of functions. Where each item in the array will be used for one parameter
* utils.toHex, // formats paramter 1
* function(param){ if(!param) return false; } // formats paramter 2
* function(param){ return !!param; } // formats paramter 2
* ]
* },
*
@ -46,10 +47,12 @@
* @constructor
*/
"use strict";
var formatters = require('./formatters');
var utils = require('../utils/utils');
var Method = require('./method');
var Property = require('./property');
var blockCall = function (args) {
return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? "eth_getBlockByHash" : "eth_getBlockByNumber";
@ -72,75 +75,178 @@ var uncleCountCall = function (args) {
};
/// @returns an array of objects describing web3.eth api methods
var getBalance = new Method({
name: 'getBalance',
call: 'eth_getBalance',
params: 2,
inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter],
outputFormatter: formatters.outputBigNumberFormatter
});
var getStorageAt = new Method({
name: 'getStorageAt',
call: 'eth_getStorageAt',
params: 3,
inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter]
});
var getCode = new Method({
name: 'getCode',
call: 'eth_getCode',
params: 2,
inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter]
});
var getBlock = new Method({
name: 'getBlock',
call: blockCall,
params: 2,
inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }],
outputFormatter: formatters.outputBlockFormatter
});
var getUncle = new Method({
name: 'getUncle',
call: uncleCall,
params: 3,
inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex, function (val) { return !!val; }],
outputFormatter: formatters.outputBlockFormatter,
});
var getCompilers = new Method({
name: 'getCompilers',
call: 'eth_getCompilers',
params: 0
});
var getBlockTransactionCount = new Method({
name: 'getBlockTransactionCount',
call: getBlockTransactionCountCall,
params: 1,
inputFormatter: [formatters.inputBlockNumberFormatter],
outputFormatter: utils.toDecimal
});
var getBlockUncleCount = new Method({
name: 'getBlockUncleCount',
call: uncleCountCall,
params: 1,
inputFormatter: [formatters.inputBlockNumberFormatter],
outputFormatter: utils.toDecimal
});
var getTransaction = new Method({
name: 'getTransaction',
call: 'eth_getTransactionByHash',
params: 1,
outputFormatter: formatters.outputTransactionFormatter
});
var getTransactionFromBlock = new Method({
name: 'getTransactionFromBlock',
call: transactionFromBlockCall,
params: 2,
inputFormatter: [utils.toHex, utils.toHex],
outputFormatter: formatters.outputTransactionFormatter
});
var getTransactionCount = new Method({
name: 'getTransactionCount',
call: 'eth_getTransactionCount',
params: 2,
inputFormatter: [null, formatters.inputDefaultBlockNumberFormatter],
outputFormatter: utils.toDecimal
});
var sendTransaction = new Method({
name: 'sendTransaction',
call: 'eth_sendTransaction',
params: 1,
inputFormatter: [formatters.inputTransactionFormatter]
});
var call = new Method({
name: 'call',
call: 'eth_call',
params: 2,
inputFormatter: [formatters.inputTransactionFormatter, formatters.inputDefaultBlockNumberFormatter]
});
var compileSolidity = new Method({
name: 'compile.solidity',
call: 'eth_compileSolidity',
params: 1
});
var compileLLL = new Method({
name: 'compile.lll',
call: 'eth_compileLLL',
params: 1
});
var compileSerpent = new Method({
name: 'compile.serpent',
call: 'eth_compileSerpent',
params: 1
});
var flush = new Method({
name: 'flush',
call: 'eth_flush',
params: 0
});
var methods = [
{ name: 'getBalance', call: 'eth_getBalance', addDefaultblock: 2,
outputFormatter: formatters.convertToBigNumber},
{ name: 'getStorageAt', call: 'eth_getStorageAt', addDefaultblock: 3,
inputFormatter: utils.toHex},
{ name: 'getCode', call: 'eth_getCode', addDefaultblock: 2},
{ name: 'getBlock', call: blockCall,
outputFormatter: formatters.outputBlockFormatter,
inputFormatter: [utils.toHex, function(param){ return (!param) ? false : true; }]},
{ name: 'getUncle', call: uncleCall,
outputFormatter: formatters.outputBlockFormatter,
inputFormatter: [utils.toHex, utils.toHex, function(param){ return (!param) ? false : true; }]},
{ name: 'getCompilers', call: 'eth_getCompilers' },
{ name: 'getBlockTransactionCount', call: getBlockTransactionCountCall,
outputFormatter: utils.toDecimal,
inputFormatter: utils.toHex },
{ name: 'getBlockUncleCount', call: uncleCountCall,
outputFormatter: utils.toDecimal,
inputFormatter: utils.toHex },
{ name: 'getTransaction', call: 'eth_getTransactionByHash',
outputFormatter: formatters.outputTransactionFormatter },
{ name: 'getTransactionFromBlock', call: transactionFromBlockCall,
outputFormatter: formatters.outputTransactionFormatter,
inputFormatter: utils.toHex },
{ name: 'getTransactionCount', call: 'eth_getTransactionCount', addDefaultblock: 2,
outputFormatter: utils.toDecimal},
{ name: 'sendTransaction', call: 'eth_sendTransaction',
inputFormatter: formatters.inputTransactionFormatter },
{ name: 'call', call: 'eth_call', addDefaultblock: 2,
inputFormatter: formatters.inputCallFormatter },
{ name: 'compile.solidity', call: 'eth_compileSolidity' },
{ name: 'compile.lll', call: 'eth_compileLLL', inputFormatter: utils.toHex },
{ name: 'compile.serpent', call: 'eth_compileSerpent', inputFormatter: utils.toHex },
{ name: 'flush', call: 'eth_flush' },
// deprecated methods
{ name: 'balanceAt', call: 'eth_balanceAt', newMethod: 'eth.getBalance' },
{ name: 'stateAt', call: 'eth_stateAt', newMethod: 'eth.getStorageAt' },
{ name: 'storageAt', call: 'eth_storageAt', newMethod: 'eth.getStorage' },
{ name: 'countAt', call: 'eth_countAt', newMethod: 'eth.getTransactionCount' },
{ name: 'codeAt', call: 'eth_codeAt', newMethod: 'eth.getCode' },
{ name: 'transact', call: 'eth_transact', newMethod: 'eth.sendTransaction' },
{ name: 'block', call: blockCall, newMethod: 'eth.getBlock' },
{ name: 'transaction', call: transactionFromBlockCall, newMethod: 'eth.getTransaction' },
{ name: 'uncle', call: uncleCall, newMethod: 'eth.getUncle' },
{ name: 'compilers', call: 'eth_compilers', newMethod: 'eth.getCompilers' },
{ name: 'solidity', call: 'eth_solidity', newMethod: 'eth.compile.solidity' },
{ name: 'lll', call: 'eth_lll', newMethod: 'eth.compile.lll' },
{ name: 'serpent', call: 'eth_serpent', newMethod: 'eth.compile.serpent' },
{ name: 'transactionCount', call: getBlockTransactionCountCall, newMethod: 'eth.getBlockTransactionCount' },
{ name: 'uncleCount', call: uncleCountCall, newMethod: 'eth.getBlockUncleCount' },
{ name: 'logs', call: 'eth_logs' }
getBalance,
getStorageAt,
getCode,
getBlock,
getUncle,
getCompilers,
getBlockTransactionCount,
getBlockUncleCount,
getTransaction,
getTransactionFromBlock,
getTransactionCount,
call,
sendTransaction,
compileSolidity,
compileLLL,
compileSerpent,
flush
];
/// @returns an array of objects describing web3.eth api properties
var properties = [
{ name: 'coinbase', getter: 'eth_coinbase'},
{ name: 'mining', getter: 'eth_mining'},
{ name: 'gasPrice', getter: 'eth_gasPrice', outputFormatter: formatters.convertToBigNumber},
{ name: 'accounts', getter: 'eth_accounts' },
{ name: 'blockNumber', getter: 'eth_blockNumber', outputFormatter: utils.toDecimal},
// deprecated properties
{ name: 'listening', getter: 'net_listening', setter: 'eth_setListening', newProperty: 'net.listening'},
{ name: 'peerCount', getter: 'net_peerCount', newProperty: 'net.peerCount'},
{ name: 'number', getter: 'eth_number', newProperty: 'eth.blockNumber'}
new Property({
name: 'coinbase',
getter: 'eth_coinbase'
}),
new Property({
name: 'mining',
getter: 'eth_mining'
}),
new Property({
name: 'gasPrice',
getter: 'eth_gasPrice',
outputFormatter: formatters.inputNumberFormatter
}),
new Property({
name: 'accounts',
getter: 'eth_accounts'
}),
new Property({
name: 'blockNumber',
getter: 'eth_blockNumber',
outputFormatter: utils.toDecimal
})
];
module.exports = {
methods: methods,
properties: properties

4
libjsqrc/ethereumjs/lib/web3/event.js

@ -57,7 +57,7 @@ var indexedParamsToTopics = function (event, indexed) {
return abi.formatInput(inputs, [v]);
});
}
return abi.formatInput(inputs, [value]);
return '0x' + abi.formatInput(inputs, [value]);
});
};
@ -101,10 +101,10 @@ var outputParser = function (event) {
args: {}
};
output.topics = output.topic; // fallback for go-ethereum
if (!output.topics) {
return result;
}
output.data = output.data || '';
var indexedOutputs = filterInputs(event.inputs, true);
var indexedData = "0x" + output.topics.slice(1, output.topics.length).map(function (topics) { return topics.slice(2); }).join("");

171
libjsqrc/ethereumjs/lib/web3/filter.js

@ -24,148 +24,87 @@
* @date 2014
*/
var RequestManager = require('./requestmanager');
var formatters = require('./formatters');
var utils = require('../utils/utils');
/// Should be called to check if filter implementation is valid
/// @returns true if it is, otherwise false
var implementationIsValid = function (i) {
return !!i &&
typeof i.newFilter === 'function' &&
typeof i.getLogs === 'function' &&
typeof i.uninstallFilter === 'function' &&
typeof i.startPolling === 'function' &&
typeof i.stopPolling === 'function';
};
/// This method should be called on options object, to verify deprecated properties && lazy load dynamic ones
/// @param should be string or object
/// @returns options string or object
var getOptions = function (options) {
/*jshint maxcomplexity:9 */
if (typeof options === 'string') {
if (utils.isString(options)) {
return options;
}
options = options || {};
if (options.topic) {
console.warn('"topic" is deprecated, is "topics" instead');
options.topics = options.topic;
}
if (options.earliest) {
console.warn('"earliest" is deprecated, is "fromBlock" instead');
options.fromBlock = options.earliest;
}
if (options.latest) {
console.warn('"latest" is deprecated, is "toBlock" instead');
options.toBlock = options.latest;
}
// make sure topics, get converted to hex
if(options.topics instanceof Array) {
options.topics = options.topics.map(function(topic){
return utils.toHex(topic);
});
}
options.topics = options.topics || [];
options.topics = options.topics.map(function(topic){
return utils.toHex(topic);
});
var asBlockNumber = function(n) {
if (n == null)
return null;
if (n == 'latest' || n == 'pending')
return n;
return utils.toHex(n);
};
// evaluate lazy properties
// lazy load
return {
fromBlock: asBlockNumber(options.fromBlock),
toBlock: asBlockNumber(options.toBlock),
topics: options.topics,
to: options.to,
address: options.address,
topics: options.topics
};
fromBlock: formatters.inputBlockNumberFormatter(options.fromBlock),
toBlock: formatters.inputBlockNumberFormatter(options.toBlock)
};
};
var Filter = function (options, methods, formatter) {
var implementation = {};
methods.forEach(function (method) {
method.attachToObject(implementation);
});
this.options = getOptions(options);
this.implementation = implementation;
this.callbacks = [];
this.formatter = formatter;
this.filterId = this.implementation.newFilter(this.options);
};
/// Should be used when we want to watch something
/// it's using inner polling mechanism and is notified about changes
/// @param options are filter options
/// @param implementation, an abstract polling implementation
/// @param formatter (optional), callback function which formats output before 'real' callback
var filter = function(options, implementation, formatter) {
if (!implementationIsValid(implementation)) {
console.error('filter implemenation is invalid');
return;
}
options = getOptions(options);
var callbacks = [];
var filterId = implementation.newFilter(options);
// call the callbacks
var onMessages = function (messages) {
Filter.prototype.watch = function (callback) {
this.callbacks.push(callback);
var self = this;
var onMessage = function (error, messages) {
if (error) {
return self.callbacks.forEach(function (callback) {
callback(error);
});
}
messages.forEach(function (message) {
message = formatter ? formatter(message) : message;
callbacks.forEach(function (callback) {
callback(message);
message = self.formatter ? self.formatter(message) : message;
self.callbacks.forEach(function (callback) {
callback(null, message);
});
});
};
implementation.startPolling(filterId, onMessages, implementation.uninstallFilter);
var watch = function(callback) {
callbacks.push(callback);
};
var stopWatching = function() {
implementation.stopPolling(filterId);
implementation.uninstallFilter(filterId);
callbacks = [];
};
RequestManager.getInstance().startPolling({
method: this.implementation.poll.call,
params: [this.filterId],
}, this.filterId, onMessage, this.stopWatching.bind(this));
};
var get = function () {
var results = implementation.getLogs(filterId);
Filter.prototype.stopWatching = function () {
RequestManager.getInstance().stopPolling(this.filterId);
this.implementation.uninstallFilter(this.filterId);
this.callbacks = [];
};
return utils.isArray(results) ? results.map(function(message){
return formatter ? formatter(message) : message;
}) : results;
};
return {
watch: watch,
stopWatching: stopWatching,
get: get,
// DEPRECATED methods
changed: function(){
console.warn('watch().changed() is deprecated please use filter().watch() instead.');
return watch.apply(this, arguments);
},
arrived: function(){
console.warn('watch().arrived() is deprecated please use filter().watch() instead.');
return watch.apply(this, arguments);
},
happened: function(){
console.warn('watch().happened() is deprecated please use filter().watch() instead.');
return watch.apply(this, arguments);
},
uninstall: function(){
console.warn('watch().uninstall() is deprecated please use filter().stopWatching() instead.');
return stopWatching.apply(this, arguments);
},
messages: function(){
console.warn('watch().messages() is deprecated please use filter().get() instead.');
return get.apply(this, arguments);
},
logs: function(){
console.warn('watch().logs() is deprecated please use filter().get() instead.');
return get.apply(this, arguments);
}
};
Filter.prototype.get = function () {
var logs = this.implementation.getLogs(this.filterId);
var self = this;
return logs.map(function (log) {
return self.formatter ? self.formatter(log) : log;
});
};
module.exports = filter;
module.exports = Filter;

96
libjsqrc/ethereumjs/lib/web3/formatters.js

@ -14,24 +14,45 @@
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file formatters.js
* @authors:
* Marek Kotewicz <marek@ethdev.com>
* Fabian Vogelsteller <fabian@ethdev.com>
/**
* @file formatters.js
* @author Marek Kotewicz <marek@ethdev.com>
* @author Fabian Vogelsteller <fabian@ethdev.com>
* @date 2015
*/
var utils = require('../utils/utils');
var config = require('../utils/config');
/**
* Should the input to a big number
* Should the format output to a big number
*
* @method convertToBigNumber
* @method outputBigNumberFormatter
* @param {String|Number|BigNumber}
* @returns {BigNumber} object
*/
var convertToBigNumber = function (value) {
return utils.toBigNumber(value);
var outputBigNumberFormatter = function (number) {
return utils.toBigNumber(number);
};
var isPredefinedBlockNumber = function (blockNumber) {
return blockNumber === 'latest' || blockNumber === 'pending' || blockNumber === 'earliest';
};
var inputDefaultBlockNumberFormatter = function (blockNumber) {
if (blockNumber === undefined) {
return config.ETH_DEFAULTBLOCK;
}
return inputBlockNumberFormatter(blockNumber);
};
var inputBlockNumberFormatter = function (blockNumber) {
if (blockNumber === undefined) {
return undefined;
} else if (isPredefinedBlockNumber(blockNumber)) {
return blockNumber;
}
return utils.toHex(blockNumber);
};
/**
@ -49,11 +70,13 @@ var inputTransactionFormatter = function (options){
delete options.code;
}
['gasPrice', 'gas', 'value'].forEach(function(key){
['gasPrice', 'gas', 'value'].filter(function (key) {
return options[key] !== undefined;
}).forEach(function(key){
options[key] = utils.fromDecimal(options[key]);
});
return options;
return options;
};
/**
@ -64,31 +87,14 @@ var inputTransactionFormatter = function (options){
* @returns {Object} transaction
*/
var outputTransactionFormatter = function (tx){
tx.blockNumber = utils.toDecimal(tx.blockNumber);
tx.transactionIndex = utils.toDecimal(tx.transactionIndex);
tx.gas = utils.toDecimal(tx.gas);
tx.gasPrice = utils.toBigNumber(tx.gasPrice);
tx.value = utils.toBigNumber(tx.value);
return tx;
};
/**
* Formats the input of a call and converts all values to HEX
*
* @method inputCallFormatter
* @param {Object} transaction options
* @returns object
*/
var inputCallFormatter = function (options){
// make code -> data
if (options.code) {
options.data = options.code;
delete options.code;
}
return options;
};
/**
* Formats the output of a block to its proper values
*
@ -96,7 +102,7 @@ var inputCallFormatter = function (options){
* @param {Object} block object
* @returns {Object} block object
*/
var outputBlockFormatter = function(block){
var outputBlockFormatter = function(block) {
// transform to number
block.gasLimit = utils.toDecimal(block.gasLimit);
@ -109,7 +115,7 @@ var outputBlockFormatter = function(block){
block.difficulty = utils.toBigNumber(block.difficulty);
block.totalDifficulty = utils.toBigNumber(block.totalDifficulty);
if(block.transactions instanceof Array) {
if (utils.isArray(block.transactions)) {
block.transactions.forEach(function(item){
if(!utils.isString(item))
return outputTransactionFormatter(item);
@ -126,7 +132,11 @@ var outputBlockFormatter = function(block){
* @param {Object} log object
* @returns {Object} log
*/
var outputLogFormatter = function(log){
var outputLogFormatter = function(log) {
if (log === null) { // 'pending' && 'latest' filters are nulls
return null;
}
log.blockNumber = utils.toDecimal(log.blockNumber);
log.transactionIndex = utils.toDecimal(log.transactionIndex);
log.logIndex = utils.toDecimal(log.logIndex);
@ -134,7 +144,6 @@ var outputLogFormatter = function(log){
return log;
};
/**
* Formats the input of a whisper post and converts all values to HEX
*
@ -142,22 +151,22 @@ var outputLogFormatter = function(log){
* @param {Object} transaction object
* @returns {Object}
*/
var inputPostFormatter = function(post){
var inputPostFormatter = function(post) {
post.payload = utils.toHex(post.payload);
post.ttl = utils.fromDecimal(post.ttl);
post.priority = utils.fromDecimal(post.priority);
if(!(post.topics instanceof Array))
if(!utils.isArray(post.topics)) {
post.topics = [post.topics];
}
// format the following options
post.topics = post.topics.map(function(topic){
return utils.fromAscii(topic);
});
return post;
return post;
};
/**
@ -176,10 +185,8 @@ var outputPostFormatter = function(post){
post.payloadRaw = post.payload;
post.payload = utils.toAscii(post.payload);
if(post.payload.indexOf('{') === 0 || post.payload.indexOf('[') === 0) {
try {
post.payload = JSON.parse(post.payload);
} catch (e) { }
if (utils.isJson(post.payload)) {
post.payload = JSON.parse(post.payload);
}
// format the following options
@ -191,13 +198,14 @@ var outputPostFormatter = function(post){
};
module.exports = {
convertToBigNumber: convertToBigNumber,
inputDefaultBlockNumberFormatter: inputDefaultBlockNumberFormatter,
inputBlockNumberFormatter: inputBlockNumberFormatter,
inputTransactionFormatter: inputTransactionFormatter,
inputPostFormatter: inputPostFormatter,
outputBigNumberFormatter: outputBigNumberFormatter,
outputTransactionFormatter: outputTransactionFormatter,
inputCallFormatter: inputCallFormatter,
outputBlockFormatter: outputBlockFormatter,
outputLogFormatter: outputLogFormatter,
inputPostFormatter: inputPostFormatter,
outputPostFormatter: outputPostFormatter
};

56
libjsqrc/ethereumjs/lib/web3/httpprovider.js

@ -22,47 +22,39 @@
* @date 2014
*/
if (process.env.NODE_ENV !== 'build') {
var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line
}
"use strict";
var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line
var HttpProvider = function (host) {
this.name = 'HTTP';
this.handlers = [];
this.host = host || 'http://localhost:8080';
};
HttpProvider.prototype.send = function (payload, callback) {
HttpProvider.prototype.send = function (payload) {
var request = new XMLHttpRequest();
// ASYNC
if(typeof callback === 'function') {
request.onreadystatechange = function() {
if(request.readyState === 4) {
var result = '';
try {
result = JSON.parse(request.responseText);
} catch(error) {
result = error;
}
callback(result, request.status);
}
};
request.open('POST', this.host, true);
request.send(JSON.stringify(payload));
request.open('POST', this.host, false);
request.send(JSON.stringify(payload));
// SYNC
} else {
request.open('POST', this.host, false);
request.send(JSON.stringify(payload));
// check request.status
// TODO: throw an error here! it cannot silently fail!!!
//if (request.status !== 200) {
//return;
//}
return JSON.parse(request.responseText);
};
// check request.status
if(request.status !== 200)
return;
return JSON.parse(request.responseText);
}
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));
}
};
request.open('POST', this.host, true);
request.send(JSON.stringify(payload));
};
module.exports = HttpProvider;

70
libjsqrc/ethereumjs/lib/web3/jsonrpc.js

@ -20,13 +20,33 @@
* @date 2015
*/
var messageId = 1;
var Jsonrpc = function () {
// singleton pattern
if (arguments.callee._singletonInstance) {
return arguments.callee._singletonInstance;
}
arguments.callee._singletonInstance = this;
/// Should be called to valid json create payload object
/// @param method of jsonrpc call, required
/// @param params, an array of method params, optional
/// @returns valid jsonrpc payload object
var toPayload = function (method, params) {
this.messageId = 1;
};
/**
* @return {Jsonrpc} singleton
*/
Jsonrpc.getInstance = function () {
var instance = new Jsonrpc();
return instance;
};
/**
* Should be called to valid json create payload object
*
* @method toPayload
* @param {Function} method of jsonrpc call, required
* @param {Array} params, an array of method params, optional
* @returns {Object} valid jsonrpc payload object
*/
Jsonrpc.prototype.toPayload = function (method, params) {
if (!method)
console.error('jsonrpc method should be specified!');
@ -34,13 +54,18 @@ var toPayload = function (method, params) {
jsonrpc: '2.0',
method: method,
params: params || [],
id: messageId++
};
id: this.messageId++
};
};
/// Should be called to check if jsonrpc response is valid
/// @returns true if response is valid, otherwise false
var isValidResponse = function (response) {
/**
* Should be called to check if jsonrpc response is valid
*
* @method isValidResponse
* @param {Object}
* @returns {Boolean} true if response is valid, otherwise false
*/
Jsonrpc.prototype.isValidResponse = function (response) {
return !!response &&
!response.error &&
response.jsonrpc === '2.0' &&
@ -48,18 +73,19 @@ var isValidResponse = function (response) {
response.result !== undefined; // only undefined is not valid json object
};
/// Should be called to create batch payload object
/// @param messages, an array of objects with method (required) and params (optional) fields
var toBatchPayload = function (messages) {
/**
* Should be called to create batch payload object
*
* @method toBatchPayload
* @param {Array} messages, an array of objects with method (required) and params (optional) fields
* @returns {Array} batch payload
*/
Jsonrpc.prototype.toBatchPayload = function (messages) {
var self = this;
return messages.map(function (message) {
return toPayload(message.method, message.params);
});
};
module.exports = {
toPayload: toPayload,
isValidResponse: isValidResponse,
toBatchPayload: toBatchPayload
return self.toPayload(message.method, message.params);
});
};
module.exports = Jsonrpc;

159
libjsqrc/ethereumjs/lib/web3/method.js

@ -0,0 +1,159 @@
/*
This file is part of ethereum.js.
ethereum.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethereum.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file method.js
* @author Marek Kotewicz <marek@ethdev.com>
* @date 2015
*/
var RequestManager = require('./requestmanager');
var utils = require('../utils/utils');
var errors = require('./errors');
var Method = function (options) {
this.name = options.name;
this.call = options.call;
this.params = options.params || 0;
this.inputFormatter = options.inputFormatter;
this.outputFormatter = options.outputFormatter;
};
/**
* Should be used to determine name of the jsonrpc method based on arguments
*
* @method getCall
* @param {Array} arguments
* @return {String} name of jsonrpc method
*/
Method.prototype.getCall = function (args) {
return utils.isFunction(this.call) ? this.call(args) : this.call;
};
/**
* Should be used to extract callback from array of arguments. Modifies input param
*
* @method extractCallback
* @param {Array} arguments
* @return {Function|Null} callback, if exists
*/
Method.prototype.extractCallback = function (args) {
if (utils.isFunction(args[args.length - 1])) {
return args.pop(); // modify the args array!
}
return null;
};
/**
* Should be called to check if the number of arguments is correct
*
* @method validateArgs
* @param {Array} arguments
* @throws {Error} if it is not
*/
Method.prototype.validateArgs = function (args) {
if (args.length !== this.params) {
throw errors.InvalidNumberOfParams;
}
};
/**
* Should be called to format input args of method
*
* @method formatInput
* @param {Array}
* @return {Array}
*/
Method.prototype.formatInput = function (args) {
if (!this.inputFormatter) {
return args;
}
return this.inputFormatter.map(function (formatter, index) {
return formatter ? formatter(args[index]) : args[index];
});
};
/**
* Should be called to format output(result) of method
*
* @method formatOutput
* @param {Object}
* @return {Object}
*/
Method.prototype.formatOutput = function (result) {
return this.outputFormatter && result !== null ? this.outputFormatter(result) : result;
};
/**
* Should attach function to method
*
* @method attachToObject
* @param {Object}
* @param {Function}
*/
Method.prototype.attachToObject = function (obj) {
var func = this.send.bind(this);
func.call = this.call; // that's ugly. filter.js uses it
var name = this.name.split('.');
if (name.length > 1) {
obj[name[0]] = obj[name[0]] || {};
obj[name[0]][name[1]] = func;
} else {
obj[name[0]] = func;
}
};
/**
* Should create payload from given input args
*
* @method toPayload
* @param {Array} args
* @return {Object}
*/
Method.prototype.toPayload = function (args) {
var call = this.getCall(args);
var callback = this.extractCallback(args);
var params = this.formatInput(args);
this.validateArgs(params);
return {
method: call,
params: params,
callback: callback
};
};
/**
* Should send request to the API
*
* @method send
* @param list of params
* @return result
*/
Method.prototype.send = function () {
var payload = this.toPayload(Array.prototype.slice.call(arguments));
if (payload.callback) {
var self = this;
return RequestManager.getInstance().sendAsync(payload, function (err, result) {
payload.callback(null, self.formatOutput(result));
});
}
return this.formatOutput(RequestManager.getInstance().send(payload));
};
module.exports = Method;

13
libjsqrc/ethereumjs/lib/web3/net.js

@ -21,16 +21,23 @@
*/
var utils = require('../utils/utils');
var Property = require('./property');
/// @returns an array of objects describing web3.eth api methods
var methods = [
// { name: 'getBalance', call: 'eth_balanceAt', outputFormatter: formatters.convertToBigNumber},
];
/// @returns an array of objects describing web3.eth api properties
var properties = [
{ name: 'listening', getter: 'net_listening'},
{ name: 'peerCount', getter: 'net_peerCount', outputFormatter: utils.toDecimal },
new Property({
name: 'listening',
getter: 'net_listening'
}),
new Property({
name: 'peerCount',
getter: 'net_peerCount',
outputFormatter: utils.toDecimal
})
];

104
libjsqrc/ethereumjs/lib/web3/property.js

@ -0,0 +1,104 @@
/*
This file is part of ethereum.js.
ethereum.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethereum.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file property.js
* @author Fabian Vogelsteller <fabian@frozeman.de>
* @author Marek Kotewicz <marek@ethdev.com>
* @date 2015
*/
var RequestManager = require('./requestmanager');
var Property = function (options) {
this.name = options.name;
this.getter = options.getter;
this.setter = options.setter;
this.outputFormatter = options.outputFormatter;
this.inputFormatter = options.inputFormatter;
};
/**
* Should be called to format input args of method
*
* @method formatInput
* @param {Array}
* @return {Array}
*/
Property.prototype.formatInput = function (arg) {
return this.inputFormatter ? this.inputFormatter(arg) : arg;
};
/**
* Should be called to format output(result) of method
*
* @method formatOutput
* @param {Object}
* @return {Object}
*/
Property.prototype.formatOutput = function (result) {
return this.outputFormatter && result !== null ? this.outputFormatter(result) : result;
};
/**
* Should attach function to method
*
* @method attachToObject
* @param {Object}
* @param {Function}
*/
Property.prototype.attachToObject = function (obj) {
var proto = {
get: this.get.bind(this),
set: this.set.bind(this)
};
var name = this.name.split('.');
if (name.length > 1) {
obj[name[0]] = obj[name[0]] || {};
Object.defineProperty(obj[name[0]], name[1], proto);
} else {
Object.defineProperty(obj, name[0], proto);
}
};
/**
* Should be used to get value of the property
*
* @method get
* @return {Object} value of the property
*/
Property.prototype.get = function () {
return this.formatOutput(RequestManager.getInstance().send({
method: this.getter
}));
};
/**
* Should be used to set value of the property
*
* @method set
* @param {Object} new value of the property
*/
Property.prototype.set = function (value) {
return RequestManager.getInstance().send({
method: this.setter,
params: [this.formatInput(value)]
});
};
module.exports = Property;

300
libjsqrc/ethereumjs/lib/web3/requestmanager.js

@ -14,148 +14,206 @@
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file requestmanager.js
* @authors:
* Jeffrey Wilcke <jeff@ethdev.com>
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
* Fabian Vogelsteller <fabian@ethdev.com>
* Gav Wood <g@ethdev.com>
/**
* @file requestmanager.js
* @author Jeffrey Wilcke <jeff@ethdev.com>
* @author Marek Kotewicz <marek@ethdev.com>
* @author Marian Oancea <marian@ethdev.com>
* @author Fabian Vogelsteller <fabian@ethdev.com>
* @author Gav Wood <g@ethdev.com>
* @date 2014
*/
var jsonrpc = require('./jsonrpc');
var Jsonrpc = require('./jsonrpc');
var utils = require('../utils/utils');
var c = require('../utils/config');
var errors = require('./errors');
/**
* It's responsible for passing messages to providers
* It's also responsible for polling the ethereum node for incoming messages
* Default poll timeout is 1 second
* Singleton
*/
var requestManager = function() {
var polls = [];
var timeout = null;
var provider;
var send = function (data, callback) {
/*jshint maxcomplexity: 8 */
// FORMAT BASED ON ONE FORMATTER function
if(typeof data.inputFormatter === 'function') {
data.params = Array.prototype.map.call(data.params, function(item, index){
// format everything besides the defaultblock, which is already formated
return (!data.addDefaultblock || index+1 < data.addDefaultblock) ? data.inputFormatter(item) : item;
});
// FORMAT BASED ON the input FORMATTER ARRAY
} else if(data.inputFormatter instanceof Array) {
data.params = Array.prototype.map.call(data.inputFormatter, function(formatter, index){
// format everything besides the defaultblock, which is already formated
return (!data.addDefaultblock || index+1 < data.addDefaultblock) ? formatter(data.params[index]) : data.params[index];
});
}
var RequestManager = function (provider) {
// singleton pattern
if (arguments.callee._singletonInstance) {
return arguments.callee._singletonInstance;
}
arguments.callee._singletonInstance = this;
this.provider = provider;
this.polls = [];
this.timeout = null;
this.poll();
};
/**
* @return {RequestManager} singleton
*/
RequestManager.getInstance = function () {
var instance = new RequestManager();
return instance;
};
var payload = jsonrpc.toPayload(data.method, data.params);
if (!provider) {
console.error('provider is not set');
return null;
}
/**
* Should be used to synchronously send request
*
* @method send
* @param {Object} data
* @return {Object}
*/
RequestManager.prototype.send = function (data) {
if (!this.provider) {
console.error(errors.InvalidProvider);
return null;
}
// HTTP ASYNC (only when callback is given, and it a HttpProvidor)
if(typeof callback === 'function' && provider.name === 'HTTP'){
provider.send(payload, function(result, status){
if (!jsonrpc.isValidResponse(result)) {
if(typeof result === 'object' && result.error && result.error.message) {
console.error(result.error.message);
callback(result.error);
} else {
callback(new Error({
status: status,
error: result,
message: 'Bad Request'
}));
}
return null;
}
// format the output
callback(null, (typeof data.outputFormatter === 'function') ? data.outputFormatter(result.result) : result.result);
});
// SYNC
} else {
var result = provider.send(payload);
if (!jsonrpc.isValidResponse(result)) {
if(typeof result === 'object' && result.error && result.error.message)
console.error(result.error.message);
return null;
}
var payload = Jsonrpc.getInstance().toPayload(data.method, data.params);
var result = this.provider.send(payload);
if (!Jsonrpc.getInstance().isValidResponse(result)) {
throw errors.InvalidResponse(result);
}
// format the output
return (typeof data.outputFormatter === 'function') ? data.outputFormatter(result.result) : result.result;
return result.result;
};
/**
* Should be used to asynchronously send request
*
* @method sendAsync
* @param {Object} data
* @param {Function} callback
*/
RequestManager.prototype.sendAsync = function (data, callback) {
if (!this.provider) {
return callback(errors.InvalidProvider);
}
var payload = Jsonrpc.getInstance().toPayload(data.method, data.params);
this.provider.sendAsync(payload, function (err, result) {
if (err) {
return callback(err);
}
};
var setProvider = function (p) {
provider = p;
};
/*jshint maxparams:4 */
var startPolling = function (data, pollId, callback, uninstall) {
polls.push({data: data, id: pollId, callback: callback, uninstall: uninstall});
};
/*jshint maxparams:3 */
var stopPolling = function (pollId) {
for (var i = polls.length; i--;) {
var poll = polls[i];
if (poll.id === pollId) {
polls.splice(i, 1);
}
if (!Jsonrpc.getInstance().isValidResponse(result)) {
return callback(errors.InvalidResponse(result));
}
};
var reset = function () {
polls.forEach(function (poll) {
poll.uninstall(poll.id);
});
polls = [];
callback(null, result.result);
});
};
if (timeout) {
clearTimeout(timeout);
timeout = null;
/**
* Should be used to set provider of request manager
*
* @method setProvider
* @param {Object}
*/
RequestManager.prototype.setProvider = function (p) {
this.provider = p;
};
/*jshint maxparams:4 */
/**
* Should be used to start polling
*
* @method startPolling
* @param {Object} data
* @param {Number} pollId
* @param {Function} callback
* @param {Function} uninstall
*
* @todo cleanup number of params
*/
RequestManager.prototype.startPolling = function (data, pollId, callback, uninstall) {
this.polls.push({data: data, id: pollId, callback: callback, uninstall: uninstall});
};
/*jshint maxparams:3 */
/**
* Should be used to stop polling for filter with given id
*
* @method stopPolling
* @param {Number} pollId
*/
RequestManager.prototype.stopPolling = function (pollId) {
for (var i = this.polls.length; i--;) {
var poll = this.polls[i];
if (poll.id === pollId) {
this.polls.splice(i, 1);
}
}
};
/**
* Should be called to reset polling mechanism of request manager
*
* @method reset
*/
RequestManager.prototype.reset = function () {
this.polls.forEach(function (poll) {
poll.uninstall(poll.id);
});
this.polls = [];
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = null;
}
this.poll();
};
/**
* Should be called to poll for changes on filter with given id
*
* @method poll
*/
RequestManager.prototype.poll = function () {
this.timeout = setTimeout(this.poll.bind(this), c.ETH_POLLING_TIMEOUT);
if (!this.polls.length) {
return;
}
if (!this.provider) {
console.error(errors.InvalidProvider);
return;
}
var payload = Jsonrpc.getInstance().toBatchPayload(this.polls.map(function (data) {
return data.data;
}));
var self = this;
this.provider.sendAsync(payload, function (error, results) {
// TODO: console log?
if (error) {
return;
}
if (!utils.isArray(results)) {
throw errors.InvalidResponse(results);
}
poll();
};
var poll = function () {
polls.forEach(function (data) {
// send async
send(data.data, function(error, result){
if (!(result instanceof Array) || result.length === 0) {
return;
}
data.callback(result);
});
results.map(function (result, index) {
result.callback = self.polls[index].callback;
return result;
}).filter(function (result) {
var valid = Jsonrpc.getInstance().isValidResponse(result);
if (!valid) {
result.callback(errors.InvalidResponse(result));
}
return valid;
}).filter(function (result) {
return utils.isArray(result.result) && result.result.length > 0;
}).forEach(function (result) {
result.callback(null, result.result);
});
timeout = setTimeout(poll, c.ETH_POLLING_TIMEOUT);
};
poll();
return {
send: send,
setProvider: setProvider,
startPolling: startPolling,
stopPolling: stopPolling,
reset: reset
};
});
};
module.exports = requestManager;
module.exports = RequestManager;

52
libjsqrc/ethereumjs/lib/web3/shh.js

@ -20,21 +20,47 @@
* @date 2015
*/
var Method = require('./method');
var formatters = require('./formatters');
/// @returns an array of objects describing web3.shh api methods
var methods = function () {
return [
{ name: 'post', call: 'shh_post', inputFormatter: formatters.inputPostFormatter },
{ name: 'newIdentity', call: 'shh_newIdentity' },
{ name: 'hasIdentity', call: 'shh_hasIdentity' },
{ name: 'newGroup', call: 'shh_newGroup' },
{ name: 'addToGroup', call: 'shh_addToGroup' },
// deprecated
{ name: 'haveIdentity', call: 'shh_haveIdentity', newMethod: 'shh.hasIdentity' },
];
};
var post = new Method({
name: 'post',
call: 'shh_post',
params: 1,
inputFormatter: formatters.inputPostFormatter
});
var newIdentity = new Method({
name: 'newIdentity',
call: 'shh_newIdentity',
params: 0
});
var hasIdentity = new Method({
name: 'hasIdentity',
call: 'shh_hasIdentity',
params: 1
});
var newGroup = new Method({
name: 'newGroup',
call: 'shh_newGroup',
params: 0
});
var addToGroup = new Method({
name: 'addToGroup',
call: 'shh_addToGroup',
params: 0
});
var methods = [
post,
newIdentity,
hasIdentity,
newGroup,
addToGroup
];
module.exports = {
methods: methods

66
libjsqrc/ethereumjs/lib/web3/watches.js

@ -20,25 +20,77 @@
* @date 2015
*/
var Method = require('./method');
/// @returns an array of objects describing web3.eth.filter api methods
var eth = function () {
var newFilter = function (args) {
var newFilterCall = function (args) {
return typeof args[0] === 'string' ? 'eth_newBlockFilter' : 'eth_newFilter';
};
var newFilter = new Method({
name: 'newFilter',
call: newFilterCall,
params: 1
});
var uninstallFilter = new Method({
name: 'uninstallFilter',
call: 'eth_uninstallFilter',
params: 1
});
var getLogs = new Method({
name: 'getLogs',
call: 'eth_getFilterLogs',
params: 1
});
var poll = new Method({
name: 'poll',
call: 'eth_getFilterChanges',
params: 1
});
return [
{ name: 'newFilter', call: newFilter },
{ name: 'uninstallFilter', call: 'eth_uninstallFilter' },
{ name: 'getLogs', call: 'eth_getFilterLogs' }
newFilter,
uninstallFilter,
getLogs,
poll
];
};
/// @returns an array of objects describing web3.shh.watch api methods
var shh = function () {
var newFilter = new Method({
name: 'newFilter',
call: 'shh_newFilter',
params: 1
});
var uninstallFilter = new Method({
name: 'uninstallFilter',
call: 'shh_uninstallFilter',
params: 1
});
var getLogs = new Method({
name: 'getLogs',
call: 'shh_getMessages',
params: 1
});
var poll = new Method({
name: 'poll',
call: 'shh_getFilterChanges',
params: 1
});
return [
{ name: 'newFilter', call: 'shh_newFilter' },
{ name: 'uninstallFilter', call: 'shh_uninstallFilter' },
{ name: 'getLogs', call: 'shh_getMessages' }
newFilter,
uninstallFilter,
getLogs,
poll
];
};

3
libjsqrc/ethereumjs/package-init.js

@ -1,7 +1,8 @@
/* jshint ignore:start */
if(typeof web3 === 'undefined') {
web3 = require('web3');
web3 = require('ethereum.js');
BigNumber = require('bignumber.js');
}
/* jshint ignore:end */

8
libjsqrc/ethereumjs/package.js

@ -1,7 +1,7 @@
/* jshint ignore:start */
Package.describe({
name: 'ethereum:js',
version: '0.1.3',
version: '0.2.5',
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.
@ -12,10 +12,10 @@ Package.describe({
Package.onUse(function(api) {
api.versionsFrom('1.0.3.2');
api.use('3stack:bignumber@2.0.0', 'client');
// api.use('3stack:bignumber@2.0.0', 'client');
api.export('BigNumber', 'client');
api.export('web3', 'client');
// api.export('BigNumber', 'client');
api.export(['web3', 'BigNumber'], 'client');
api.addFiles('dist/ethereum.js', 'client');
api.addFiles('package-init.js', 'client');

30
libjsqrc/ethereumjs/package.json

@ -1,18 +1,19 @@
{
"name": "ethereum.js",
"name": "web3",
"namespace": "ethereum",
"version": "0.1.3",
"description": "Ethereum JavaScript API, middleware to talk to a ethreum node over RPC",
"version": "0.2.5",
"description": "Ethereum JavaScript API, middleware to talk to a ethereum node over RPC",
"main": "./index.js",
"directories": {
"lib": "./lib"
},
"dependencies": {
"bignumber.js": ">=2.0.0",
"envify": "^3.0.0",
"unreachable-branch-transform": "^0.1.0",
"xmlhttprequest": "*"
},
"browser": {
"xmlhttprequest": "./lib/utils/browser-xhr.js"
},
"devDependencies": {
"bower": ">=1.3.0",
"browserify": ">=6.0",
@ -35,6 +36,7 @@
"karma-mocha": "^0.1.10",
"karma-safari-launcher": "^0.1.1",
"mocha": ">=2.1.0",
"sandboxed-module": "^2.0.0",
"vinyl-source-stream": "^1.0.0"
},
"scripts": {
@ -53,19 +55,6 @@
"bugs": {
"url": "https://github.com/ethereum/ethereum.js/issues"
},
"browserify": {
"transform": [
[
"envify",
{
"NODE_ENV": "build"
}
],
[
"unreachable-branch-transform"
]
]
},
"keywords": [
"ethereum",
"javascript",
@ -92,6 +81,11 @@
"name": "Fabian Vogelsteller",
"email": "fabian@frozeman.de",
"homepage": "http://frozeman.de"
},
{
"name": "Gav Wood",
"email": "g@ethdev.com",
"homepage": "http://gavwood.com"
}
],
"license": "LGPL-3.0"

2
libjsqrc/ethereumjs/test/abi.inputParser.js

@ -19,7 +19,7 @@ var description = [{
]
}];
describe('abi', function() {
describe('lib/solidity/abi', function() {
describe('inputParser', function() {
it('should parse input uint', function() {

2
libjsqrc/ethereumjs/test/abi.outputParser.js

@ -19,7 +19,7 @@ var description = [{
]
}];
describe('abi', function() {
describe('lib/solidity/abi', function() {
describe('outputParser', function() {
it('should parse output fixed bytes type', function() {

229
libjsqrc/ethereumjs/test/contract.js

@ -0,0 +1,229 @@
var chai = require('chai');
var assert = chai.assert;
var web3 = require('../index');
var FakeHttpProvider = require('./helpers/FakeHttpProvider');
var utils = require('../lib/utils/utils');
var desc = [{
"name": "balance(address)",
"type": "function",
"inputs": [{
"name": "who",
"type": "address"
}],
"constant": true,
"outputs": [{
"name": "value",
"type": "uint256"
}]
}, {
"name": "send(address,uint256)",
"type": "function",
"inputs": [{
"name": "to",
"type": "address"
}, {
"name": "value",
"type": "uint256"
}],
"outputs": []
}, {
"name":"Changed",
"type":"event",
"inputs": [
{"name":"from","type":"address","indexed":true},
{"name":"amount","type":"uint256","indexed":true},
{"name":"t1","type":"uint256","indexed":false},
{"name":"t2","type":"uint256","indexed":false}
],
}];
var address = '0x1234567890123456789012345678901234567890';
describe('web3.eth.contract', function () {
describe('event', function () {
it('should create event filter', function (done) {
var provider = new FakeHttpProvider();
web3.setProvider(provider);
web3.reset(); // reset different polls
var sha3 = '0x5131231231231231231231';
provider.injectResult(sha3);
var step = 0;
provider.injectValidation(function (payload) {
if (step === 0) {
step = 1;
assert.equal(payload.jsonrpc, '2.0');
assert.equal(payload.method, 'web3_sha3');
assert.equal(payload.params[0], web3.fromAscii('Changed(address,uint256,uint256,uint256)'));
} else if (step === 1) {
step = 2;
provider.injectResult(3);
assert.equal(payload.jsonrpc, '2.0');
assert.equal(payload.method, 'eth_newFilter');
assert.deepEqual(payload.params[0], {
topics: [
sha3,
'0x1234567890123456789012345678901234567890'
],
address: '0x1234567890123456789012345678901234567890'
});
} else if (step === 2 && utils.isArray(payload)) {
provider.injectBatchResults([[{
address: address,
topics: [
sha3,
'0x0000000000000000000000001234567890123456789012345678901234567890',
'0x0000000000000000000000000000000000000000000000000000000000000001'
],
number: 2,
data: '0x0000000000000000000000000000000000000000000000000000000000000001' +
'0000000000000000000000000000000000000000000000000000000000000008'
}]]);
var r = payload.filter(function (p) {
return p.jsonrpc === '2.0' && p.method === 'eth_getFilterChanges' && p.params[0] === 3;
});
assert.equal(r.length > 0, true);
}
});
var Contract = web3.eth.contract(desc);
var contract = new Contract(address);
contract.Changed({from: address}).watch(function(err, result) {
assert.equal(result.args.from, address);
assert.equal(result.args.amount, 1);
assert.equal(result.args.t1, 1);
assert.equal(result.args.t2, 8);
done();
});
});
it('should call constant function', function () {
var provider = new FakeHttpProvider();
web3.setProvider(provider);
web3.reset();
var sha3 = '0x5131231231231231231231';
var address = '0x1234567890123456789012345678901234567890';
provider.injectResult(sha3);
var step = 0;
provider.injectValidation(function (payload) {
if (step === 0) {
step = 1;
assert.equal(payload.jsonrpc, '2.0');
assert.equal(payload.method, 'web3_sha3');
assert.equal(payload.params[0], web3.fromAscii('balance(address)'));
} else if (step === 1) {
assert.equal(payload.method, 'eth_call');
assert.deepEqual(payload.params, [{
data: sha3.slice(0, 10) + '0000000000000000000000001234567890123456789012345678901234567890',
to: address
}, 'latest']);
}
});
var Contract = web3.eth.contract(desc);
var contract = new Contract(address);
contract.balance(address);
});
it('should sendTransaction to contract function', function () {
var provider = new FakeHttpProvider();
web3.setProvider(provider);
web3.reset();
var sha3 = '0x5131231231231231231231';
var address = '0x1234567890123456789012345678901234567890';
provider.injectResult(sha3);
var step = 0;
provider.injectValidation(function (payload) {
if (step === 0) {
step = 1;
assert.equal(payload.jsonrpc, '2.0');
assert.equal(payload.method, 'web3_sha3');
assert.equal(payload.params[0], web3.fromAscii('send(address,uint256)'));
} else if (step === 1) {
assert.equal(payload.method, 'eth_sendTransaction');
assert.deepEqual(payload.params, [{
data: sha3.slice(0, 10) +
'0000000000000000000000001234567890123456789012345678901234567890' +
'0000000000000000000000000000000000000000000000000000000000000011' ,
to: address
}]);
}
});
var Contract = web3.eth.contract(desc);
var contract = new Contract(address);
contract.send(address, 17);
});
it('should make a call with optional params', function () {
var provider = new FakeHttpProvider();
web3.setProvider(provider);
web3.reset();
var sha3 = '0x5131231231231231231231';
var address = '0x1234567890123456789012345678901234567890';
provider.injectResult(sha3);
var step = 0;
provider.injectValidation(function (payload) {
if (step === 0) {
step = 1;
assert.equal(payload.jsonrpc, '2.0');
assert.equal(payload.method, 'web3_sha3');
assert.equal(payload.params[0], web3.fromAscii('balance(address)'));
} else if (step === 1) {
assert.equal(payload.method, 'eth_call');
assert.deepEqual(payload.params, [{
data: sha3.slice(0, 10) + '0000000000000000000000001234567890123456789012345678901234567890',
to: address,
from: address,
gas: '0xc350'
}, 'latest']);
}
});
var Contract = web3.eth.contract(desc);
var contract = new Contract(address);
contract.call({from: address, gas: 50000}).balance(address);
});
it('should sendTransaction with optional params', function () {
var provider = new FakeHttpProvider();
web3.setProvider(provider);
web3.reset();
var sha3 = '0x5131231231231231231231';
var address = '0x1234567890123456789012345678901234567890';
provider.injectResult(sha3);
var step = 0;
provider.injectValidation(function (payload) {
if (step === 0) {
step = 1;
assert.equal(payload.jsonrpc, '2.0');
assert.equal(payload.method, 'web3_sha3');
assert.equal(payload.params[0], web3.fromAscii('send(address,uint256)'));
} else if (step === 1) {
assert.equal(payload.method, 'eth_sendTransaction');
assert.deepEqual(payload.params, [{
data: sha3.slice(0, 10) +
'0000000000000000000000001234567890123456789012345678901234567890' +
'0000000000000000000000000000000000000000000000000000000000000011' ,
to: address,
from: address,
gas: '0xc350',
gasPrice: '0xbb8',
value: '0x2710'
}]);
}
});
var Contract = web3.eth.contract(desc);
var contract = new Contract(address);
contract.sendTransaction({from: address, gas: 50000, gasPrice: 3000, value: 10000}).send(address, 17);
});
});
});

26
libjsqrc/ethereumjs/test/event.inputParser.js

@ -2,7 +2,7 @@ var assert = require('assert');
var event = require('../lib/web3/event.js');
var f = require('../lib/solidity/formatters.js');
describe('event', function () {
describe('lib/web3/event', function () {
describe('inputParser', function () {
it('should create basic filter input object', function () {
@ -33,8 +33,6 @@ describe('event', function () {
var options = {
fromBlock: 1,
toBlock: 2,
offset: 3,
limit: 4
};
var e = {
name: 'Event',
@ -51,8 +49,6 @@ describe('event', function () {
assert.equal(result.topics[0], signature);
assert.equal(result.fromBlock, options.fromBlock);
assert.equal(result.toBlock, options.toBlock);
assert.equal(result.offset, options.offset);
assert.equal(result.limit, options.limit);
});
@ -63,9 +59,7 @@ describe('event', function () {
var signature = '0x987654';
var options = {
fromBlock: 1,
toBlock: 2,
offset: 3,
limit: 4
toBlock: 2
};
var e = {
name: 'Event',
@ -80,11 +74,9 @@ describe('event', function () {
assert.equal(result.address, address);
assert.equal(result.topics.length, 2);
assert.equal(result.topics[0], signature);
assert.equal(result.topics[1], f.formatInputInt(4));
assert.equal(result.topics[1], '0x' + f.formatInputInt(4));
assert.equal(result.fromBlock, options.fromBlock);
assert.equal(result.toBlock, options.toBlock);
assert.equal(result.offset, options.offset);
assert.equal(result.limit, options.limit);
});
@ -94,10 +86,8 @@ describe('event', function () {
var address = '0x012345';
var signature = '0x987654';
var options = {
earliest: 1,
latest: 2,
offset: 3,
max: 4
fromBlock: 1,
toBlock: 2,
};
var e = {
name: 'Event',
@ -114,10 +104,8 @@ describe('event', function () {
assert.equal(result.topics[0], signature);
assert.equal(result.topics[1][0], f.formatInputInt(4));
assert.equal(result.topics[1][1], f.formatInputInt(69));
assert.equal(result.earliest, options.earliest);
assert.equal(result.latest, options.latest);
assert.equal(result.offset, options.offset);
assert.equal(result.max, options.max);
assert.equal(result.fromBlock, options.fromBlock);
assert.equal(result.toBlock, options.toBlock);
});
});

6
libjsqrc/ethereumjs/test/event.outputParser.js

@ -1,7 +1,7 @@
var assert = require('assert');
var event = require('../lib/web3/event.js');
describe('event', function () {
describe('lib/web3/event', function () {
describe('outputParser', function () {
it('should parse basic event output object', function () {
@ -10,7 +10,7 @@ describe('event', function () {
"address":"0x78dfc5983baecf65f73e3de3a96cee24e6b7981e",
"data":"0x000000000000000000000000000000000000000000000000000000000000004b",
"number":2,
"topic":[
"topics":[
"0x6e61ef44ac2747ff8b84d353a908eb8bd5c3fb118334d57698c5cfc7041196ad",
"0x0000000000000000000000000000000000000000000000000000000000000001"
]
@ -43,7 +43,7 @@ describe('event', function () {
"000000000000000000000000000000000000000000000000000000000000004c" +
"0000000000000000000000000000000000000000000000000000000000000001",
"number":3,
"topic":[
"topics":[
"0x6e61ef44ac2747ff8b84d353a908eb8bd5c3fb118334d57698c5cfc7041196ad",
"0x0000000000000000000000000000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000000000000000000000000000005"

24
libjsqrc/ethereumjs/test/filter.methods.js

@ -1,24 +0,0 @@
var assert = require('assert');
var filter = require('../lib/web3/filter');
var u = require('./test.utils.js');
var empty = function () {};
var implementation = {
newFilter: empty,
getLogs: empty,
uninstallFilter: empty,
startPolling: empty,
stopPolling: empty,
};
describe('web3', function () {
describe('eth', function () {
describe('filter', function () {
var f = filter({}, implementation);
u.methodExists(f, 'watch');
u.methodExists(f, 'stopWatching');
u.methodExists(f, 'get');
});
});
});

24
libjsqrc/ethereumjs/test/formatters.inputDefaultBlockFormatter.js

@ -0,0 +1,24 @@
var chai = require('chai');
var assert = chai.assert;
var formatters = require('../lib/web3/formatters');
var tests = [
{ value: 'latest', expected: 'latest' },
{ value: 'pending', expected: 'pending' },
{ value: 'earliest', expected: 'earliest' },
{ value: 1, expected: '0x1' },
{ value: '0x1', expected: '0x1' }
];
describe('lib/web3/formatters', function () {
describe('inputDefaultBlockNumberFormatter', function () {
tests.forEach(function (test) {
it('should turn ' + test.value + ' to ' + test.expected, function () {
assert.strictEqual(formatters.inputDefaultBlockNumberFormatter(test.value), test.expected);
});
});
});
});

3
libjsqrc/ethereumjs/test/formatters.inputPostFormatter.js

@ -1,6 +1,6 @@
var chai = require('chai');
var formatters = require('../lib/web3/formatters.js');
var assert = chai.assert;
var formatters = require('../lib/web3/formatters.js');
describe('formatters', function () {
describe('inputPostFormatter', function () {
@ -26,3 +26,4 @@ describe('formatters', function () {
});
});
});

11
libjsqrc/ethereumjs/test/formatters.inputTransactionFormatter.js

@ -1,4 +1,5 @@
var assert = require('assert');
var chai = require('chai');
var assert = chai.assert;
var formatters = require('../lib/web3/formatters.js');
var BigNumber = require('bignumber.js');
@ -7,19 +8,19 @@ describe('formatters', function () {
it('should return the correct value', function () {
assert.deepEqual(formatters.inputTransactionFormatter({
data: '0x34234kjh23kj4234',
data: '0x34234bf23bf4234',
value: new BigNumber(100),
from: '0x00000',
to: '0x00000',
gas: 1000,
gasPrice: new BigNumber(1000),
gasPrice: new BigNumber(1000)
}), {
data: '0x34234kjh23kj4234',
data: '0x34234bf23bf4234',
value: '0x64',
from: '0x00000',
to: '0x00000',
gas: '0x3e8',
gasPrice: '0x3e8',
gasPrice: '0x3e8'
});
});
});

8
libjsqrc/ethereumjs/test/formatters.outputTransactionFormatter.js

@ -12,7 +12,10 @@ describe('formatters', function () {
to: '0x00000',
value: '0x3e8',
gas: '0x3e8',
gasPrice: '0x3e8'
gasPrice: '0x3e8',
transactionIndex: '0x1',
blockNumber: '0x3e8',
blockHash: '0x34234bf23bf4234'
}), {
input: '0x34234kjh23kj4234',
from: '0x00000',
@ -20,6 +23,9 @@ describe('formatters', function () {
value: new BigNumber(1000),
gas: 1000,
gasPrice: new BigNumber(1000),
blockNumber: 1000,
blockHash: '0x34234bf23bf4234',
transactionIndex: 1
});
});
});

68
libjsqrc/ethereumjs/test/helpers/FakeHttpProvider.js

@ -0,0 +1,68 @@
var chai = require('chai');
var assert = require('assert');
var utils = require('../../lib/utils/utils');
var getResponseStub = function () {
return {
jsonrpc: '2.0',
id: 1,
result: 0
};
};
var FakeHttpProvider = function () {
this.response = getResponseStub();
this.error = null;
this.validation = null;
};
FakeHttpProvider.prototype.send = function (payload) {
assert.equal(utils.isArray(payload) || utils.isObject(payload), true);
// TODO: validate jsonrpc request
if (this.error) {
throw this.error;
}
if (this.validation) {
// imitate plain json object
this.validation(JSON.parse(JSON.stringify(payload)));
}
return this.response;
};
FakeHttpProvider.prototype.sendAsync = function (payload, callback) {
assert.equal(utils.isArray(payload) || utils.isObject(payload), true);
assert.equal(utils.isFunction(callback), true);
if (this.validation) {
// imitate plain json object
this.validation(JSON.parse(JSON.stringify(payload)), callback);
}
callback(this.error, this.response);
};
FakeHttpProvider.prototype.injectResponse = function (response) {
this.response = response;
};
FakeHttpProvider.prototype.injectResult = function (result) {
this.response = getResponseStub();
this.response.result = result;
};
FakeHttpProvider.prototype.injectBatchResults = function (results) {
this.response = results.map(function (r) {
var response = getResponseStub();
response.result = r;
return response;
});
};
FakeHttpProvider.prototype.injectError = function (error) {
this.error = error;
};
FakeHttpProvider.prototype.injectValidation = function (callback) {
this.validation = callback;
};
module.exports = FakeHttpProvider;

11
libjsqrc/ethereumjs/test/helpers/FakeQtNavigator.js

@ -0,0 +1,11 @@
var navigator = {
qt: {
callMethod: function (payload) {
return "{}";
}
}
};
module.exports = navigator;

31
libjsqrc/ethereumjs/test/helpers/FakeXMLHttpRequest.js

@ -0,0 +1,31 @@
var chai = require('chai');
var assert = chai.assert;
var FakeXMLHttpRequest = function () {
this.responseText = "{}";
this.readyState = 4;
this.onreadystatechange = null;
this.async = false;
};
FakeXMLHttpRequest.prototype.open = function (method, host, async) {
assert.equal(method, 'POST');
assert.notEqual(host, null);
assert.equal(async === false || async === true, true);
this.async = async;
};
FakeXMLHttpRequest.prototype.send = function (payload) {
assert.equal(typeof payload, 'string');
if (this.async) {
assert.equal(typeof this.onreadystatechange, 'function');
this.onreadystatechange();
return;
}
return this.responseText;
};
module.exports = {
XMLHttpRequest: FakeXMLHttpRequest
};

68
libjsqrc/ethereumjs/test/helpers/test.method.js

@ -0,0 +1,68 @@
var chai = require('chai');
var assert = chai.assert;
var web3 = require('../../index');
var FakeHttpProvider = require('./FakeHttpProvider');
var runTests = function (obj, method, tests) {
var testName = obj ? 'web3.' + obj : 'web';
describe(testName, function () {
describe(method, function () {
tests.forEach(function (test, index) {
it('sync 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, test.formattedArgs);
});
// when
var result = (obj)
? web3[obj][method].apply(null, test.args.slice(0))
: web3[method].apply(null, test.args.slice(0));
// then
assert.deepEqual(test.formattedResult, result);
});
it('async test: ' + index, function (done) {
// 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, test.formattedArgs);
});
var args = test.args.slice(0);
// add callback
args.push(function (err, result) {
assert.deepEqual(test.formattedResult, result);
done();
});
// when
if(obj)
web3[obj][method].apply(null, args);
else
web3[method].apply(null, args);
});
});
});
});
};
module.exports = {
runTests: runTests
}

9
libjsqrc/ethereumjs/test/test.utils.js → libjsqrc/ethereumjs/test/helpers/test.utils.js

@ -1,13 +1,20 @@
var assert = require('assert');
var chai = require('chai');
var assert = chai.assert;
var web3 = require('../../index');
var FakeHttpProvider = require('./FakeHttpProvider');
var methodExists = function (object, method) {
it('should have method ' + method + ' implemented', function() {
web3.setProvider(null);
assert.equal('function', typeof object[method], 'method ' + method + ' is not implemented');
});
};
var propertyExists = function (object, property) {
it('should have property ' + property + ' implemented', function() {
// set dummy providor, to prevent error
web3.setProvider(new FakeHttpProvider());
assert.notEqual('undefined', typeof object[property], 'property ' + property + ' is not implemented');
});
};

33
libjsqrc/ethereumjs/test/httpprovider.js

@ -0,0 +1,33 @@
var chai = require('chai');
var assert = chai.assert;
var SandboxedModule = require('sandboxed-module');
SandboxedModule.registerBuiltInSourceTransformer('istanbul');
var HttpProvider = SandboxedModule.require('../lib/web3/httpprovider', {
requires: {
'xmlhttprequest': require('./helpers/FakeXMLHttpRequest')
}
});
describe('lib/web3/httpprovider', function () {
describe('send', function () {
it('should send basic request', function () {
var provider = new HttpProvider();
var result = provider.send({});
assert.equal(typeof result, 'object');
});
});
describe('sendAsync', function () {
it('should send basic async request', function (done) {
var provider = new HttpProvider();
provider.sendAsync({}, function (err, result) {
assert.equal(typeof result, 'object');
done();
});
});
});
});

23
libjsqrc/ethereumjs/test/jsonrpc.id.js

@ -0,0 +1,23 @@
var chai = require('chai');
var assert = chai.assert;
var Jsonrpc = require('../lib/web3/jsonrpc');
describe('lib/web3/jsonrpc', function () {
describe('id', function () {
it('should increment the id', function () {
// given
var a = Jsonrpc.getInstance();
var b = Jsonrpc.getInstance();
var method = 'm';
// when
var p1 = a.toPayload(method);
var p2 = b.toPayload(method);
// then
assert.equal(p2.id, p1.id + 1);
});
});
});

1
libjsqrc/ethereumjs/test/jsonrpc.isValidResponse.js

@ -1,5 +1,6 @@
var assert = require('assert');
var jsonrpc = require('../lib/web3/jsonrpc');
jsonrpc = new jsonrpc();
describe('jsonrpc', function () {
describe('isValidResponse', function () {

1
libjsqrc/ethereumjs/test/jsonrpc.toBatchPayload.js

@ -1,5 +1,6 @@
var assert = require('assert');
var jsonrpc = require('../lib/web3/jsonrpc');
jsonrpc = new jsonrpc();
describe('jsonrpc', function () {
describe('toBatchPayload', function () {

4
libjsqrc/ethereumjs/test/jsonrpc.toPayload.js

@ -1,5 +1,7 @@
var assert = require('assert');
var chai = require('chai');
var assert = chai.assert;
var jsonrpc = require('../lib/web3/jsonrpc');
jsonrpc = new jsonrpc();
describe('jsonrpc', function () {
describe('toPayload', function () {

44
libjsqrc/ethereumjs/test/method.attachToObject.js

@ -0,0 +1,44 @@
var chai = require('chai');
var assert = chai.assert;
var Method = require('../lib/web3/method');
var utils = require('../lib/utils/utils');
describe('lib/web3/method', function () {
describe('attachToObject', function () {
//it('attach simple function to an object', function () {
//// given
//var method = new Method({
//name: 'hello'
//});
//var object = {};
//var func = function () { return 1; };
//// when
//method.attachToObject(object, func);
//// then
//assert.equal(utils.isFunction(object.hello), true);
//assert.equal(object.hello(), 1);
//});
//it('attach nested function to an object', function () {
//// given
//var method = new Method({
//name: 'hello.world'
//});
//var object = {};
//var func = function () { return 1; };
//// when
//method.attachToObject(object, func);
//// then
//assert.equal(utils.isObject(object.hello), true);
//assert.equal(utils.isFunction(object.hello.world), true);
//assert.equal(object.hello.world(), 1);
//});
});
});

52
libjsqrc/ethereumjs/test/method.extractCallback.js

@ -0,0 +1,52 @@
var chai = require('chai');
var assert = chai.assert;
var Method = require('../lib/web3/method');
describe('lib/web3/method', function () {
describe('extractCallback', function () {
it('should extract callback', function () {
// given
var method = new Method({});
var callback = function () { };
var args = [1, callback]
// when
var result = method.extractCallback(args);
// then
assert.equal(args.length, 1);
assert.equal(callback, result);
});
it('should extract callback created using newFunction', function () {
// given
var method = new Method({});
var callback = new Function ();
var args = [1, callback]
// when
var result = method.extractCallback(args);
// then
assert.equal(args.length, 1);
assert.equal(callback, result);
});
it('should not extract the callback', function () {
// given
var method = new Method({});
var args = [1, 2]
// when
var result = method.extractCallback(args);
// then
assert.equal(args.length, 2);
assert.equal(result, null);
});
});
});

41
libjsqrc/ethereumjs/test/method.formatInput.js

@ -0,0 +1,41 @@
var chai = require('chai');
var assert = chai.assert;
var Method = require('../lib/web3/method');
describe('lib/web3/method', function () {
describe('formatInput', function () {
it('should format plain input', function () {
// given
var star = function (arg) {
return arg + '*';
};
var method = new Method({
inputFormatter: [star, star, star]
});
var args = ['1','2','3'];
var expectedArgs = ['1*', '2*', '3*'];
// when
var result = method.formatInput(args);
// then
assert.deepEqual(result, expectedArgs);
});
it('should do nothing if there is no formatter', function () {
// given
var method = new Method({});
var args = [1,2,3];
// when
var result = method.formatInput(args);
// then
assert.deepEqual(result, args);
});
});
});

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save