Browse Source

Merge branch 'develop' of github.com:ethereum/cpp-ethereum into develop

cl-refactor
Gav Wood 10 years ago
parent
commit
2b0c9c8ce7
  1. 5
      alethzero/CMakeLists.txt
  2. 3
      alethzero/OurWebThreeStubServer.cpp
  3. 2
      alethzero/OurWebThreeStubServer.h
  4. 10
      eth/main.cpp
  5. 35
      libdevcore/Base64.cpp
  6. 3
      libdevcore/FixedHash.h
  7. 162
      libdevcore/TrieDB.h
  8. 6
      libdevcrypto/Common.cpp
  9. 3
      libdevcrypto/Common.h
  10. 2
      libethcore/Ethash.cpp
  11. 2
      libethereum/BlockChain.cpp
  12. 3
      libethereum/BlockChain.h
  13. 1
      libethereum/BlockChainSync.cpp
  14. 4
      libethereum/BlockDetails.h
  15. 9
      libethereum/ClientBase.cpp
  16. 5
      libethereum/ClientBase.h
  17. 3
      libethereum/Interface.cpp
  18. 5
      libethereum/Interface.h
  19. 2
      libethereum/TransactionQueue.h
  20. 10
      libweb3jsonrpc/AccountHolder.cpp
  21. 6
      libweb3jsonrpc/AccountHolder.h
  22. 27
      libweb3jsonrpc/JsonHelper.cpp
  23. 3
      libweb3jsonrpc/JsonHelper.h
  24. 27
      libweb3jsonrpc/WebThreeStubServerBase.cpp
  25. 1
      libweb3jsonrpc/WebThreeStubServerBase.h
  26. 6
      libweb3jsonrpc/abstractwebthreestubserver.h
  27. 1
      libweb3jsonrpc/spec.json
  28. 5
      mix/CMakeLists.txt
  29. 4
      mix/MixClient.cpp
  30. 4
      mix/MixClient.h
  31. 6
      neth/main.cpp
  32. 40
      test/libdevcore/FixedHash.cpp
  33. 41
      test/libdevcore/core.cpp
  34. 10
      test/libweb3jsonrpc/webthreestubclient.h

5
alethzero/CMakeLists.txt

@ -7,6 +7,11 @@ if (${CMAKE_MAJOR_VERSION} GREATER 2)
cmake_policy(SET CMP0043 OLD)
endif()
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
# Supress warnings for qt headers for clang+ccache
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-inconsistent-missing-override")
endif ()
set(CMAKE_INCLUDE_CURRENT_DIR ON)
aux_source_directory(. SRC_LIST)

3
alethzero/OurWebThreeStubServer.cpp

@ -99,10 +99,11 @@ bool OurAccountHolder::showUnknownCallNotice(TransactionSkeleton const& _t, bool
"REJECT UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!");
}
void OurAccountHolder::authenticate(TransactionSkeleton const& _t)
h256 OurAccountHolder::authenticate(TransactionSkeleton const& _t)
{
Guard l(x_queued);
m_queued.push(_t);
return h256();
}
void OurAccountHolder::doValidations()

2
alethzero/OurWebThreeStubServer.h

@ -43,7 +43,7 @@ protected:
// easiest to return keyManager.addresses();
virtual dev::AddressHash realAccounts() const override;
// use web3 to submit a signed transaction to accept
virtual void authenticate(dev::eth::TransactionSkeleton const& _t) override;
virtual dev::h256 authenticate(dev::eth::TransactionSkeleton const& _t) override;
private:
bool showAuthenticationPopup(std::string const& _title, std::string const& _text);

10
eth/main.cpp

@ -1026,9 +1026,7 @@ void interactiveMode(eth::Client* c, std::shared_ptr<eth::TrivialGasPricer> gasP
{
string path;
iss >> path;
RLPStream config(2);
config << signingKey << beneficiary;
writeFile(path, config.out());
writeFile(path, rlpList(signingKey, beneficiary));
}
else
cwarn << "Require parameter: exportConfig PATH";
@ -1486,11 +1484,7 @@ int main(int argc, char** argv)
for (auto const& s: passwordsToNote)
keyManager.notePassword(s);
{
RLPStream config(2);
config << signingKey << beneficiary;
writeFile(configFile, config.out());
}
writeFile(configFile, rlpList(signingKey, beneficiary));
if (sessionKey)
signingKey = sessionKey;

35
libdevcore/Base64.cpp

@ -27,6 +27,8 @@
/// Originally by René Nyffenegger, modified by some other guy and then devified by Gav Wood.
#include "Base64.h"
using namespace std;
using namespace dev;
static inline bool is_base64(byte c)
@ -44,14 +46,14 @@ static inline byte find_base64_char_index(byte c)
else return 1 + find_base64_char_index('/');
}
std::string dev::toBase64(bytesConstRef _in)
string dev::toBase64(bytesConstRef _in)
{
static const char base64_chars[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
std::string ret;
string ret;
int i = 0;
int j = 0;
byte char_array_3[3];
@ -60,15 +62,17 @@ std::string dev::toBase64(bytesConstRef _in)
auto buf = _in.data();
auto bufLen = _in.size();
while (bufLen--) {
while (bufLen--)
{
char_array_3[i++] = *(buf++);
if (i == 3) {
if (i == 3)
{
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++)
for (i = 0; i < 4; i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
@ -84,28 +88,31 @@ std::string dev::toBase64(bytesConstRef _in)
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++)
for (j = 0; j < i + 1; j++)
ret += base64_chars[char_array_4[j]];
while((i++ < 3))
while (i++ < 3)
ret += '=';
}
return ret;
}
bytes dev::fromBase64(std::string const& encoded_string)
bytes dev::fromBase64(string const& encoded_string)
{
auto in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
byte char_array_4[4], char_array_3[3];
byte char_array_3[3];
byte char_array_4[4];
bytes ret;
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
while (in_len-- && encoded_string[in_] != '=' && is_base64(encoded_string[in_]))
{
char_array_4[i++] = encoded_string[in_]; in_++;
if (i == 4) {
if (i == 4)
{
for (i = 0; i < 4; i++)
char_array_4[i] = find_base64_char_index(char_array_4[i]);
@ -119,7 +126,8 @@ bytes dev::fromBase64(std::string const& encoded_string)
}
}
if (i) {
if (i)
{
for (j = i; j < 4; j++)
char_array_4[j] = 0;
@ -130,7 +138,8 @@ bytes dev::fromBase64(std::string const& encoded_string)
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) ret.push_back(char_array_3[j]);
for (j = 0; j < i - 1; j++)
ret.push_back(char_array_3[j]);
}
return ret;

3
libdevcore/FixedHash.h

@ -81,7 +81,7 @@ public:
explicit FixedHash(byte const* _bs, ConstructFromPointerType) { memcpy(m_data.data(), _bs, N); }
/// Explicitly construct, copying from a string.
explicit FixedHash(std::string const& _s, ConstructFromStringType _t = FromHex, ConstructFromHashType _ht = FailIfDifferent): FixedHash(_t == FromHex ? fromHex(_s) : dev::asBytes(_s), _ht) {}
explicit FixedHash(std::string const& _s, ConstructFromStringType _t = FromHex, ConstructFromHashType _ht = FailIfDifferent): FixedHash(_t == FromHex ? fromHex(_s, WhenError::Throw) : dev::asBytes(_s), _ht) {}
/// Convert to arithmetic type.
operator Arith() const { return fromBigEndian<Arith>(m_data); }
@ -105,6 +105,7 @@ public:
FixedHash& operator&=(FixedHash const& _c) { for (unsigned i = 0; i < N; ++i) m_data[i] &= _c.m_data[i]; return *this; }
FixedHash operator&(FixedHash const& _c) const { return FixedHash(*this) &= _c; }
FixedHash operator~() const { FixedHash ret; for (unsigned i = 0; i < N; ++i) ret[i] = ~m_data[i]; return ret; }
FixedHash& operator++() { for (unsigned i = size; i > 0 && !++m_data[--i]; ) {} return *this; }
/// @returns true if all one-bits in @a _c are set in this object.
bool contains(FixedHash const& _c) const { return (*this & _c) == _c; }

162
libdevcore/TrieDB.h

@ -66,7 +66,7 @@ class GenericTrieDB
public:
using DB = _DB;
GenericTrieDB(DB* _db = nullptr): m_db(_db) {}
explicit GenericTrieDB(DB* _db = nullptr): m_db(_db) {}
GenericTrieDB(DB* _db, h256 const& _root, Verification _v = Verification::Normal) { open(_db, _root, _v); }
~GenericTrieDB() {}
@ -96,11 +96,72 @@ public:
/// True if the trie is initialised but empty (i.e. that the DB contains the root node which is empty).
bool isEmpty() const { return m_root == c_shaNull && node(m_root).size(); }
h256 const& root() const { if (!node(m_root).size()) BOOST_THROW_EXCEPTION(BadRoot()); /*std::cout << "Returning root as " << ret << " (really " << m_root << ")" << std::endl;*/ return m_root; } // patch the root in the case of the empty trie. TODO: handle this properly.
h256 const& root() const { if (node(m_root).empty()) BOOST_THROW_EXCEPTION(BadRoot()); /*std::cout << "Returning root as " << ret << " (really " << m_root << ")" << std::endl;*/ return m_root; } // patch the root in the case of the empty trie. TODO: handle this properly.
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
{
public:
using value_type = std::pair<bytesConstRef, bytesConstRef>;
iterator() {}
explicit iterator(GenericTrieDB const* _db);
iterator(GenericTrieDB const* _db, bytesConstRef _key);
iterator& operator++() { next(); return *this; }
value_type operator*() const { return at(); }
value_type operator->() const { return at(); }
bool operator==(iterator const& _c) const { return _c.m_trail == m_trail; }
bool operator!=(iterator const& _c) const { return _c.m_trail != m_trail; }
value_type at() const;
private:
void next();
void next(NibbleSlice _key);
struct Node
{
std::string rlp;
std::string key; // as hexPrefixEncoding.
byte child; // 255 -> entering, 16 -> actually at the node, 17 -> exiting, 0-15 -> actual children.
// 255 -> 16 -> 0 -> 1 -> ... -> 15 -> 17
void setChild(unsigned _i) { child = _i; }
void setFirstChild() { child = 16; }
void incrementChild() { child = child == 16 ? 0 : child == 15 ? 17 : (child + 1); }
bool operator==(Node const& _c) const { return rlp == _c.rlp && key == _c.key && child == _c.child; }
bool operator!=(Node const& _c) const { return !operator==(_c); }
};
protected:
std::vector<Node> m_trail;
GenericTrieDB<DB> const* m_that;
};
iterator begin() const { return iterator(this); }
iterator end() const { return iterator(); }
iterator lower_bound(bytesConstRef _key) const { return iterator(this, _key); }
void debugPrint() {}
void descendKey(h256 _k, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent = 0) const
/// Used for debugging, scans the whole trie.
void descendKey(h256 const& _k, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent = 0) const
{
_keyMask.erase(_k);
if (_k == m_root && _k == c_shaNull) // root allowed to be empty
@ -108,6 +169,7 @@ public:
descendList(RLP(node(_k)), _keyMask, _wasExt, _out, _indent); // if not, it must be a list
}
/// Used for debugging, scans the whole trie.
void descendEntry(RLP const& _r, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent) const
{
if (_r.isData() && _r.size() == 32)
@ -118,6 +180,7 @@ public:
BOOST_THROW_EXCEPTION(InvalidTrie());
}
/// Used for debugging, scans the whole trie.
void descendList(RLP const& _r, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent) const
{
if (_r.isList() && _r.itemCount() == 2 && (!_wasExt || _out))
@ -139,6 +202,7 @@ public:
BOOST_THROW_EXCEPTION(InvalidTrie());
}
/// Used for debugging, scans the whole trie.
h256Hash leftOvers(std::ostream* _out = nullptr) const
{
h256Hash k = m_db->keys();
@ -146,11 +210,14 @@ public:
return k;
}
/// Used for debugging, scans the whole trie.
void debugStructure(std::ostream& _out) const
{
leftOvers(&_out);
}
/// Used for debugging, scans the whole trie.
/// @param _requireNoLeftOvers if true, requires that all keys are reachable.
bool check(bool _requireNoLeftOvers) const
{
try
@ -164,66 +231,6 @@ 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
{
public:
using value_type = std::pair<bytesConstRef, bytesConstRef>;
iterator() {}
iterator(GenericTrieDB const* _db);
iterator(GenericTrieDB const* _db, bytesConstRef _key);
iterator& operator++() { next(); return *this; }
value_type operator*() const { return at(); }
value_type operator->() const { return at(); }
bool operator==(iterator const& _c) const { return _c.m_trail == m_trail; }
bool operator!=(iterator const& _c) const { return _c.m_trail != m_trail; }
value_type at() const;
private:
void next();
void next(NibbleSlice _key);
struct Node
{
std::string rlp;
std::string key; // as hexPrefixEncoding.
byte child; // 255 -> entering, 16 -> actually at the node, 17 -> exiting, 0-15 -> actual children.
// 255 -> 16 -> 0 -> 1 -> ... -> 15 -> 17
void setChild(unsigned _i) { child = _i; }
void setFirstChild() { child = 16; }
void incrementChild() { child = child == 16 ? 0 : child == 15 ? 17 : (child + 1); }
bool operator==(Node const& _c) const { return rlp == _c.rlp && key == _c.key && child == _c.child; }
bool operator!=(Node const& _c) const { return !operator==(_c); }
};
protected:
std::vector<Node> m_trail;
GenericTrieDB<DB> const* m_that;
};
iterator begin() const { return this; }
iterator end() const { return iterator(); }
iterator lower_bound(bytesConstRef _key) const { return iterator(this, _key); }
protected:
DB* db() const { return m_db; }
@ -279,12 +286,12 @@ private:
bool isTwoItemNode(RLP const& _n) const;
std::string deref(RLP const& _n) const;
std::string node(h256 _h) const { return m_db->lookup(_h); }
std::string node(h256 const& _h) const { return m_db->lookup(_h); }
// These are low-level node insertion functions that just go straight through into the DB.
h256 forceInsertNode(bytesConstRef _v) { auto h = sha3(_v); forceInsertNode(h, _v); return h; }
void forceInsertNode(h256 _h, bytesConstRef _v) { m_db->insert(_h, _v); }
void forceKillNode(h256 _h) { m_db->kill(_h); }
void forceInsertNode(h256 const& _h, bytesConstRef _v) { m_db->insert(_h, _v); }
void forceKillNode(h256 const& _h) { m_db->kill(_h); }
// This are semantically-aware node insertion functions that only kills when the node's
// data is < 32 bytes. It can safely be used when pruning the trie but won't work correctly
@ -305,6 +312,9 @@ std::ostream& operator<<(std::ostream& _out, GenericTrieDB<DB> const& _db)
return _out;
}
/**
* Different view on a GenericTrieDB that can use different key types.
*/
template <class Generic, class _KeyType>
class SpecificTrieDB: public Generic
{
@ -753,14 +763,14 @@ template <class DB> void GenericTrieDB<DB>::insert(bytesConstRef _key, bytesCons
tdebug << "Insert" << toHex(_key.cropped(0, 4)) << "=>" << toHex(_value);
#endif
std::string rv = node(m_root);
assert(rv.size());
bytes b = mergeAt(RLP(rv), m_root, NibbleSlice(_key), _value);
std::string rootValue = node(m_root);
assert(rootValue.size());
bytes b = mergeAt(RLP(rootValue), m_root, NibbleSlice(_key), _value);
// mergeAt won't attempt to delete the node if it's less than 32 bytes
// However, we know it's the root node and thus always hashed.
// So, if it's less than 32 (and thus should have been deleted but wasn't) then we delete it here.
if (rv.size() < 32)
if (rootValue.size() < 32)
forceKillNode(m_root);
m_root = forceInsertNode(&b);
}
@ -1066,11 +1076,11 @@ template <class DB> bytes GenericTrieDB<DB>::place(RLP const& _orig, NibbleSlice
killNode(_orig);
if (_orig.isEmpty())
return (RLPStream(2) << hexPrefixEncode(_k, true) << _s).out();
return rlpList(hexPrefixEncode(_k, true), _s);
assert(_orig.isList() && (_orig.itemCount() == 2 || _orig.itemCount() == 17));
if (_orig.itemCount() == 2)
return (RLPStream(2) << _orig[0] << _s).out();
return rlpList(_orig[0], _s);
auto s = RLPStream(17);
for (unsigned i = 0; i < 16; ++i)
@ -1152,7 +1162,7 @@ template <class DB> bytes GenericTrieDB<DB>::graft(RLP const& _orig)
}
assert(n.itemCount() == 2);
return (RLPStream(2) << hexPrefixEncode(keyOf(_orig), keyOf(n), isLeaf(n)) << n[1]).out();
return rlpList(hexPrefixEncode(keyOf(_orig), keyOf(n), isLeaf(n)), n[1]);
// auto ret =
// std::cout << keyOf(_orig) << " ++ " << keyOf(n) << " == " << keyOf(RLP(ret)) << std::endl;
// return ret;
@ -1201,11 +1211,7 @@ template <class DB> bytes GenericTrieDB<DB>::branch(RLP const& _orig)
for (unsigned i = 0; i < 16; ++i)
if (i == b)
if (isLeaf(_orig) || k.size() > 1)
{
RLPStream bottom(2);
bottom << hexPrefixEncode(k.mid(1), isLeaf(_orig)) << _orig[1];
streamNode(r, bottom.out());
}
streamNode(r, rlpList(hexPrefixEncode(k.mid(1), isLeaf(_orig)), _orig[1]));
else
r << _orig[1];
else

6
libdevcrypto/Common.cpp

@ -29,6 +29,7 @@
#include <libdevcore/Guards.h>
#include <libdevcore/SHA3.h>
#include <libdevcore/FileSystem.h>
#include <libdevcore/RLP.h>
#if ETH_HAVE_SECP256K1
#include <secp256k1/secp256k1.h>
#endif
@ -90,6 +91,11 @@ Address dev::toAddress(Secret const& _secret)
return toAddress(p);
}
Address dev::toAddress(Address const& _from, u256 const& _nonce)
{
return right160(sha3(rlpList(_from, _nonce)));
}
void dev::encrypt(Public const& _k, bytesConstRef _plain, bytes& o_cipher)
{
bytes io = _plain.toBytes();

3
libdevcrypto/Common.h

@ -85,6 +85,9 @@ Address toAddress(Public const& _public);
/// @returns 0 if it's not a valid secret key.
Address toAddress(Secret const& _secret);
// Convert transaction from and nonce to address.
Address toAddress(Address const& _from, u256 const& _nonce);
/// Encrypts plain text using Public key.
void encrypt(Public const& _k, bytesConstRef _plain, bytes& o_cipher);

2
libethcore/Ethash.cpp

@ -56,7 +56,7 @@ namespace eth
const unsigned Ethash::defaultLocalWorkSize = 64;
const unsigned Ethash::defaultGlobalWorkSizeMultiplier = 512; // * CL_DEFAULT_LOCAL_WORK_SIZE
const unsigned Ethash::defaultMSPerBatch = 100;
const unsigned Ethash::defaultMSPerBatch = 0;
const Ethash::WorkPackage Ethash::NullWorkPackage = Ethash::WorkPackage();
std::string Ethash::name()

2
libethereum/BlockChain.cpp

@ -273,7 +273,7 @@ void BlockChain::rebuild(std::string const& _path, std::function<void(unsigned,
h256 lastHash = m_lastBlockHash;
Timer t;
for (unsigned d = 1; d < originalNumber; ++d)
for (unsigned d = 1; d <= originalNumber; ++d)
{
if (!(d % 1000))
{

3
libethereum/BlockChain.h

@ -142,6 +142,9 @@ public:
BlockReceipts receipts(h256 const& _hash) const { return queryExtras<BlockReceipts, ExtraReceipts>(_hash, m_receipts, x_receipts, NullBlockReceipts); }
BlockReceipts receipts() const { return receipts(currentHash()); }
/// Get the transaction receipt by transaction hash. Thread-safe.
TransactionReceipt transactionReceipt(h256 const& _transactionHash) const {TransactionAddress ta = queryExtras<TransactionAddress, ExtraTransactionAddress>(_transactionHash, m_transactionAddresses, x_transactionAddresses, NullTransactionAddress); if (!ta) return bytesConstRef(); return receipts(ta.blockHash).receipts[ta.index]; }
/// Get a list of transaction hashes for a given block. Thread-safe.
TransactionHashes transactionHashes(h256 const& _hash) const { auto b = block(_hash); RLP rlp(b); h256s ret; for (auto t: rlp[1]) ret.push_back(sha3(t.data())); return ret; }
TransactionHashes transactionHashes() const { return transactionHashes(currentHash()); }

1
libethereum/BlockChainSync.cpp

@ -397,7 +397,6 @@ void PV60Sync::transition(std::shared_ptr<EthereumPeer> _peer, SyncState _s, boo
if (m_state == SyncState::Idle && _s != SyncState::Idle)
_peer->m_requireTransactions = true;
RLPStream s;
if (_s == SyncState::Hashes)
{
if (m_state == SyncState::Idle || m_state == SyncState::Hashes)

4
libethereum/BlockDetails.h

@ -59,7 +59,7 @@ struct BlockLogBlooms
{
BlockLogBlooms() {}
BlockLogBlooms(RLP const& _r) { blooms = _r.toVector<LogBloom>(); size = _r.data().size(); }
bytes rlp() const { RLPStream s; s << blooms; size = s.out().size(); return s.out(); }
bytes rlp() const { bytes r = dev::rlp(blooms); size = r.size(); return r; }
LogBlooms blooms;
mutable unsigned size;
@ -69,7 +69,7 @@ struct BlocksBlooms
{
BlocksBlooms() {}
BlocksBlooms(RLP const& _r) { blooms = _r.toArray<LogBloom, c_bloomIndexSize>(); size = _r.data().size(); }
bytes rlp() const { RLPStream s; s << blooms; size = s.out().size(); return s.out(); }
bytes rlp() const { bytes r = dev::rlp(blooms); size = r.size(); return r; }
std::array<LogBloom, c_bloomIndexSize> blooms;
mutable unsigned size;

9
libethereum/ClientBase.cpp

@ -45,7 +45,7 @@ State ClientBase::asOf(BlockNumber _h) const
return asOf(bc().numberHash(_h));
}
Address ClientBase::submitTransaction(TransactionSkeleton const& _t, Secret const& _secret)
h256 ClientBase::submitTransaction(TransactionSkeleton const& _t, Secret const& _secret)
{
prepareForTransaction();
@ -59,7 +59,7 @@ Address ClientBase::submitTransaction(TransactionSkeleton const& _t, Secret cons
StructuredLogger::transactionReceived(t.sha3().abridged(), t.sender().abridged());
cnote << "New transaction " << t;
return _t.creation ? right160(sha3(rlpList(ts.from, ts.nonce))) : Address();
return t.sha3();
}
// TODO: remove try/catch, allow exceptions
@ -327,6 +327,11 @@ Transaction ClientBase::transaction(h256 _blockHash, unsigned _i) const
return Transaction();
}
TransactionReceipt ClientBase::transactionReceipt(h256 const& _transactionHash) const
{
return bc().transactionReceipt(_transactionHash);
}
pair<h256, unsigned> ClientBase::transactionLocation(h256 const& _transactionHash) const
{
return bc().transactionLocation(_transactionHash);

5
libethereum/ClientBase.h

@ -76,8 +76,8 @@ public:
virtual ~ClientBase() {}
/// Submits the given transaction.
/// @returns the new contract's address (assuming it all goes through).
virtual Address submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) override;
/// @returns the new transaction's hash.
virtual h256 submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) override;
using Interface::submitTransaction;
/// Makes the given call. Nothing is recorded into the state.
@ -119,6 +119,7 @@ public:
virtual BlockDetails blockDetails(h256 _hash) const override;
virtual Transaction transaction(h256 _transactionHash) const override;
virtual Transaction transaction(h256 _blockHash, unsigned _i) const override;
virtual TransactionReceipt transactionReceipt(h256 const& _transactionHash) const override;
virtual std::pair<h256, unsigned> transactionLocation(h256 const& _transactionHash) const override;
virtual Transactions transactions(h256 _blockHash) const override;
virtual TransactionHashes transactionHashes(h256 _blockHash) const override;

3
libethereum/Interface.cpp

@ -46,5 +46,6 @@ Address Interface::submitTransaction(Secret const& _secret, u256 const& _endowme
ts.gas = _gas;
ts.gasPrice = _gasPrice;
ts.nonce = _nonce;
return submitTransaction(ts, _secret);
submitTransaction(ts, _secret);
return toAddress(toAddress(_secret), _nonce);
}

5
libethereum/Interface.h

@ -66,8 +66,8 @@ public:
// [TRANSACTION API]
/// Submits a new transaction.
/// @returns the new contract's address (assuming it all goes through and it's contract creation).
virtual Address submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) = 0;
/// @returns the transaction's hash.
virtual h256 submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) = 0;
/// Submits the given message-call transaction.
void submitTransaction(Secret const& _secret, u256 const& _value, Address const& _dest, bytes const& _data = bytes(), u256 const& _gas = 10000, u256 const& _gasPrice = 10 * szabo, u256 const& _nonce = UndefinedU256);
@ -135,6 +135,7 @@ public:
virtual bool isKnownTransaction(h256 const& _transactionHash) const = 0;
virtual Transaction transaction(h256 _transactionHash) const = 0;
virtual TransactionReceipt transactionReceipt(h256 const& _transactionHash) const = 0;
virtual std::pair<h256, unsigned> transactionLocation(h256 const& _transactionHash) const = 0;
virtual h256 hashFromNumber(BlockNumber _number) const = 0;
virtual BlockNumber numberFromHash(h256 _blockHash) const = 0;

2
libethereum/TransactionQueue.h

@ -89,7 +89,7 @@ private:
struct UnverifiedTransaction
{
UnverifiedTransaction() {}
UnverifiedTransaction(bytesConstRef const& _t, h512 const& _nodeId): transaction(std::move(_t.toBytes())), nodeId(_nodeId) {}
UnverifiedTransaction(bytesConstRef const& _t, h512 const& _nodeId): transaction(_t.toBytes()), nodeId(_nodeId) {}
UnverifiedTransaction(UnverifiedTransaction&& _t): transaction(std::move(_t.transaction)) {}
UnverifiedTransaction& operator=(UnverifiedTransaction&& _other) { transaction = std::move(_other.transaction); nodeId = std::move(_other.nodeId); return *this; }

10
libweb3jsonrpc/AccountHolder.cpp

@ -106,20 +106,22 @@ AddressHash SimpleAccountHolder::realAccounts() const
return m_keyManager.accountsHash();
}
void SimpleAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t)
h256 SimpleAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t)
{
if (isRealAccount(_t.from))
m_client()->submitTransaction(_t, m_keyManager.secret(_t.from, [&](){ return m_getPassword(_t.from); }));
return m_client()->submitTransaction(_t, m_keyManager.secret(_t.from, [&](){ return m_getPassword(_t.from); }));
else if (isProxyAccount(_t.from))
queueTransaction(_t);
return h256();
}
void FixedAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t)
h256 FixedAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t)
{
if (isRealAccount(_t.from))
m_client()->submitTransaction(_t, m_accounts[_t.from]);
return m_client()->submitTransaction(_t, m_accounts[_t.from]);
else if (isProxyAccount(_t.from))
queueTransaction(_t);
return h256();
}

6
libweb3jsonrpc/AccountHolder.h

@ -51,7 +51,7 @@ public:
virtual AddressHash realAccounts() const = 0;
// use m_web3's submitTransaction
// or use AccountHolder::queueTransaction(_t) to accept
virtual void authenticate(dev::eth::TransactionSkeleton const& _t) = 0;
virtual h256 authenticate(dev::eth::TransactionSkeleton const& _t) = 0;
Addresses allAccounts() const;
bool isRealAccount(Address const& _account) const { return realAccounts().count(_account) > 0; }
@ -85,7 +85,7 @@ public:
{}
AddressHash realAccounts() const override;
void authenticate(dev::eth::TransactionSkeleton const& _t) override;
h256 authenticate(dev::eth::TransactionSkeleton const& _t) override;
private:
std::function<std::string(Address)> m_getPassword;
@ -117,7 +117,7 @@ public:
// use m_web3's submitTransaction
// or use AccountHolder::queueTransaction(_t) to accept
void authenticate(dev::eth::TransactionSkeleton const& _t) override;
h256 authenticate(dev::eth::TransactionSkeleton const& _t) override;
private:
std::unordered_map<dev::Address, dev::Secret> m_accounts;

27
libweb3jsonrpc/JsonHelper.cpp

@ -182,6 +182,33 @@ Json::Value toJson(dev::eth::TransactionReceipt const& _t)
return res;
}
Json::Value toJson(dev::eth::TransactionReceipt const& _tr, std::pair<h256, unsigned> _location, BlockNumber _blockNumber, Transaction const& _t)
{
Json::Value res;
h256 h = _t.sha3();
res["transactionHash"] = toJS(h);
res["transactionIndex"] = _location.second;
res["blockHash"] = toJS(_location.first);
res["blockNumber"] = _blockNumber;
res["cumulativeGasUsed"] = toJS(_tr.gasUsed()); // TODO: check if this is fine
res["gasUsed"] = toJS(_tr.gasUsed());
res["contractAddress"] = toJS(toAddress(_t.from(), _t.nonce()));
res["logs"] = Json::Value(Json::arrayValue);
for (unsigned i = 0; i < _tr.log().size(); i++)
{
LogEntry e = _tr.log()[i];
Json::Value l = toJson(e);
l["type"] = "mined";
l["blockNumber"] = _blockNumber;
l["blockHash"] = toJS(_location.first);
l["logIndex"] = i;
l["transactionHash"] = toJS(h);
l["transactionIndex"] = _location.second;
res["logs"].append(l);
}
return res;
}
Json::Value toJson(dev::eth::Transaction const& _t)
{
Json::Value res;

3
libweb3jsonrpc/JsonHelper.h

@ -50,12 +50,15 @@ using UncleHashes = h256s;
using TransactionHashes = h256s;
Json::Value toJson(BlockInfo const& _bi);
//TODO: wrap these params into one structure eg. "LocalisedTransaction"
Json::Value toJson(Transaction const& _t, std::pair<h256, unsigned> _location, BlockNumber _blockNumber);
Json::Value toJson(BlockInfo const& _bi, BlockDetails const& _bd, UncleHashes const& _us, Transactions const& _ts);
Json::Value toJson(BlockInfo const& _bi, BlockDetails const& _bd, UncleHashes const& _us, TransactionHashes const& _ts);
Json::Value toJson(TransactionSkeleton const& _t);
Json::Value toJson(Transaction const& _t);
Json::Value toJson(TransactionReceipt const& _t);
//TODO: wrap these params into one structure eg. "LocalisedTransactionReceipt"
Json::Value toJson(TransactionReceipt const& _tr, std::pair<h256, unsigned> _location, BlockNumber _blockNumber, Transaction const& _t);
Json::Value toJson(LocalisedLogEntry const& _e);
Json::Value toJson(LogEntry const& _e);
TransactionSkeleton toTransactionSkeleton(Json::Value const& _json);

27
libweb3jsonrpc/WebThreeStubServerBase.cpp

@ -242,21 +242,16 @@ string WebThreeStubServerBase::eth_sendTransaction(Json::Value const& _json)
{
try
{
string ret;
TransactionSkeleton t = toTransactionSkeleton(_json);
if (!t.from)
t.from = m_ethAccounts->defaultTransactAccount();
if (t.creation)
ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from)))));
if (t.gasPrice == UndefinedU256)
t.gasPrice = 10 * dev::eth::szabo; // TODO: should be determined by user somehow.
if (t.gas == UndefinedU256)
t.gas = min<u256>(client()->gasLimitRemaining() / 5, client()->balanceAt(t.from) / t.gasPrice);
m_ethAccounts->authenticate(t);
return ret;
return toJS(m_ethAccounts->authenticate(t));
}
catch (...)
{
@ -268,13 +263,10 @@ string WebThreeStubServerBase::eth_signTransaction(Json::Value const& _json)
{
try
{
string ret;
TransactionSkeleton t = toTransactionSkeleton(_json);
if (!t.from)
t.from = m_ethAccounts->defaultTransactAccount();
if (t.creation)
ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from)))));;
if (t.gasPrice == UndefinedU256)
t.gasPrice = 10 * dev::eth::szabo; // TODO: should be determined by user somehow.
if (t.gas == UndefinedU256)
@ -427,6 +419,23 @@ Json::Value WebThreeStubServerBase::eth_getTransactionByBlockNumberAndIndex(stri
}
}
Json::Value WebThreeStubServerBase::eth_getTransactionReceipt(string const& _transactionHash)
{
try
{
h256 h = jsToFixed<32>(_transactionHash);
if (!client()->isKnownTransaction(h))
return Json::Value(Json::nullValue);
auto l = client()->transactionLocation(h);
return toJson(client()->transactionReceipt(h), l, client()->numberFromHash(l.first), client()->transaction(h));
}
catch (...)
{
BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS));
}
}
Json::Value WebThreeStubServerBase::eth_getUncleByBlockHashAndIndex(string const& _blockHash, string const& _uncleIndex)
{
try

1
libweb3jsonrpc/WebThreeStubServerBase.h

@ -119,6 +119,7 @@ public:
virtual Json::Value eth_getTransactionByHash(std::string const& _transactionHash);
virtual Json::Value eth_getTransactionByBlockHashAndIndex(std::string const& _blockHash, std::string const& _transactionIndex);
virtual Json::Value eth_getTransactionByBlockNumberAndIndex(std::string const& _blockNumber, std::string const& _transactionIndex);
virtual Json::Value eth_getTransactionReceipt(std::string const& _transactionHash);
virtual Json::Value eth_getUncleByBlockHashAndIndex(std::string const& _blockHash, std::string const& _uncleIndex);
virtual Json::Value eth_getUncleByBlockNumberAndIndex(std::string const& _blockNumber, std::string const& _uncleIndex);
virtual Json::Value eth_getCompilers();

6
libweb3jsonrpc/abstractwebthreestubserver.h

@ -40,6 +40,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer<AbstractWebThr
this->bindAndAddMethod(jsonrpc::Procedure("eth_getTransactionByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getTransactionByHashI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_getTransactionByBlockHashAndIndex", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getTransactionByBlockHashAndIndexI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_getTransactionByBlockNumberAndIndex", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getTransactionByBlockNumberAndIndexI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_getTransactionReceipt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getTransactionReceiptI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleByBlockHashAndIndex", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getUncleByBlockHashAndIndexI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleByBlockNumberAndIndex", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getUncleByBlockNumberAndIndexI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_getCompilers", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &AbstractWebThreeStubServer::eth_getCompilersI);
@ -224,6 +225,10 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer<AbstractWebThr
{
response = this->eth_getTransactionByBlockNumberAndIndex(request[0u].asString(), request[1u].asString());
}
inline virtual void eth_getTransactionReceiptI(const Json::Value &request, Json::Value &response)
{
response = this->eth_getTransactionReceipt(request[0u].asString());
}
inline virtual void eth_getUncleByBlockHashAndIndexI(const Json::Value &request, Json::Value &response)
{
response = this->eth_getUncleByBlockHashAndIndex(request[0u].asString(), request[1u].asString());
@ -489,6 +494,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer<AbstractWebThr
virtual Json::Value eth_getTransactionByHash(const std::string& param1) = 0;
virtual Json::Value eth_getTransactionByBlockHashAndIndex(const std::string& param1, const std::string& param2) = 0;
virtual Json::Value eth_getTransactionByBlockNumberAndIndex(const std::string& param1, const std::string& param2) = 0;
virtual Json::Value eth_getTransactionReceipt(const std::string& param1) = 0;
virtual Json::Value eth_getUncleByBlockHashAndIndex(const std::string& param1, const std::string& param2) = 0;
virtual Json::Value eth_getUncleByBlockNumberAndIndex(const std::string& param1, const std::string& param2) = 0;
virtual Json::Value eth_getCompilers() = 0;

1
libweb3jsonrpc/spec.json

@ -29,6 +29,7 @@
{ "name": "eth_getTransactionByHash", "params": [""], "order": [], "returns": {}},
{ "name": "eth_getTransactionByBlockHashAndIndex", "params": ["", ""], "order": [], "returns": {}},
{ "name": "eth_getTransactionByBlockNumberAndIndex", "params": ["", ""], "order": [], "returns": {}},
{ "name": "eth_getTransactionReceipt", "params": [""], "order": [], "returns": {}},
{ "name": "eth_getUncleByBlockHashAndIndex", "params": ["", ""], "order": [], "returns": {}},
{ "name": "eth_getUncleByBlockNumberAndIndex", "params": ["", ""], "order": [], "returns": {}},
{ "name": "eth_getCompilers", "params": [], "order": [], "returns": []},

5
mix/CMakeLists.txt

@ -15,6 +15,11 @@ include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS})
include_directories(${Boost_INCLUDE_DIRS})
include_directories(BEFORE ..)
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
# Supress warnings for qt headers for clang+ccache
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-inconsistent-missing-override")
endif ()
find_package (Qt5WebEngine QUIET)
qt5_add_resources(UI_RESOURCES res.qrc qml.qrc)

4
mix/MixClient.cpp

@ -303,14 +303,14 @@ State MixClient::asOf(h256 const& _block) const
return ret;
}
Address MixClient::submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret, bool _gasAuto)
h256 MixClient::submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret, bool _gasAuto)
{
WriteGuard l(x_state);
TransactionSkeleton ts = _ts;
ts.nonce = m_state.transactionsFrom(toAddress(_secret));
eth::Transaction t(ts, _secret);
executeTransaction(t, m_state, false, _gasAuto, _secret);
return _ts.creation ? right160(sha3(rlpList(ts.to, ts.nonce))) : Address();
return t.sha3();
}
dev::eth::ExecutionResult MixClient::call(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, bool _gasAuto, FudgeFactor _ff)

4
mix/MixClient.h

@ -58,8 +58,8 @@ public:
dev::eth::ExecutionResult create(Address const& _secret, u256 _value, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * eth::szabo, eth::BlockNumber _blockNumber = eth::PendingBlock, eth::FudgeFactor _ff = eth::FudgeFactor::Strict) override;
using ClientBase::submitTransaction;
virtual Address submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret) override { return submitTransaction(_ts, _secret, false); }
Address submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret, bool _gasAuto);
virtual h256 submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret) override { return submitTransaction(_ts, _secret, false); }
h256 submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret, bool _gasAuto);
dev::eth::ExecutionResult call(Address const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, eth::BlockNumber _blockNumber, bool _gasAuto, eth::FudgeFactor _ff = eth::FudgeFactor::Strict);
void setAddress(Address _us) override;

6
neth/main.cpp

@ -363,11 +363,7 @@ int main(int argc, char** argv)
coinbase = config[1].toHash<Address>();
}
else
{
RLPStream config(2);
config << us.secret() << coinbase;
writeFile(configFile, config.out());
}
writeFile(configFile, rlpList(us.secret(), coinbase));
for (int i = 1; i < argc; ++i)
{

40
test/libdevcore/FixedHash.cpp

@ -100,6 +100,46 @@ BOOST_AUTO_TEST_CASE(FixedHashContains)
BOOST_CHECK(!h1.contains(h3));
}
void incrementSingleIteration(unsigned seed)
{
unsigned next = seed + 1;
FixedHash<4> h1(seed);
FixedHash<4> h2 = h1;
FixedHash<4> h3(next);
FixedHash<32> hh1(seed);
FixedHash<32> hh2 = hh1;
FixedHash<32> hh3(next);
BOOST_CHECK_EQUAL(++h2, h3);
BOOST_CHECK_EQUAL(++hh2, hh3);
BOOST_CHECK(h2 > h1);
BOOST_CHECK(hh2 > hh1);
unsigned reverse1 = ((FixedHash<4>::Arith)h2).convert_to<unsigned>();
unsigned reverse2 = ((FixedHash<32>::Arith)hh2).convert_to<unsigned>();
BOOST_CHECK_EQUAL(next, reverse1);
BOOST_CHECK_EQUAL(next, reverse2);
}
BOOST_AUTO_TEST_CASE(FixedHashIncrement)
{
incrementSingleIteration(0);
incrementSingleIteration(1);
incrementSingleIteration(0xBAD);
incrementSingleIteration(0xBEEF);
incrementSingleIteration(0xFFFF);
incrementSingleIteration(0xFEDCBA);
incrementSingleIteration(0x7FFFFFFF);
FixedHash<4> h(0xFFFFFFFF);
FixedHash<4> zero;
BOOST_CHECK_EQUAL(++h, zero);
}
BOOST_AUTO_TEST_SUITE_END()
}

41
test/libdevcore/core.cpp

@ -0,0 +1,41 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file core.cpp
* @author Dimitry Khokhlov <winsvega@mail.ru>
* @date 2014
* CORE test functions.
*/
#include <boost/test/unit_test.hpp>
#include <libdevcore/CommonIO.h>
#include <test/TestHelper.h>
BOOST_AUTO_TEST_SUITE(CoreLibTests)
BOOST_AUTO_TEST_CASE(byteRef)
{
cnote << "bytesRef copyTo and toString...";
dev::bytes originalSequence = dev::fromHex("0102030405060708091011121314151617181920212223242526272829303132");
dev::bytesRef out(&originalSequence.at(0), 32);
dev::h256 hash32("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347");
hash32.ref().copyTo(out);
BOOST_CHECK_MESSAGE(out.size() == 32, "Error wrong result size when h256::ref().copyTo(dev::bytesRef out)");
BOOST_CHECK_MESSAGE(out.toBytes() == originalSequence, "Error when h256::ref().copyTo(dev::bytesRef out)");
}
BOOST_AUTO_TEST_SUITE_END()

10
test/libweb3jsonrpc/webthreestubclient.h

@ -302,6 +302,16 @@ class WebThreeStubClient : public jsonrpc::Client
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value eth_getTransactionReceipt(const std::string& param1) throw (jsonrpc::JsonRpcException)
{
Json::Value p;
p.append(param1);
Json::Value result = this->CallMethod("eth_getTransactionReceipt",p);
if (result.isObject())
return result;
else
throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
}
Json::Value eth_getUncleByBlockHashAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
{
Json::Value p;

Loading…
Cancel
Save