diff --git a/CMakeLists.txt b/CMakeLists.txt index 52721a702..25487d0ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,7 +115,7 @@ include(EthDependenciesDeprecated) createBuildInfo() add_subdirectory(libdevcore) -add_subdirectory(libevmface) +add_subdirectory(libevmcore) add_subdirectory(liblll) add_subdirectory(libserpent) add_subdirectory(libsolidity) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index 0da0acb4f..01dfb88dc 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -53,7 +53,7 @@ else () endif () qt5_use_modules(${EXECUTEABLE} Core)# Gui Widgets Network WebKit WebKitWidgets) -target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore devcrypto secp256k1 gmp ${CRYPTOPP_LS} serpent lll solidity evmface devcore web3jsonrpc jsqrc) +target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore devcrypto secp256k1 gmp ${CRYPTOPP_LS} serpent lll solidity evmcore devcore web3jsonrpc jsqrc) if (APPLE) # First have qt5 install plugins and frameworks diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 343097bbf..0ad5ba938 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -610,6 +610,7 @@ void Main::readSettings(bool _skipGeometry) } } ethereum()->setAddress(m_myKeys.back().address()); + m_server->setAccounts(keysAsVector(m_myKeys)); } { @@ -1257,9 +1258,10 @@ void Main::on_blocks_currentItemChanged() s << "
Coinbase: " << pretty(info.coinbaseAddress).toHtmlEscaped().toStdString() << " " << info.coinbaseAddress; s << "
Nonce: " << info.nonce << ""; s << "
Parent: " << info.parentHash << ""; - s << "
Bloom: " << details.bloom << ""; +// s << "
Bloom: " << details.bloom << ""; s << "
Log Bloom: " << info.logBloom << ""; s << "
Transactions: " << block[1].itemCount() << " @" << info.transactionsRoot << ""; + s << "
Receipts: @" << info.receiptsRoot << ":"; s << "
Uncles: " << block[2].itemCount() << " @" << info.sha3Uncles << ""; for (auto u: block[2]) { @@ -1282,6 +1284,7 @@ void Main::on_blocks_currentItemChanged() Transaction tx(block[1][txi].data()); auto ss = tx.safeSender(); h256 th = sha3(rlpList(ss, tx.nonce())); + auto receipt = ethereum()->blockChain().receipts(h).receipts[txi]; s << "

" << th << "

"; s << "

" << h << "[" << txi << "]

"; s << "
From: " << pretty(ss).toHtmlEscaped().toStdString() << " " << ss; @@ -1297,6 +1300,10 @@ void Main::on_blocks_currentItemChanged() s << "
R: " << hex << nouppercase << tx.signature().r << ""; s << "
S: " << hex << nouppercase << tx.signature().s << ""; s << "
Msg: " << tx.sha3(eth::WithoutSignature) << ""; + s << "
Hex: " << toHex(block[1][txi].data()) << "
"; + auto r = receipt.rlp(); + s << "
Receipt: " << toString(RLP(r)) << "
"; + s << "
Receipt-Hex: " << toHex(receipt.rlp()) << "
"; if (tx.isCreation()) { if (tx.data().size()) @@ -1374,7 +1381,7 @@ void Main::populateDebugger(dev::bytesConstRef _r) debugFinished(); vector levels; m_codes.clear(); - bytesConstRef lastExtCode; + bytes lastExtCode; bytesConstRef lastData; h256 lastHash; h256 lastDataHash; @@ -1387,7 +1394,7 @@ void Main::populateDebugger(dev::bytesConstRef _r) lastExtCode = ext.code; lastHash = sha3(lastExtCode); if (!m_codes.count(lastHash)) - m_codes[lastHash] = ext.code.toBytes(); + m_codes[lastHash] = ext.code; } if (ext.data != lastData) { @@ -1601,15 +1608,15 @@ void Main::on_data_textChanged() } else if (src.substr(0, 8) == "contract") // improve this heuristic { - shared_ptr scanner = make_shared(); + dev::solidity::CompilerStack compiler; try { - m_data = dev::solidity::CompilerStack::compile(src, scanner); + m_data = compiler.compile(src, m_enableOptimizer); } catch (dev::Exception const& exception) { ostringstream error; - solidity::SourceReferenceFormatter::printExceptionInformation(error, exception, "Error", *scanner); + solidity::SourceReferenceFormatter::printExceptionInformation(error, exception, "Error", compiler.getScanner()); solidity = "

Solidity

" + QString::fromStdString(error.str()).toHtmlEscaped() + "
"; } catch (...) @@ -1821,6 +1828,7 @@ void Main::on_send_clicked() void Main::keysChanged() { onBalancesChange(); + m_server->setAccounts(keysAsVector(m_myKeys)); } void Main::on_debug_clicked() @@ -2218,7 +2226,7 @@ void Main::refreshWhispers() time_t ex = e.expiry(); QString t(ctime(&ex)); t.chop(1); - QString item = QString("[%1 - %2s] *%3 %5 %4").arg(t).arg(e.ttl()).arg(e.workProved()).arg(toString(e.topic()).c_str()).arg(msg); + QString item = QString("[%1 - %2s] *%3 %5 %4").arg(t).arg(e.ttl()).arg(e.workProved()).arg(toString(e.topics()).c_str()).arg(msg); ui->whispers->addItem(item); } } diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 57f9c5ebd..9f7ad97de 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -154,6 +154,7 @@ private slots: void on_newIdentity_triggered(); void refreshWhisper(); + void refreshBlockChain(); void addNewId(QString _ids); signals: @@ -214,7 +215,6 @@ private: void refreshPending(); void refreshAccounts(); void refreshDestination(); - void refreshBlockChain(); void refreshBlockCount(); void refreshBalances(); diff --git a/alethzero/OurWebThreeStubServer.cpp b/alethzero/OurWebThreeStubServer.cpp index ca1b77649..a40727e1e 100644 --- a/alethzero/OurWebThreeStubServer.cpp +++ b/alethzero/OurWebThreeStubServer.cpp @@ -28,7 +28,7 @@ OurWebThreeStubServer::OurWebThreeStubServer(jsonrpc::AbstractServerConnector* _ WebThreeStubServer(_conn, _web3, _accounts) {} -std::string OurWebThreeStubServer::newIdentity() +std::string OurWebThreeStubServer::shh_newIdentity() { dev::KeyPair kp = dev::KeyPair::create(); emit onNewId(QString::fromStdString(toJS(kp.sec()))); diff --git a/alethzero/OurWebThreeStubServer.h b/alethzero/OurWebThreeStubServer.h index be06da62d..b3492df5e 100644 --- a/alethzero/OurWebThreeStubServer.h +++ b/alethzero/OurWebThreeStubServer.h @@ -31,7 +31,7 @@ class OurWebThreeStubServer: public QObject, public WebThreeStubServer public: OurWebThreeStubServer(jsonrpc::AbstractServerConnector* _conn, dev::WebThreeDirect& _web3, std::vector const& _accounts); - virtual std::string newIdentity() override; + virtual std::string shh_newIdentity() override; signals: void onNewId(QString _s); diff --git a/eth/main.cpp b/eth/main.cpp index 759dd40d0..408654018 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -32,7 +32,7 @@ #include #endif #include -#include +#include #include #include #include diff --git a/evmcc/CMakeLists.txt b/evmcc/CMakeLists.txt index 488893509..26a586271 100644 --- a/evmcc/CMakeLists.txt +++ b/evmcc/CMakeLists.txt @@ -13,7 +13,7 @@ target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} ethereum) target_link_libraries(${EXECUTABLE} evm) -target_link_libraries(${EXECUTABLE} evmface) +target_link_libraries(${EXECUTABLE} evmcore) target_link_libraries(${EXECUTABLE} evmjit) if ("${TARGET_PLATFORM}" STREQUAL "w64") diff --git a/evmcc/evmcc.cpp b/evmcc/evmcc.cpp index 535a9aed9..16ab23e9b 100644 --- a/evmcc/evmcc.cpp +++ b/evmcc/evmcc.cpp @@ -14,7 +14,8 @@ #include #include -#include +#include +#include #include #include @@ -31,9 +32,12 @@ void parseProgramOptions(int _argc, char** _argv, boost::program_options::variab ("gas,g", opt::value(), "set initial gas for execution") ("disassemble,d", "dissassemble the code") ("dump-cfg", "dump control flow graph to graphviz file") - ("optimize-stack,os", "optimize stack use between basic blocks") + ("dont-optimize", "turn off optimizations") + ("optimize-stack", "optimize stack use between basic blocks (default: on)") + ("rewrite-switch", "rewrite LLVM switch to branches (default: on)") ("output-ll", opt::value(), "dump generated LLVM IR to file") ("output-bc", opt::value(), "dump generated LLVM bitcode to file") + ("show-logs", "output LOG statements to stderr") ("verbose,V", "enable verbose output"); opt::options_description implicitOpts("Input files"); @@ -118,10 +122,12 @@ int main(int argc, char** argv) eth::jit::Compiler::Options compilerOptions; compilerOptions.dumpCFG = options.count("dump-cfg") > 0; - compilerOptions.optimizeStack = options.count("optimize-stack") > 0; + bool optimize = options.count("dont-optimize") == 0; + compilerOptions.optimizeStack = optimize || options.count("optimize-stack") > 0; + compilerOptions.rewriteSwitchToBranches = optimize || options.count("rewrite-switch") > 0; auto compiler = eth::jit::Compiler(compilerOptions); - auto module = compiler.compile({bytecode.data(), bytecode.size()}); + auto module = compiler.compile(bytecode); auto compilationEndTime = std::chrono::high_resolution_clock::now(); @@ -156,7 +162,6 @@ int main(int argc, char** argv) ofs.close(); } - if (options.count("verbose")) { std::cerr << "*** Compilation time: " @@ -168,7 +173,24 @@ int main(int argc, char** argv) { auto engine = eth::jit::ExecutionEngine(); u256 gas = initialGas; - auto result = engine.run(std::move(module), gas); + + // Create fake ExtVM interface + eth::ExtVMFace ext; + ext.myAddress = Address(1122334455667788); + ext.caller = Address(0xfacefacefaceface); + ext.origin = Address(101010101010101010); + ext.value = 0xabcd; + ext.gasPrice = 1002; + ext.previousBlock.hash = u256(1003); + ext.currentBlock.coinbaseAddress = Address(1004); + ext.currentBlock.timestamp = 1005; + ext.currentBlock.number = 1006; + ext.currentBlock.difficulty = 1007; + ext.currentBlock.gasLimit = 1008; + ext.data = std::string("Hello the Beautiful World of Ethereum!"); + ext.code = { 0x0d, 0x0e, 0x0a, 0x0d, 0x0b, 0x0e, 0xe, 0xf }; + + auto result = engine.run(std::move(module), gas, options.count("show-logs") > 0, ext); return result; } } diff --git a/exp/main.cpp b/exp/main.cpp index 3af192380..8be79cad5 100644 --- a/exp/main.cpp +++ b/exp/main.cpp @@ -36,7 +36,7 @@ using namespace dev::eth; using namespace dev::p2p; using namespace dev::shh; -#if 0 +#if 1 int main() { DownloadMan man; @@ -44,18 +44,19 @@ int main() DownloadSub s1(man); DownloadSub s2(man); man.resetToChain(h256s({u256(0), u256(1), u256(2), u256(3), u256(4), u256(5), u256(6), u256(7), u256(8)})); - cnote << s0.nextFetch(2); - cnote << s1.nextFetch(2); - cnote << s2.nextFetch(2); - s0.noteBlock(u256(0)); + assert((s0.nextFetch(2) == h256Set{(u256)7, (u256)8})); + assert((s1.nextFetch(2) == h256Set{(u256)5, (u256)6})); + assert((s2.nextFetch(2) == h256Set{(u256)3, (u256)4})); + s0.noteBlock(u256(8)); s0.doneFetch(); - cnote << s0.nextFetch(2); - s1.noteBlock(u256(2)); - s1.noteBlock(u256(3)); + assert((s0.nextFetch(2) == h256Set{(u256)2, (u256)7})); + s1.noteBlock(u256(6)); + s1.noteBlock(u256(5)); s1.doneFetch(); - cnote << s1.nextFetch(2); - s0.doneFetch(); - cnote << s0.nextFetch(2); + assert((s1.nextFetch(2) == h256Set{(u256)0, (u256)1})); + s0.doneFetch(); // TODO: check exact semantics of doneFetch & nextFetch. Not sure if they're right -> doneFetch calls resetFetch which kills all the info of past fetches. + cdebug << s0.nextFetch(2); + assert((s0.nextFetch(2) == h256Set{(u256)3, (u256)4})); /* RangeMask m(0, 100); cnote << m; @@ -73,49 +74,70 @@ int main() } #endif -int main(int argc, char** argv) +/*int other(bool& o_started) { - g_logVerbosity = 20; - - short listenPort = 30303; - string remoteHost; - short remotePort = 30303; + setThreadName("other"); - for (int i = 1; i < argc; ++i) - { - string arg = argv[i]; - if (arg == "-l" && i + 1 < argc) - listenPort = (short)atoi(argv[++i]); - else if (arg == "-r" && i + 1 < argc) - remoteHost = argv[++i]; - else if (arg == "-p" && i + 1 < argc) - remotePort = (short)atoi(argv[++i]); - else - remoteHost = argv[i]; - } + short listenPort = 30300; Host ph("Test", NetworkPreferences(listenPort, "", false, true)); auto wh = ph.registerCapability(new WhisperHost()); ph.start(); - if (!remoteHost.empty()) - ph.connect(remoteHost, remotePort); + o_started = true; /// Only interested in odd packets auto w = wh->installWatch(BuildTopicMask()("odd")); - KeyPair us = KeyPair::create(); - for (int i = 0; ; ++i) + unsigned last = 0; + unsigned total = 0; + + for (int i = 0; i < 100 && last < 81; ++i) { - wh->post(us.sec(), RLPStream().append(i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even")); for (auto i: wh->checkWatch(w)) { Message msg = wh->envelope(i).open(); - + last = RLP(msg.payload()).toInt(); cnote << "New message from:" << msg.from().abridged() << RLP(msg.payload()).toInt(); + total += last; } - this_thread::sleep_for(chrono::seconds(1)); + this_thread::sleep_for(chrono::milliseconds(50)); } - return 0; + return total; } + +int main(int, char**) +{ + g_logVerbosity = 0; + + bool started = false; + unsigned result; + std::thread listener([&](){ return (result = other(started)); }); + while (!started) + this_thread::sleep_for(chrono::milliseconds(50)); + + short listenPort = 30303; + string remoteHost = "127.0.0.1"; + short remotePort = 30300; + + Host ph("Test", NetworkPreferences(listenPort, "", false, true)); + auto wh = ph.registerCapability(new WhisperHost()); + + ph.start(); + + if (!remoteHost.empty()) + ph.connect(remoteHost, remotePort); + + KeyPair us = KeyPair::create(); + for (int i = 0; i < 10; ++i) + { + wh->post(us.sec(), RLPStream().append(i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even")); + this_thread::sleep_for(chrono::milliseconds(250)); + } + + listener.join(); + assert(result == 1 + 9 + 25 + 49 + 81); + + return 0; +}*/ diff --git a/iethxi/MainWin.cpp b/iethxi/MainWin.cpp index 276ff7630..2d5b57094 100644 --- a/iethxi/MainWin.cpp +++ b/iethxi/MainWin.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include "BuildInfo.h" diff --git a/libdevcore/Common.cpp b/libdevcore/Common.cpp index 78dbed65b..ae073b9b1 100644 --- a/libdevcore/Common.cpp +++ b/libdevcore/Common.cpp @@ -27,7 +27,7 @@ using namespace dev; namespace dev { -char const* Version = "0.7.9"; +char const* Version = "0.7.10"; } diff --git a/libdevcore/CommonData.cpp b/libdevcore/CommonData.cpp index bfcbc5e2e..bd7841402 100644 --- a/libdevcore/CommonData.cpp +++ b/libdevcore/CommonData.cpp @@ -29,14 +29,20 @@ using namespace dev; std::string dev::escaped(std::string const& _s, bool _all) { + static const map prettyEscapes{{'\r', 'r'}, {'\n', 'n'}, {'\t', 't'}, {'\v', 'v'}}; std::string ret; - ret.reserve(_s.size()); + ret.reserve(_s.size() + 2); ret.push_back('"'); for (auto i: _s) if (i == '"' && !_all) ret += "\\\""; else if (i == '\\' && !_all) ret += "\\\\"; + else if (prettyEscapes.count(i)) + { + ret += '\\'; + ret += prettyEscapes.find(i)->second; + } else if (i < ' ' || _all) { ret += "\\x"; diff --git a/libdevcore/CommonIO.cpp b/libdevcore/CommonIO.cpp index 3d2eccf13..8fc4fedb3 100644 --- a/libdevcore/CommonIO.cpp +++ b/libdevcore/CommonIO.cpp @@ -30,7 +30,7 @@ string dev::memDump(bytes const& _b, unsigned _w, bool _html) { stringstream ret; if (_html) - ret << "
";
+		ret << "
";
 	for (unsigned i = 0; i < _b.size(); i += _w)
 	{
 		ret << hex << setw(4) << setfill('0') << i << " ";
diff --git a/libdevcore/Log.h b/libdevcore/Log.h
index 704660276..2e111332c 100644
--- a/libdevcore/Log.h
+++ b/libdevcore/Log.h
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include "vector_ref.h"
+#include "CommonIO.h"
 
 namespace dev
 {
diff --git a/libdevcore/RLP.h b/libdevcore/RLP.h
index 248a2e645..3101f63d6 100644
--- a/libdevcore/RLP.h
+++ b/libdevcore/RLP.h
@@ -158,8 +158,13 @@ public:
 
 	/// Best-effort conversion operators.
 	explicit operator std::string() const { return toString(); }
+	explicit operator bytes() const { return toBytes(); }
 	explicit operator RLPs() const { return toList(); }
-	explicit operator byte() const { return toInt(); }
+	explicit operator uint8_t() const { return toInt(); }
+	explicit operator uint16_t() const { return toInt(); }
+	explicit operator uint32_t() const { return toInt(); }
+	explicit operator uint64_t() const { return toInt(); }
+	explicit operator u160() const { return toInt(); }
 	explicit operator u256() const { return toInt(); }
 	explicit operator bigint() const { return toInt(); }
 	template  explicit operator FixedHash<_N>() const { return toHash>(); }
@@ -337,7 +342,7 @@ public:
 	RLPStream& append(char const* _s) { return append(std::string(_s)); }
 	template  RLPStream& append(FixedHash _s, bool _compact = false, bool _allOrNothing = false) { return _allOrNothing && !_s ? append(bytesConstRef()) : append(_s.ref(), _compact); }
 
-	/// Appends an arbitrary RLP fragment - this *must* be a single item.
+	/// Appends an arbitrary RLP fragment - this *must* be a single item unless @a _itemCount is given.
 	RLPStream& append(RLP const& _rlp, unsigned _itemCount = 1) { return appendRaw(_rlp.data(), _itemCount); }
 
 	/// Appends a sequence of data to the stream as a list.
diff --git a/libdevcrypto/Common.cpp b/libdevcrypto/Common.cpp
index d82098655..2db65aae3 100644
--- a/libdevcrypto/Common.cpp
+++ b/libdevcrypto/Common.cpp
@@ -21,6 +21,7 @@
  */
 
 #include 
+#include 
 #include 
 #include "EC.h"
 #include "SHA3.h"
@@ -39,7 +40,7 @@ Address dev::toAddress(Secret _secret)
 
 KeyPair KeyPair::create()
 {
-	static mt19937_64 s_eng(time(0));
+	static mt19937_64 s_eng(time(0) + chrono::high_resolution_clock::now().time_since_epoch().count());
 	uniform_int_distribution d(0, 255);
 
 	for (int i = 0; i < 100; ++i)
diff --git a/libdevcrypto/EC.cpp b/libdevcrypto/EC.cpp
index 7bc17ab99..e6e6d2329 100644
--- a/libdevcrypto/EC.cpp
+++ b/libdevcrypto/EC.cpp
@@ -37,6 +37,8 @@ using namespace dev::crypto;
 using namespace CryptoPP;
 using namespace pp;
 
+static const int c_publicKeySize = 65;	// Public key size for I/O is 65 bytes (there's an extra byte that we don't really need).
+
 void crypto::toPublic(Secret const& _s, Public& o_public)
 {
 	exponentToPublic(Integer(_s.data(), sizeof(_s)), o_public);
@@ -134,16 +136,16 @@ bool crypto::verify(Signature const& _signature, bytesConstRef _message)
 
 bool crypto::verify(Public const& _p, Signature const& _sig, bytesConstRef _message, bool _hashed)
 {
-	static const size_t derMaxEncodingLength = 72;
+	static const size_t c_derMaxEncodingLength = 72;
 	if (_hashed)
 	{
 		assert(_message.size() == 32);
 		byte encpub[65] = {0x04};
 		memcpy(&encpub[1], _p.data(), 64);
-		byte dersig[derMaxEncodingLength];
-		size_t cssz = DSAConvertSignatureFormat(dersig, derMaxEncodingLength, DSA_DER, _sig.data(), 64, DSA_P1363);
-		assert(cssz <= derMaxEncodingLength);
-		return (1 == secp256k1_ecdsa_verify(_message.data(), _message.size(), dersig, cssz, encpub, 65));
+		byte dersig[c_derMaxEncodingLength];
+		size_t cssz = DSAConvertSignatureFormat(dersig, c_derMaxEncodingLength, DSA_DER, _sig.data(), 64, DSA_P1363);
+		assert(cssz <= c_derMaxEncodingLength);
+		return (1 == secp256k1_ecdsa_verify(_message.data(), _message.size(), dersig, cssz, encpub, c_publicKeySize));
 	}
 	
 	ECDSA::Verifier verifier;
@@ -155,10 +157,9 @@ Public crypto::recover(Signature _signature, bytesConstRef _message)
 {
 	secp256k1_start();
 	
-	static const int c_pubkeylen = 65;
-	auto pubkeylen = c_pubkeylen;
-	byte pubkey[c_pubkeylen];
-	if (!secp256k1_ecdsa_recover_compact(_message.data(), 32, _signature.data(), pubkey, &pubkeylen, 0, (int)_signature[64]))
+	byte pubkey[c_publicKeySize];
+	int keySize;
+	if (!secp256k1_ecdsa_recover_compact(_message.data(), 32, _signature.data(), pubkey, &keySize, 0, (int)_signature[64]) || keySize != c_publicKeySize)
 		return Public();
 	
 #if ETH_CRYPTO_TRACE
@@ -181,14 +182,14 @@ bool crypto::verifySecret(Secret const& _s, Public const& _p)
 	if (!ok)
 		return false;
 	
-	static const int c_pubkeylen = 65;
-	auto pubkeylen = c_pubkeylen;
-	byte pubkey[c_pubkeylen];
-	ok = secp256k1_ecdsa_pubkey_create(pubkey, &pubkeylen, _s.data(), 0);
-	if (!ok || pubkeylen != 65)
+	byte pubkey[c_publicKeySize];
+
+	int keySize;
+	ok = secp256k1_ecdsa_pubkey_create(pubkey, &keySize, _s.data(), 0);
+	if (!ok || keySize != c_publicKeySize)
 		return false;
 	
-	ok = secp256k1_ecdsa_pubkey_verify(pubkey, 65);
+	ok = secp256k1_ecdsa_pubkey_verify(pubkey, c_publicKeySize);
 	if (!ok)
 		return false;
 	
diff --git a/libethcore/CommonEth.cpp b/libethcore/CommonEth.cpp
index 8e21884ee..3c0a93481 100644
--- a/libethcore/CommonEth.cpp
+++ b/libethcore/CommonEth.cpp
@@ -34,7 +34,7 @@ namespace dev
 namespace eth
 {
 
-const unsigned c_protocolVersion = 39;
+const unsigned c_protocolVersion = 42;
 const unsigned c_databaseVersion = 4;
 
 static const vector> g_units =
diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp
index 2a28f99ed..30676765f 100644
--- a/libethereum/Executive.cpp
+++ b/libethereum/Executive.cpp
@@ -80,14 +80,14 @@ bool Executive::setup(bytesConstRef _rlp)
 	if (m_s.balance(m_sender) < cost)
 	{
 		clog(StateDetail) << "Not enough cash: Require >" << cost << " Got" << m_s.balance(m_sender);
-		BOOST_THROW_EXCEPTION(NotEnoughCash());
+		BOOST_THROW_EXCEPTION(NotEnoughCash() << RequirementError((int)cost, (int)m_s.balance(m_sender)));
 	}
 
 	u256 startGasUsed = m_s.gasUsed();
 	if (startGasUsed + m_t.gas() > m_s.m_currentBlock.gasLimit)
 	{
 		clog(StateDetail) << "Too much gas used in this block: Require <" << (m_s.m_currentBlock.gasLimit - startGasUsed) << " Got" << m_t.gas();
-		BOOST_THROW_EXCEPTION(BlockGasLimitReached());
+		BOOST_THROW_EXCEPTION(BlockGasLimitReached() << RequirementError((int)(m_s.m_currentBlock.gasLimit - startGasUsed), (int)m_t.gas()));
 	}
 
 	// Increment associated nonce for sender.
@@ -123,11 +123,7 @@ bool Executive::call(Address _receiveAddress, Address _senderAddress, u256 _valu
 		m_ext = new ExtVM(m_s, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &c, m_ms);
 	}
 	else
-	{
 		m_endGas = _gas;
-		if (m_ext)
-			m_ext->sub.logs.push_back(LogEntry(_receiveAddress, {u256((u160)_senderAddress) + 1}, bytes()));
-	}
 	return !m_ext;
 }
 
@@ -177,7 +173,10 @@ bool Executive::go(OnOpFunc const& _onOp)
 		{
 			m_out = m_vm->go(*m_ext, _onOp);
 			if (m_ext)
+			{
 				m_endGas += min((m_t.gas() - m_endGas) / 2, m_ext->sub.refunds);
+				m_logs = m_ext->sub.logs;
+			}
 			m_endGas = m_vm->gas();
 		}
 		catch (StepsDone const&)
diff --git a/libethereum/Executive.h b/libethereum/Executive.h
index 79b58d252..1a9a27d52 100644
--- a/libethereum/Executive.h
+++ b/libethereum/Executive.h
@@ -23,7 +23,7 @@
 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include "Transaction.h"
 #include "Manifest.h"
diff --git a/libethereum/ExtVM.h b/libethereum/ExtVM.h
index 758672e49..24ce618ed 100644
--- a/libethereum/ExtVM.h
+++ b/libethereum/ExtVM.h
@@ -40,7 +40,7 @@ class ExtVM: public ExtVMFace
 public:
 	/// Full constructor.
 	ExtVM(State& _s, Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytesConstRef _code, Manifest* o_ms, unsigned _depth = 0):
-		ExtVMFace(_myAddress, _caller, _origin, _value, _gasPrice, _data, _code, _s.m_previousBlock, _s.m_currentBlock, _depth), m_s(_s), m_origCache(_s.m_cache), m_ms(o_ms)
+		ExtVMFace(_myAddress, _caller, _origin, _value, _gasPrice, _data, _code.toBytes(), _s.m_previousBlock, _s.m_currentBlock, _depth), m_s(_s), m_origCache(_s.m_cache), m_ms(o_ms)
 	{
 		m_s.ensureCached(_myAddress, true, true);
 	}
diff --git a/libethereum/State.cpp b/libethereum/State.cpp
index 4cfe66cc1..2645e228b 100644
--- a/libethereum/State.cpp
+++ b/libethereum/State.cpp
@@ -21,12 +21,13 @@
 
 #include "State.h"
 
-#include 
-#include 
+#include 
 #include 
+#include 
+#include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include "BlockChain.h"
@@ -555,10 +556,12 @@ h256s State::sync(TransactionQueue& _tq, bool* o_transactionQueueChanged)
 				try
 				{
 					uncommitToMine();
+//					boost::timer t;
 					execute(i.second);
 					ret.push_back(m_receipts.back().changes().bloom());
 					_tq.noteGood(i);
 					++goodTxs;
+//					cnote << "TX took:" << t.elapsed() * 1000;
 				}
 				catch (InvalidNonce const& in)
 				{
@@ -1196,11 +1199,14 @@ bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderA
 	auto it = !(_codeAddress & ~h160(0xffffffff)) ? c_precompiled.find((unsigned)(u160)_codeAddress) : c_precompiled.end();
 	if (it != c_precompiled.end())
 	{
-		if (*_gas >= it->second.gas)
+		if (*_gas < it->second.gas)
 		{
-			*_gas -= it->second.gas;
-			it->second.exec(_data, _out);
+			*_gas = 0;
+			return false;
 		}
+
+		*_gas -= it->second.gas;
+		it->second.exec(_data, _out);
 	}
 	else if (addressHasCode(_codeAddress))
 	{
@@ -1242,12 +1248,6 @@ bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderA
 
 		return !revert;
 	}
-	else
-	{
-		// non-contract call
-		if (o_sub)
-			o_sub->logs.push_back(LogEntry(_receiveAddress, {u256((u160)_senderAddress) + 1}, bytes()));
-	}
 	return true;
 }
 
diff --git a/libethereum/TransactionReceipt.h b/libethereum/TransactionReceipt.h
index 26539c4a9..e24c224e7 100644
--- a/libethereum/TransactionReceipt.h
+++ b/libethereum/TransactionReceipt.h
@@ -55,6 +55,8 @@ public:
 			l.streamRLP(_s);
 	}
 
+	bytes rlp() const { RLPStream s; streamRLP(s); return s.out(); }
+
 private:
 	h256 m_stateRoot;
 	u256 m_gasUsed;
diff --git a/libevm/CMakeLists.txt b/libevm/CMakeLists.txt
index 0c31a9fc3..b4aa1eef2 100644
--- a/libevm/CMakeLists.txt
+++ b/libevm/CMakeLists.txt
@@ -17,7 +17,7 @@ include_directories(..)
 
 target_link_libraries(${EXECUTABLE} ethcore)
 target_link_libraries(${EXECUTABLE} devcrypto)
-target_link_libraries(${EXECUTABLE} evmface)
+target_link_libraries(${EXECUTABLE} evmcore)
 target_link_libraries(${EXECUTABLE} devcore)
 target_link_libraries(${EXECUTABLE} secp256k1)
 target_link_libraries(${EXECUTABLE} gmp)
diff --git a/libevm/ExtVMFace.cpp b/libevm/ExtVMFace.cpp
index da189d899..8a08a290c 100644
--- a/libevm/ExtVMFace.cpp
+++ b/libevm/ExtVMFace.cpp
@@ -25,7 +25,7 @@ using namespace std;
 using namespace dev;
 using namespace dev::eth;
 
-ExtVMFace::ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytesConstRef _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, unsigned _depth):
+ExtVMFace::ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes const& _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, unsigned _depth):
 	myAddress(_myAddress),
 	caller(_caller),
 	origin(_origin),
diff --git a/libevm/ExtVMFace.h b/libevm/ExtVMFace.h
index 62132a462..65761e410 100644
--- a/libevm/ExtVMFace.h
+++ b/libevm/ExtVMFace.h
@@ -27,7 +27,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 
@@ -49,7 +49,7 @@ using LogBloom = h512;
 struct LogEntry
 {
 	LogEntry() {}
-	LogEntry(RLP const& _r) { address = (Address)_r[0]; topics = (h256Set)_r[1]; data = (bytes)_r[2]; }
+	LogEntry(RLP const& _r) { address = (Address)_r[0]; topics = (h256Set)_r[1]; data = _r[2].toBytes(); }
 	LogEntry(Address const& _address, h256s const& _ts, bytes&& _d): address(_address), topics(toSet(_ts)), data(std::move(_d)) {}
 
 	void streamRLP(RLPStream& _s) const { _s.appendList(3) << address << topics << data; }
@@ -104,7 +104,7 @@ public:
 	ExtVMFace() = default;
 
 	/// Full constructor.
-	ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytesConstRef _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, unsigned _depth);
+	ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes const& _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, unsigned _depth);
 
 	virtual ~ExtVMFace() = default;
 
@@ -153,7 +153,7 @@ public:
 	u256 value;					///< Value (in Wei) that was passed to this address.
 	u256 gasPrice;				///< Price of gas (that we already paid).
 	bytesConstRef data;			///< Current input data.
-	bytesConstRef code;			///< Current code that is executing.
+	bytes code;			///< Current code that is executing.
 	BlockInfo previousBlock;	///< The previous block's information.
 	BlockInfo currentBlock;		///< The current block's information.
 	SubState sub;				///< Sub-band VM state (suicides, refund counter, logs).
diff --git a/libevm/FeeStructure.cpp b/libevm/FeeStructure.cpp
index 47236b506..6d868cac5 100644
--- a/libevm/FeeStructure.cpp
+++ b/libevm/FeeStructure.cpp
@@ -37,3 +37,6 @@ u256 const dev::eth::c_callGas = 20;
 u256 const dev::eth::c_memoryGas = 1;
 u256 const dev::eth::c_txDataGas = 5;
 u256 const dev::eth::c_txGas = 500;
+u256 const dev::eth::c_logGas = 32;
+u256 const dev::eth::c_logDataGas = 1;
+u256 const dev::eth::c_logTopicGas = 32;
diff --git a/libevm/FeeStructure.h b/libevm/FeeStructure.h
index 84a2551d9..e57f7ccf8 100644
--- a/libevm/FeeStructure.h
+++ b/libevm/FeeStructure.h
@@ -40,6 +40,9 @@ extern u256 const c_callGas;			///< Once per CALL operation & message call trans
 extern u256 const c_memoryGas;			///< Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL.
 extern u256 const c_txDataGas;			///< Per byte of data attached to a transaction. NOTE: Not payable on data of calls between transactions.
 extern u256 const c_txGas;				///< Per transaction. NOTE: Not payable on data of calls between transactions.
+extern u256 const c_logGas;				///< Per LOG* operation.
+extern u256 const c_logDataGas;			///< Per byte in a LOG* operation's data.
+extern u256 const c_logTopicGas;		///< Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas.
 
 }
 }
diff --git a/libevm/VM.h b/libevm/VM.h
index 3f67ce902..73d80b944 100644
--- a/libevm/VM.h
+++ b/libevm/VM.h
@@ -24,7 +24,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include "VMFace.h"
@@ -184,14 +184,15 @@ template  dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
 		{
 			unsigned n = (unsigned)inst - (unsigned)Instruction::LOG0;
 			require(n + 2);
-			newTempSize = memNeed(m_stack[m_stack.size() - 1 - n], m_stack[m_stack.size() - 2 - n]);
+			runGas = c_logGas + c_logTopicGas * n + (bigint)c_logDataGas * m_stack[m_stack.size() - 2];
+			newTempSize = memNeed(m_stack[m_stack.size() - 1], m_stack[m_stack.size() - 2]);
 			break;
 		}
 
 		case Instruction::CALL:
 		case Instruction::CALLCODE:
 			require(7);
-			runGas = c_callGas + m_stack[m_stack.size() - 1];
+			runGas = (bigint)c_callGas + m_stack[m_stack.size() - 1];
 			newTempSize = std::max(memNeed(m_stack[m_stack.size() - 6], m_stack[m_stack.size() - 7]), memNeed(m_stack[m_stack.size() - 4], m_stack[m_stack.size() - 5]));
 			break;
 
@@ -679,7 +680,7 @@ template  dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
 			break;
 		case Instruction::JUMP:
 			nextPC = m_stack.back();
-			if (!m_jumpDests.count((unsigned)nextPC))
+			if (!m_jumpDests.count(nextPC))
 				BOOST_THROW_EXCEPTION(BadJumpDestination());
 			m_stack.pop_back();
 			break;
@@ -687,7 +688,7 @@ template  dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
 			if (m_stack[m_stack.size() - 2])
 			{
 				nextPC = m_stack.back();
-				if (!m_jumpDests.count((unsigned)nextPC))
+				if (!m_jumpDests.count(nextPC))
 					BOOST_THROW_EXCEPTION(BadJumpDestination());
 			}
 			m_stack.pop_back();
@@ -721,18 +722,38 @@ template  dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
 			break;*/
 		case Instruction::LOG0:
 			_ext.log({}, bytesConstRef(m_temp.data() + (unsigned)m_stack[m_stack.size() - 1], (unsigned)m_stack[m_stack.size() - 2]));
+			m_stack.pop_back();
+			m_stack.pop_back();
 			break;
 		case Instruction::LOG1:
 			_ext.log({m_stack[m_stack.size() - 3]}, bytesConstRef(m_temp.data() + (unsigned)m_stack[m_stack.size() - 1], (unsigned)m_stack[m_stack.size() - 2]));
+			m_stack.pop_back();
+			m_stack.pop_back();
+			m_stack.pop_back();
 			break;
 		case Instruction::LOG2:
 			_ext.log({m_stack[m_stack.size() - 3], m_stack[m_stack.size() - 4]}, bytesConstRef(m_temp.data() + (unsigned)m_stack[m_stack.size() - 1], (unsigned)m_stack[m_stack.size() - 2]));
+			m_stack.pop_back();
+			m_stack.pop_back();
+			m_stack.pop_back();
+			m_stack.pop_back();
 			break;
 		case Instruction::LOG3:
 			_ext.log({m_stack[m_stack.size() - 3], m_stack[m_stack.size() - 4], m_stack[m_stack.size() - 5]}, bytesConstRef(m_temp.data() + (unsigned)m_stack[m_stack.size() - 1], (unsigned)m_stack[m_stack.size() - 2]));
+			m_stack.pop_back();
+			m_stack.pop_back();
+			m_stack.pop_back();
+			m_stack.pop_back();
+			m_stack.pop_back();
 			break;
 		case Instruction::LOG4:
 			_ext.log({m_stack[m_stack.size() - 3], m_stack[m_stack.size() - 4], m_stack[m_stack.size() - 5], m_stack[m_stack.size() - 6]}, bytesConstRef(m_temp.data() + (unsigned)m_stack[m_stack.size() - 1], (unsigned)m_stack[m_stack.size() - 2]));
+			m_stack.pop_back();
+			m_stack.pop_back();
+			m_stack.pop_back();
+			m_stack.pop_back();
+			m_stack.pop_back();
+			m_stack.pop_back();
 			break;
 		case Instruction::CREATE:
 		{
diff --git a/liblll/Assembly.cpp b/libevmcore/Assembly.cpp
similarity index 82%
rename from liblll/Assembly.cpp
rename to libevmcore/Assembly.cpp
index d4f6c0a73..4725c8c1a 100644
--- a/liblll/Assembly.cpp
+++ b/libevmcore/Assembly.cpp
@@ -70,7 +70,12 @@ unsigned Assembly::bytesRequired() const
 			case PushData:
 			case PushSub:
 				ret += 1 + br;
-			default:;
+				break;
+			case NoOptimizeBegin:
+			case NoOptimizeEnd:
+				break;
+			default:
+				BOOST_THROW_EXCEPTION(InvalidOpcode());
 			}
 		if (dev::bytesRequired(ret) <= br)
 			return ret;
@@ -140,9 +145,17 @@ ostream& dev::eth::operator<<(ostream& _out, AssemblyItemsConstRef _i)
 		case PushSubSize:
 			_out << " PUSHss[" << hex << h256(i.data()).abridged() << "]";
 			break;
+		case NoOptimizeBegin:
+			_out << " DoNotOptimze{{";
+			break;
+		case NoOptimizeEnd:
+			_out << " DoNotOptimze}}";
+			break;
 		case UndefinedItem:
 			_out << " ???";
-		default:;
+			break;
+		default:
+			BOOST_THROW_EXCEPTION(InvalidOpcode());
 		}
 	return _out;
 }
@@ -177,7 +190,14 @@ ostream& Assembly::streamRLP(ostream& _out, string const& _prefix) const
 		case PushData:
 			_out << _prefix << "  PUSH [" << hex << (unsigned)i.m_data << "]" << endl;
 			break;
-		default:;
+		case NoOptimizeBegin:
+			_out << _prefix << "DoNotOptimze{{" << endl;
+			break;
+		case NoOptimizeEnd:
+			_out << _prefix << "DoNotOptimze}}" << endl;
+			break;
+		default:
+			BOOST_THROW_EXCEPTION(InvalidOpcode());
 		}
 
 	if (m_data.size() || m_subs.size())
@@ -217,6 +237,12 @@ inline bool matches(AssemblyItemsConstRef _a, AssemblyItemsConstRef _b)
 	return true;
 }
 
+inline bool popCountIncreased(AssemblyItemsConstRef _pre, AssemblyItems const& _post)
+{
+	auto isPop = [](AssemblyItem const& _item) -> bool { return _item.match(AssemblyItem(Instruction::POP)); };
+	return count_if(begin(_post), end(_post), isPop) > count_if(begin(_pre), end(_pre), isPop);
+}
+
 struct OptimiserChannel: public LogChannel { static const char* name() { return "OPT"; } static const int verbosity = 12; };
 #define copt dev::LogOutputStream()
 
@@ -224,6 +250,14 @@ Assembly& Assembly::optimise(bool _enable)
 {
 	if (!_enable)
 		return *this;
+	auto signextend = [](u256 a, u256 b) -> u256
+	{
+		if (a >= 31)
+			return b;
+		unsigned testBit = unsigned(a) * 8 + 7;
+		u256 mask = (u256(1) << testBit) - 1;
+		return boost::multiprecision::bit_test(b, testBit) ? b | ~mask : b & mask;
+	};
 	map> c_simple =
 	{
 		{ Instruction::SUB, [](u256 a, u256 b)->u256{return a - b;} },
@@ -232,6 +266,7 @@ Assembly& Assembly::optimise(bool _enable)
 		{ Instruction::MOD, [](u256 a, u256 b)->u256{return a % b;} },
 		{ Instruction::SMOD, [](u256 a, u256 b)->u256{return s2u(u2s(a) % u2s(b));} },
 		{ Instruction::EXP, [](u256 a, u256 b)->u256{return (u256)boost::multiprecision::powm((bigint)a, (bigint)b, bigint(2) << 256);} },
+		{ Instruction::SIGNEXTEND, signextend },
 		{ Instruction::LT, [](u256 a, u256 b)->u256{return a < b ? 1 : 0;} },
 		{ Instruction::GT, [](u256 a, u256 b)->u256{return a > b ? 1 : 0;} },
 		{ Instruction::SLT, [](u256 a, u256 b)->u256{return u2s(a) < u2s(b) ? 1 : 0;} },
@@ -242,6 +277,9 @@ Assembly& Assembly::optimise(bool _enable)
 	{
 		{ Instruction::ADD, [](u256 a, u256 b)->u256{return a + b;} },
 		{ Instruction::MUL, [](u256 a, u256 b)->u256{return a * b;} },
+		{ Instruction::AND, [](u256 a, u256 b)->u256{return a & b;} },
+		{ Instruction::OR, [](u256 a, u256 b)->u256{return a | b;} },
+		{ Instruction::XOR, [](u256 a, u256 b)->u256{return a ^ b;} },
 	};
 	std::vector>> rules =
 	{
@@ -260,8 +298,23 @@ Assembly& Assembly::optimise(bool _enable)
 	{
 		rules.push_back({ { Push, Push, i.first }, [&](AssemblyItemsConstRef m) -> AssemblyItems { return { i.second(m[1].data(), m[0].data()) }; } });
 		rules.push_back({ { Push, i.first, Push, i.first }, [&](AssemblyItemsConstRef m) -> AssemblyItems { return { i.second(m[2].data(), m[0].data()), i.first }; } });
-		rules.push_back({ { PushTag, Instruction::JUMP, Tag }, [&](AssemblyItemsConstRef m) -> AssemblyItems { if (m[0].m_data == m[2].m_data) return {}; else return m.toVector(); }});
 	}
+	// jump to next instruction
+	rules.push_back({ { PushTag, Instruction::JUMP, Tag }, [&](AssemblyItemsConstRef m) -> AssemblyItems { if (m[0].m_data == m[2].m_data) return {m[2]}; else return m.toVector(); }});
+
+	// pop optimization, do not compute values that are popped again anyway
+	rules.push_back({ { AssemblyItem(UndefinedItem), Instruction::POP }, [](AssemblyItemsConstRef m) -> AssemblyItems
+					  {
+						  if (m[0].type() != Operation)
+							return m.toVector();
+						  Instruction instr = Instruction(byte(m[0].data()));
+						  if (Instruction::DUP1 <= instr && instr <= Instruction::DUP16)
+							return {};
+						  InstructionInfo info = instructionInfo(instr);
+						  if (info.sideEffects || info.additional != 0 || info.ret != 1)
+							  return m.toVector();
+						  return AssemblyItems(info.args, Instruction::POP);
+					  } });
 
 	copt << *this;
 
@@ -269,16 +322,21 @@ Assembly& Assembly::optimise(bool _enable)
 	for (unsigned count = 1; count > 0; total += count)
 	{
 		count = 0;
-		map tags;
 		for (unsigned i = 0; i < m_items.size(); ++i)
 		{
+			if (m_items[i].type() == NoOptimizeBegin)
+			{
+				while (i < m_items.size() && m_items[i].type() != NoOptimizeEnd)
+					++i;
+				continue;
+			}
 			for (auto const& r: rules)
 			{
 				auto vr = AssemblyItemsConstRef(&m_items).cropped(i, r.first.size());
-				if (matches(&r.first, vr))
+				if (matches(vr, &r.first))
 				{
 					auto rw = r.second(vr);
-					if (rw.size() < vr.size())
+					if (rw.size() < vr.size() || (rw.size() == vr.size() && popCountIncreased(vr, rw)))
 					{
 						copt << vr << "matches" << AssemblyItemsConstRef(&r.first) << "becomes...";
 						for (unsigned j = 0; j < vr.size(); ++j)
@@ -297,6 +355,8 @@ Assembly& Assembly::optimise(bool _enable)
 				bool o = false;
 				while (m_items.size() > i + 1 && m_items[i + 1].type() != Tag)
 				{
+					if (m_items[i + 1].type() == NoOptimizeBegin)
+						break;
 					m_items.erase(m_items.begin() + i + 1);
 					o = true;
 				}
@@ -308,6 +368,7 @@ Assembly& Assembly::optimise(bool _enable)
 			}
 		}
 
+		map tags;
 		for (unsigned i = 0; i < m_items.size(); ++i)
 			if (m_items[i].type() == Tag)
 				tags.insert(make_pair(m_items[i].data(), i));
@@ -416,7 +477,11 @@ bytes Assembly::assemble() const
 			tagPos[(unsigned)i.m_data] = ret.size();
 			ret.push_back((byte)Instruction::JUMPDEST);
 			break;
-		default:;
+		case NoOptimizeBegin:
+		case NoOptimizeEnd:
+			break;
+		default:
+			BOOST_THROW_EXCEPTION(InvalidOpcode());
 		}
 
 	for (auto const& i: tagRef)
diff --git a/liblll/Assembly.h b/libevmcore/Assembly.h
similarity index 97%
rename from liblll/Assembly.h
rename to libevmcore/Assembly.h
index e39f1899b..b8e59a474 100644
--- a/liblll/Assembly.h
+++ b/libevmcore/Assembly.h
@@ -24,7 +24,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include "Exceptions.h"
 
 namespace dev
@@ -32,7 +32,7 @@ namespace dev
 namespace eth
 {
 
-enum AssemblyItemType { UndefinedItem, Operation, Push, PushString, PushTag, PushSub, PushSubSize, Tag, PushData };
+enum AssemblyItemType { UndefinedItem, Operation, Push, PushString, PushTag, PushSub, PushSubSize, Tag, PushData, NoOptimizeBegin, NoOptimizeEnd };
 
 class Assembly;
 
diff --git a/libevmface/CMakeLists.txt b/libevmcore/CMakeLists.txt
similarity index 95%
rename from libevmface/CMakeLists.txt
rename to libevmcore/CMakeLists.txt
index f82d2b96b..738303271 100644
--- a/libevmface/CMakeLists.txt
+++ b/libevmcore/CMakeLists.txt
@@ -4,7 +4,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
 
 aux_source_directory(. SRC_LIST)
 
-set(EXECUTABLE evmface)
+set(EXECUTABLE evmcore)
 
 file(GLOB HEADERS "*.h")
 if(ETH_STATIC)
diff --git a/libevmcore/Exceptions.h b/libevmcore/Exceptions.h
new file mode 100644
index 000000000..57e1ac9c6
--- /dev/null
+++ b/libevmcore/Exceptions.h
@@ -0,0 +1,36 @@
+/*
+	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 .
+*/
+/** @file Exceptions.h
+ * @author Christian 
+ * @date 2014
+ */
+
+#pragma once
+
+#include 
+
+namespace dev
+{
+namespace eth
+{
+
+struct AssemblyException: virtual Exception {};
+struct InvalidDeposit: virtual AssemblyException {};
+struct InvalidOpcode: virtual AssemblyException {};
+
+}
+}
diff --git a/libevmcore/Instruction.cpp b/libevmcore/Instruction.cpp
new file mode 100644
index 000000000..9062fd8ed
--- /dev/null
+++ b/libevmcore/Instruction.cpp
@@ -0,0 +1,337 @@
+/*
+	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 .
+*/
+/** @file Instruction.cpp
+ * @author Gav Wood 
+ * @date 2014
+ */
+
+#include "Instruction.h"
+
+#include 
+#include 
+#include 
+using namespace std;
+using namespace dev;
+using namespace dev::eth;
+
+const std::map dev::eth::c_instructions =
+{
+	{ "STOP", Instruction::STOP },
+	{ "ADD", Instruction::ADD },
+	{ "SUB", Instruction::SUB },
+	{ "MUL", Instruction::MUL },
+	{ "DIV", Instruction::DIV },
+	{ "SDIV", Instruction::SDIV },
+	{ "MOD", Instruction::MOD },
+	{ "SMOD", Instruction::SMOD },
+	{ "EXP", Instruction::EXP },
+	{ "BNOT", Instruction::NOT },
+	{ "LT", Instruction::LT },
+	{ "GT", Instruction::GT },
+	{ "SLT", Instruction::SLT },
+	{ "SGT", Instruction::SGT },
+	{ "EQ", Instruction::EQ },
+	{ "NOT", Instruction::ISZERO },
+	{ "AND", Instruction::AND },
+	{ "OR", Instruction::OR },
+	{ "XOR", Instruction::XOR },
+	{ "BYTE", Instruction::BYTE },
+	{ "ADDMOD", Instruction::ADDMOD },
+	{ "MULMOD", Instruction::MULMOD },
+	{ "SIGNEXTEND", Instruction::SIGNEXTEND },
+	{ "SHA3", Instruction::SHA3 },
+	{ "ADDRESS", Instruction::ADDRESS },
+	{ "BALANCE", Instruction::BALANCE },
+	{ "ORIGIN", Instruction::ORIGIN },
+	{ "CALLER", Instruction::CALLER },
+	{ "CALLVALUE", Instruction::CALLVALUE },
+	{ "CALLDATALOAD", Instruction::CALLDATALOAD },
+	{ "CALLDATASIZE", Instruction::CALLDATASIZE },
+	{ "CALLDATACOPY", Instruction::CALLDATACOPY },
+	{ "CODESIZE", Instruction::CODESIZE },
+	{ "CODECOPY", Instruction::CODECOPY },
+	{ "GASPRICE", Instruction::GASPRICE },
+	{ "EXTCODESIZE", Instruction::EXTCODESIZE },
+	{ "EXTCODECOPY", Instruction::EXTCODECOPY },
+	{ "PREVHASH", Instruction::PREVHASH },
+	{ "COINBASE", Instruction::COINBASE },
+	{ "TIMESTAMP", Instruction::TIMESTAMP },
+	{ "NUMBER", Instruction::NUMBER },
+	{ "DIFFICULTY", Instruction::DIFFICULTY },
+	{ "GASLIMIT", Instruction::GASLIMIT },
+	{ "POP", Instruction::POP },
+	{ "MLOAD", Instruction::MLOAD },
+	{ "MSTORE", Instruction::MSTORE },
+	{ "MSTORE8", Instruction::MSTORE8 },
+	{ "SLOAD", Instruction::SLOAD },
+	{ "SSTORE", Instruction::SSTORE },
+	{ "JUMP", Instruction::JUMP },
+	{ "JUMPI", Instruction::JUMPI },
+	{ "PC", Instruction::PC },
+	{ "MSIZE", Instruction::MSIZE },
+	{ "GAS", Instruction::GAS },
+	{ "JUMPDEST", Instruction::JUMPDEST },
+	{ "PUSH1", Instruction::PUSH1 },
+	{ "PUSH2", Instruction::PUSH2 },
+	{ "PUSH3", Instruction::PUSH3 },
+	{ "PUSH4", Instruction::PUSH4 },
+	{ "PUSH5", Instruction::PUSH5 },
+	{ "PUSH6", Instruction::PUSH6 },
+	{ "PUSH7", Instruction::PUSH7 },
+	{ "PUSH8", Instruction::PUSH8 },
+	{ "PUSH9", Instruction::PUSH9 },
+	{ "PUSH10", Instruction::PUSH10 },
+	{ "PUSH11", Instruction::PUSH11 },
+	{ "PUSH12", Instruction::PUSH12 },
+	{ "PUSH13", Instruction::PUSH13 },
+	{ "PUSH14", Instruction::PUSH14 },
+	{ "PUSH15", Instruction::PUSH15 },
+	{ "PUSH16", Instruction::PUSH16 },
+	{ "PUSH17", Instruction::PUSH17 },
+	{ "PUSH18", Instruction::PUSH18 },
+	{ "PUSH19", Instruction::PUSH19 },
+	{ "PUSH20", Instruction::PUSH20 },
+	{ "PUSH21", Instruction::PUSH21 },
+	{ "PUSH22", Instruction::PUSH22 },
+	{ "PUSH23", Instruction::PUSH23 },
+	{ "PUSH24", Instruction::PUSH24 },
+	{ "PUSH25", Instruction::PUSH25 },
+	{ "PUSH26", Instruction::PUSH26 },
+	{ "PUSH27", Instruction::PUSH27 },
+	{ "PUSH28", Instruction::PUSH28 },
+	{ "PUSH29", Instruction::PUSH29 },
+	{ "PUSH30", Instruction::PUSH30 },
+	{ "PUSH31", Instruction::PUSH31 },
+	{ "PUSH32", Instruction::PUSH32 },
+	{ "DUP1", Instruction::DUP1 },
+	{ "DUP2", Instruction::DUP2 },
+	{ "DUP3", Instruction::DUP3 },
+	{ "DUP4", Instruction::DUP4 },
+	{ "DUP5", Instruction::DUP5 },
+	{ "DUP6", Instruction::DUP6 },
+	{ "DUP7", Instruction::DUP7 },
+	{ "DUP8", Instruction::DUP8 },
+	{ "DUP9", Instruction::DUP9 },
+	{ "DUP10", Instruction::DUP10 },
+	{ "DUP11", Instruction::DUP11 },
+	{ "DUP12", Instruction::DUP12 },
+	{ "DUP13", Instruction::DUP13 },
+	{ "DUP14", Instruction::DUP14 },
+	{ "DUP15", Instruction::DUP15 },
+	{ "DUP16", Instruction::DUP16 },
+	{ "SWAP1", Instruction::SWAP1 },
+	{ "SWAP2", Instruction::SWAP2 },
+	{ "SWAP3", Instruction::SWAP3 },
+	{ "SWAP4", Instruction::SWAP4 },
+	{ "SWAP5", Instruction::SWAP5 },
+	{ "SWAP6", Instruction::SWAP6 },
+	{ "SWAP7", Instruction::SWAP7 },
+	{ "SWAP8", Instruction::SWAP8 },
+	{ "SWAP9", Instruction::SWAP9 },
+	{ "SWAP10", Instruction::SWAP10 },
+	{ "SWAP11", Instruction::SWAP11 },
+	{ "SWAP12", Instruction::SWAP12 },
+	{ "SWAP13", Instruction::SWAP13 },
+	{ "SWAP14", Instruction::SWAP14 },
+	{ "SWAP15", Instruction::SWAP15 },
+	{ "SWAP16", Instruction::SWAP16 },
+	{ "LOG0", Instruction::LOG0 },
+	{ "LOG1", Instruction::LOG1 },
+	{ "LOG2", Instruction::LOG2 },
+	{ "LOG3", Instruction::LOG3 },
+	{ "LOG4", Instruction::LOG4 },
+	{ "CREATE", Instruction::CREATE },
+	{ "CALL", Instruction::CALL },
+	{ "CALLCODE", Instruction::CALLCODE },
+	{ "RETURN", Instruction::RETURN },
+	{ "SUICIDE", Instruction::SUICIDE }
+};
+
+static const std::map c_instructionInfo =
+{ //												Add, Args, Ret, SideEffects
+	{ Instruction::STOP,		{ "STOP",			0, 0, 0, true } },
+	{ Instruction::ADD,			{ "ADD",			0, 2, 1, false } },
+	{ Instruction::SUB,			{ "SUB",			0, 2, 1, false } },
+	{ Instruction::MUL,			{ "MUL",			0, 2, 1, false } },
+	{ Instruction::DIV,			{ "DIV",			0, 2, 1, false } },
+	{ Instruction::SDIV,		{ "SDIV",			0, 2, 1, false } },
+	{ Instruction::MOD,			{ "MOD",			0, 2, 1, false } },
+	{ Instruction::SMOD,		{ "SMOD",			0, 2, 1, false } },
+	{ Instruction::EXP,			{ "EXP",			0, 2, 1, false } },
+	{ Instruction::NOT,			{ "NOT",			0, 1, 1, false } },
+	{ Instruction::LT,			{ "LT",				0, 2, 1, false } },
+	{ Instruction::GT,			{ "GT",				0, 2, 1, false } },
+	{ Instruction::SLT,			{ "SLT",			0, 2, 1, false } },
+	{ Instruction::SGT,			{ "SGT",			0, 2, 1, false } },
+	{ Instruction::EQ,			{ "EQ",				0, 2, 1, false } },
+	{ Instruction::ISZERO,		{ "ISZERO",			0, 1, 1, false } },
+	{ Instruction::AND,			{ "AND",			0, 2, 1, false } },
+	{ Instruction::OR,			{ "OR",				0, 2, 1, false } },
+	{ Instruction::XOR,			{ "XOR",			0, 2, 1, false } },
+	{ Instruction::BYTE,		{ "BYTE",			0, 2, 1, false } },
+	{ Instruction::ADDMOD,		{ "ADDMOD",			0, 3, 1, false } },
+	{ Instruction::MULMOD,		{ "MULMOD",			0, 3, 1, false } },
+	{ Instruction::SIGNEXTEND,	{ "SIGNEXTEND",		0, 2, 1, false } },
+	{ Instruction::SHA3,		{ "SHA3",			0, 2, 1, false } },
+	{ Instruction::ADDRESS,		{ "ADDRESS",		0, 0, 1, false } },
+	{ Instruction::BALANCE,		{ "BALANCE",		0, 1, 1, false } },
+	{ Instruction::ORIGIN,		{ "ORIGIN",			0, 0, 1, false } },
+	{ Instruction::CALLER,		{ "CALLER",			0, 0, 1, false } },
+	{ Instruction::CALLVALUE,	{ "CALLVALUE",		0, 0, 1, false } },
+	{ Instruction::CALLDATALOAD,{ "CALLDATALOAD",	0, 1, 1, false } },
+	{ Instruction::CALLDATASIZE,{ "CALLDATASIZE",	0, 0, 1, false } },
+	{ Instruction::CALLDATACOPY,{ "CALLDATACOPY",	0, 3, 0, true } },
+	{ Instruction::CODESIZE,	{ "CODESIZE",		0, 0, 1, false } },
+	{ Instruction::CODECOPY,	{ "CODECOPY",		0, 3, 0, true } },
+	{ Instruction::GASPRICE,	{ "GASPRICE",		0, 0, 1, false } },
+	{ Instruction::EXTCODESIZE,	{ "EXTCODESIZE",	0, 1, 1, false } },
+	{ Instruction::EXTCODECOPY,	{ "EXTCODECOPY",	0, 4, 0, true } },
+	{ Instruction::PREVHASH,	{ "PREVHASH",		0, 0, 1, false } },
+	{ Instruction::COINBASE,	{ "COINBASE",		0, 0, 1, false } },
+	{ Instruction::TIMESTAMP,	{ "TIMESTAMP",		0, 0, 1, false } },
+	{ Instruction::NUMBER,		{ "NUMBER",			0, 0, 1, false } },
+	{ Instruction::DIFFICULTY,	{ "DIFFICULTY",		0, 0, 1, false } },
+	{ Instruction::GASLIMIT,	{ "GASLIMIT",		0, 0, 1, false } },
+	{ Instruction::POP,			{ "POP",			0, 1, 0, false } },
+	{ Instruction::MLOAD,		{ "MLOAD",			0, 1, 1, false } },
+	{ Instruction::MSTORE,		{ "MSTORE",			0, 2, 0, true } },
+	{ Instruction::MSTORE8,		{ "MSTORE8",		0, 2, 0, true } },
+	{ Instruction::SLOAD,		{ "SLOAD",			0, 1, 1, false } },
+	{ Instruction::SSTORE,		{ "SSTORE",			0, 2, 0, true } },
+	{ Instruction::JUMP,		{ "JUMP",			0, 1, 0, true } },
+	{ Instruction::JUMPI,		{ "JUMPI",			0, 2, 0, true } },
+	{ Instruction::PC,			{ "PC",				0, 0, 1, false } },
+	{ Instruction::MSIZE,		{ "MSIZE",			0, 0, 1, false } },
+	{ Instruction::GAS,			{ "GAS",			0, 0, 1, false } },
+	{ Instruction::JUMPDEST,	{ "JUMPDEST",		0, 1, 0, true } },
+	{ Instruction::PUSH1,		{ "PUSH1",			1, 0, 1, false } },
+	{ Instruction::PUSH2,		{ "PUSH2",			2, 0, 1, false } },
+	{ Instruction::PUSH3,		{ "PUSH3",			3, 0, 1, false } },
+	{ Instruction::PUSH4,		{ "PUSH4",			4, 0, 1, false } },
+	{ Instruction::PUSH5,		{ "PUSH5",			5, 0, 1, false } },
+	{ Instruction::PUSH6,		{ "PUSH6",			6, 0, 1, false } },
+	{ Instruction::PUSH7,		{ "PUSH7",			7, 0, 1, false } },
+	{ Instruction::PUSH8,		{ "PUSH8",			8, 0, 1, false } },
+	{ Instruction::PUSH9,		{ "PUSH9",			9, 0, 1, false } },
+	{ Instruction::PUSH10,		{ "PUSH10",			10, 0, 1, false } },
+	{ Instruction::PUSH11,		{ "PUSH11",			11, 0, 1, false } },
+	{ Instruction::PUSH12,		{ "PUSH12",			12, 0, 1, false } },
+	{ Instruction::PUSH13,		{ "PUSH13",			13, 0, 1, false } },
+	{ Instruction::PUSH14,		{ "PUSH14",			14, 0, 1, false } },
+	{ Instruction::PUSH15,		{ "PUSH15",			15, 0, 1, false } },
+	{ Instruction::PUSH16,		{ "PUSH16",			16, 0, 1, false } },
+	{ Instruction::PUSH17,		{ "PUSH17",			17, 0, 1, false } },
+	{ Instruction::PUSH18,		{ "PUSH18",			18, 0, 1, false } },
+	{ Instruction::PUSH19,		{ "PUSH19",			19, 0, 1, false } },
+	{ Instruction::PUSH20,		{ "PUSH20",			20, 0, 1, false } },
+	{ Instruction::PUSH21,		{ "PUSH21",			21, 0, 1, false } },
+	{ Instruction::PUSH22,		{ "PUSH22",			22, 0, 1, false } },
+	{ Instruction::PUSH23,		{ "PUSH23",			23, 0, 1, false } },
+	{ Instruction::PUSH24,		{ "PUSH24",			24, 0, 1, false } },
+	{ Instruction::PUSH25,		{ "PUSH25",			25, 0, 1, false } },
+	{ Instruction::PUSH26,		{ "PUSH26",			26, 0, 1, false } },
+	{ Instruction::PUSH27,		{ "PUSH27",			27, 0, 1, false } },
+	{ Instruction::PUSH28,		{ "PUSH28",			28, 0, 1, false } },
+	{ Instruction::PUSH29,		{ "PUSH29",			29, 0, 1, false } },
+	{ Instruction::PUSH30,		{ "PUSH30",			30, 0, 1, false } },
+	{ Instruction::PUSH31,		{ "PUSH31",			31, 0, 1, false } },
+	{ Instruction::PUSH32,		{ "PUSH32",			32, 0, 1, false } },
+	{ Instruction::DUP1,		{ "DUP1",			0, 1, 2, false } },
+	{ Instruction::DUP2,		{ "DUP2",			0, 2, 3, false } },
+	{ Instruction::DUP3,		{ "DUP3",			0, 3, 4, false } },
+	{ Instruction::DUP4,		{ "DUP4",			0, 4, 5, false } },
+	{ Instruction::DUP5,		{ "DUP5",			0, 5, 6, false } },
+	{ Instruction::DUP6,		{ "DUP6",			0, 6, 7, false } },
+	{ Instruction::DUP7,		{ "DUP7",			0, 7, 8, false } },
+	{ Instruction::DUP8,		{ "DUP8",			0, 8, 9, false } },
+	{ Instruction::DUP9,		{ "DUP9",			0, 9, 10, false } },
+	{ Instruction::DUP10,		{ "DUP10",			0, 10, 11, false } },
+	{ Instruction::DUP11,		{ "DUP11",			0, 11, 12, false } },
+	{ Instruction::DUP12,		{ "DUP12",			0, 12, 13, false } },
+	{ Instruction::DUP13,		{ "DUP13",			0, 13, 14, false } },
+	{ Instruction::DUP14,		{ "DUP14",			0, 14, 15, false } },
+	{ Instruction::DUP15,		{ "DUP15",			0, 15, 16, false } },
+	{ Instruction::DUP16,		{ "DUP16",			0, 16, 17, false } },
+	{ Instruction::SWAP1,		{ "SWAP1",			0, 2, 2, false } },
+	{ Instruction::SWAP2,		{ "SWAP2",			0, 3, 3, false } },
+	{ Instruction::SWAP3,		{ "SWAP3",			0, 4, 4, false } },
+	{ Instruction::SWAP4,		{ "SWAP4",			0, 5, 5, false } },
+	{ Instruction::SWAP5,		{ "SWAP5",			0, 6, 6, false } },
+	{ Instruction::SWAP6,		{ "SWAP6",			0, 7, 7, false } },
+	{ Instruction::SWAP7,		{ "SWAP7",			0, 8, 8, false } },
+	{ Instruction::SWAP8,		{ "SWAP8",			0, 9, 9, false } },
+	{ Instruction::SWAP9,		{ "SWAP9",			0, 10, 10, false } },
+	{ Instruction::SWAP10,		{ "SWAP10",			0, 11, 11, false } },
+	{ Instruction::SWAP11,		{ "SWAP11",			0, 12, 12, false } },
+	{ Instruction::SWAP12,		{ "SWAP12",			0, 13, 13, false } },
+	{ Instruction::SWAP13,		{ "SWAP13",			0, 14, 14, false } },
+	{ Instruction::SWAP14,		{ "SWAP14",			0, 15, 15, false } },
+	{ Instruction::SWAP15,		{ "SWAP15",			0, 16, 16, false } },
+	{ Instruction::SWAP16,		{ "SWAP16",			0, 17, 17, false } },
+	{ Instruction::LOG0,		{ "LOG0",			0, 2, 0, true } },
+	{ Instruction::LOG1,		{ "LOG1",			0, 3, 0, true } },
+	{ Instruction::LOG2,		{ "LOG2",			0, 4, 0, true } },
+	{ Instruction::LOG3,		{ "LOG3",			0, 5, 0, true } },
+	{ Instruction::LOG4,		{ "LOG4",			0, 6, 0, true } },
+	{ Instruction::CREATE,		{ "CREATE",			0, 3, 1, true } },
+	{ Instruction::CALL,		{ "CALL",			0, 7, 1, true } },
+	{ Instruction::CALLCODE,	{ "CALLCODE",		0, 7, 1, true } },
+	{ Instruction::RETURN,		{ "RETURN",			0, 2, 0, true } },
+	{ Instruction::SUICIDE,		{ "SUICIDE",		0, 1, 0, true } }
+};
+
+string dev::eth::disassemble(bytes const& _mem)
+{
+	stringstream ret;
+	unsigned numerics = 0;
+	for (auto it = _mem.begin(); it != _mem.end(); ++it)
+	{
+		byte n = *it;
+		auto iit = c_instructionInfo.find((Instruction)n);
+		if (numerics || iit == c_instructionInfo.end() || (byte)iit->first != n)	// not an instruction or expecting an argument...
+		{
+			if (numerics)
+				numerics--;
+			ret << "0x" << hex << (int)n << " ";
+		}
+		else
+		{
+			auto const& ii = iit->second;
+			ret << ii.name << " ";
+			numerics = ii.additional;
+		}
+	}
+	return ret.str();
+}
+
+InstructionInfo dev::eth::instructionInfo(Instruction _inst)
+{
+	try
+	{
+		return c_instructionInfo.at(_inst);
+	}
+	catch (...)
+	{
+		cwarn << "\n" << boost::current_exception_diagnostic_information();
+		return InstructionInfo({"", 0, 0, 0, false});
+	}
+}
+
+bool dev::eth::isValidInstruction(Instruction _inst)
+{
+	return !!c_instructionInfo.count(_inst);
+}
diff --git a/libevmface/Instruction.h b/libevmcore/Instruction.h
similarity index 98%
rename from libevmface/Instruction.h
rename to libevmcore/Instruction.h
index fadb5ab14..eb85c0610 100644
--- a/libevmface/Instruction.h
+++ b/libevmcore/Instruction.h
@@ -22,18 +22,13 @@
 #pragma once
 
 #include 
-#include 
-
-namespace boost { namespace spirit { class utree; } }
-namespace sp = boost::spirit;
+#include 
 
 namespace dev
 {
 namespace eth
 {
 
-struct InvalidOpcode: virtual Exception {};
-
 /// Virtual machine bytecode instruction.
 enum class Instruction: uint8_t
 {
@@ -209,6 +204,7 @@ struct InstructionInfo
 	int additional;		///< Additional items required in memory for this instructions (only for PUSH).
 	int args;			///< Number of items required on the stack for this instruction (and, for the purposes of ret, the number taken from the stack).
 	int ret;			///< Number of items placed (back) on the stack by this instruction, assuming args items were removed.
+	bool sideEffects;	///< false if the only effect on the execution environment (apart from gas usage) is a change to a topmost segment of the stack
 };
 
 /// Information on all the instructions.
diff --git a/libevmface/Instruction.cpp b/libevmface/Instruction.cpp
deleted file mode 100644
index a55cc2242..000000000
--- a/libevmface/Instruction.cpp
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
-	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 .
-*/
-/** @file Instruction.cpp
- * @author Gav Wood 
- * @date 2014
- */
-
-#include "Instruction.h"
-
-#include 
-#include 
-#include 
-using namespace std;
-using namespace dev;
-using namespace dev::eth;
-
-const std::map dev::eth::c_instructions =
-{
-	{ "STOP", Instruction::STOP },
-	{ "ADD", Instruction::ADD },
-	{ "SUB", Instruction::SUB },
-	{ "MUL", Instruction::MUL },
-	{ "DIV", Instruction::DIV },
-	{ "SDIV", Instruction::SDIV },
-	{ "MOD", Instruction::MOD },
-	{ "SMOD", Instruction::SMOD },
-	{ "EXP", Instruction::EXP },
-	{ "BNOT", Instruction::NOT },
-	{ "LT", Instruction::LT },
-	{ "GT", Instruction::GT },
-	{ "SLT", Instruction::SLT },
-	{ "SGT", Instruction::SGT },
-	{ "EQ", Instruction::EQ },
-	{ "NOT", Instruction::ISZERO },
-	{ "AND", Instruction::AND },
-	{ "OR", Instruction::OR },
-	{ "XOR", Instruction::XOR },
-	{ "BYTE", Instruction::BYTE },
-	{ "ADDMOD", Instruction::ADDMOD },
-	{ "MULMOD", Instruction::MULMOD },
-	{ "SIGNEXTEND", Instruction::SIGNEXTEND },
-	{ "SHA3", Instruction::SHA3 },
-	{ "ADDRESS", Instruction::ADDRESS },
-	{ "BALANCE", Instruction::BALANCE },
-	{ "ORIGIN", Instruction::ORIGIN },
-	{ "CALLER", Instruction::CALLER },
-	{ "CALLVALUE", Instruction::CALLVALUE },
-	{ "CALLDATALOAD", Instruction::CALLDATALOAD },
-	{ "CALLDATASIZE", Instruction::CALLDATASIZE },
-	{ "CALLDATACOPY", Instruction::CALLDATACOPY },
-	{ "CODESIZE", Instruction::CODESIZE },
-	{ "CODECOPY", Instruction::CODECOPY },
-	{ "GASPRICE", Instruction::GASPRICE },
-	{ "EXTCODESIZE", Instruction::EXTCODESIZE },
-	{ "EXTCODECOPY", Instruction::EXTCODECOPY },
-	{ "PREVHASH", Instruction::PREVHASH },
-	{ "COINBASE", Instruction::COINBASE },
-	{ "TIMESTAMP", Instruction::TIMESTAMP },
-	{ "NUMBER", Instruction::NUMBER },
-	{ "DIFFICULTY", Instruction::DIFFICULTY },
-	{ "GASLIMIT", Instruction::GASLIMIT },
-	{ "POP", Instruction::POP },
-	{ "MLOAD", Instruction::MLOAD },
-	{ "MSTORE", Instruction::MSTORE },
-	{ "MSTORE8", Instruction::MSTORE8 },
-	{ "SLOAD", Instruction::SLOAD },
-	{ "SSTORE", Instruction::SSTORE },
-	{ "JUMP", Instruction::JUMP },
-	{ "JUMPI", Instruction::JUMPI },
-	{ "PC", Instruction::PC },
-	{ "MSIZE", Instruction::MSIZE },
-	{ "GAS", Instruction::GAS },
-	{ "JUMPDEST", Instruction::JUMPDEST },
-	{ "PUSH1", Instruction::PUSH1 },
-	{ "PUSH2", Instruction::PUSH2 },
-	{ "PUSH3", Instruction::PUSH3 },
-	{ "PUSH4", Instruction::PUSH4 },
-	{ "PUSH5", Instruction::PUSH5 },
-	{ "PUSH6", Instruction::PUSH6 },
-	{ "PUSH7", Instruction::PUSH7 },
-	{ "PUSH8", Instruction::PUSH8 },
-	{ "PUSH9", Instruction::PUSH9 },
-	{ "PUSH10", Instruction::PUSH10 },
-	{ "PUSH11", Instruction::PUSH11 },
-	{ "PUSH12", Instruction::PUSH12 },
-	{ "PUSH13", Instruction::PUSH13 },
-	{ "PUSH14", Instruction::PUSH14 },
-	{ "PUSH15", Instruction::PUSH15 },
-	{ "PUSH16", Instruction::PUSH16 },
-	{ "PUSH17", Instruction::PUSH17 },
-	{ "PUSH18", Instruction::PUSH18 },
-	{ "PUSH19", Instruction::PUSH19 },
-	{ "PUSH20", Instruction::PUSH20 },
-	{ "PUSH21", Instruction::PUSH21 },
-	{ "PUSH22", Instruction::PUSH22 },
-	{ "PUSH23", Instruction::PUSH23 },
-	{ "PUSH24", Instruction::PUSH24 },
-	{ "PUSH25", Instruction::PUSH25 },
-	{ "PUSH26", Instruction::PUSH26 },
-	{ "PUSH27", Instruction::PUSH27 },
-	{ "PUSH28", Instruction::PUSH28 },
-	{ "PUSH29", Instruction::PUSH29 },
-	{ "PUSH30", Instruction::PUSH30 },
-	{ "PUSH31", Instruction::PUSH31 },
-	{ "PUSH32", Instruction::PUSH32 },
-	{ "DUP1", Instruction::DUP1 },
-	{ "DUP2", Instruction::DUP2 },
-	{ "DUP3", Instruction::DUP3 },
-	{ "DUP4", Instruction::DUP4 },
-	{ "DUP5", Instruction::DUP5 },
-	{ "DUP6", Instruction::DUP6 },
-	{ "DUP7", Instruction::DUP7 },
-	{ "DUP8", Instruction::DUP8 },
-	{ "DUP9", Instruction::DUP9 },
-	{ "DUP10", Instruction::DUP10 },
-	{ "DUP11", Instruction::DUP11 },
-	{ "DUP12", Instruction::DUP12 },
-	{ "DUP13", Instruction::DUP13 },
-	{ "DUP14", Instruction::DUP14 },
-	{ "DUP15", Instruction::DUP15 },
-	{ "DUP16", Instruction::DUP16 },
-	{ "SWAP1", Instruction::SWAP1 },
-	{ "SWAP2", Instruction::SWAP2 },
-	{ "SWAP3", Instruction::SWAP3 },
-	{ "SWAP4", Instruction::SWAP4 },
-	{ "SWAP5", Instruction::SWAP5 },
-	{ "SWAP6", Instruction::SWAP6 },
-	{ "SWAP7", Instruction::SWAP7 },
-	{ "SWAP8", Instruction::SWAP8 },
-	{ "SWAP9", Instruction::SWAP9 },
-	{ "SWAP10", Instruction::SWAP10 },
-	{ "SWAP11", Instruction::SWAP11 },
-	{ "SWAP12", Instruction::SWAP12 },
-	{ "SWAP13", Instruction::SWAP13 },
-	{ "SWAP14", Instruction::SWAP14 },
-	{ "SWAP15", Instruction::SWAP15 },
-	{ "SWAP16", Instruction::SWAP16 },
-	{ "LOG0", Instruction::LOG0 },
-	{ "LOG1", Instruction::LOG1 },
-	{ "LOG2", Instruction::LOG2 },
-	{ "LOG3", Instruction::LOG3 },
-	{ "LOG4", Instruction::LOG4 },
-	{ "CREATE", Instruction::CREATE },
-	{ "CALL", Instruction::CALL },
-	{ "CALLCODE", Instruction::CALLCODE },
-	{ "RETURN", Instruction::RETURN },
-	{ "SUICIDE", Instruction::SUICIDE }
-};
-
-static const std::map c_instructionInfo =
-{ //												Add, Args, Ret
-	{ Instruction::STOP,		{ "STOP",			0, 0, 0 } },
-	{ Instruction::ADD,			{ "ADD",			0, 2, 1 } },
-	{ Instruction::SUB,			{ "SUB",			0, 2, 1 } },
-	{ Instruction::MUL,			{ "MUL",			0, 2, 1 } },
-	{ Instruction::DIV,			{ "DIV",			0, 2, 1 } },
-	{ Instruction::SDIV,		{ "SDIV",			0, 2, 1 } },
-	{ Instruction::MOD,			{ "MOD",			0, 2, 1 } },
-	{ Instruction::SMOD,		{ "SMOD",			0, 2, 1 } },
-	{ Instruction::EXP,			{ "EXP",			0, 2, 1 } },
-	{ Instruction::NOT,		{ "BNOT",			0, 1, 1 } },
-	{ Instruction::LT,			{ "LT",				0, 2, 1 } },
-	{ Instruction::GT,			{ "GT",				0, 2, 1 } },
-	{ Instruction::SLT,			{ "SLT",			0, 2, 1 } },
-	{ Instruction::SGT,			{ "SGT",			0, 2, 1 } },
-	{ Instruction::EQ,			{ "EQ",				0, 2, 1 } },
-	{ Instruction::ISZERO,			{ "NOT",			0, 1, 1 } },
-	{ Instruction::AND,			{ "AND",			0, 2, 1 } },
-	{ Instruction::OR,			{ "OR",				0, 2, 1 } },
-	{ Instruction::XOR,			{ "XOR",			0, 2, 1 } },
-	{ Instruction::BYTE,		{ "BYTE",			0, 2, 1 } },
-	{ Instruction::ADDMOD,		{ "ADDMOD",			0, 3, 1 } },
-	{ Instruction::MULMOD,		{ "MULMOD",			0, 3, 1 } },
-	{ Instruction::SIGNEXTEND,	{ "SIGNEXTEND",		0, 2, 1 } },
-	{ Instruction::SHA3,		{ "SHA3",			0, 2, 1 } },
-	{ Instruction::ADDRESS,		{ "ADDRESS",		0, 0, 1 } },
-	{ Instruction::BALANCE,		{ "BALANCE",		0, 1, 1 } },
-	{ Instruction::ORIGIN,		{ "ORIGIN",			0, 0, 1 } },
-	{ Instruction::CALLER,		{ "CALLER",			0, 0, 1 } },
-	{ Instruction::CALLVALUE,	{ "CALLVALUE",		0, 0, 1 } },
-	{ Instruction::CALLDATALOAD,{ "CALLDATALOAD",	0, 1, 1 } },
-	{ Instruction::CALLDATASIZE,{ "CALLDATASIZE",	0, 0, 1 } },
-	{ Instruction::CALLDATACOPY,{ "CALLDATACOPY",	0, 3, 0 } },
-	{ Instruction::CODESIZE,	{ "CODESIZE",		0, 0, 1 } },
-	{ Instruction::CODECOPY,	{ "CODECOPY",		0, 3, 0 } },
-	{ Instruction::GASPRICE,	{ "GASPRICE",		0, 0, 1 } },
-	{ Instruction::EXTCODESIZE,	{ "EXTCODESIZE",	0, 1, 1 } },
-	{ Instruction::EXTCODECOPY,	{ "EXTCODECOPY",	0, 4, 0 } },
-	{ Instruction::PREVHASH,	{ "PREVHASH",		0, 0, 1 } },
-	{ Instruction::COINBASE,	{ "COINBASE",		0, 0, 1 } },
-	{ Instruction::TIMESTAMP,	{ "TIMESTAMP",		0, 0, 1 } },
-	{ Instruction::NUMBER,		{ "NUMBER",			0, 0, 1 } },
-	{ Instruction::DIFFICULTY,	{ "DIFFICULTY",		0, 0, 1 } },
-	{ Instruction::GASLIMIT,	{ "GASLIMIT",		0, 0, 1 } },
-	{ Instruction::POP,			{ "POP",			0, 1, 0 } },
-	{ Instruction::MLOAD,		{ "MLOAD",			0, 1, 1 } },
-	{ Instruction::MSTORE,		{ "MSTORE",			0, 2, 0 } },
-	{ Instruction::MSTORE8,		{ "MSTORE8",		0, 2, 0 } },
-	{ Instruction::SLOAD,		{ "SLOAD",			0, 1, 1 } },
-	{ Instruction::SSTORE,		{ "SSTORE",			0, 2, 0 } },
-	{ Instruction::JUMP,		{ "JUMP",			0, 1, 0 } },
-	{ Instruction::JUMPI,		{ "JUMPI",			0, 2, 0 } },
-	{ Instruction::PC,			{ "PC",				0, 0, 1 } },
-	{ Instruction::MSIZE,		{ "MSIZE",			0, 0, 1 } },
-	{ Instruction::GAS,			{ "GAS",			0, 0, 1 } },
-	{ Instruction::JUMPDEST,	{ "JUMPDEST",		0, 1, 0 } },
-	{ Instruction::PUSH1,		{ "PUSH1",			1, 0, 1 } },
-	{ Instruction::PUSH2,		{ "PUSH2",			2, 0, 1 } },
-	{ Instruction::PUSH3,		{ "PUSH3",			3, 0, 1 } },
-	{ Instruction::PUSH4,		{ "PUSH4",			4, 0, 1 } },
-	{ Instruction::PUSH5,		{ "PUSH5",			5, 0, 1 } },
-	{ Instruction::PUSH6,		{ "PUSH6",			6, 0, 1 } },
-	{ Instruction::PUSH7,		{ "PUSH7",			7, 0, 1 } },
-	{ Instruction::PUSH8,		{ "PUSH8",			8, 0, 1 } },
-	{ Instruction::PUSH9,		{ "PUSH9",			9, 0, 1 } },
-	{ Instruction::PUSH10,		{ "PUSH10",			10, 0, 1 } },
-	{ Instruction::PUSH11,		{ "PUSH11",			11, 0, 1 } },
-	{ Instruction::PUSH12,		{ "PUSH12",			12, 0, 1 } },
-	{ Instruction::PUSH13,		{ "PUSH13",			13, 0, 1 } },
-	{ Instruction::PUSH14,		{ "PUSH14",			14, 0, 1 } },
-	{ Instruction::PUSH15,		{ "PUSH15",			15, 0, 1 } },
-	{ Instruction::PUSH16,		{ "PUSH16",			16, 0, 1 } },
-	{ Instruction::PUSH17,		{ "PUSH17",			17, 0, 1 } },
-	{ Instruction::PUSH18,		{ "PUSH18",			18, 0, 1 } },
-	{ Instruction::PUSH19,		{ "PUSH19",			19, 0, 1 } },
-	{ Instruction::PUSH20,		{ "PUSH20",			20, 0, 1 } },
-	{ Instruction::PUSH21,		{ "PUSH21",			21, 0, 1 } },
-	{ Instruction::PUSH22,		{ "PUSH22",			22, 0, 1 } },
-	{ Instruction::PUSH23,		{ "PUSH23",			23, 0, 1 } },
-	{ Instruction::PUSH24,		{ "PUSH24",			24, 0, 1 } },
-	{ Instruction::PUSH25,		{ "PUSH25",			25, 0, 1 } },
-	{ Instruction::PUSH26,		{ "PUSH26",			26, 0, 1 } },
-	{ Instruction::PUSH27,		{ "PUSH27",			27, 0, 1 } },
-	{ Instruction::PUSH28,		{ "PUSH28",			28, 0, 1 } },
-	{ Instruction::PUSH29,		{ "PUSH29",			29, 0, 1 } },
-	{ Instruction::PUSH30,		{ "PUSH30",			30, 0, 1 } },
-	{ Instruction::PUSH31,		{ "PUSH31",			31, 0, 1 } },
-	{ Instruction::PUSH32,		{ "PUSH32",			32, 0, 1 } },
-	{ Instruction::DUP1,		{ "DUP1",			0, 1, 2 } },
-	{ Instruction::DUP2,		{ "DUP2",			0, 2, 3 } },
-	{ Instruction::DUP3,		{ "DUP3",			0, 3, 4 } },
-	{ Instruction::DUP4,		{ "DUP4",			0, 4, 5 } },
-	{ Instruction::DUP5,		{ "DUP5",			0, 5, 6 } },
-	{ Instruction::DUP6,		{ "DUP6",			0, 6, 7 } },
-	{ Instruction::DUP7,		{ "DUP7",			0, 7, 8 } },
-	{ Instruction::DUP8,		{ "DUP8",			0, 8, 9 } },
-	{ Instruction::DUP9,		{ "DUP9",			0, 9, 10 } },
-	{ Instruction::DUP10,		{ "DUP10",			0, 10, 11 } },
-	{ Instruction::DUP11,		{ "DUP11",			0, 11, 12 } },
-	{ Instruction::DUP12,		{ "DUP12",			0, 12, 13 } },
-	{ Instruction::DUP13,		{ "DUP13",			0, 13, 14 } },
-	{ Instruction::DUP14,		{ "DUP14",			0, 14, 15 } },
-	{ Instruction::DUP15,		{ "DUP15",			0, 15, 16 } },
-	{ Instruction::DUP16,		{ "DUP16",			0, 16, 17 } },
-	{ Instruction::SWAP1,		{ "SWAP1",			0, 2, 2 } },
-	{ Instruction::SWAP2,		{ "SWAP2",			0, 3, 3 } },
-	{ Instruction::SWAP3,		{ "SWAP3",			0, 4, 4 } },
-	{ Instruction::SWAP4,		{ "SWAP4",			0, 5, 5 } },
-	{ Instruction::SWAP5,		{ "SWAP5",			0, 6, 6 } },
-	{ Instruction::SWAP6,		{ "SWAP6",			0, 7, 7 } },
-	{ Instruction::SWAP7,		{ "SWAP7",			0, 8, 8 } },
-	{ Instruction::SWAP8,		{ "SWAP8",			0, 9, 9 } },
-	{ Instruction::SWAP9,		{ "SWAP9",			0, 10, 10 } },
-	{ Instruction::SWAP10,		{ "SWAP10",			0, 11, 11 } },
-	{ Instruction::SWAP11,		{ "SWAP11",			0, 12, 12 } },
-	{ Instruction::SWAP12,		{ "SWAP12",			0, 13, 13 } },
-	{ Instruction::SWAP13,		{ "SWAP13",			0, 14, 14 } },
-	{ Instruction::SWAP14,		{ "SWAP14",			0, 15, 15 } },
-	{ Instruction::SWAP15,		{ "SWAP15",			0, 16, 16 } },
-	{ Instruction::SWAP16,		{ "SWAP16",			0, 17, 17 } },
-	{ Instruction::LOG0,		{ "LOG0",			0, 1, 0 } },
-	{ Instruction::LOG1,		{ "LOG1",			0, 2, 0 } },
-	{ Instruction::LOG2,		{ "LOG2",			0, 3, 0 } },
-	{ Instruction::LOG3,		{ "LOG3",			0, 4, 0 } },
-	{ Instruction::LOG4,		{ "LOG4",			0, 5, 0 } },
-	{ Instruction::CREATE,		{ "CREATE",			0, 3, 1 } },
-	{ Instruction::CALL,		{ "CALL",			0, 7, 1 } },
-	{ Instruction::CALLCODE,	{ "CALLCODE",		0, 7, 1 } },
-	{ Instruction::RETURN,		{ "RETURN",			0, 2, 0 } },
-	{ Instruction::SUICIDE,		{ "SUICIDE",		0, 1, 0} }
-};
-
-string dev::eth::disassemble(bytes const& _mem)
-{
-	stringstream ret;
-	unsigned numerics = 0;
-	for (auto it = _mem.begin(); it != _mem.end(); ++it)
-	{
-		byte n = *it;
-		auto iit = c_instructionInfo.find((Instruction)n);
-		if (numerics || iit == c_instructionInfo.end() || (byte)iit->first != n)	// not an instruction or expecting an argument...
-		{
-			if (numerics)
-				numerics--;
-			ret << "0x" << hex << (int)n << " ";
-		}
-		else
-		{
-			auto const& ii = iit->second;
-			ret << ii.name << " ";
-			numerics = ii.additional;
-		}
-	}
-	return ret.str();
-}
-
-InstructionInfo dev::eth::instructionInfo(Instruction _inst)
-{
-	try
-	{
-		return c_instructionInfo.at(_inst);
-	}
-	catch (...)
-	{
-		cwarn << "\n" << boost::current_exception_diagnostic_information();
-		return InstructionInfo({"", 0, 0, 0});
-	}
-}
-
-bool dev::eth::isValidInstruction(Instruction _inst)
-{
-	return !!c_instructionInfo.count(_inst);
-}
diff --git a/libevmjit/CMakeLists.txt b/libevmjit/CMakeLists.txt
index cc63e72db..b06316dd2 100644
--- a/libevmjit/CMakeLists.txt
+++ b/libevmjit/CMakeLists.txt
@@ -18,7 +18,7 @@ include_directories(..)
 target_link_libraries(${EXECUTABLE} devcore)
 target_link_libraries(${EXECUTABLE} ethcore)
 target_link_libraries(${EXECUTABLE} evm)
-target_link_libraries(${EXECUTABLE} evmface)
+target_link_libraries(${EXECUTABLE} evmcore)
 
 
 if ("${TARGET_PLATFORM}" STREQUAL "w64")
diff --git a/libevmjit/Compiler.cpp b/libevmjit/Compiler.cpp
index 295f3a131..94e1450cd 100644
--- a/libevmjit/Compiler.cpp
+++ b/libevmjit/Compiler.cpp
@@ -13,7 +13,7 @@
 #include 
 #include 
 
-#include 
+#include 
 
 #include "Type.h"
 #include "Memory.h"
@@ -39,7 +39,7 @@ Compiler::Compiler(Options const& _options):
 	Type::init(m_builder.getContext());
 }
 
-void Compiler::createBasicBlocks(bytesConstRef _bytecode)
+void Compiler::createBasicBlocks(bytes const& _bytecode)
 {
 	std::set splitPoints; // Sorted collections of instruction indices where basic blocks start/end
 
@@ -151,7 +151,7 @@ void Compiler::createBasicBlocks(bytesConstRef _bytecode)
 		m_indirectJumpTargets.push_back(&basicBlocks.find(*it)->second);
 }
 
-std::unique_ptr Compiler::compile(bytesConstRef _bytecode)
+std::unique_ptr Compiler::compile(bytes const& _bytecode)
 {
 	auto module = std::unique_ptr(new llvm::Module("main", m_builder.getContext()));
 
@@ -247,7 +247,7 @@ std::unique_ptr Compiler::compile(bytesConstRef _bytecode)
 }
 
 
-void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytesConstRef _bytecode, RuntimeManager& _runtimeManager,
+void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode, RuntimeManager& _runtimeManager,
                                  Arith256& _arith, Memory& _memory, Ext& _ext, GasMeter& _gasMeter, llvm::BasicBlock* _nextBasicBlock)
 {
 	if (!_nextBasicBlock) // this is the last block in the code
@@ -508,7 +508,11 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytesConstRef _bytecod
 
 		case Instruction::POP:
 		{
-			stack.pop();
+			auto val = stack.pop();
+			static_cast(val);
+			// Generate a dummy use of val to make sure that a get(0) will be emitted at this point,
+			// so that StackTooSmall will be thrown
+			// m_builder.CreateICmpEQ(val, val, "dummy");
 			break;
 		}
 
@@ -791,6 +795,25 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytesConstRef _bytecod
 			break;
 		}
 
+		case Instruction::LOG0:
+		case Instruction::LOG1:
+		case Instruction::LOG2:
+		case Instruction::LOG3:
+		case Instruction::LOG4:
+		{
+			auto beginIdx = stack.pop();
+			auto numBytes = stack.pop();
+			_memory.require(beginIdx, numBytes);
+
+			std::array topics;
+			auto numTopics = static_cast(inst) - static_cast(Instruction::LOG0);
+			for (size_t i = 0; i < numTopics; ++i)
+				topics[i] = stack.pop();
+
+			_ext.log(beginIdx, numBytes, numTopics, topics);
+			break;
+		}
+
 		default: // Invalid instruction - runtime exception
 		{
 			_runtimeManager.raiseException(ReturnCode::BadInstruction);
diff --git a/libevmjit/Compiler.h b/libevmjit/Compiler.h
index 12b7f6e0e..a618f41a3 100644
--- a/libevmjit/Compiler.h
+++ b/libevmjit/Compiler.h
@@ -40,13 +40,13 @@ public:
 
 	Compiler(Options const& _options);
 
-	std::unique_ptr compile(bytesConstRef _bytecode);
+	std::unique_ptr compile(bytes const& _bytecode);
 
 private:
 
-	void createBasicBlocks(bytesConstRef _bytecode);
+    void createBasicBlocks(bytes const& _bytecode);
 
-	void compileBasicBlock(BasicBlock& _basicBlock, bytesConstRef _bytecode, class RuntimeManager& _runtimeManager, class Arith256& _arith, class Memory& _memory, class Ext& _ext, class GasMeter& _gasMeter, llvm::BasicBlock* _nextBasicBlock);
+    void compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode, class RuntimeManager& _runtimeManager, class Arith256& _arith, class Memory& _memory, class Ext& _ext, class GasMeter& _gasMeter, llvm::BasicBlock* _nextBasicBlock);
 
 	void removeDeadBlocks();
 
diff --git a/libevmjit/ExecutionEngine.cpp b/libevmjit/ExecutionEngine.cpp
index 4c617d9ea..02b12d373 100644
--- a/libevmjit/ExecutionEngine.cpp
+++ b/libevmjit/ExecutionEngine.cpp
@@ -37,10 +37,9 @@ namespace jit
 
 ExecutionEngine::ExecutionEngine()
 {
-
 }
 
-int ExecutionEngine::run(std::unique_ptr _module, u256& _gas, ExtVMFace* _ext)
+int ExecutionEngine::run(std::unique_ptr _module, u256& _gas, bool _outputLogs, ExtVMFace& _ext)
 {
 	auto module = _module.get(); // Keep ownership of the module in _module
 
@@ -83,34 +82,13 @@ int ExecutionEngine::run(std::unique_ptr _module, u256& _gas, ExtV
 	clog(JIT) << "Module finalization time: "
 			  << std::chrono::duration_cast(finalizationEndTime - finalizationStartTime).count();
 
-	// Create fake ExtVM interface
-	if (!_ext)
-	{
-		_ext = new ExtVMFace;
-		_ext->myAddress = Address(1122334455667788);
-		_ext->caller = Address(0xfacefacefaceface);
-		_ext->origin = Address(101010101010101010);
-		_ext->value = 0xabcd;
-		_ext->gasPrice = 1002;
-		_ext->previousBlock.hash = u256(1003);
-		_ext->currentBlock.coinbaseAddress = Address(1004);
-		_ext->currentBlock.timestamp = 1005;
-		_ext->currentBlock.number = 1006;
-		_ext->currentBlock.difficulty = 1007;
-		_ext->currentBlock.gasLimit = 1008;
-		std::string calldata = "Hello the Beautiful World of Ethereum!";
-		_ext->data = calldata;
-		unsigned char fakecode[] = {0x0d, 0x0e, 0x0a, 0x0d, 0x0b, 0x0e, 0xe, 0xf};
-		_ext->code = decltype(_ext->code)(fakecode, 8);
-	}
-
 	auto entryFunc = module->getFunction("main");
 	if (!entryFunc)
 		BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("main function not found"));
 
 	ReturnCode returnCode;
 	std::jmp_buf buf;
-	Runtime runtime(_gas, *_ext, buf);
+	Runtime runtime(_gas, _ext, buf, _outputLogs);
 	auto r = setjmp(buf);
 	if (r == 0)
 	{
diff --git a/libevmjit/ExecutionEngine.h b/libevmjit/ExecutionEngine.h
index 15a4e6ef7..8cf1ec746 100644
--- a/libevmjit/ExecutionEngine.h
+++ b/libevmjit/ExecutionEngine.h
@@ -18,7 +18,7 @@ class ExecutionEngine
 public:
 	ExecutionEngine();
 
-	int run(std::unique_ptr module, u256& _gas, ExtVMFace* _ext = nullptr);
+	int run(std::unique_ptr module, u256& _gas, bool _outputLogs, ExtVMFace& _ext);
 
 	bytes returnData;
 };
diff --git a/libevmjit/Ext.cpp b/libevmjit/Ext.cpp
index f39ab5755..17cbf5dc4 100644
--- a/libevmjit/Ext.cpp
+++ b/libevmjit/Ext.cpp
@@ -59,6 +59,11 @@ Ext::Ext(RuntimeManager& _runtimeManager):
 	m_exp = llvm::Function::Create(llvm::FunctionType::get(Type::Void, {argsTypes, 4}, false), Linkage::ExternalLinkage, "ext_exp", module);
 	m_codeAt = llvm::Function::Create(llvm::FunctionType::get(Type::BytePtr, {argsTypes, 2}, false), Linkage::ExternalLinkage, "ext_codeAt", module);
 	m_codesizeAt = llvm::Function::Create(llvm::FunctionType::get(Type::Void, {argsTypes, 3}, false), Linkage::ExternalLinkage, "ext_codesizeAt", module);
+	m_log0 = llvm::Function::Create(llvm::FunctionType::get(Type::Void, {argsTypes, 3}, false), Linkage::ExternalLinkage, "ext_log0", module);
+	m_log1 = llvm::Function::Create(llvm::FunctionType::get(Type::Void, {argsTypes, 4}, false), Linkage::ExternalLinkage, "ext_log1", module);
+	m_log2 = llvm::Function::Create(llvm::FunctionType::get(Type::Void, {argsTypes, 5}, false), Linkage::ExternalLinkage, "ext_log2", module);
+	m_log3 = llvm::Function::Create(llvm::FunctionType::get(Type::Void, {argsTypes, 6}, false), Linkage::ExternalLinkage, "ext_log3", module);
+	m_log4 = llvm::Function::Create(llvm::FunctionType::get(Type::Void, {argsTypes, 7}, false), Linkage::ExternalLinkage, "ext_log4", module);
 }
 
 llvm::Value* Ext::store(llvm::Value* _index)
@@ -160,6 +165,21 @@ llvm::Value* Ext::codesizeAt(llvm::Value* _addr)
 	return m_builder.CreateLoad(m_args[1]);
 }
 
+void Ext::log(llvm::Value* _memIdx, llvm::Value* _numBytes, size_t _numTopics, std::array const& _topics)
+{
+	static llvm::Value* args[] = {nullptr, m_args[0], m_args[1], m_arg2, m_arg3, m_arg4, m_arg5};
+	static llvm::Value* funcs[] = {m_log0, m_log1, m_log2, m_log3, m_log4};
+
+	args[0] = getRuntimeManager().getRuntimePtr();
+	m_builder.CreateStore(_memIdx, m_args[0]);
+	m_builder.CreateStore(_numBytes, m_args[1]);
+
+	for (size_t i = 0; i < _numTopics; ++i)
+		m_builder.CreateStore(_topics[i], args[i + 3]);
+
+	m_builder.CreateCall(funcs[_numTopics], llvm::ArrayRef(args, _numTopics + 3));
+}
+
 }
 
 
@@ -289,6 +309,111 @@ extern "C"
 		*o_ret = eth2llvm(u256(code.size()));
 	}
 
+	void ext_show_bytes(bytesConstRef _bytes)
+	{
+		for (auto b : _bytes)
+			std::cerr << std::hex << std::setw(2) << std::setfill('0') << static_cast(b) << " ";
+		std::cerr << std::endl;
+	}
+
+	EXPORT void ext_log0(Runtime* _rt, i256* _memIdx, i256* _numBytes)
+	{
+		auto&& ext = _rt->getExt();
+
+		auto memIdx = static_cast(llvm2eth(*_memIdx));
+		auto numBytes = static_cast(llvm2eth(*_numBytes));
+
+		auto dataRef = bytesConstRef(_rt->getMemory().data() + memIdx, numBytes);
+		ext.log({}, dataRef);
+
+		if (_rt->outputLogs())
+		{
+			std::cerr << "LOG: ";
+			ext_show_bytes(dataRef);
+		}
+	}
+
+	EXPORT void ext_log1(Runtime* _rt, i256* _memIdx, i256* _numBytes, i256* _topic1)
+	{
+		auto&& ext = _rt->getExt();
+
+		auto memIdx = static_cast(llvm2eth(*_memIdx));
+		auto numBytes = static_cast(llvm2eth(*_numBytes));
+
+		auto topic1 = llvm2eth(*_topic1);
+
+		auto dataRef = bytesConstRef(_rt->getMemory().data() + memIdx, numBytes);
+		ext.log({topic1}, dataRef);
+
+		if (_rt->outputLogs())
+		{
+			std::cerr << "LOG [" << topic1 << "]: ";
+			ext_show_bytes(dataRef);
+		}
+	}
+
+	EXPORT void ext_log2(Runtime* _rt, i256* _memIdx, i256* _numBytes, i256* _topic1, i256* _topic2)
+	{
+		auto&& ext = _rt->getExt();
+
+		auto memIdx = static_cast(llvm2eth(*_memIdx));
+		auto numBytes = static_cast(llvm2eth(*_numBytes));
+
+		auto topic1 = llvm2eth(*_topic1);
+		auto topic2 = llvm2eth(*_topic2);
+
+		auto dataRef = bytesConstRef(_rt->getMemory().data() + memIdx, numBytes);
+		ext.log({topic1, topic2}, dataRef);
+
+		if (_rt->outputLogs())
+		{
+			std::cerr << "LOG [" << topic1 << "][" << topic2 << "]: ";
+			ext_show_bytes(dataRef);
+		}
+	}
+
+	EXPORT void ext_log3(Runtime* _rt, i256* _memIdx, i256* _numBytes, i256* _topic1, i256* _topic2, i256* _topic3)
+	{
+		auto&& ext = _rt->getExt();
+
+		auto memIdx = static_cast(llvm2eth(*_memIdx));
+		auto numBytes = static_cast(llvm2eth(*_numBytes));
+
+		auto topic1 = llvm2eth(*_topic1);
+		auto topic2 = llvm2eth(*_topic2);
+		auto topic3 = llvm2eth(*_topic3);
+
+		auto dataRef = bytesConstRef(_rt->getMemory().data() + memIdx, numBytes);
+		ext.log({topic1, topic2, topic3}, dataRef);
+
+		if (_rt->outputLogs())
+		{
+			std::cerr << "LOG [" << topic1 << "][" << topic2 << "][" << topic3 << "]: ";
+			ext_show_bytes(dataRef);
+		}
+	}
+
+	EXPORT void ext_log4(Runtime* _rt, i256* _memIdx, i256* _numBytes, i256* _topic1, i256* _topic2, i256* _topic3, i256* _topic4)
+	{
+		auto&& ext = _rt->getExt();
+
+		auto memIdx = static_cast(llvm2eth(*_memIdx));
+		auto numBytes = static_cast(llvm2eth(*_numBytes));
+
+		auto topic1 = llvm2eth(*_topic1);
+		auto topic2 = llvm2eth(*_topic2);
+		auto topic3 = llvm2eth(*_topic3);
+		auto topic4 = llvm2eth(*_topic4);
+
+		auto dataRef = bytesConstRef(_rt->getMemory().data() + memIdx, numBytes);
+		ext.log({topic1, topic2, topic3, topic4}, dataRef);
+
+		if (_rt->outputLogs())
+		{
+			std::cerr << "LOG [" << topic1 << "][" << topic2 << "][" << topic3 << "][" << topic4 << "]: ";
+			ext_show_bytes(dataRef);
+		}
+	}
 }
 }
 }
diff --git a/libevmjit/Ext.h b/libevmjit/Ext.h
index 8e70af7d0..54380dda6 100644
--- a/libevmjit/Ext.h
+++ b/libevmjit/Ext.h
@@ -31,8 +31,10 @@ public:
 	llvm::Value* codeAt(llvm::Value* _addr);
 	llvm::Value* codesizeAt(llvm::Value* _addr);
 
+	void log(llvm::Value* _memIdx, llvm::Value* _numBytes, size_t _numTopics, std::array const& _topics);
 
 private:
+
 	llvm::Value* m_args[2];
 	llvm::Value* m_arg2;
 	llvm::Value* m_arg3;
@@ -53,6 +55,11 @@ private:
 	llvm::Function* m_exp;
 	llvm::Function* m_codeAt;
 	llvm::Function* m_codesizeAt;
+	llvm::Function* m_log0;
+	llvm::Function* m_log1;
+	llvm::Function* m_log2;
+	llvm::Function* m_log3;
+	llvm::Function* m_log4;
 };
 
 
diff --git a/libevmjit/GasMeter.cpp b/libevmjit/GasMeter.cpp
index 7a6a0ebd2..734931c32 100644
--- a/libevmjit/GasMeter.cpp
+++ b/libevmjit/GasMeter.cpp
@@ -5,7 +5,7 @@
 #include 
 #include 
 
-#include 
+#include 
 #include 
 
 #include "Type.h"
diff --git a/libevmjit/GasMeter.h b/libevmjit/GasMeter.h
index 3de227651..4be6c1a02 100644
--- a/libevmjit/GasMeter.h
+++ b/libevmjit/GasMeter.h
@@ -1,7 +1,7 @@
 
 #pragma once
 
-#include 
+#include 
 
 #include "CompilerHelper.h"
 
diff --git a/libevmjit/Memory.cpp b/libevmjit/Memory.cpp
index 89cef4d48..53cccf92b 100644
--- a/libevmjit/Memory.cpp
+++ b/libevmjit/Memory.cpp
@@ -147,24 +147,18 @@ llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType, GasMet
 llvm::Value* Memory::loadWord(llvm::Value* _addr)
 {
 	auto value = m_builder.CreateCall(m_loadWord, _addr);
-
-	dump(0);
 	return value;
 }
 
 void Memory::storeWord(llvm::Value* _addr, llvm::Value* _word)
 {
 	m_builder.CreateCall2(m_storeWord, _addr, _word);
-
-	dump(0);
 }
 
 void Memory::storeByte(llvm::Value* _addr, llvm::Value* _word)
 {
 	auto byte = m_builder.CreateTrunc(_word, Type::Byte, "byte");
 	m_builder.CreateCall2(m_storeByte, _addr, byte);
-
-	dump(0);
 }
 
 llvm::Value* Memory::getData()
@@ -205,18 +199,6 @@ void Memory::copyBytes(llvm::Value* _srcPtr, llvm::Value* _srcSize, llvm::Value*
 	m_builder.CreateMemCpy(destPtr, srcPtr, bytesToCopy, 0);
 }
 
-void Memory::dump(uint64_t _begin, uint64_t _end)
-{
-	if (getenv("EVMCC_DEBUG_MEMORY") == nullptr)
-		return;
-
-	auto beginVal = llvm::ConstantInt::get(m_builder.getInt64Ty(), _begin);
-	auto endVal = llvm::ConstantInt::get(m_builder.getInt64Ty(), _end);
-
-	std::vector args = {beginVal, endVal};
-	m_builder.CreateCall(m_memDump, llvm::ArrayRef(args));
-}
-
 }
 }
 }
diff --git a/libevmjit/Memory.h b/libevmjit/Memory.h
index 37bfb15f5..c6ba02a54 100644
--- a/libevmjit/Memory.h
+++ b/libevmjit/Memory.h
@@ -27,8 +27,6 @@ public:
 	/// Requires the amount of memory to for data defined by offset and size. And counts gas fee for that memory.
 	void require(llvm::Value* _offset, llvm::Value* _size);
 
-	void dump(uint64_t _begin, uint64_t _end = 0);
-
 private:
 	llvm::Function* createFunc(bool _isStore, llvm::Type* _type, GasMeter& _gasMeter);
 	llvm::Function* createRequireFunc(GasMeter& _gasMeter, RuntimeManager& _runtimeManager);
diff --git a/libevmjit/Runtime.cpp b/libevmjit/Runtime.cpp
index 982dd9f36..8e52b648a 100644
--- a/libevmjit/Runtime.cpp
+++ b/libevmjit/Runtime.cpp
@@ -58,8 +58,9 @@ llvm::Twine getName(RuntimeData::Index _index)
 }
 }
 
-Runtime::Runtime(u256 _gas, ExtVMFace& _ext, jmp_buf _jmpBuf):
-	m_ext(_ext)
+Runtime::Runtime(u256 _gas, ExtVMFace& _ext, jmp_buf _jmpBuf, bool _outputLogs):
+	m_ext(_ext),
+	m_outputLogs(_outputLogs)
 {
 	set(RuntimeData::Gas, _gas);
 	set(RuntimeData::Address, fromAddress(_ext.myAddress));
@@ -101,6 +102,11 @@ bytesConstRef Runtime::getReturnData() const
 	return {m_memory.data() + offset, size};
 }
 
+bool Runtime::outputLogs() const
+{
+	return m_outputLogs;
+}
+
 
 RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder): CompilerHelper(_builder)
 {
diff --git a/libevmjit/Runtime.h b/libevmjit/Runtime.h
index 8c784b394..8f485794a 100644
--- a/libevmjit/Runtime.h
+++ b/libevmjit/Runtime.h
@@ -63,7 +63,7 @@ using MemoryImpl = bytes;
 class Runtime
 {
 public:
-	Runtime(u256 _gas, ExtVMFace& _ext, jmp_buf _jmpBuf);
+	Runtime(u256 _gas, ExtVMFace& _ext, jmp_buf _jmpBuf, bool _outputLogs);
 
 	Runtime(const Runtime&) = delete;
 	void operator=(const Runtime&) = delete;
@@ -77,6 +77,7 @@ public:
 	u256 getGas() const;
 	bytesConstRef getReturnData() const;
 	decltype(&jmp_buf{}[0]) getJmpBuf() { return m_data.jmpBuf; }
+	bool outputLogs() const;
 
 private:
 	void set(RuntimeData::Index _index, u256 _value);
@@ -86,6 +87,7 @@ private:
 	StackImpl m_stack;
 	MemoryImpl m_memory;
 	ExtVMFace& m_ext;
+	bool m_outputLogs; ///< write LOG statements to console
 };
 
 class RuntimeManager: public CompilerHelper
diff --git a/libevmjit/Utils.cpp b/libevmjit/Utils.cpp
index 966dc69bd..548ee0e1f 100644
--- a/libevmjit/Utils.cpp
+++ b/libevmjit/Utils.cpp
@@ -35,7 +35,7 @@ i256 eth2llvm(u256 _u)
 	return i;
 }
 
-u256 readPushData(const byte*& _curr, const byte* _end)
+u256 readPushData(bytes::const_iterator& _curr, bytes::const_iterator _end)
 {
 	auto pushInst = *_curr;
 	assert(Instruction(pushInst) >= Instruction::PUSH1 && Instruction(pushInst) <= Instruction::PUSH32);
diff --git a/libevmjit/Utils.h b/libevmjit/Utils.h
index 9fa9f050e..54291f3e0 100644
--- a/libevmjit/Utils.h
+++ b/libevmjit/Utils.h
@@ -5,7 +5,7 @@
 
 #include 
 #include 
-#include 
+#include 
 
 namespace dev
 {
@@ -33,7 +33,7 @@ i256 eth2llvm(u256);
 /// Reads PUSH data from pointed fragment of bytecode and constructs number out of it
 /// Reading out of bytecode means reading 0
 /// @param _curr is updates and points the last real byte read
-u256 readPushData(const byte*& _curr, const byte* _end);
+u256 readPushData(bytes::const_iterator& _curr, bytes::const_iterator _end);
 
 #define ANY_PUSH	  PUSH1:  \
 	case Instruction::PUSH2:  \
diff --git a/libevmjit/VM.cpp b/libevmjit/VM.cpp
index 0c89587e9..9b60fccf1 100644
--- a/libevmjit/VM.cpp
+++ b/libevmjit/VM.cpp
@@ -20,7 +20,7 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const&, uint64_t)
 	auto module = Compiler(defaultOptions).compile(_ext.code);
 
 	ExecutionEngine engine;
-	auto exitCode = engine.run(std::move(module), m_gas, &_ext);
+	auto exitCode = engine.run(std::move(module), m_gas, false, _ext);
 
 	switch (static_cast(exitCode))
 	{
diff --git a/libjsqrc/main.js b/libjsqrc/main.js
index 821de6382..09fe00105 100644
--- a/libjsqrc/main.js
+++ b/libjsqrc/main.js
@@ -2,19 +2,19 @@
     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 General Public License as published by
+    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 General Public License for more details.
+    GNU Lesser General Public License for more details.
 
-    You should have received a copy of the GNU General Public License
+    You should have received a copy of the GNU Lesser General Public License
     along with ethereum.js.  If not, see .
 */
-/** @file ethereum.js
+/** @file main.js
  * @authors:
  *   Marek Kotewicz 
  * @date 2014
@@ -66,82 +66,83 @@
 
     var ethMethods = function () {
         var blockCall = function (args) {
-            return typeof args[0] === "string" ? "blockByHash" : "blockByNumber";
+            return typeof args[0] === "string" ? "eth_blockByHash" : "eth_blockByNumber";
         };
 
         var transactionCall = function (args) {
-            return typeof args[0] === "string" ? 'transactionByHash' : 'transactionByNumber';   
+            return typeof args[0] === "string" ? 'eth_transactionByHash' : 'eth_transactionByNumber';   
         };
 
         var uncleCall = function (args) {
-            return typeof args[0] === "string" ? 'uncleByHash' : 'uncleByNumber';       
+            return typeof args[0] === "string" ? 'eth_uncleByHash' : 'eth_uncleByNumber';       
         };
 
         var methods = [
-        { name: 'balanceAt', call: 'balanceAt' },
-        { name: 'stateAt', call: 'stateAt' },
-        { name: 'countAt', call: 'countAt'},
-        { name: 'codeAt', call: 'codeAt' },
-        { name: 'transact', call: 'transact' },
-        { name: 'call', call: 'call' },
+        { name: 'balanceAt', call: 'eth_balanceAt' },
+        { name: 'stateAt', call: 'eth_stateAt' },
+        { name: 'countAt', call: 'eth_countAt'},
+        { name: 'codeAt', call: 'eth_codeAt' },
+        { name: 'transact', call: 'eth_transact' },
+        { name: 'call', call: 'eth_call' },
         { name: 'block', call: blockCall },
         { name: 'transaction', call: transactionCall },
         { name: 'uncle', call: uncleCall },
-        { name: 'compile', call: 'compile' }
+        { name: 'compile', call: 'eth_compile' },
+        { name: 'lll', call: 'eth_lll' }
         ];
         return methods;
     };
 
     var ethProperties = function () {
         return [
-        { name: 'coinbase', getter: 'coinbase', setter: 'setCoinbase' },
-        { name: 'listening', getter: 'listening', setter: 'setListening' },
-        { name: 'mining', getter: 'mining', setter: 'setMining' },
-        { name: 'gasPrice', getter: 'gasPrice' },
-        { name: 'account', getter: 'account' },
-        { name: 'accounts', getter: 'accounts' },
-        { name: 'peerCount', getter: 'peerCount' },
-        { name: 'defaultBlock', getter: 'defaultBlock', setter: 'setDefaultBlock' },
-        { name: 'number', getter: 'number'}
+        { name: 'coinbase', getter: 'eth_coinbase', setter: 'eth_setCoinbase' },
+        { name: 'listening', getter: 'eth_listening', setter: 'eth_setListening' },
+        { name: 'mining', getter: 'eth_mining', setter: 'eth_setMining' },
+        { name: 'gasPrice', getter: 'eth_gasPrice' },
+        { name: 'account', getter: 'eth_account' },
+        { name: 'accounts', getter: 'eth_accounts' },
+        { name: 'peerCount', getter: 'eth_peerCount' },
+        { name: 'defaultBlock', getter: 'eth_defaultBlock', setter: 'eth_setDefaultBlock' },
+        { name: 'number', getter: 'eth_number'}
         ];
     };
 
     var dbMethods = function () {
         return [
-        { name: 'put', call: 'put' },
-        { name: 'get', call: 'get' },
-        { name: 'putString', call: 'putString' },
-        { name: 'getString', call: 'getString' }
+        { name: 'put', call: 'db_put' },
+        { name: 'get', call: 'db_get' },
+        { name: 'putString', call: 'db_putString' },
+        { name: 'getString', call: 'db_getString' }
         ];
     };
 
     var shhMethods = function () {
         return [
-        { name: 'post', call: 'post' },
-        { name: 'newIdentity', call: 'newIdentity' },
-        { name: 'haveIdentity', call: 'haveIdentity' },
-        { name: 'newGroup', call: 'newGroup' },
-        { name: 'addToGroup', call: 'addToGroup' }
+        { name: 'post', call: 'shh_post' },
+        { name: 'newIdentity', call: 'shh_newIdentity' },
+        { name: 'haveIdentity', call: 'shh_haveIdentity' },
+        { name: 'newGroup', call: 'shh_newGroup' },
+        { name: 'addToGroup', call: 'shh_addToGroup' }
         ];
     };
 
     var ethWatchMethods = function () {
         var newFilter = function (args) {
-            return typeof args[0] === 'string' ? 'newFilterString' : 'newFilter';
+            return typeof args[0] === 'string' ? 'eth_newFilterString' : 'eth_newFilter';
         };
 
         return [
         { name: 'newFilter', call: newFilter },
-        { name: 'uninstallFilter', call: 'uninstallFilter' },
-        { name: 'getMessages', call: 'getMessages' }
+        { name: 'uninstallFilter', call: 'eth_uninstallFilter' },
+        { name: 'getMessages', call: 'eth_getMessages' }
         ];
     };
 
     var shhWatchMethods = function () {
         return [
-        { name: 'newFilter', call: 'shhNewFilter' },
-        { name: 'uninstallFilter', call: 'shhUninstallFilter' },
-        { name: 'getMessage', call: 'shhGetMessages' }
+        { name: 'newFilter', call: 'shh_newFilter' },
+        { name: 'uninstallFilter', call: 'shh_uninstallFilter' },
+        { name: 'getMessage', call: 'shh_getMessages' }
         ];
     };
 
@@ -153,15 +154,15 @@
                     return {call: call, args: args};
                 }).then(function (request) {
                     return new Promise(function (resolve, reject) {
-                        web3.provider.send(request, function (result) {
-                            if (result || typeof result === "boolean") {
+                        web3.provider.send(request, function (err, result) {
+                            if (!err) {
                                 resolve(result);
                                 return;
                             } 
-                            reject(result);
+                            reject(err);
                         });
                     });
-                }).catch(function( err) {
+                }).catch(function(err) {
                     console.error(err);
                 });
             };
@@ -173,8 +174,12 @@
             var proto = {};
             proto.get = function () {
                 return new Promise(function(resolve, reject) {
-                    web3.provider.send({call: property.getter}, function(result) {
-                        resolve(result);
+                    web3.provider.send({call: property.getter}, function(err, result) {
+                        if (!err) {
+                            resolve(result);
+                            return;
+                        }
+                        reject(err);
                     });
                 });
             };
@@ -182,12 +187,12 @@
                 proto.set = function (val) {
                     return flattenPromise([val]).then(function (args) {
                         return new Promise(function (resolve) {
-                            web3.provider.send({call: property.setter, args: args}, function (result) {
-                                if (result) {
+                            web3.provider.send({call: property.setter, args: args}, function (err, result) {
+                                if (!err) {
                                     resolve(result);
-                                } else {
-                                    reject(result);
+                                    return;
                                 }
+                                reject(err);
                             });
                         });
                     }).catch(function (err) {
@@ -218,7 +223,7 @@
             var str = "";
             var i = 0, l = hex.length;
             if (hex.substring(0, 2) == '0x')
-            	i = 2;
+                i = 2;
             for(; i < l; i+=2) {
                 var code = hex.charCodeAt(i)
                 if(code == 0) {
@@ -240,7 +245,7 @@
             var hex = this.toHex(str);
             while(hex.length < pad*2)
                 hex += "00";
-            return "0x" + hex
+            return "0x" + hex;
         },
 
         eth: {
@@ -295,11 +300,11 @@
     setupMethods(web3.shh, shhMethods());
 
     var ethWatch = {
-        changed: 'changed'
+        changed: 'eth_changed'
     };
     setupMethods(ethWatch, ethWatchMethods());
     var shhWatch = {
-        changed: 'shhChanged'
+        changed: 'shh_changed'
     };
     setupMethods(shhWatch, shhWatchMethods());
 
@@ -410,8 +415,10 @@
     };
 
     Filter.prototype.trigger = function(messages) {
-        for(var i = 0; i < this.callbacks.length; i++) {
-            this.callbacks[i].call(this, messages);
+    	if (!(messages instanceof Array) || messages.length) {
+            for(var i = 0; i < this.callbacks.length; i++) {
+                this.callbacks[i].call(this, messages);
+            }
         }
     };
 
@@ -440,7 +447,7 @@
         if(data._id) {
             var cb = web3._callbacks[data._id];
             if (cb) {
-                cb.call(this, data.data)
+                cb.call(this, data.error, data.data);
                 delete web3._callbacks[data._id];
             }
         }
diff --git a/libjsqrc/qt.js b/libjsqrc/qt.js
index f0312eb2f..aedd34236 100644
--- a/libjsqrc/qt.js
+++ b/libjsqrc/qt.js
@@ -2,19 +2,19 @@
     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 General Public License as published by
+    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 General Public License for more details.
+    GNU Lesser General Public License for more details.
 
-    You should have received a copy of the GNU General Public License
+    You should have received a copy of the GNU Lesser General Public License
     along with ethereum.js.  If not, see .
 */
-/** @file ethereum.js
+/** @file qt.js
  * @authors:
  *   Marek Kotewicz 
  * @date 2014
diff --git a/libjsqrc/setup.js b/libjsqrc/setup.js
index 549222119..5142412a6 100644
--- a/libjsqrc/setup.js
+++ b/libjsqrc/setup.js
@@ -14,7 +14,7 @@
 	You should have received a copy of the GNU General Public License
 	along with cpp-ethereum.  If not, see .
 */
-/** @file QEthereum.cpp
+/** @file setup.js
  * @authors:
  *   Marek Kotewicz 
  * @date 2014
diff --git a/liblll/All.h b/liblll/All.h
index ec6989e66..7c4192f62 100644
--- a/liblll/All.h
+++ b/liblll/All.h
@@ -1,6 +1,5 @@
 #pragma once
 
-#include "Assembly.h"
 #include "CodeFragment.h"
 #include "Compiler.h"
 #include "CompilerState.h"
diff --git a/liblll/CMakeLists.txt b/liblll/CMakeLists.txt
index cb50cc36e..8b1581785 100644
--- a/liblll/CMakeLists.txt
+++ b/liblll/CMakeLists.txt
@@ -15,7 +15,7 @@ endif()
 
 include_directories(..)
 
-target_link_libraries(${EXECUTABLE} evmface)
+target_link_libraries(${EXECUTABLE} evmcore)
 target_link_libraries(${EXECUTABLE} devcore)
 
 
diff --git a/liblll/CodeFragment.cpp b/liblll/CodeFragment.cpp
index 47df8f3b9..2c200caa5 100644
--- a/liblll/CodeFragment.cpp
+++ b/liblll/CodeFragment.cpp
@@ -25,7 +25,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include "CompilerState.h"
 #include "Parser.h"
 using namespace std;
diff --git a/liblll/CodeFragment.h b/liblll/CodeFragment.h
index d6ca86bbe..b24b474da 100644
--- a/liblll/CodeFragment.h
+++ b/liblll/CodeFragment.h
@@ -22,8 +22,8 @@
 #pragma once
 
 #include 
-#include 
-#include "Assembly.h"
+#include 
+#include 
 #include "Exceptions.h"
 
 namespace boost { namespace spirit { class utree; } }
diff --git a/liblll/Exceptions.h b/liblll/Exceptions.h
index c45215f1a..1e9671b36 100644
--- a/liblll/Exceptions.h
+++ b/liblll/Exceptions.h
@@ -32,16 +32,13 @@ namespace eth
 class CompilerException: public dev::Exception {};
 class InvalidOperation: public CompilerException {};
 class IntegerOutOfRange: public CompilerException {};
-class StringTooLong: public CompilerException {};
 class EmptyList: public CompilerException {};
 class DataNotExecutable: public CompilerException {};
 class IncorrectParameterCount: public CompilerException {};
-class InvalidDeposit: public CompilerException {};
 class InvalidName: public CompilerException {};
 class InvalidMacroArgs: public CompilerException {};
 class InvalidLiteral: public CompilerException {};
 class BareSymbol: public CompilerException {};
-class ExpectedLiteral: public CompilerException {};
 
 }
 }
diff --git a/libpyserpent/CMakeLists.txt b/libpyserpent/CMakeLists.txt
index 5108000f4..e6f32ec81 100644
--- a/libpyserpent/CMakeLists.txt
+++ b/libpyserpent/CMakeLists.txt
@@ -13,7 +13,7 @@ include_directories(..)
 
 target_link_libraries(${EXECUTABLE} serpent)
 target_link_libraries(${EXECUTABLE} lll)
-target_link_libraries(${EXECUTABLE} evmface)
+target_link_libraries(${EXECUTABLE} evmcore)
 target_link_libraries(${EXECUTABLE} devcore)
 target_link_libraries(${EXECUTABLE} ${PYTHON_LS})
 
diff --git a/libqethereum/QEthereum.cpp b/libqethereum/QEthereum.cpp
index 08165d9db..5e5253829 100644
--- a/libqethereum/QEthereum.cpp
+++ b/libqethereum/QEthereum.cpp
@@ -59,13 +59,13 @@ void QWebThree::poll()
 {
 	if (m_watches.size() > 0)
 	{
-		QString batch = toJsonRpcBatch(m_watches, "changed");
-		emit processData(batch, "changed");
+		QString batch = toJsonRpcBatch(m_watches, "eth_changed");
+		emit processData(batch, "eth_changed");
 	}
 	if (m_shhWatches.size() > 0)
 	{
-		QString batch = toJsonRpcBatch(m_shhWatches, "shhChanged");
-		emit processData(batch, "shhChanged");
+		QString batch = toJsonRpcBatch(m_shhWatches, "shh_changed");
+		emit processData(batch, "shh_changed");
 	}
 }
 
@@ -73,13 +73,13 @@ void QWebThree::clearWatches()
 {
 	if (m_watches.size() > 0)
 	{
-		QString batch = toJsonRpcBatch(m_watches, "uninstallFilter");
+		QString batch = toJsonRpcBatch(m_watches, "eth_uninstallFilter");
 		m_watches.clear();
 		emit processData(batch, "internal");
 	}
 	if (m_shhWatches.size() > 0)
 	{
-		QString batch = toJsonRpcBatch(m_shhWatches, "shhUninstallFilter");
+		QString batch = toJsonRpcBatch(m_shhWatches, "shh_uninstallFilter");
 		m_shhWatches.clear();
 		emit processData(batch, "internal");
 	}
@@ -106,7 +106,12 @@ void QWebThree::postMessage(QString _json)
 	QJsonObject f = QJsonDocument::fromJson(_json.toUtf8()).object();
 
 	QString method = f["call"].toString();
-	if (!method.compare("uninstallFilter") && f["args"].isArray() && f["args"].toArray().size())
+	if (!method.compare("eth_uninstallFilter") && f["args"].isArray() && f["args"].toArray().size())
+	{
+		int idToRemove = f["args"].toArray()[0].toInt();
+		m_watches.erase(std::remove(m_watches.begin(), m_watches.end(), idToRemove), m_watches.end());
+	}
+	else if (!method.compare("eth_uninstallFilter") && f["args"].isArray() && f["args"].toArray().size())
 	{
 		int idToRemove = f["args"].toArray()[0].toInt();
 		m_watches.erase(std::remove(m_watches.begin(), m_watches.end(), idToRemove), m_watches.end());
@@ -120,6 +125,7 @@ static QString formatOutput(QJsonObject const& _object)
 	QJsonObject res;
 	res["_id"] = _object["id"];
 	res["data"] = _object["result"];
+	res["error"] = _object["error"];
 	return QString::fromUtf8(QJsonDocument(res).toJson());
 }
 
@@ -128,7 +134,7 @@ void QWebThree::onDataProcessed(QString _json, QString _addInfo)
 	if (!_addInfo.compare("internal"))
 		return;
 
-	if (!_addInfo.compare("changed"))
+	if (!_addInfo.compare("eth_changed"))
 	{
 		QJsonArray resultsArray = QJsonDocument::fromJson(_json.toUtf8()).array();
 		for (int i = 0; i < resultsArray.size(); i++)
@@ -145,7 +151,7 @@ void QWebThree::onDataProcessed(QString _json, QString _addInfo)
 		return;
 	}
 	
-	if (!_addInfo.compare("shhChanged"))
+	if (!_addInfo.compare("shh_changed"))
 	{
 		QJsonArray resultsArray = QJsonDocument::fromJson(_json.toUtf8()).array();
 		for (int i = 0; i < resultsArray.size(); i++)
@@ -164,11 +170,11 @@ void QWebThree::onDataProcessed(QString _json, QString _addInfo)
 	
 	QJsonObject f = QJsonDocument::fromJson(_json.toUtf8()).object();
 	
-	if ((!_addInfo.compare("newFilter") || !_addInfo.compare("newFilterString")) && f.contains("result"))
+	if ((!_addInfo.compare("eth_newFilter") || !_addInfo.compare("eth_newFilterString")) && f.contains("result"))
 		m_watches.push_back(f["result"].toInt());
-	if (!_addInfo.compare("shhNewFilter") && f.contains("result"))
+	else if (!_addInfo.compare("shh_newFilter") && f.contains("result"))
 		m_shhWatches.push_back(f["result"].toInt());
-	if (!_addInfo.compare("newIdentity") && f.contains("result"))
+	else if (!_addInfo.compare("shh_newIdentity") && f.contains("result"))
 		emit onNewId(f["result"].toString());
 
 	response(formatOutput(f));
diff --git a/libqethereum/QmlEthereum.cpp b/libqethereum/QmlEthereum.cpp
index a7ed3df4d..b1b926f42 100644
--- a/libqethereum/QmlEthereum.cpp
+++ b/libqethereum/QmlEthereum.cpp
@@ -4,7 +4,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
diff --git a/libserpent/CMakeLists.txt b/libserpent/CMakeLists.txt
index 0090b5dc3..c2fe89cc0 100644
--- a/libserpent/CMakeLists.txt
+++ b/libserpent/CMakeLists.txt
@@ -16,7 +16,7 @@ endif()
 include_directories(..)
 
 target_link_libraries(${EXECUTABLE} lll)
-target_link_libraries(${EXECUTABLE} evmface)
+target_link_libraries(${EXECUTABLE} evmcore)
 target_link_libraries(${EXECUTABLE} devcore)
 
 if("${TARGET_PLATFORM}" STREQUAL "w64")
diff --git a/libserpent/compiler.cpp b/libserpent/compiler.cpp
index 623ab3950..30628fbc9 100644
--- a/libserpent/compiler.cpp
+++ b/libserpent/compiler.cpp
@@ -131,8 +131,7 @@ programData opcodeify(Node node,
         }
         // Declare variable
         else {
-            Node nodelist[] = { };
-            return pd(aux, multiToken(nodelist, 0, m), 0);
+			return pd(aux, multiToken(nullptr, 0, m), 0);
         }
     }
     // Define functions (TODO: eventually move to rewriter.cpp, keep
diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp
index 44cf39291..70af8f98e 100644
--- a/libsolidity/AST.cpp
+++ b/libsolidity/AST.cpp
@@ -263,6 +263,21 @@ TypeError ASTNode::createTypeError(string const& _description)
 	return TypeError() << errinfo_sourceLocation(getLocation()) << errinfo_comment(_description);
 }
 
+vector ContractDefinition::getInterfaceFunctions() const
+{
+	vector exportedFunctions;
+	for (ASTPointer const& f: m_definedFunctions)
+		if (f->isPublic() && f->getName() != getName())
+			exportedFunctions.push_back(f.get());
+	auto compareNames = [](FunctionDefinition const* _a, FunctionDefinition const* _b)
+	{
+		return _a->getName().compare(_b->getName()) < 0;
+	};
+
+	sort(exportedFunctions.begin(), exportedFunctions.end(), compareNames);
+	return exportedFunctions;
+}
+
 void Block::checkTypeRequirements()
 {
 	for (shared_ptr const& statement: m_statements)
@@ -337,9 +352,11 @@ void ExpressionStatement::checkTypeRequirements()
 void Expression::expectType(Type const& _expectedType)
 {
 	checkTypeRequirements();
-	if (!getType()->isImplicitlyConvertibleTo(_expectedType))
-		BOOST_THROW_EXCEPTION(createTypeError("Type not implicitly convertible to expected type."));
-	//@todo provide more information to the exception
+	Type const& type = *getType();
+	if (!type.isImplicitlyConvertibleTo(_expectedType))
+		BOOST_THROW_EXCEPTION(createTypeError("Type " + type.toString() +
+											  " not implicitly convertible to expected type "
+											  + _expectedType.toString() + "."));
 }
 
 void UnaryOperation::checkTypeRequirements()
@@ -363,14 +380,18 @@ void BinaryOperation::checkTypeRequirements()
 	else if (m_left->getType()->isImplicitlyConvertibleTo(*m_right->getType()))
 		m_commonType = m_right->getType();
 	else
-		BOOST_THROW_EXCEPTION(createTypeError("No common type found in binary operation."));
+		BOOST_THROW_EXCEPTION(createTypeError("No common type found in binary operation: " +
+											  m_left->getType()->toString() + " vs. " +
+											  m_right->getType()->toString()));
 	if (Token::isCompareOp(m_operator))
 		m_type = make_shared();
 	else
 	{
 		m_type = m_commonType;
 		if (!m_commonType->acceptsBinaryOperator(m_operator))
-			BOOST_THROW_EXCEPTION(createTypeError("Operator not compatible with type."));
+			BOOST_THROW_EXCEPTION(createTypeError("Operator " + string(Token::toString(m_operator)) +
+												  " not compatible with type " +
+												  m_commonType->toString()));
 	}
 }
 
@@ -479,6 +500,8 @@ void ElementaryTypeNameExpression::checkTypeRequirements()
 void Literal::checkTypeRequirements()
 {
 	m_type = Type::forLiteral(*this);
+	if (!m_type)
+		BOOST_THROW_EXCEPTION(createTypeError("Literal value too large."));
 }
 
 }
diff --git a/libsolidity/AST.h b/libsolidity/AST.h
index 793ce863f..7b266f132 100644
--- a/libsolidity/AST.h
+++ b/libsolidity/AST.h
@@ -116,10 +116,12 @@ public:
 
 	virtual void accept(ASTVisitor& _visitor) override;
 
-	std::vector> const& getDefinedStructs() { return m_definedStructs; }
-	std::vector> const& getStateVariables() { return m_stateVariables; }
-	std::vector> const& getDefinedFunctions() { return m_definedFunctions; }
+	std::vector> const& getDefinedStructs() const { return m_definedStructs; }
+	std::vector> const& getStateVariables() const { return m_stateVariables; }
+	std::vector> const& getDefinedFunctions() const { return m_definedFunctions; }
 
+	/// Returns the functions that make up the calling interface in the intended order.
+	std::vector getInterfaceFunctions() const;
 private:
 	std::vector> m_definedStructs;
 	std::vector> m_stateVariables;
@@ -135,6 +137,8 @@ public:
 		Declaration(_location, _name), m_members(_members) {}
 	virtual void accept(ASTVisitor& _visitor) override;
 
+	std::vector> const& getMembers() const { return m_members; }
+
 private:
 	std::vector> m_members;
 };
@@ -565,12 +569,15 @@ public:
 	Expression& getLeftExpression() const { return *m_left; }
 	Expression& getRightExpression() const { return *m_right; }
 	Token::Value getOperator() const { return m_operator; }
+	Type const& getCommonType() const { return *m_commonType; }
 
 private:
 	ASTPointer m_left;
 	Token::Value m_operator;
 	ASTPointer m_right;
 
+	/// The common type that is used for the operation, not necessarily the result type (e.g. for
+	/// comparisons, this is always bool).
 	std::shared_ptr m_commonType;
 };
 
diff --git a/libsolidity/ASTPrinter.cpp b/libsolidity/ASTPrinter.cpp
index eb9d92f08..987ad11cc 100644
--- a/libsolidity/ASTPrinter.cpp
+++ b/libsolidity/ASTPrinter.cpp
@@ -30,8 +30,8 @@ namespace dev
 namespace solidity
 {
 
-ASTPrinter::ASTPrinter(ASTPointer const& _ast, string const& _source):
-	m_indentation(0), m_source(_source), m_ast(_ast)
+ASTPrinter::ASTPrinter(ASTNode& _ast, string const& _source):
+	m_indentation(0), m_source(_source), m_ast(&_ast)
 {
 }
 
@@ -430,8 +430,8 @@ void ASTPrinter::printSourcePart(ASTNode const& _node)
 	if (!m_source.empty())
 	{
 		Location const& location(_node.getLocation());
-		*m_ostream << getIndentation() << "   Source: |"
-				   << m_source.substr(location.start, location.end - location.start) << "|" << endl;
+		*m_ostream << getIndentation() << "   Source: "
+				   << escaped(m_source.substr(location.start, location.end - location.start), false) << endl;
 	}
 }
 
diff --git a/libsolidity/ASTPrinter.h b/libsolidity/ASTPrinter.h
index e87b2ba3b..e0757fbc4 100644
--- a/libsolidity/ASTPrinter.h
+++ b/libsolidity/ASTPrinter.h
@@ -38,7 +38,7 @@ class ASTPrinter: public ASTVisitor
 public:
 	/// Create a printer for the given abstract syntax tree. If the source is specified,
 	/// the corresponding parts of the source are printed with each node.
-	ASTPrinter(ASTPointer const& _ast, std::string const& _source = std::string());
+	ASTPrinter(ASTNode& _ast, std::string const& _source = std::string());
 	/// Output the string representation of the AST to _stream.
 	void print(std::ostream& _stream);
 
@@ -114,7 +114,7 @@ private:
 
 	int m_indentation;
 	std::string m_source;
-	ASTPointer m_ast;
+	ASTNode* m_ast;
 	std::ostream* m_ostream;
 };
 
diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt
index f425bba48..ea2ef4b74 100644
--- a/libsolidity/CMakeLists.txt
+++ b/libsolidity/CMakeLists.txt
@@ -6,18 +6,16 @@ aux_source_directory(. SRC_LIST)
 
 set(EXECUTABLE solidity)
 
+file(GLOB HEADERS "*.h") 
 if(ETH_STATIC)
-	add_library(${EXECUTABLE} STATIC ${SRC_LIST})
+	add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS})
 else()
-	add_library(${EXECUTABLE} SHARED ${SRC_LIST})
+	add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS})
 endif()
 
-file(GLOB HEADERS "*.h") 
-
 include_directories(..)
 
-# @todo we only depend on Assembly, not on all of lll
-target_link_libraries(${EXECUTABLE} evmface devcore lll)
+target_link_libraries(${EXECUTABLE} evmcore devcore)
 
 install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
 install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )
diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp
index d05552b9e..da28ba8a3 100644
--- a/libsolidity/Compiler.cpp
+++ b/libsolidity/Compiler.cpp
@@ -21,6 +21,8 @@
  */
 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -30,11 +32,11 @@ using namespace std;
 namespace dev {
 namespace solidity {
 
-bytes Compiler::compile(ContractDefinition& _contract)
+bytes Compiler::compile(ContractDefinition& _contract, bool _optimize)
 {
 	Compiler compiler;
 	compiler.compileContract(_contract);
-	return compiler.m_context.getAssembledBytecode();
+	return compiler.m_context.getAssembledBytecode(_optimize);
 }
 
 void Compiler::compileContract(ContractDefinition& _contract)
@@ -42,10 +44,12 @@ void Compiler::compileContract(ContractDefinition& _contract)
 	m_context = CompilerContext(); // clear it just in case
 
 	//@todo constructor
-	//@todo register state variables
 
 	for (ASTPointer const& function: _contract.getDefinedFunctions())
 		m_context.addFunction(*function);
+	//@todo sort them?
+	for (ASTPointer const& variable: _contract.getStateVariables())
+		m_context.addStateVariable(*variable);
 
 	appendFunctionSelector(_contract.getDefinedFunctions());
 	for (ASTPointer const& function: _contract.getDefinedFunctions())
@@ -77,35 +81,34 @@ void Compiler::appendFunctionSelector(vector> con
 	if (publicFunctions.size() > 255)
 		BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("More than 255 public functions for contract."));
 
-	//@todo check for calldatasize?
-	// retrieve the first byte of the call data
-	m_context << u256(0) << eth::Instruction::CALLDATALOAD << u256(0) << eth::Instruction::BYTE;
-	// check that it is not too large
-	m_context << eth::Instruction::DUP1 << u256(publicFunctions.size() - 1) << eth::Instruction::LT;
-	eth::AssemblyItem returnTag = m_context.appendConditionalJump();
+	// retrieve the first byte of the call data, which determines the called function
+	// @todo This code had a jump table in a previous version which was more efficient but also
+	// error prone (due to the optimizer and variable length tag addresses)
+	m_context << u256(1) << u256(0) // some constants
+			  << eth::dupInstruction(1) << eth::Instruction::CALLDATALOAD
+			  << eth::dupInstruction(2) << eth::Instruction::BYTE
+			  << eth::dupInstruction(2);
 
-	// otherwise, jump inside jump table (each entry of the table has size 4)
-	m_context << u256(4) << eth::Instruction::MUL;
-	eth::AssemblyItem jumpTableStart = m_context.pushNewTag();
-	m_context << eth::Instruction::ADD << eth::Instruction::JUMP;
-
-	// jump table @todo it could be that the optimizer destroys this
-	m_context << jumpTableStart;
+	// stack here: 1 0  0, stack top will be counted up until it matches funid
 	for (pair> const& f: publicFunctions)
-		m_context.appendJumpTo(f.second.second) << eth::Instruction::JUMPDEST;
-
-	m_context << returnTag << eth::Instruction::STOP;
+	{
+		eth::AssemblyItem const& callDataUnpackerEntry = f.second.second;
+		m_context << eth::dupInstruction(2) << eth::dupInstruction(2) << eth::Instruction::EQ;
+		m_context.appendConditionalJumpTo(callDataUnpackerEntry);
+		m_context << eth::dupInstruction(4) << eth::Instruction::ADD;
+		//@todo avoid the last ADD (or remove it in the optimizer)
+	}
+	m_context << eth::Instruction::STOP; // function not found
 
 	for (pair> const& f: publicFunctions)
 	{
 		FunctionDefinition const& function = *f.second.first;
-		m_context << f.second.second;
-
+		eth::AssemblyItem const& callDataUnpackerEntry = f.second.second;
+		m_context << callDataUnpackerEntry;
 		eth::AssemblyItem returnTag = m_context.pushNewTag();
 		appendCalldataUnpacker(function);
 		m_context.appendJumpTo(m_context.getFunctionEntryLabel(function));
 		m_context << returnTag;
-
 		appendReturnValuePacker(function);
 	}
 }
@@ -122,7 +125,7 @@ void Compiler::appendCalldataUnpacker(FunctionDefinition const& _function)
 		if (numBytes == 0)
 			BOOST_THROW_EXCEPTION(CompilerError()
 								  << errinfo_sourceLocation(var->getLocation())
-								  << errinfo_comment("Type not yet supported."));
+								  << errinfo_comment("Type " + var->getType()->toString() + " not yet supported."));
 		if (numBytes == 32)
 			m_context << u256(dataOffset) << eth::Instruction::CALLDATALOAD;
 		else
@@ -139,11 +142,12 @@ void Compiler::appendReturnValuePacker(FunctionDefinition const& _function)
 	vector> const& parameters = _function.getReturnParameters();
 	for (unsigned i = 0; i < parameters.size(); ++i)
 	{
-		unsigned numBytes = parameters[i]->getType()->getCalldataEncodedSize();
+		Type const& paramType = *parameters[i]->getType();
+		unsigned numBytes = paramType.getCalldataEncodedSize();
 		if (numBytes == 0)
 			BOOST_THROW_EXCEPTION(CompilerError()
 								  << errinfo_sourceLocation(parameters[i]->getLocation())
-								  << errinfo_comment("Type not yet supported."));
+								  << errinfo_comment("Type " + paramType.toString() + " not yet supported."));
 		m_context << eth::dupInstruction(parameters.size() - i);
 		if (numBytes != 32)
 			m_context << (u256(1) << ((32 - numBytes) * 8)) << eth::Instruction::MUL;
@@ -271,8 +275,9 @@ bool Compiler::visit(Return& _return)
 	{
 		ExpressionCompiler::compileExpression(m_context, *expression);
 		VariableDeclaration const& firstVariable = *_return.getFunctionReturnParameters().getParameters().front();
-		ExpressionCompiler::cleanHigherOrderBitsIfNeeded(*expression->getType(), *firstVariable.getType());
-		int stackPosition = m_context.getStackPositionOfVariable(firstVariable);
+		ExpressionCompiler::appendTypeConversion(m_context, *expression->getType(), *firstVariable.getType());
+
+		unsigned stackPosition = m_context.baseToCurrentStackOffset(m_context.getBaseStackOffsetOfVariable(firstVariable));
 		m_context << eth::swapInstruction(stackPosition) << eth::Instruction::POP;
 	}
 	m_context.appendJumpTo(m_returnTag);
@@ -284,9 +289,11 @@ bool Compiler::visit(VariableDefinition& _variableDefinition)
 	if (Expression* expression = _variableDefinition.getExpression())
 	{
 		ExpressionCompiler::compileExpression(m_context, *expression);
-		ExpressionCompiler::cleanHigherOrderBitsIfNeeded(*expression->getType(),
-														 *_variableDefinition.getDeclaration().getType());
-		int stackPosition = m_context.getStackPositionOfVariable(_variableDefinition.getDeclaration());
+		ExpressionCompiler::appendTypeConversion(m_context,
+												 *expression->getType(),
+												 *_variableDefinition.getDeclaration().getType());
+		unsigned baseStackOffset = m_context.getBaseStackOffsetOfVariable(_variableDefinition.getDeclaration());
+		unsigned stackPosition = m_context.baseToCurrentStackOffset(baseStackOffset);
 		m_context << eth::swapInstruction(stackPosition) << eth::Instruction::POP;
 	}
 	return false;
diff --git a/libsolidity/Compiler.h b/libsolidity/Compiler.h
index 4e4d90d45..d931f5359 100644
--- a/libsolidity/Compiler.h
+++ b/libsolidity/Compiler.h
@@ -33,11 +33,11 @@ public:
 	Compiler(): m_returnTag(m_context.newTag()) {}
 
 	void compileContract(ContractDefinition& _contract);
-	bytes getAssembledBytecode() { return m_context.getAssembledBytecode(); }
+	bytes getAssembledBytecode(bool _optimize = false) { return m_context.getAssembledBytecode(_optimize); }
 	void streamAssembly(std::ostream& _stream) const { m_context.streamAssembly(_stream); }
 
 	/// Compile the given contract and return the EVM bytecode.
-	static bytes compile(ContractDefinition& _contract);
+	static bytes compile(ContractDefinition& _contract, bool _optimize);
 
 private:
 	/// Creates a new compiler context / assembly and packs the current code into the data part.
diff --git a/libsolidity/CompilerContext.cpp b/libsolidity/CompilerContext.cpp
index 99cf090e0..3c1acdfa7 100644
--- a/libsolidity/CompilerContext.cpp
+++ b/libsolidity/CompilerContext.cpp
@@ -30,6 +30,12 @@ using namespace std;
 namespace dev {
 namespace solidity {
 
+void CompilerContext::addStateVariable(VariableDeclaration const& _declaration)
+{
+	m_stateVariables[&_declaration] = m_stateVariablesSize;
+	m_stateVariablesSize += _declaration.getType()->getStorageSize();
+}
+
 void CompilerContext::initializeLocalVariables(unsigned _numVariables)
 {
 	if (_numVariables > 0)
@@ -41,12 +47,9 @@ void CompilerContext::initializeLocalVariables(unsigned _numVariables)
 	}
 }
 
-int CompilerContext::getStackPositionOfVariable(Declaration const& _declaration)
+bool CompilerContext::isLocalVariable(Declaration const* _declaration) const
 {
-	auto res = find(begin(m_localVariables), end(m_localVariables), &_declaration);
-	if (asserts(res != m_localVariables.end()))
-		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Variable not found on stack."));
-	return end(m_localVariables) - res - 1 + m_asm.deposit();
+	return std::find(m_localVariables.begin(), m_localVariables.end(), _declaration) != m_localVariables.end();
 }
 
 eth::AssemblyItem CompilerContext::getFunctionEntryLabel(FunctionDefinition const& _function) const
@@ -57,5 +60,28 @@ eth::AssemblyItem CompilerContext::getFunctionEntryLabel(FunctionDefinition cons
 	return res->second.tag();
 }
 
+unsigned CompilerContext::getBaseStackOffsetOfVariable(Declaration const& _declaration) const
+{
+	auto res = find(begin(m_localVariables), end(m_localVariables), &_declaration);
+	if (asserts(res != m_localVariables.end()))
+		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Variable not found on stack."));
+	return unsigned(end(m_localVariables) - res - 1);
+}
+
+unsigned CompilerContext::baseToCurrentStackOffset(unsigned _baseOffset) const
+{
+	return _baseOffset + m_asm.deposit();
+}
+
+u256 CompilerContext::getStorageLocationOfVariable(const Declaration& _declaration) const
+{
+	auto it = m_stateVariables.find(&_declaration);
+	if (it == m_stateVariables.end())
+		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Variable not found in storage."));
+	return it->second;
+}
+
+
+
 }
 }
diff --git a/libsolidity/CompilerContext.h b/libsolidity/CompilerContext.h
index 46c4c72ab..562c29321 100644
--- a/libsolidity/CompilerContext.h
+++ b/libsolidity/CompilerContext.h
@@ -23,8 +23,8 @@
 #pragma once
 
 #include 
-#include 
-#include 
+#include 
+#include 
 #include 
 
 namespace dev {
@@ -38,19 +38,28 @@ namespace solidity {
 class CompilerContext
 {
 public:
-	CompilerContext() {}
+	CompilerContext(): m_stateVariablesSize(0) {}
 
+	void addStateVariable(VariableDeclaration const& _declaration);
 	void startNewFunction() { m_localVariables.clear(); m_asm.setDeposit(0); }
 	void initializeLocalVariables(unsigned _numVariables);
 	void addVariable(VariableDeclaration const& _declaration) { m_localVariables.push_back(&_declaration); }
-	/// Returns the distance of the given local variable from the top of the stack.
-	int getStackPositionOfVariable(Declaration const& _declaration);
-
 	void addFunction(FunctionDefinition const& _function) { m_functionEntryLabels.insert(std::make_pair(&_function, m_asm.newTag())); }
-	eth::AssemblyItem getFunctionEntryLabel(FunctionDefinition const& _function) const;
 
 	void adjustStackOffset(int _adjustment) { m_asm.adjustDeposit(_adjustment); }
 
+	bool isFunctionDefinition(Declaration const* _declaration) const { return m_functionEntryLabels.count(_declaration); }
+	bool isLocalVariable(Declaration const* _declaration) const;
+	bool isStateVariable(Declaration const* _declaration) const { return m_stateVariables.count(_declaration); }
+
+	eth::AssemblyItem getFunctionEntryLabel(FunctionDefinition const& _function) const;
+	/// Returns the distance of the given local variable from the top of the local variable stack.
+	unsigned getBaseStackOffsetOfVariable(Declaration const& _declaration) const;
+	/// If supplied by a value returned by @ref getBaseStackOffsetOfVariable(variable), returns
+	/// the distance of that variable from the current top of the stack.
+	unsigned baseToCurrentStackOffset(unsigned _baseOffset) const;
+	u256 getStorageLocationOfVariable(Declaration const& _declaration) const;
+
 	/// Appends a JUMPI instruction to a new tag and @returns the tag
 	eth::AssemblyItem appendConditionalJump() { return m_asm.appendJumpI().tag(); }
 	/// Appends a JUMPI instruction to @a _tag
@@ -75,14 +84,18 @@ public:
 
 	eth::Assembly const& getAssembly() const { return m_asm; }
 	void streamAssembly(std::ostream& _stream) const { _stream << m_asm; }
-	bytes getAssembledBytecode() const { return m_asm.assemble(); }
+	bytes getAssembledBytecode(bool _optimize = false) { return m_asm.optimise(_optimize).assemble(); }
 private:
 	eth::Assembly m_asm;
 
+	/// Size of the state variables, offset of next variable to be added.
+	u256 m_stateVariablesSize;
+	/// Storage offsets of state variables
+	std::map m_stateVariables;
 	/// Offsets of local variables on the stack.
 	std::vector m_localVariables;
 	/// Labels pointing to the entry points of funcitons.
-	std::map m_functionEntryLabels;
+	std::map m_functionEntryLabels;
 };
 
 }
diff --git a/libsolidity/CompilerStack.cpp b/libsolidity/CompilerStack.cpp
index bbd693ae5..d87c27916 100644
--- a/libsolidity/CompilerStack.cpp
+++ b/libsolidity/CompilerStack.cpp
@@ -34,16 +34,101 @@ namespace dev
 namespace solidity
 {
 
-bytes CompilerStack::compile(std::string const& _sourceCode, shared_ptr _scanner)
+void CompilerStack::setSource(string const& _sourceCode)
 {
-	if (!_scanner)
-		_scanner = make_shared();
-	_scanner->reset(CharStream(_sourceCode));
+	reset();
+	m_scanner = make_shared(CharStream(_sourceCode));
+}
+
+void CompilerStack::parse()
+{
+	if (!m_scanner)
+		BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Source not available."));
+	m_contractASTNode = Parser().parse(m_scanner);
+	NameAndTypeResolver().resolveNamesAndTypes(*m_contractASTNode);
+	m_parseSuccessful = true;
+}
+
+void CompilerStack::parse(string const& _sourceCode)
+{
+	setSource(_sourceCode);
+	parse();
+}
+
+bytes const& CompilerStack::compile(bool _optimize)
+{
+	if (!m_parseSuccessful)
+		BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful."));
+	m_bytecode.clear();
+	m_compiler = make_shared();
+	m_compiler->compileContract(*m_contractASTNode);
+	return m_bytecode = m_compiler->getAssembledBytecode(_optimize);
+}
 
-	ASTPointer contract = Parser().parse(_scanner);
-	NameAndTypeResolver().resolveNamesAndTypes(*contract);
-	return Compiler::compile(*contract);
+bytes const& CompilerStack::compile(string const& _sourceCode, bool _optimize)
+{
+	parse(_sourceCode);
+	return compile(_optimize);
 }
 
+void CompilerStack::streamAssembly(ostream& _outStream)
+{
+	if (!m_compiler || m_bytecode.empty())
+		BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Compilation was not successful."));
+	m_compiler->streamAssembly(_outStream);
+}
+
+string const& CompilerStack::getInterface()
+{
+	if (!m_parseSuccessful)
+		BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful."));
+	if (m_interface.empty())
+	{
+		stringstream interface;
+		interface << '[';
+		vector exportedFunctions = m_contractASTNode->getInterfaceFunctions();
+		unsigned functionsCount = exportedFunctions.size();
+		for (FunctionDefinition const* f: exportedFunctions)
+		{
+			auto streamVariables = [&](vector> const& _vars)
+			{
+				unsigned varCount = _vars.size();
+				for (ASTPointer const& var: _vars)
+				{
+					interface << "{"
+							  << "\"name\":" << escaped(var->getName(), false) << ","
+							  << "\"type\":" << escaped(var->getType()->toString(), false)
+							  << "}";
+					if (--varCount > 0)
+						interface << ",";
+				}
+			};
+
+			interface << '{'
+					  << "\"name\":" << escaped(f->getName(), false) << ","
+					  << "\"inputs\":[";
+			streamVariables(f->getParameters());
+			interface << "],"
+					  << "\"outputs\":[";
+			streamVariables(f->getReturnParameters());
+			interface << "]"
+					  << "}";
+			if (--functionsCount > 0)
+				interface << ",";
+		}
+		interface << ']';
+		m_interface = interface.str();
+	}
+	return m_interface;
+}
+
+bytes CompilerStack::staticCompile(std::string const& _sourceCode, bool _optimize)
+{
+	CompilerStack stack;
+	return stack.compile(_sourceCode, _optimize);
+}
+
+
+
 }
 }
diff --git a/libsolidity/CompilerStack.h b/libsolidity/CompilerStack.h
index 9f3f81c04..2fb505897 100644
--- a/libsolidity/CompilerStack.h
+++ b/libsolidity/CompilerStack.h
@@ -22,6 +22,7 @@
 
 #pragma once
 
+#include 
 #include 
 #include 
 #include 
@@ -30,13 +31,51 @@ namespace dev {
 namespace solidity {
 
 class Scanner; // forward
+class ContractDefinition; // forward
+class Compiler; // forward
 
+/**
+ * Easy to use and self-contained Solidity compiler with as few header dependencies as possible.
+ * It holds state and can be used to either step through the compilation stages (and abort e.g.
+ * before compilation to bytecode) or run the whole compilation in one call.
+ */
 class CompilerStack
 {
 public:
+	CompilerStack() {}
+	void reset() {  *this = CompilerStack(); }
+	void setSource(std::string const& _sourceCode);
+	void parse();
+	void parse(std::string const& _sourceCode);
+	/// Compiles the contract that was previously parsed.
+	bytes const& compile(bool _optimize = false);
+	/// Parses and compiles the given source code.
+	bytes const& compile(std::string const& _sourceCode, bool _optimize = false);
+
+	bytes const& getBytecode() const { return m_bytecode; }
+	/// Streams a verbose version of the assembly to @a _outStream.
+	/// Prerequisite: Successful compilation.
+	void streamAssembly(std::ostream& _outStream);
+
+	/// Returns a string representing the contract interface in JSON.
+	/// Prerequisite: Successful call to parse or compile.
+	std::string const& getInterface();
+
+	/// Returns the previously used scanner, useful for counting lines during error reporting.
+	Scanner const& getScanner() const { return *m_scanner; }
+	ContractDefinition& getAST() const { return *m_contractASTNode; }
+
 	/// Compile the given @a _sourceCode to bytecode. If a scanner is provided, it is used for
 	/// scanning the source code - this is useful for printing exception information.
-	static bytes compile(std::string const& _sourceCode, std::shared_ptr _scanner = std::shared_ptr());
+	static bytes staticCompile(std::string const& _sourceCode, bool _optimize = false);
+
+private:
+	std::shared_ptr m_scanner;
+	std::shared_ptr m_contractASTNode;
+	bool m_parseSuccessful;
+	std::string m_interface;
+	std::shared_ptr m_compiler;
+	bytes m_bytecode;
 };
 
 }
diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp
index d23579b11..05bbb0916 100644
--- a/libsolidity/ExpressionCompiler.cpp
+++ b/libsolidity/ExpressionCompiler.cpp
@@ -37,25 +37,25 @@ void ExpressionCompiler::compileExpression(CompilerContext& _context, Expression
 	_expression.accept(compiler);
 }
 
-bool ExpressionCompiler::visit(Assignment& _assignment)
+void ExpressionCompiler::appendTypeConversion(CompilerContext& _context,
+											  Type const& _typeOnStack, Type const& _targetType)
 {
-	m_currentLValue = nullptr;
+	ExpressionCompiler compiler(_context);
+	compiler.appendTypeConversion(_typeOnStack, _targetType);
+}
 
-	Expression& rightHandSide = _assignment.getRightHandSide();
-	rightHandSide.accept(*this);
-	Type const& resultType = *_assignment.getType();
-	cleanHigherOrderBitsIfNeeded(*rightHandSide.getType(), resultType);
+bool ExpressionCompiler::visit(Assignment& _assignment)
+{
+	_assignment.getRightHandSide().accept(*this);
+	appendTypeConversion(*_assignment.getRightHandSide().getType(), *_assignment.getType());
+	m_currentLValue.reset();
 	_assignment.getLeftHandSide().accept(*this);
 
 	Token::Value op = _assignment.getAssignmentOperator();
-	if (op != Token::ASSIGN)
-	{
-		// compound assignment
-		m_context << eth::Instruction::SWAP1;
-		appendOrdinaryBinaryOperatorCode(Token::AssignmentToBinaryOp(op), resultType);
-	}
+	if (op != Token::ASSIGN) // compound assignment
+		appendOrdinaryBinaryOperatorCode(Token::AssignmentToBinaryOp(op), *_assignment.getType());
 	else
-		m_context << eth::Instruction::POP; //@todo do not retrieve the value in the first place
+		m_context << eth::Instruction::POP;
 
 	storeInLValue(_assignment);
 	return false;
@@ -92,10 +92,7 @@ void ExpressionCompiler::endVisit(UnaryOperation& _unaryOperation)
 			m_context << eth::Instruction::ADD;
 		else
 			m_context << eth::Instruction::SWAP1 << eth::Instruction::SUB; // @todo avoid the swap
-		if (_unaryOperation.isPrefixOperation())
-			storeInLValue(_unaryOperation);
-		else
-			moveToLValue(_unaryOperation);
+		storeInLValue(_unaryOperation, !_unaryOperation.isPrefixOperation());
 		break;
 	case Token::ADD: // +
 		// unary add, so basically no-op
@@ -113,31 +110,26 @@ bool ExpressionCompiler::visit(BinaryOperation& _binaryOperation)
 {
 	Expression& leftExpression = _binaryOperation.getLeftExpression();
 	Expression& rightExpression = _binaryOperation.getRightExpression();
-	Type const& resultType = *_binaryOperation.getType();
+	Type const& commonType = _binaryOperation.getCommonType();
 	Token::Value const op = _binaryOperation.getOperator();
 
-	if (op == Token::AND || op == Token::OR)
-	{
-		// special case: short-circuiting
+	if (op == Token::AND || op == Token::OR) // special case: short-circuiting
 		appendAndOrOperatorCode(_binaryOperation);
-	}
-	else if (Token::isCompareOp(op))
-	{
-		leftExpression.accept(*this);
-		rightExpression.accept(*this);
-
-		// the types to compare have to be the same, but the resulting type is always bool
-		if (asserts(*leftExpression.getType() == *rightExpression.getType()))
-			BOOST_THROW_EXCEPTION(InternalCompilerError());
-		appendCompareOperatorCode(op, *leftExpression.getType());
-	}
 	else
 	{
-		leftExpression.accept(*this);
-		cleanHigherOrderBitsIfNeeded(*leftExpression.getType(), resultType);
+		bool cleanupNeeded = false;
+		if (commonType.getCategory() == Type::Category::INTEGER)
+			if (Token::isCompareOp(op) || op == Token::DIV || op == Token::MOD)
+				cleanupNeeded = true;
+
 		rightExpression.accept(*this);
-		cleanHigherOrderBitsIfNeeded(*rightExpression.getType(), resultType);
-		appendOrdinaryBinaryOperatorCode(op, resultType);
+		appendTypeConversion(*rightExpression.getType(), commonType, cleanupNeeded);
+		leftExpression.accept(*this);
+		appendTypeConversion(*leftExpression.getType(), commonType, cleanupNeeded);
+		if (Token::isCompareOp(op))
+			appendCompareOperatorCode(op, commonType);
+		else
+			appendOrdinaryBinaryOperatorCode(op, commonType);
 	}
 
 	// do not visit the child nodes, we already did that explicitly
@@ -153,15 +145,19 @@ bool ExpressionCompiler::visit(FunctionCall& _functionCall)
 			BOOST_THROW_EXCEPTION(InternalCompilerError());
 		Expression& firstArgument = *_functionCall.getArguments().front();
 		firstArgument.accept(*this);
-		cleanHigherOrderBitsIfNeeded(*firstArgument.getType(), *_functionCall.getType());
+		appendTypeConversion(*firstArgument.getType(), *_functionCall.getType());
 	}
 	else
 	{
 		// Calling convention: Caller pushes return address and arguments
 		// Callee removes them and pushes return values
-		m_currentLValue = nullptr;
+		m_currentLValue.reset();
 		_functionCall.getExpression().accept(*this);
-		FunctionDefinition const& function = dynamic_cast(*m_currentLValue);
+		if (asserts(m_currentLValue.isInCode()))
+			BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Code reference expected."));
+		eth::AssemblyItem functionTag(eth::PushTag, m_currentLValue.location);
+
+		FunctionDefinition const& function = dynamic_cast(*_functionCall.getExpression().getType()).getFunction();
 
 		eth::AssemblyItem returnLabel = m_context.pushNewTag();
 		std::vector> const& arguments = _functionCall.getArguments();
@@ -170,11 +166,10 @@ bool ExpressionCompiler::visit(FunctionCall& _functionCall)
 		for (unsigned i = 0; i < arguments.size(); ++i)
 		{
 			arguments[i]->accept(*this);
-			cleanHigherOrderBitsIfNeeded(*arguments[i]->getType(),
-										 *function.getParameters()[i]->getType());
+			appendTypeConversion(*arguments[i]->getType(), *function.getParameters()[i]->getType());
 		}
 
-		m_context.appendJumpTo(m_context.getFunctionEntryLabel(function));
+		m_context.appendJumpTo(functionTag);
 		m_context << returnLabel;
 
 		// callee adds return parameters, but removes arguments and return label
@@ -200,24 +195,20 @@ void ExpressionCompiler::endVisit(IndexAccess&)
 
 void ExpressionCompiler::endVisit(Identifier& _identifier)
 {
-	m_currentLValue = _identifier.getReferencedDeclaration();
-	switch (_identifier.getType()->getCategory())
-	{
-	case Type::Category::BOOL:
-	case Type::Category::INTEGER:
-	case Type::Category::REAL:
-	{
-		//@todo we also have to check where to retrieve them from once we add storage variables
-		unsigned stackPos = stackPositionOfLValue();
-		if (stackPos >= 15) //@todo correct this by fetching earlier or moving to memory
-			BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_identifier.getLocation())
-												  << errinfo_comment("Stack too deep."));
-		m_context << eth::dupInstruction(stackPos + 1);
-		break;
-	}
-	default:
-		break;
-	}
+	Declaration const* declaration = _identifier.getReferencedDeclaration();
+	if (m_context.isLocalVariable(declaration))
+		m_currentLValue = LValueLocation(LValueLocation::STACK,
+										 m_context.getBaseStackOffsetOfVariable(*declaration));
+	else if (m_context.isStateVariable(declaration))
+		m_currentLValue = LValueLocation(LValueLocation::STORAGE,
+										 m_context.getStorageLocationOfVariable(*declaration));
+	else if (m_context.isFunctionDefinition(declaration))
+		m_currentLValue = LValueLocation(LValueLocation::CODE,
+										 m_context.getFunctionEntryLabel(dynamic_cast(*declaration)).data());
+	else
+		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Identifier type not supported or identifier not found."));
+
+	retrieveLValueValue(_identifier);
 }
 
 void ExpressionCompiler::endVisit(Literal& _literal)
@@ -233,28 +224,6 @@ void ExpressionCompiler::endVisit(Literal& _literal)
 	}
 }
 
-void ExpressionCompiler::cleanHigherOrderBitsIfNeeded(Type const& _typeOnStack, Type const& _targetType)
-{
-	// If the type of one of the operands is extended, we need to remove all
-	// higher-order bits that we might have ignored in previous operations.
-	// @todo: store in the AST whether the operand might have "dirty" higher
-	// order bits
-
-	if (_typeOnStack == _targetType)
-		return;
-	if (_typeOnStack.getCategory() == Type::Category::INTEGER &&
-			_targetType.getCategory() == Type::Category::INTEGER)
-	{
-		//@todo
-	}
-	else
-	{
-		// If we get here, there is either an implementation missing to clean higher oder bits
-		// for non-integer types that are explicitly convertible or we got here in error.
-		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid type conversion requested."));
-	}
-}
-
 void ExpressionCompiler::appendAndOrOperatorCode(BinaryOperation& _binaryOperation)
 {
 	Token::Value const op = _binaryOperation.getOperator();
@@ -284,23 +253,21 @@ void ExpressionCompiler::appendCompareOperatorCode(Token::Value _operator, Type
 		IntegerType const& type = dynamic_cast(_type);
 		bool const isSigned = type.isSigned();
 
-		// note that EVM opcodes compare like "stack[0] < stack[1]",
-		// but our left value is at stack[1], so everyhing is reversed.
 		switch (_operator)
 		{
 		case Token::GTE:
-			m_context << (isSigned ? eth::Instruction::SGT : eth::Instruction::GT)
+			m_context << (isSigned ? eth::Instruction::SLT : eth::Instruction::LT)
 					  << eth::Instruction::ISZERO;
 			break;
 		case Token::LTE:
-			m_context << (isSigned ? eth::Instruction::SLT : eth::Instruction::LT)
+			m_context << (isSigned ? eth::Instruction::SGT : eth::Instruction::GT)
 					  << eth::Instruction::ISZERO;
 			break;
 		case Token::GT:
-			m_context << (isSigned ? eth::Instruction::SLT : eth::Instruction::LT);
+			m_context << (isSigned ? eth::Instruction::SGT : eth::Instruction::GT);
 			break;
 		case Token::LT:
-			m_context << (isSigned ? eth::Instruction::SGT : eth::Instruction::GT);
+			m_context << (isSigned ? eth::Instruction::SLT : eth::Instruction::LT);
 			break;
 		default:
 			BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown comparison operator."));
@@ -331,16 +298,16 @@ void ExpressionCompiler::appendArithmeticOperatorCode(Token::Value _operator, Ty
 		m_context << eth::Instruction::ADD;
 		break;
 	case Token::SUB:
-		m_context << eth::Instruction::SWAP1 << eth::Instruction::SUB;
+		m_context << eth::Instruction::SUB;
 		break;
 	case Token::MUL:
 		m_context << eth::Instruction::MUL;
 		break;
 	case Token::DIV:
-		m_context << eth::Instruction::SWAP1 << (isSigned ? eth::Instruction::SDIV : eth::Instruction::DIV);
+		m_context  << (isSigned ? eth::Instruction::SDIV : eth::Instruction::DIV);
 		break;
 	case Token::MOD:
-		m_context << eth::Instruction::SWAP1 << (isSigned ? eth::Instruction::SMOD : eth::Instruction::MOD);
+		m_context << (isSigned ? eth::Instruction::SMOD : eth::Instruction::MOD);
 		break;
 	default:
 		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown arithmetic operator."));
@@ -379,31 +346,90 @@ void ExpressionCompiler::appendShiftOperatorCode(Token::Value _operator)
 	}
 }
 
-void ExpressionCompiler::storeInLValue(Expression const& _expression)
+void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded)
 {
-	moveToLValue(_expression);
-	unsigned stackPos = stackPositionOfLValue();
-	if (stackPos > 16)
-		BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_expression.getLocation())
-											  << errinfo_comment("Stack too deep."));
-	m_context << eth::dupInstruction(stackPos + 1);
+	// For a type extension, we need to remove all higher-order bits that we might have ignored in
+	// previous operations.
+	// @todo: store in the AST whether the operand might have "dirty" higher order bits
+
+	if (_typeOnStack == _targetType && !_cleanupNeeded)
+		return;
+	if (_typeOnStack.getCategory() == Type::Category::INTEGER)
+		appendHighBitsCleanup(dynamic_cast(_typeOnStack));
+	else if (_typeOnStack != _targetType)
+		// All other types should not be convertible to non-equal types.
+		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid type conversion requested."));
 }
 
-void ExpressionCompiler::moveToLValue(Expression const& _expression)
+void ExpressionCompiler::appendHighBitsCleanup(IntegerType const& _typeOnStack)
 {
-	unsigned stackPos = stackPositionOfLValue();
-	if (stackPos > 16)
-		BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_expression.getLocation())
-											  << errinfo_comment("Stack too deep."));
-	else if (stackPos > 0)
-		m_context << eth::swapInstruction(stackPos) << eth::Instruction::POP;
+	if (_typeOnStack.getNumBits() == 256)
+		return;
+	else if (_typeOnStack.isSigned())
+		m_context << u256(_typeOnStack.getNumBits() / 8 - 1) << eth::Instruction::SIGNEXTEND;
+	else
+		m_context << ((u256(1) << _typeOnStack.getNumBits()) - 1) << eth::Instruction::AND;
 }
 
-unsigned ExpressionCompiler::stackPositionOfLValue() const
+void ExpressionCompiler::retrieveLValueValue(Expression const& _expression)
 {
-	if (asserts(m_currentLValue))
-		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("LValue not available on request."));
-	return m_context.getStackPositionOfVariable(*m_currentLValue);
+	switch (m_currentLValue.locationType)
+	{
+	case LValueLocation::CODE:
+		// not stored on the stack
+		break;
+	case LValueLocation::STACK:
+	{
+		unsigned stackPos = m_context.baseToCurrentStackOffset(unsigned(m_currentLValue.location));
+		if (stackPos >= 15) //@todo correct this by fetching earlier or moving to memory
+			BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_expression.getLocation())
+												  << errinfo_comment("Stack too deep."));
+		m_context << eth::dupInstruction(stackPos + 1);
+		break;
+	}
+	case LValueLocation::STORAGE:
+		m_context << m_currentLValue.location << eth::Instruction::SLOAD;
+		break;
+	case LValueLocation::MEMORY:
+		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Location type not yet implemented."));
+		break;
+	default:
+		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unsupported location type."));
+		break;
+	}
+}
+
+void ExpressionCompiler::storeInLValue(Expression const& _expression, bool _move)
+{
+	switch (m_currentLValue.locationType)
+	{
+	case LValueLocation::STACK:
+	{
+		unsigned stackPos = m_context.baseToCurrentStackOffset(unsigned(m_currentLValue.location));
+		if (stackPos > 16)
+			BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_expression.getLocation())
+												  << errinfo_comment("Stack too deep."));
+		else if (stackPos > 0)
+			m_context << eth::swapInstruction(stackPos) << eth::Instruction::POP;
+		if (!_move)
+			retrieveLValueValue(_expression);
+		break;
+	}
+	case LValueLocation::STORAGE:
+		if (!_move)
+			m_context << eth::Instruction::DUP1;
+		m_context << m_currentLValue.location << eth::Instruction::SSTORE;
+		break;
+	case LValueLocation::CODE:
+		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Location type does not support assignment."));
+		break;
+	case LValueLocation::MEMORY:
+		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Location type not yet implemented."));
+		break;
+	default:
+		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unsupported location type."));
+		break;
+	}
 }
 
 }
diff --git a/libsolidity/ExpressionCompiler.h b/libsolidity/ExpressionCompiler.h
index a930723cc..bd5a9f866 100644
--- a/libsolidity/ExpressionCompiler.h
+++ b/libsolidity/ExpressionCompiler.h
@@ -20,16 +20,25 @@
  * Solidity AST to EVM bytecode compiler for expressions.
  */
 
+#include 
 #include 
 
 namespace dev {
+namespace eth
+{
+class AssemblyItem; // forward
+}
 namespace solidity {
 
 class CompilerContext; // forward
+class Type; // forward
+class IntegerType; // forward
 
-/// Compiler for expressions, i.e. converts an AST tree whose root is an Expression into a stream
-/// of EVM instructions. It needs a compiler context that is the same for the whole compilation
-/// unit.
+/**
+ * Compiler for expressions, i.e. converts an AST tree whose root is an Expression into a stream
+ * of EVM instructions. It needs a compiler context that is the same for the whole compilation
+ * unit.
+ */
 class ExpressionCompiler: private ASTVisitor
 {
 public:
@@ -37,10 +46,10 @@ public:
 	static void compileExpression(CompilerContext& _context, Expression& _expression);
 
 	/// Appends code to remove dirty higher order bits in case of an implicit promotion to a wider type.
-	static void cleanHigherOrderBitsIfNeeded(Type const& _typeOnStack, Type const& _targetType);
+	static void appendTypeConversion(CompilerContext& _context, Type const& _typeOnStack, Type const& _targetType);
 
 private:
-	ExpressionCompiler(CompilerContext& _compilerContext): m_currentLValue(nullptr), m_context(_compilerContext) {}
+	ExpressionCompiler(CompilerContext& _compilerContext): m_context(_compilerContext) {}
 
 	virtual bool visit(Assignment& _assignment) override;
 	virtual void endVisit(UnaryOperation& _unaryOperation) override;
@@ -62,15 +71,44 @@ private:
 	void appendShiftOperatorCode(Token::Value _operator);
 	/// @}
 
-	/// Stores the value on top of the stack in the current lvalue and copies that value to the
-	/// top of the stack again
-	void storeInLValue(Expression const& _expression);
-	/// The same as storeInLValue but do not again retrieve the value to the top of the stack.
-	void moveToLValue(Expression const& _expression);
-	/// Returns the position of @a m_currentLValue in the stack, where 0 is the top of the stack.
-	unsigned stackPositionOfLValue() const;
-
-	Declaration* m_currentLValue;
+	/// Appends an implicit or explicit type conversion. For now this comprises only erasing
+	/// higher-order bits (@see appendHighBitCleanup) when widening integer types.
+	/// If @a _cleanupNeeded, high order bits cleanup is also done if no type conversion would be
+	/// necessary.
+	void appendTypeConversion(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded = false);
+	//// Appends code that cleans higher-order bits for integer types.
+	void appendHighBitsCleanup(IntegerType const& _typeOnStack);
+
+	/// Copies the value of the current lvalue to the top of the stack.
+	void retrieveLValueValue(Expression const& _expression);
+	/// Stores the value on top of the stack in the current lvalue. Removes it from the stack if
+	/// @a _move is true.
+	void storeInLValue(Expression const& _expression, bool _move = false);
+
+	/**
+	 * Location of an lvalue, either in code (for a function) on the stack, in the storage or memory.
+	 */
+	struct LValueLocation
+	{
+		enum LocationType { INVALID, CODE, STACK, MEMORY, STORAGE };
+
+		LValueLocation() { reset(); }
+		LValueLocation(LocationType _type, u256 const& _location): locationType(_type), location(_location) {}
+		void reset() { locationType = INVALID; location = 0; }
+		bool isValid() const { return locationType != INVALID; }
+		bool isInCode() const { return locationType == CODE; }
+		bool isInOnStack() const { return locationType == STACK; }
+		bool isInMemory() const { return locationType == MEMORY; }
+		bool isInStorage() const { return locationType == STORAGE; }
+
+		LocationType locationType;
+		/// Depending on the type, this is the id of a tag (code), the base offset of a stack
+		/// variable (@see CompilerContext::getBaseStackOffsetOfVariable) or the offset in
+		/// storage or memory.
+		u256 location;
+	};
+
+	LValueLocation m_currentLValue;
 	CompilerContext& m_context;
 };
 
diff --git a/libsolidity/Scanner.cpp b/libsolidity/Scanner.cpp
index c36820317..b13e52d7e 100644
--- a/libsolidity/Scanner.cpp
+++ b/libsolidity/Scanner.cpp
@@ -271,7 +271,7 @@ void Scanner::scanToken()
 				token = Token::ADD;
 			break;
 		case '-':
-			// - -- -=
+			// - -- -= Number
 			advance();
 			if (m_char == '-')
 			{
@@ -280,6 +280,8 @@ void Scanner::scanToken()
 			}
 			else if (m_char == '=')
 				token = selectToken(Token::ASSIGN_SUB);
+			else if (m_char == '.' || IsDecimalDigit(m_char))
+				token = scanNumber('-');
 			else
 				token = Token::SUB;
 			break;
@@ -331,7 +333,7 @@ void Scanner::scanToken()
 			// . Number
 			advance();
 			if (IsDecimalDigit(m_char))
-				token = scanNumber(true);
+				token = scanNumber('.');
 			else
 				token = Token::PERIOD;
 			break;
@@ -372,7 +374,7 @@ void Scanner::scanToken()
 			if (IsIdentifierStart(m_char))
 				token = scanIdentifierOrKeyword();
 			else if (IsDecimalDigit(m_char))
-				token = scanNumber(false);
+				token = scanNumber();
 			else if (skipWhitespace())
 				token = Token::WHITESPACE;
 			else if (isSourcePastEndOfInput())
@@ -461,14 +463,11 @@ void Scanner::scanDecimalDigits()
 }
 
 
-Token::Value Scanner::scanNumber(bool _periodSeen)
+Token::Value Scanner::scanNumber(char _charSeen)
 {
-	// the first digit of the number or the fraction
-	if (asserts(IsDecimalDigit(m_char)))
-		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Number does not start with decimal digit."));
-	enum { DECIMAL, HEX, OCTAL, IMPLICIT_OCTAL, BINARY } kind = DECIMAL;
+	enum { DECIMAL, HEX, BINARY } kind = DECIMAL;
 	LiteralScope literal(this);
-	if (_periodSeen)
+	if (_charSeen == '.')
 	{
 		// we have already seen a decimal point of the float
 		addLiteralChar('.');
@@ -476,12 +475,13 @@ Token::Value Scanner::scanNumber(bool _periodSeen)
 	}
 	else
 	{
+		if (_charSeen == '-')
+			addLiteralChar('-');
 		// if the first character is '0' we must check for octals and hex
 		if (m_char == '0')
 		{
 			addLiteralCharAndAdvance();
-			// either 0, 0exxx, 0Exxx, 0.xxx, a hex number, a binary number or
-			// an octal number.
+			// either 0, 0exxx, 0Exxx, 0.xxx or a hex number
 			if (m_char == 'x' || m_char == 'X')
 			{
 				// hex number
@@ -556,17 +556,73 @@ Token::Value Scanner::scanNumber(bool _periodSeen)
 	KEYWORD("function", Token::FUNCTION)                                       \
 	KEYWORD_GROUP('h')                                                         \
 	KEYWORD("hash", Token::HASH)                                               \
+	KEYWORD("hash8", Token::HASH8)                                             \
+	KEYWORD("hash16", Token::HASH16)                                           \
+	KEYWORD("hash24", Token::HASH24)                                           \
 	KEYWORD("hash32", Token::HASH32)                                           \
+	KEYWORD("hash40", Token::HASH40)                                           \
+	KEYWORD("hash48", Token::HASH48)                                           \
+	KEYWORD("hash56", Token::HASH56)                                           \
 	KEYWORD("hash64", Token::HASH64)                                           \
+	KEYWORD("hash72", Token::HASH72)                                           \
+	KEYWORD("hash80", Token::HASH80)                                           \
+	KEYWORD("hash88", Token::HASH88)                                           \
+	KEYWORD("hash96", Token::HASH96)                                           \
+	KEYWORD("hash104", Token::HASH104)                                         \
+	KEYWORD("hash112", Token::HASH112)                                         \
+	KEYWORD("hash120", Token::HASH120)                                         \
 	KEYWORD("hash128", Token::HASH128)                                         \
+	KEYWORD("hash136", Token::HASH136)                                         \
+	KEYWORD("hash144", Token::HASH144)                                         \
+	KEYWORD("hash152", Token::HASH152)                                         \
+	KEYWORD("hash160", Token::HASH160)                                         \
+	KEYWORD("hash168", Token::HASH168)                                         \
+	KEYWORD("hash178", Token::HASH176)                                         \
+	KEYWORD("hash184", Token::HASH184)                                         \
+	KEYWORD("hash192", Token::HASH192)                                         \
+	KEYWORD("hash200", Token::HASH200)                                         \
+	KEYWORD("hash208", Token::HASH208)                                         \
+	KEYWORD("hash216", Token::HASH216)                                         \
+	KEYWORD("hash224", Token::HASH224)                                         \
+	KEYWORD("hash232", Token::HASH232)                                         \
+	KEYWORD("hash240", Token::HASH240)                                         \
+	KEYWORD("hash248", Token::HASH248)                                         \
 	KEYWORD("hash256", Token::HASH256)                                         \
 	KEYWORD_GROUP('i')                                                         \
 	KEYWORD("if", Token::IF)                                                   \
 	KEYWORD("in", Token::IN)                                                   \
 	KEYWORD("int", Token::INT)                                                 \
+	KEYWORD("int8", Token::INT8)                                               \
+	KEYWORD("int16", Token::INT16)                                             \
+	KEYWORD("int24", Token::INT24)                                             \
 	KEYWORD("int32", Token::INT32)                                             \
+	KEYWORD("int40", Token::INT40)                                             \
+	KEYWORD("int48", Token::INT48)                                             \
+	KEYWORD("int56", Token::INT56)                                             \
 	KEYWORD("int64", Token::INT64)                                             \
+	KEYWORD("int72", Token::INT72)                                             \
+	KEYWORD("int80", Token::INT80)                                             \
+	KEYWORD("int88", Token::INT88)                                             \
+	KEYWORD("int96", Token::INT96)                                             \
+	KEYWORD("int104", Token::INT104)                                           \
+	KEYWORD("int112", Token::INT112)                                           \
+	KEYWORD("int120", Token::INT120)                                           \
 	KEYWORD("int128", Token::INT128)                                           \
+	KEYWORD("int136", Token::INT136)                                           \
+	KEYWORD("int144", Token::INT144)                                           \
+	KEYWORD("int152", Token::INT152)                                           \
+	KEYWORD("int160", Token::INT160)                                           \
+	KEYWORD("int168", Token::INT168)                                           \
+	KEYWORD("int178", Token::INT176)                                           \
+	KEYWORD("int184", Token::INT184)                                           \
+	KEYWORD("int192", Token::INT192)                                           \
+	KEYWORD("int200", Token::INT200)                                           \
+	KEYWORD("int208", Token::INT208)                                           \
+	KEYWORD("int216", Token::INT216)                                           \
+	KEYWORD("int224", Token::INT224)                                           \
+	KEYWORD("int232", Token::INT232)                                           \
+	KEYWORD("int240", Token::INT240)                                           \
+	KEYWORD("int248", Token::INT248)                                           \
 	KEYWORD("int256", Token::INT256)                                           \
 	KEYWORD_GROUP('l')                                                         \
 	KEYWORD_GROUP('m')                                                         \
@@ -591,9 +647,37 @@ Token::Value Scanner::scanNumber(bool _periodSeen)
 	KEYWORD("true", Token::TRUE_LITERAL)                                       \
 	KEYWORD_GROUP('u')                                                         \
 	KEYWORD("uint", Token::UINT)                                               \
+	KEYWORD("uint8", Token::UINT8)                                             \
+	KEYWORD("uint16", Token::UINT16)                                           \
+	KEYWORD("uint24", Token::UINT24)                                           \
 	KEYWORD("uint32", Token::UINT32)                                           \
+	KEYWORD("uint40", Token::UINT40)                                           \
+	KEYWORD("uint48", Token::UINT48)                                           \
+	KEYWORD("uint56", Token::UINT56)                                           \
 	KEYWORD("uint64", Token::UINT64)                                           \
+	KEYWORD("uint72", Token::UINT72)                                           \
+	KEYWORD("uint80", Token::UINT80)                                           \
+	KEYWORD("uint88", Token::UINT88)                                           \
+	KEYWORD("uint96", Token::UINT96)                                           \
+	KEYWORD("uint104", Token::UINT104)                                         \
+	KEYWORD("uint112", Token::UINT112)                                         \
+	KEYWORD("uint120", Token::UINT120)                                         \
 	KEYWORD("uint128", Token::UINT128)                                         \
+	KEYWORD("uint136", Token::UINT136)                                         \
+	KEYWORD("uint144", Token::UINT144)                                         \
+	KEYWORD("uint152", Token::UINT152)                                         \
+	KEYWORD("uint160", Token::UINT160)                                         \
+	KEYWORD("uint168", Token::UINT168)                                         \
+	KEYWORD("uint178", Token::UINT176)                                         \
+	KEYWORD("uint184", Token::UINT184)                                         \
+	KEYWORD("uint192", Token::UINT192)                                         \
+	KEYWORD("uint200", Token::UINT200)                                         \
+	KEYWORD("uint208", Token::UINT208)                                         \
+	KEYWORD("uint216", Token::UINT216)                                         \
+	KEYWORD("uint224", Token::UINT224)                                         \
+	KEYWORD("uint232", Token::UINT232)                                         \
+	KEYWORD("uint240", Token::UINT240)                                         \
+	KEYWORD("uint248", Token::UINT248)                                         \
 	KEYWORD("uint256", Token::UINT256)                                         \
 	KEYWORD("ureal", Token::UREAL)                                             \
 	KEYWORD_GROUP('v')                                                         \
diff --git a/libsolidity/Scanner.h b/libsolidity/Scanner.h
index 537c2434e..997365f3c 100644
--- a/libsolidity/Scanner.h
+++ b/libsolidity/Scanner.h
@@ -180,7 +180,7 @@ private:
 	Token::Value skipMultiLineComment();
 
 	void scanDecimalDigits();
-	Token::Value scanNumber(bool _periodSeen);
+	Token::Value scanNumber(char _charSeen = 0);
 	Token::Value scanIdentifierOrKeyword();
 
 	Token::Value scanString();
diff --git a/libsolidity/Token.h b/libsolidity/Token.h
index 0fb9b670f..67971c3d0 100644
--- a/libsolidity/Token.h
+++ b/libsolidity/Token.h
@@ -169,19 +169,103 @@ namespace solidity
 	 * the implementation in Types.cpp has to be synced to this here
 	 *  TODO more to be added */                                       \
 	K(INT, "int", 0)                                                   \
+	K(INT8, "int8", 0)                                                 \
+	K(INT16, "int16", 0)                                               \
+	K(INT24, "int24", 0)                                               \
 	K(INT32, "int32", 0)                                               \
+	K(INT40, "int40", 0)                                               \
+	K(INT48, "int48", 0)                                               \
+	K(INT56, "int56", 0)                                               \
 	K(INT64, "int64", 0)                                               \
+	K(INT72, "int72", 0)                                               \
+	K(INT80, "int80", 0)                                               \
+	K(INT88, "int88", 0)                                               \
+	K(INT96, "int96", 0)                                               \
+	K(INT104, "int104", 0)                                             \
+	K(INT112, "int112", 0)                                             \
+	K(INT120, "int120", 0)                                             \
 	K(INT128, "int128", 0)                                             \
+	K(INT136, "int136", 0)                                             \
+	K(INT144, "int144", 0)                                             \
+	K(INT152, "int152", 0)                                             \
+	K(INT160, "int160", 0)                                             \
+	K(INT168, "int168", 0)                                             \
+	K(INT176, "int178", 0)                                             \
+	K(INT184, "int184", 0)                                             \
+	K(INT192, "int192", 0)                                             \
+	K(INT200, "int200", 0)                                             \
+	K(INT208, "int208", 0)                                             \
+	K(INT216, "int216", 0)                                             \
+	K(INT224, "int224", 0)                                             \
+	K(INT232, "int232", 0)                                             \
+	K(INT240, "int240", 0)                                             \
+	K(INT248, "int248", 0)                                             \
 	K(INT256, "int256", 0)                                             \
 	K(UINT, "uint", 0)                                                 \
+	K(UINT8, "uint8", 0)                                               \
+	K(UINT16, "uint16", 0)                                             \
+	K(UINT24, "uint24", 0)                                             \
 	K(UINT32, "uint32", 0)                                             \
+	K(UINT40, "uint40", 0)                                             \
+	K(UINT48, "uint48", 0)                                             \
+	K(UINT56, "uint56", 0)                                             \
 	K(UINT64, "uint64", 0)                                             \
+	K(UINT72, "uint72", 0)                                             \
+	K(UINT80, "uint80", 0)                                             \
+	K(UINT88, "uint88", 0)                                             \
+	K(UINT96, "uint96", 0)                                             \
+	K(UINT104, "uint104", 0)                                           \
+	K(UINT112, "uint112", 0)                                           \
+	K(UINT120, "uint120", 0)                                           \
 	K(UINT128, "uint128", 0)                                           \
+	K(UINT136, "uint136", 0)                                           \
+	K(UINT144, "uint144", 0)                                           \
+	K(UINT152, "uint152", 0)                                           \
+	K(UINT160, "uint160", 0)                                           \
+	K(UINT168, "uint168", 0)                                           \
+	K(UINT176, "uint178", 0)                                           \
+	K(UINT184, "uint184", 0)                                           \
+	K(UINT192, "uint192", 0)                                           \
+	K(UINT200, "uint200", 0)                                           \
+	K(UINT208, "uint208", 0)                                           \
+	K(UINT216, "uint216", 0)                                           \
+	K(UINT224, "uint224", 0)                                           \
+	K(UINT232, "uint232", 0)                                           \
+	K(UINT240, "uint240", 0)                                           \
+	K(UINT248, "uint248", 0)                                           \
 	K(UINT256, "uint256", 0)                                           \
 	K(HASH, "hash", 0)                                                 \
+	K(HASH8, "hash8", 0)                                               \
+	K(HASH16, "hash16", 0)                                             \
+	K(HASH24, "hash24", 0)                                             \
 	K(HASH32, "hash32", 0)                                             \
+	K(HASH40, "hash40", 0)                                             \
+	K(HASH48, "hash48", 0)                                             \
+	K(HASH56, "hash56", 0)                                             \
 	K(HASH64, "hash64", 0)                                             \
+	K(HASH72, "hash72", 0)                                             \
+	K(HASH80, "hash80", 0)                                             \
+	K(HASH88, "hash88", 0)                                             \
+	K(HASH96, "hash96", 0)                                             \
+	K(HASH104, "hash104", 0)                                           \
+	K(HASH112, "hash112", 0)                                           \
+	K(HASH120, "hash120", 0)                                           \
 	K(HASH128, "hash128", 0)                                           \
+	K(HASH136, "hash136", 0)                                           \
+	K(HASH144, "hash144", 0)                                           \
+	K(HASH152, "hash152", 0)                                           \
+	K(HASH160, "hash160", 0)                                           \
+	K(HASH168, "hash168", 0)                                           \
+	K(HASH176, "hash178", 0)                                           \
+	K(HASH184, "hash184", 0)                                           \
+	K(HASH192, "hash192", 0)                                           \
+	K(HASH200, "hash200", 0)                                           \
+	K(HASH208, "hash208", 0)                                           \
+	K(HASH216, "hash216", 0)                                           \
+	K(HASH224, "hash224", 0)                                           \
+	K(HASH232, "hash232", 0)                                           \
+	K(HASH240, "hash240", 0)                                           \
+	K(HASH248, "hash248", 0)                                           \
 	K(HASH256, "hash256", 0)                                           \
 	K(ADDRESS, "address", 0)                                           \
 	K(BOOL, "bool", 0)                                                 \
diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp
index a4d70e3a0..3a4112c45 100644
--- a/libsolidity/Types.cpp
+++ b/libsolidity/Types.cpp
@@ -25,12 +25,14 @@
 #include 
 #include 
 
+using namespace std;
+
 namespace dev
 {
 namespace solidity
 {
 
-std::shared_ptr Type::fromElementaryTypeName(Token::Value _typeToken)
+shared_ptr Type::fromElementaryTypeName(Token::Value _typeToken)
 {
 	if (asserts(Token::isElementaryTypeName(_typeToken)))
 		BOOST_THROW_EXCEPTION(InternalCompilerError());
@@ -38,66 +40,69 @@ std::shared_ptr Type::fromElementaryTypeName(Token::Value _typeToken)
 	if (Token::INT <= _typeToken && _typeToken <= Token::HASH256)
 	{
 		int offset = _typeToken - Token::INT;
-		int bits = offset % 5;
-		if (bits == 0)
-			bits = 256;
-		else
-			bits = (1 << (bits - 1)) * 32;
-		int modifier = offset / 5;
-		return std::make_shared(bits,
-											 modifier == 0 ? IntegerType::Modifier::SIGNED :
-											 modifier == 1 ? IntegerType::Modifier::UNSIGNED :
-											 IntegerType::Modifier::HASH);
+		int bytes = offset % 33;
+		if (bytes == 0)
+			bytes = 32;
+		int modifier = offset / 33;
+		return make_shared(bytes * 8,
+										modifier == 0 ? IntegerType::Modifier::SIGNED :
+										modifier == 1 ? IntegerType::Modifier::UNSIGNED :
+										IntegerType::Modifier::HASH);
 	}
 	else if (_typeToken == Token::ADDRESS)
-		return std::make_shared(0, IntegerType::Modifier::ADDRESS);
+		return make_shared(0, IntegerType::Modifier::ADDRESS);
 	else if (_typeToken == Token::BOOL)
-		return std::make_shared();
+		return make_shared();
 	else
 		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unable to convert elementary typename " +
 																		 std::string(Token::toString(_typeToken)) + " to type."));
-	return std::shared_ptr();
 }
 
-std::shared_ptr Type::fromUserDefinedTypeName(UserDefinedTypeName const& _typeName)
+shared_ptr Type::fromUserDefinedTypeName(UserDefinedTypeName const& _typeName)
 {
-	return std::make_shared(*_typeName.getReferencedStruct());
+	return make_shared(*_typeName.getReferencedStruct());
 }
 
-std::shared_ptr Type::fromMapping(Mapping const&)
+shared_ptr Type::fromMapping(Mapping const&)
 {
 	BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Mapping types not yet implemented."));
-	return std::shared_ptr();
 }
 
-std::shared_ptr Type::forLiteral(Literal const& _literal)
+shared_ptr Type::forLiteral(Literal const& _literal)
 {
 	switch (_literal.getToken())
 	{
 	case Token::TRUE_LITERAL:
 	case Token::FALSE_LITERAL:
-		return std::make_shared();
+		return make_shared();
 	case Token::NUMBER:
 		return IntegerType::smallestTypeForLiteral(_literal.getValue());
 	case Token::STRING_LITERAL:
-		return std::shared_ptr(); // @todo
+		return shared_ptr(); // @todo
 	default:
-		return std::shared_ptr();
+		return shared_ptr();
 	}
 }
 
-std::shared_ptr IntegerType::smallestTypeForLiteral(std::string const&)
+shared_ptr IntegerType::smallestTypeForLiteral(string const& _literal)
 {
-	//@todo
-	return std::make_shared(256, Modifier::UNSIGNED);
+	bigint value(_literal);
+	bool isSigned = value < 0 || (!_literal.empty() && _literal.front() == '-');
+	if (isSigned)
+		// convert to positive number of same bit requirements
+		value = ((-value) - 1) << 1;
+	unsigned bytes = max(bytesRequired(value), 1u);
+	if (bytes > 32)
+		return shared_ptr();
+	return make_shared(bytes * 8, isSigned ? Modifier::SIGNED : Modifier::UNSIGNED);
 }
 
 IntegerType::IntegerType(int _bits, IntegerType::Modifier _modifier):
 	m_bits(_bits), m_modifier(_modifier)
 {
 	if (isAddress())
-		_bits = 160;
-	if (asserts(_bits > 0 && _bits <= 256 && _bits % 8 == 0))
+		m_bits = 160;
+	if (asserts(m_bits > 0 && m_bits <= 256 && m_bits % 8 == 0))
 		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid bit number for integer type: " + dev::toString(_bits)));
 }
 
@@ -155,19 +160,17 @@ bool IntegerType::operator==(Type const& _other) const
 	return other.m_bits == m_bits && other.m_modifier == m_modifier;
 }
 
-std::string IntegerType::toString() const
+string IntegerType::toString() const
 {
 	if (isAddress())
 		return "address";
-	std::string prefix = isHash() ? "hash" : (isSigned() ? "int" : "uint");
+	string prefix = isHash() ? "hash" : (isSigned() ? "int" : "uint");
 	return prefix + dev::toString(m_bits);
 }
 
 u256 IntegerType::literalValue(Literal const& _literal) const
 {
 	bigint value(_literal.getValue());
-	//@todo check that the number is not too large
-	//@todo does this work for signed numbers?
 	return u256(value);
 }
 
@@ -202,6 +205,14 @@ bool ContractType::operator==(Type const& _other) const
 	return other.m_contract == m_contract;
 }
 
+u256 ContractType::getStorageSize() const
+{
+	u256 size = 0;
+	for (ASTPointer const& variable: m_contract.getStateVariables())
+		size += variable->getType()->getStorageSize();
+	return max(1, size);
+}
+
 bool StructType::operator==(Type const& _other) const
 {
 	if (_other.getCategory() != getCategory())
@@ -210,6 +221,14 @@ bool StructType::operator==(Type const& _other) const
 	return other.m_struct == m_struct;
 }
 
+u256 StructType::getStorageSize() const
+{
+	u256 size = 0;
+	for (ASTPointer const& variable: m_struct.getMembers())
+		size += variable->getType()->getStorageSize();
+	return max(1, size);
+}
+
 bool FunctionType::operator==(Type const& _other) const
 {
 	if (_other.getCategory() != getCategory())
diff --git a/libsolidity/Types.h b/libsolidity/Types.h
index 4493b8037..607ee3a6f 100644
--- a/libsolidity/Types.h
+++ b/libsolidity/Types.h
@@ -56,7 +56,8 @@ public:
 	static std::shared_ptr fromMapping(Mapping const& _typeName);
 	/// @}
 
-	/// Auto-detect the proper type for a literal
+	/// Auto-detect the proper type for a literal. @returns an empty pointer if the literal does
+	/// not fit any type.
 	static std::shared_ptr forLiteral(Literal const& _literal);
 
 	virtual Category getCategory() const = 0;
@@ -74,6 +75,9 @@ public:
 	/// @returns number of bytes used by this type when encoded for CALL, or 0 if the encoding
 	/// is not a simple big-endian encoding or the type cannot be stored on the stack.
 	virtual unsigned getCalldataEncodedSize() const { return 0; }
+	/// @returns number of bytes required to hold this value in storage.
+	/// For dynamically "allocated" types, it returns the size of the statically allocated head,
+	virtual u256 getStorageSize() const { return 1; }
 
 	virtual std::string toString() const = 0;
 	virtual u256 literalValue(Literal const&) const
@@ -95,6 +99,8 @@ public:
 	};
 	virtual Category getCategory() const override { return Category::INTEGER; }
 
+	/// @returns the smallest integer type for the given literal or an empty pointer
+	/// if no type fits.
 	static std::shared_ptr smallestTypeForLiteral(std::string const& _literal);
 
 	explicit IntegerType(int _bits, Modifier _modifier = Modifier::UNSIGNED);
@@ -154,7 +160,7 @@ public:
 	ContractType(ContractDefinition const& _contract): m_contract(_contract) {}
 
 	virtual bool operator==(Type const& _other) const override;
-
+	virtual u256 getStorageSize() const;
 	virtual std::string toString() const override { return "contract{...}"; }
 
 private:
@@ -175,7 +181,7 @@ public:
 	}
 
 	virtual bool operator==(Type const& _other) const override;
-
+	virtual u256 getStorageSize() const;
 	virtual std::string toString() const override { return "struct{...}"; }
 
 private:
@@ -193,9 +199,9 @@ public:
 
 	FunctionDefinition const& getFunction() const { return m_function; }
 
-	virtual std::string toString() const override { return "function(...)returns(...)"; }
-
 	virtual bool operator==(Type const& _other) const override;
+	virtual std::string toString() const override { return "function(...)returns(...)"; }
+	virtual u256 getStorageSize() const { BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Storage size of non-storable function type requested.")); }
 
 private:
 	FunctionDefinition const& m_function;
@@ -209,9 +215,9 @@ class MappingType: public Type
 public:
 	virtual Category getCategory() const override { return Category::MAPPING; }
 	MappingType() {}
-	virtual std::string toString() const override { return "mapping(...=>...)"; }
 
 	virtual bool operator==(Type const& _other) const override;
+	virtual std::string toString() const override { return "mapping(...=>...)"; }
 
 private:
 	std::shared_ptr m_keyType;
@@ -229,6 +235,7 @@ public:
 	VoidType() {}
 
 	virtual std::string toString() const override { return "void"; }
+	virtual u256 getStorageSize() const { BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Storage size of non-storable void type requested.")); }
 };
 
 /**
@@ -244,7 +251,7 @@ public:
 	std::shared_ptr const& getActualType() const { return m_actualType; }
 
 	virtual bool operator==(Type const& _other) const override;
-
+	virtual u256 getStorageSize() const { BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Storage size of non-storable type type requested.")); }
 	virtual std::string toString() const override { return "type(" + m_actualType->toString() + ")"; }
 
 private:
diff --git a/libweb3jsonrpc/WebThreeStubServer.cpp b/libweb3jsonrpc/WebThreeStubServer.cpp
index 12a18d938..092faae09 100644
--- a/libweb3jsonrpc/WebThreeStubServer.cpp
+++ b/libweb3jsonrpc/WebThreeStubServer.cpp
@@ -22,7 +22,7 @@
  */
 
 #include "WebThreeStubServer.h"
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -194,9 +194,11 @@ static dev::eth::MessageFilter toMessageFilter(Json::Value const& _json)
 	if (!_json["topics"].empty())
 	{
 		if (_json["topics"].isArray())
+		{
 			for (auto i: _json["topics"])
 				if (i.isString())
 					filter.topic(jsToU256(i.asString()));
+		}
 		else if(_json["topics"].isString())
 			filter.topic(jsToU256(_json["topics"].asString()));
 	}
@@ -268,14 +270,14 @@ static Json::Value toJson(h256 const& _h, shh::Envelope const& _e, shh::Message
 	res["sent"] = (int)_e.sent();
 	res["ttl"] = (int)_e.ttl();
 	res["workProved"] = (int)_e.workProved();
-	res["topic"] = toJS(_e.topic());
-	res["payload"] = asString(_m.payload());
+	for (auto const& t: _e.topics())
+		res["topics"].append(toJS(t));
+	res["payload"] = toJS(_m.payload());
 	res["from"] = toJS(_m.from());
 	res["to"] = toJS(_m.to());
 	return res;
 }
 
-
 WebThreeStubServer::WebThreeStubServer(jsonrpc::AbstractServerConnector* _conn, WebThreeDirect& _web3, std::vector const& _accounts):
 	AbstractWebThreeStubServer(_conn),
 	m_web3(_web3)
@@ -312,7 +314,7 @@ std::shared_ptr WebThreeStubServer::face() const
 	return m_web3.whisper();
 }
 
-Json::Value WebThreeStubServer::accounts()
+Json::Value WebThreeStubServer::eth_accounts()
 {
 	Json::Value ret(Json::arrayValue);
 	for (auto i: m_accounts)
@@ -320,27 +322,27 @@ Json::Value WebThreeStubServer::accounts()
 	return ret;
 }
 
-std::string WebThreeStubServer::addToGroup(std::string const& _group, std::string const& _who)
+std::string WebThreeStubServer::shh_addToGroup(std::string const& _group, std::string const& _who)
 {
 	(void)_group;
 	(void)_who;
 	return "";
 }
 
-std::string WebThreeStubServer::balanceAt(string const& _address)
+std::string WebThreeStubServer::eth_balanceAt(string const& _address)
 {
 	int block = 0;
 	return toJS(client()->balanceAt(jsToAddress(_address), block));
 }
 
-Json::Value WebThreeStubServer::blockByHash(std::string const& _hash)
+Json::Value WebThreeStubServer::eth_blockByHash(std::string const& _hash)
 {
 	if (!client())
 		return "";
 	return toJson(client()->blockInfo(jsToFixed<32>(_hash)));
 }
 
-Json::Value WebThreeStubServer::blockByNumber(int const& _number)
+Json::Value WebThreeStubServer::eth_blockByNumber(int const& _number)
 {
 	if (!client())
 		return "";
@@ -383,7 +385,7 @@ static TransactionSkeleton toTransaction(Json::Value const& _json)
 	return ret;
 }
 
-std::string WebThreeStubServer::call(Json::Value const& _json)
+std::string WebThreeStubServer::eth_call(Json::Value const& _json)
 {
 	std::string ret;
 	if (!client())
@@ -407,41 +409,41 @@ std::string WebThreeStubServer::call(Json::Value const& _json)
 	return ret;
 }
 
-bool WebThreeStubServer::changed(int const& _id)
+bool WebThreeStubServer::eth_changed(int const& _id)
 {
 	if (!client())
 		return false;
 	return client()->checkWatch(_id);
 }
 
-std::string WebThreeStubServer::codeAt(string const& _address)
+std::string WebThreeStubServer::eth_codeAt(string const& _address)
 {
 	int block = 0;
 	return client() ? jsFromBinary(client()->codeAt(jsToAddress(_address), block)) : "";
 }
 
-std::string WebThreeStubServer::coinbase()
+std::string WebThreeStubServer::eth_coinbase()
 {
 	return client() ? toJS(client()->address()) : "";
 }
 
-double WebThreeStubServer::countAt(string const& _address)
+double WebThreeStubServer::eth_countAt(string const& _address)
 {
 	int block = 0;
 	return client() ? (double)(uint64_t)client()->countAt(jsToAddress(_address), block) : 0;
 }
 
-int WebThreeStubServer::defaultBlock()
+int WebThreeStubServer::eth_defaultBlock()
 {
 	return client() ? client()->getDefault() : 0;
 }
 
-std::string WebThreeStubServer::gasPrice()
+std::string WebThreeStubServer::eth_gasPrice()
 {
 	return toJS(10 * dev::eth::szabo);
 }
 
-std::string WebThreeStubServer::get(std::string const& _name, std::string const& _key)
+std::string WebThreeStubServer::db_get(std::string const& _name, std::string const& _key)
 {
 	bytes k = sha3(_name).asBytes() + sha3(_key).asBytes();
 	string ret;
@@ -449,14 +451,14 @@ std::string WebThreeStubServer::get(std::string const& _name, std::string const&
 	return toJS(dev::asBytes(ret));
 }
 
-Json::Value WebThreeStubServer::getMessages(int const& _id)
+Json::Value WebThreeStubServer::eth_getMessages(int const& _id)
 {
 	if (!client())
-		return  Json::Value();
+		return Json::Value();
 	return toJson(client()->messages(_id));
 }
 
-std::string WebThreeStubServer::getString(std::string const& _name, std::string const& _key)
+std::string WebThreeStubServer::db_getString(std::string const& _name, std::string const& _key)
 {
 	bytes k = sha3(_name).asBytes() + sha3(_key).asBytes();
 	string ret;
@@ -464,22 +466,22 @@ std::string WebThreeStubServer::getString(std::string const& _name, std::string
 	return ret;
 }
 
-bool WebThreeStubServer::haveIdentity(std::string const& _id)
+bool WebThreeStubServer::shh_haveIdentity(std::string const& _id)
 {
 	return m_ids.count(jsToPublic(_id)) > 0;
 }
 
-bool WebThreeStubServer::listening()
+bool WebThreeStubServer::eth_listening()
 {
 	return m_web3.isNetworkStarted();
 }
 
-bool WebThreeStubServer::mining()
+bool WebThreeStubServer::eth_mining()
 {
 	return client() ? client()->isMining() : false;
 }
 
-int WebThreeStubServer::newFilter(Json::Value const& _json)
+int WebThreeStubServer::eth_newFilter(Json::Value const& _json)
 {
 	unsigned ret = -1;
 	if (!client())
@@ -488,7 +490,7 @@ int WebThreeStubServer::newFilter(Json::Value const& _json)
 	return ret;
 }
 
-int WebThreeStubServer::newFilterString(std::string const& _filter)
+int WebThreeStubServer::eth_newFilterString(std::string const& _filter)
 {
 	unsigned ret = -1;
 	if (!client())
@@ -500,14 +502,14 @@ int WebThreeStubServer::newFilterString(std::string const& _filter)
 	return ret;
 }
 
-std::string WebThreeStubServer::newGroup(std::string const& _id, std::string const& _who)
+std::string WebThreeStubServer::shh_newGroup(std::string const& _id, std::string const& _who)
 {
 	(void)_id;
 	(void)_who;
 	return "";
 }
 
-std::string WebThreeStubServer::newIdentity()
+std::string WebThreeStubServer::shh_newIdentity()
 {
 	cnote << this << m_ids;
 	KeyPair kp = KeyPair::create();
@@ -515,22 +517,27 @@ std::string WebThreeStubServer::newIdentity()
 	return toJS(kp.pub());
 }
 
-std::string WebThreeStubServer::compile(string const& _s)
+std::string WebThreeStubServer::eth_compile(string const& _s)
+{
+	return toJS(dev::eth::compileLLL(_s));
+}
+
+std::string WebThreeStubServer::eth_lll(string const& _s)
 {
 	return toJS(dev::eth::compileLLL(_s));
 }
 
-int WebThreeStubServer::number()
+int WebThreeStubServer::eth_number()
 {
 	return client() ? client()->number() + 1 : 0;
 }
 
-int WebThreeStubServer::peerCount()
+int WebThreeStubServer::eth_peerCount()
 {
 	return m_web3.peerCount();
 }
 
-bool WebThreeStubServer::post(Json::Value const& _json)
+bool WebThreeStubServer::shh_post(Json::Value const& _json)
 {
 	cnote << this << m_ids;
 	shh::Message m = toMessage(_json);
@@ -547,7 +554,7 @@ bool WebThreeStubServer::post(Json::Value const& _json)
 	return true;
 }
 
-bool WebThreeStubServer::put(std::string const& _name, std::string const& _key, std::string const& _value)
+bool WebThreeStubServer::db_put(std::string const& _name, std::string const& _key, std::string const& _value)
 {
 	bytes k = sha3(_name).asBytes() + sha3(_key).asBytes();
 	bytes v = jsToBytes(_value);
@@ -555,7 +562,7 @@ bool WebThreeStubServer::put(std::string const& _name, std::string const& _key,
 	return true;
 }
 
-bool WebThreeStubServer::putString(std::string const& _name, std::string const& _key, std::string const& _value)
+bool WebThreeStubServer::db_putString(std::string const& _name, std::string const& _key, std::string const& _value)
 {
 	bytes k = sha3(_name).asBytes() + sha3(_key).asBytes();
 	string v = _value;
@@ -563,7 +570,7 @@ bool WebThreeStubServer::putString(std::string const& _name, std::string const&
 	return true;
 }
 
-bool WebThreeStubServer::setCoinbase(std::string const& _address)
+bool WebThreeStubServer::eth_setCoinbase(std::string const& _address)
 {
 	if (!client())
 		return false;
@@ -571,7 +578,7 @@ bool WebThreeStubServer::setCoinbase(std::string const& _address)
 	return true;
 }
 
-bool WebThreeStubServer::setDefaultBlock(int const& _block)
+bool WebThreeStubServer::eth_setDefaultBlock(int const& _block)
 {
 	if (!client())
 		return false;
@@ -579,7 +586,7 @@ bool WebThreeStubServer::setDefaultBlock(int const& _block)
 	return true;
 }
 
-bool WebThreeStubServer::setListening(bool const& _listening)
+bool WebThreeStubServer::eth_setListening(bool const& _listening)
 {
 	if (_listening)
 		m_web3.startNetwork();
@@ -588,7 +595,7 @@ bool WebThreeStubServer::setListening(bool const& _listening)
 	return true;
 }
 
-bool WebThreeStubServer::setMining(bool const& _mining)
+bool WebThreeStubServer::eth_setMining(bool const& _mining)
 {
 	if (!client())
 		return false;
@@ -600,7 +607,7 @@ bool WebThreeStubServer::setMining(bool const& _mining)
 	return true;
 }
 
-Json::Value WebThreeStubServer::shhChanged(int const& _id)
+Json::Value WebThreeStubServer::shh_changed(int const& _id)
 {
 	Json::Value ret(Json::arrayValue);
 	auto pub = m_shhWatches[_id];
@@ -618,13 +625,13 @@ Json::Value WebThreeStubServer::shhChanged(int const& _id)
 			}
 			else
 				m = e.open();
-			ret.append(toJson(h,e,m));
+			ret.append(toJson(h, e, m));
 		}
 	
 	return ret;
 }
 
-int WebThreeStubServer::shhNewFilter(Json::Value const& _json)
+int WebThreeStubServer::shh_newFilter(Json::Value const& _json)
 {
 	auto w = toWatch(_json);
 	auto ret = face()->installWatch(w.first);
@@ -632,19 +639,19 @@ int WebThreeStubServer::shhNewFilter(Json::Value const& _json)
 	return ret;
 }
 
-bool WebThreeStubServer::shhUninstallFilter(int const& _id)
+bool WebThreeStubServer::shh_uninstallFilter(int const& _id)
 {
 	face()->uninstallWatch(_id);
 	return true;
 }
 
-std::string WebThreeStubServer::stateAt(string const& _address, string const& _storage)
+std::string WebThreeStubServer::eth_stateAt(string const& _address, string const& _storage)
 {
 	int block = 0;
 	return client() ? toJS(client()->stateAt(jsToAddress(_address), jsToU256(_storage), block)) : "";
 }
 
-std::string WebThreeStubServer::transact(Json::Value const& _json)
+std::string WebThreeStubServer::eth_transact(Json::Value const& _json)
 {
 	std::string ret;
 	if (!client())
@@ -674,35 +681,35 @@ std::string WebThreeStubServer::transact(Json::Value const& _json)
 	return ret;
 }
 
-Json::Value WebThreeStubServer::transactionByHash(std::string const& _hash, int const& _i)
+Json::Value WebThreeStubServer::eth_transactionByHash(std::string const& _hash, int const& _i)
 {
 	if (!client())
 		return "";
 	return toJson(client()->transaction(jsToFixed<32>(_hash), _i));
 }
 
-Json::Value WebThreeStubServer::transactionByNumber(int const& _number, int const& _i)
+Json::Value WebThreeStubServer::eth_transactionByNumber(int const& _number, int const& _i)
 {
 	if (!client())
 		return "";
 	return toJson(client()->transaction(client()->hashFromNumber(_number), _i));
 }
 
-Json::Value WebThreeStubServer::uncleByHash(std::string const& _hash, int const& _i)
+Json::Value WebThreeStubServer::eth_uncleByHash(std::string const& _hash, int const& _i)
 {
 	if (!client())
 		return "";
 	return toJson(client()->uncle(jsToFixed<32>(_hash), _i));
 }
 
-Json::Value WebThreeStubServer::uncleByNumber(int const& _number, int const& _i)
+Json::Value WebThreeStubServer::eth_uncleByNumber(int const& _number, int const& _i)
 {
 	if (!client())
 		return "";
 	return toJson(client()->uncle(client()->hashFromNumber(_number), _i));
 }
 
-bool WebThreeStubServer::uninstallFilter(int const& _id)
+bool WebThreeStubServer::eth_uninstallFilter(int const& _id)
 {
 	if (!client())
 		return false;
diff --git a/libweb3jsonrpc/WebThreeStubServer.h b/libweb3jsonrpc/WebThreeStubServer.h
index 33163b75e..10ca2fd76 100644
--- a/libweb3jsonrpc/WebThreeStubServer.h
+++ b/libweb3jsonrpc/WebThreeStubServer.h
@@ -64,49 +64,52 @@ class WebThreeStubServer: public AbstractWebThreeStubServer
 public:
 	WebThreeStubServer(jsonrpc::AbstractServerConnector* _conn, dev::WebThreeDirect& _web3, std::vector const& _accounts);
 	
-	virtual Json::Value accounts();
-	virtual std::string addToGroup(std::string const& _group, std::string const& _who);
-	virtual std::string balanceAt(std::string const& _address);
-	virtual Json::Value blockByHash(std::string const& _hash);
-	virtual Json::Value blockByNumber(int const& _number);
-	virtual std::string call(Json::Value const& _json);
-	virtual bool changed(int const& _id);
-	virtual std::string codeAt(std::string const& _address);
-	virtual std::string coinbase();
-	virtual std::string compile(std::string const& _s);
-	virtual double countAt(std::string const& _address);
-	virtual int defaultBlock();
-	virtual std::string gasPrice();
-	virtual std::string get(std::string const& _name, std::string const& _key);
-	virtual Json::Value getMessages(int const& _id);
-	virtual std::string getString(std::string const& _name, std::string const& _key);
-	virtual bool haveIdentity(std::string const& _id);
-	virtual bool listening();
-	virtual bool mining();
-	virtual int newFilter(Json::Value const& _json);
-	virtual int newFilterString(std::string const& _filter);
-	virtual std::string newGroup(std::string const& _id, std::string const& _who);
-	virtual std::string newIdentity();
-	virtual int number();
-	virtual int peerCount();
-	virtual bool post(Json::Value const& _json);
-	virtual bool put(std::string const& _name, std::string const& _key, std::string const& _value);
-	virtual bool putString(std::string const& _name, std::string const& _key, std::string const& _value);
-	virtual bool setCoinbase(std::string const& _address);
-	virtual bool setDefaultBlock(int const& _block);
-	virtual bool setListening(bool const& _listening);
-	virtual bool setMining(bool const& _mining);
-	virtual Json::Value shhChanged(int const& _id);
-	virtual int shhNewFilter(Json::Value const& _json);
-	virtual bool shhUninstallFilter(int const& _id);
-	virtual std::string stateAt(std::string const& _address, std::string const& _storage);
-	virtual std::string transact(Json::Value const& _json);
-	virtual Json::Value transactionByHash(std::string const& _hash, int const& _i);
-	virtual Json::Value transactionByNumber(int const& _number, int const& _i);
-	virtual Json::Value uncleByHash(std::string const& _hash, int const& _i);
-	virtual Json::Value uncleByNumber(int const& _number, int const& _i);
-	virtual bool uninstallFilter(int const& _id);
-	
+	virtual Json::Value eth_accounts();
+	virtual std::string eth_balanceAt(std::string const& _address);
+	virtual Json::Value eth_blockByHash(std::string const& _hash);
+	virtual Json::Value eth_blockByNumber(int const& _number);
+	virtual std::string eth_call(Json::Value const& _json);
+	virtual bool eth_changed(int const& _id);
+	virtual std::string eth_codeAt(std::string const& _address);
+	virtual std::string eth_coinbase();
+	virtual std::string eth_compile(std::string const& _s);
+	virtual double eth_countAt(std::string const& _address);
+	virtual int eth_defaultBlock();
+	virtual std::string eth_gasPrice();
+	virtual Json::Value eth_getMessages(int const& _id);
+	virtual bool eth_listening();
+	virtual bool eth_mining();
+	virtual int eth_newFilter(Json::Value const& _json);
+	virtual int eth_newFilterString(std::string const& _filter);
+	virtual int eth_number();
+	virtual int eth_peerCount();
+	virtual bool eth_setCoinbase(std::string const& _address);
+	virtual bool eth_setDefaultBlock(int const& _block);
+	virtual bool eth_setListening(bool const& _listening);
+	virtual std::string eth_lll(std::string const& _s);
+	virtual bool eth_setMining(bool const& _mining);
+	virtual std::string eth_stateAt(std::string const& _address, std::string const& _storage);
+	virtual std::string eth_transact(Json::Value const& _json);
+	virtual Json::Value eth_transactionByHash(std::string const& _hash, int const& _i);
+	virtual Json::Value eth_transactionByNumber(int const& _number, int const& _i);
+	virtual Json::Value eth_uncleByHash(std::string const& _hash, int const& _i);
+	virtual Json::Value eth_uncleByNumber(int const& _number, int const& _i);
+	virtual bool eth_uninstallFilter(int const& _id);
+
+	virtual std::string db_get(std::string const& _name, std::string const& _key);
+	virtual std::string db_getString(std::string const& _name, std::string const& _key);
+	virtual bool db_put(std::string const& _name, std::string const& _key, std::string const& _value);
+	virtual bool db_putString(std::string const& _name, std::string const& _key, std::string const& _value);
+
+	virtual std::string shh_addToGroup(std::string const& _group, std::string const& _who);
+	virtual Json::Value shh_changed(int const& _id);
+	virtual bool shh_haveIdentity(std::string const& _id);
+	virtual int shh_newFilter(Json::Value const& _json);
+	virtual std::string shh_newGroup(std::string const& _id, std::string const& _who);
+	virtual std::string shh_newIdentity();
+	virtual bool shh_post(Json::Value const& _json);
+	virtual bool shh_uninstallFilter(int const& _id);
+
 	void setAccounts(std::vector const& _accounts);
 	void setIdentities(std::vector const& _ids);
 	std::map const& ids() const { return m_ids; }
diff --git a/libweb3jsonrpc/abstractwebthreestubserver.h b/libweb3jsonrpc/abstractwebthreestubserver.h
index 66b9ff77d..dc99ddcc6 100644
--- a/libweb3jsonrpc/abstractwebthreestubserver.h
+++ b/libweb3jsonrpc/abstractwebthreestubserver.h
@@ -13,304 +13,311 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer(conn) 
         {
-            this->bindAndAddMethod(new jsonrpc::Procedure("accounts", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY,  NULL), &AbstractWebThreeStubServer::accountsI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("addToGroup", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::addToGroupI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("balanceAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::balanceAtI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("blockByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::blockByHashI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("blockByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::blockByNumberI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("call", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::callI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("changed", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::changedI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("codeAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::codeAtI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("coinbase", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING,  NULL), &AbstractWebThreeStubServer::coinbaseI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("compile", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::compileI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("countAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_REAL, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::countAtI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("defaultBlock", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER,  NULL), &AbstractWebThreeStubServer::defaultBlockI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("gasPrice", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING,  NULL), &AbstractWebThreeStubServer::gasPriceI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("get", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::getI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("getMessages", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::getMessagesI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("getString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::getStringI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("haveIdentity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::haveIdentityI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("listening", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN,  NULL), &AbstractWebThreeStubServer::listeningI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("mining", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN,  NULL), &AbstractWebThreeStubServer::miningI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("newFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::newFilterI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("newFilterString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::newFilterStringI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("newGroup", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::newGroupI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("newIdentity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING,  NULL), &AbstractWebThreeStubServer::newIdentityI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("number", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER,  NULL), &AbstractWebThreeStubServer::numberI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("peerCount", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER,  NULL), &AbstractWebThreeStubServer::peerCountI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("post", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::postI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("put", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::putI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("putString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::putStringI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("setCoinbase", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::setCoinbaseI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("setDefaultBlock", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::setDefaultBlockI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("setListening", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::setListeningI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("setMining", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::setMiningI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("shhChanged", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::shhChangedI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("shhNewFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::shhNewFilterI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("shhUninstallFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::shhUninstallFilterI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("stateAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::stateAtI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("transact", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::transactI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("transactionByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::transactionByHashI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("transactionByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::transactionByNumberI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("uncleByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::uncleByHashI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("uncleByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::uncleByNumberI);
-            this->bindAndAddMethod(new jsonrpc::Procedure("uninstallFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::uninstallFilterI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("db_get", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::db_getI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("db_getString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::db_getStringI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("db_put", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::db_putI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("db_putString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::db_putStringI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_accounts", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY,  NULL), &AbstractWebThreeStubServer::eth_accountsI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_balanceAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_balanceAtI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_blockByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_blockByHashI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_blockByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_blockByNumberI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_call", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_callI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_changed", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_changedI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_codeAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_codeAtI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_coinbase", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING,  NULL), &AbstractWebThreeStubServer::eth_coinbaseI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_compile", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_compileI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_countAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_REAL, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_countAtI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_defaultBlock", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER,  NULL), &AbstractWebThreeStubServer::eth_defaultBlockI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_gasPrice", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING,  NULL), &AbstractWebThreeStubServer::eth_gasPriceI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_getMessages", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_getMessagesI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_listening", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN,  NULL), &AbstractWebThreeStubServer::eth_listeningI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_lll", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_lllI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_mining", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN,  NULL), &AbstractWebThreeStubServer::eth_miningI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_newFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_newFilterI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_newFilterString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_newFilterStringI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_number", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER,  NULL), &AbstractWebThreeStubServer::eth_numberI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_peerCount", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER,  NULL), &AbstractWebThreeStubServer::eth_peerCountI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_setCoinbase", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_setCoinbaseI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_setDefaultBlock", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_setDefaultBlockI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_setListening", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::eth_setListeningI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_setMining", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::eth_setMiningI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_stateAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_stateAtI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_transact", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_transactI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_transactionByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_transactionByHashI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_transactionByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_transactionByNumberI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_uncleByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_uncleByHashI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_uncleByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_uncleByNumberI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("eth_uninstallFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_uninstallFilterI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("shh_addToGroup", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::shh_addToGroupI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("shh_changed", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::shh_changedI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("shh_haveIdentity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::shh_haveIdentityI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("shh_newFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::shh_newFilterI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("shh_newGroup", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::shh_newGroupI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("shh_newIdentity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING,  NULL), &AbstractWebThreeStubServer::shh_newIdentityI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("shh_post", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::shh_postI);
+            this->bindAndAddMethod(new jsonrpc::Procedure("shh_uninstallFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::shh_uninstallFilterI);
 
         }
         
-        inline virtual void accountsI(const Json::Value& request, Json::Value& response) 
+        inline virtual void db_getI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->accounts();
+            response = this->db_get(request[0u].asString(), request[1u].asString());
         }
 
-        inline virtual void addToGroupI(const Json::Value& request, Json::Value& response) 
+        inline virtual void db_getStringI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->addToGroup(request[0u].asString(), request[1u].asString());
+            response = this->db_getString(request[0u].asString(), request[1u].asString());
         }
 
-        inline virtual void balanceAtI(const Json::Value& request, Json::Value& response) 
+        inline virtual void db_putI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->balanceAt(request[0u].asString());
+            response = this->db_put(request[0u].asString(), request[1u].asString(), request[2u].asString());
         }
 
-        inline virtual void blockByHashI(const Json::Value& request, Json::Value& response) 
+        inline virtual void db_putStringI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->blockByHash(request[0u].asString());
+            response = this->db_putString(request[0u].asString(), request[1u].asString(), request[2u].asString());
         }
 
-        inline virtual void blockByNumberI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_accountsI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->blockByNumber(request[0u].asInt());
+            response = this->eth_accounts();
         }
 
-        inline virtual void callI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_balanceAtI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->call(request[0u]);
+            response = this->eth_balanceAt(request[0u].asString());
         }
 
-        inline virtual void changedI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_blockByHashI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->changed(request[0u].asInt());
+            response = this->eth_blockByHash(request[0u].asString());
         }
 
-        inline virtual void codeAtI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_blockByNumberI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->codeAt(request[0u].asString());
+            response = this->eth_blockByNumber(request[0u].asInt());
         }
 
-        inline virtual void coinbaseI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_callI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->coinbase();
+            response = this->eth_call(request[0u]);
         }
 
-        inline virtual void compileI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_changedI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->compile(request[0u].asString());
+            response = this->eth_changed(request[0u].asInt());
         }
 
-        inline virtual void countAtI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_codeAtI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->countAt(request[0u].asString());
+            response = this->eth_codeAt(request[0u].asString());
         }
 
-        inline virtual void defaultBlockI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_coinbaseI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->defaultBlock();
+            response = this->eth_coinbase();
         }
 
-        inline virtual void gasPriceI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_compileI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->gasPrice();
+            response = this->eth_compile(request[0u].asString());
         }
 
-        inline virtual void getI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_countAtI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->get(request[0u].asString(), request[1u].asString());
+            response = this->eth_countAt(request[0u].asString());
         }
 
-        inline virtual void getMessagesI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_defaultBlockI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->getMessages(request[0u].asInt());
+            response = this->eth_defaultBlock();
         }
 
-        inline virtual void getStringI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_gasPriceI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->getString(request[0u].asString(), request[1u].asString());
+            response = this->eth_gasPrice();
         }
 
-        inline virtual void haveIdentityI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_getMessagesI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->haveIdentity(request[0u].asString());
+            response = this->eth_getMessages(request[0u].asInt());
         }
 
-        inline virtual void listeningI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_listeningI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->listening();
+            response = this->eth_listening();
         }
 
-        inline virtual void miningI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_lllI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->mining();
+            response = this->eth_lll(request[0u].asString());
         }
 
-        inline virtual void newFilterI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_miningI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->newFilter(request[0u]);
+            response = this->eth_mining();
         }
 
-        inline virtual void newFilterStringI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_newFilterI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->newFilterString(request[0u].asString());
+            response = this->eth_newFilter(request[0u]);
         }
 
-        inline virtual void newGroupI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_newFilterStringI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->newGroup(request[0u].asString(), request[1u].asString());
+            response = this->eth_newFilterString(request[0u].asString());
         }
 
-        inline virtual void newIdentityI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_numberI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->newIdentity();
+            response = this->eth_number();
         }
 
-        inline virtual void numberI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_peerCountI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->number();
+            response = this->eth_peerCount();
         }
 
-        inline virtual void peerCountI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_setCoinbaseI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->peerCount();
+            response = this->eth_setCoinbase(request[0u].asString());
         }
 
-        inline virtual void postI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_setDefaultBlockI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->post(request[0u]);
+            response = this->eth_setDefaultBlock(request[0u].asInt());
         }
 
-        inline virtual void putI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_setListeningI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->put(request[0u].asString(), request[1u].asString(), request[2u].asString());
+            response = this->eth_setListening(request[0u].asBool());
         }
 
-        inline virtual void putStringI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_setMiningI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->putString(request[0u].asString(), request[1u].asString(), request[2u].asString());
+            response = this->eth_setMining(request[0u].asBool());
         }
 
-        inline virtual void setCoinbaseI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_stateAtI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->setCoinbase(request[0u].asString());
+            response = this->eth_stateAt(request[0u].asString(), request[1u].asString());
         }
 
-        inline virtual void setDefaultBlockI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_transactI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->setDefaultBlock(request[0u].asInt());
+            response = this->eth_transact(request[0u]);
         }
 
-        inline virtual void setListeningI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_transactionByHashI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->setListening(request[0u].asBool());
+            response = this->eth_transactionByHash(request[0u].asString(), request[1u].asInt());
         }
 
-        inline virtual void setMiningI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_transactionByNumberI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->setMining(request[0u].asBool());
+            response = this->eth_transactionByNumber(request[0u].asInt(), request[1u].asInt());
         }
 
-        inline virtual void shhChangedI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_uncleByHashI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->shhChanged(request[0u].asInt());
+            response = this->eth_uncleByHash(request[0u].asString(), request[1u].asInt());
         }
 
-        inline virtual void shhNewFilterI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_uncleByNumberI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->shhNewFilter(request[0u]);
+            response = this->eth_uncleByNumber(request[0u].asInt(), request[1u].asInt());
         }
 
-        inline virtual void shhUninstallFilterI(const Json::Value& request, Json::Value& response) 
+        inline virtual void eth_uninstallFilterI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->shhUninstallFilter(request[0u].asInt());
+            response = this->eth_uninstallFilter(request[0u].asInt());
         }
 
-        inline virtual void stateAtI(const Json::Value& request, Json::Value& response) 
+        inline virtual void shh_addToGroupI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->stateAt(request[0u].asString(), request[1u].asString());
+            response = this->shh_addToGroup(request[0u].asString(), request[1u].asString());
         }
 
-        inline virtual void transactI(const Json::Value& request, Json::Value& response) 
+        inline virtual void shh_changedI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->transact(request[0u]);
+            response = this->shh_changed(request[0u].asInt());
         }
 
-        inline virtual void transactionByHashI(const Json::Value& request, Json::Value& response) 
+        inline virtual void shh_haveIdentityI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->transactionByHash(request[0u].asString(), request[1u].asInt());
+            response = this->shh_haveIdentity(request[0u].asString());
         }
 
-        inline virtual void transactionByNumberI(const Json::Value& request, Json::Value& response) 
+        inline virtual void shh_newFilterI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->transactionByNumber(request[0u].asInt(), request[1u].asInt());
+            response = this->shh_newFilter(request[0u]);
         }
 
-        inline virtual void uncleByHashI(const Json::Value& request, Json::Value& response) 
+        inline virtual void shh_newGroupI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->uncleByHash(request[0u].asString(), request[1u].asInt());
+            response = this->shh_newGroup(request[0u].asString(), request[1u].asString());
         }
 
-        inline virtual void uncleByNumberI(const Json::Value& request, Json::Value& response) 
+        inline virtual void shh_newIdentityI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->uncleByNumber(request[0u].asInt(), request[1u].asInt());
+            response = this->shh_newIdentity();
         }
 
-        inline virtual void uninstallFilterI(const Json::Value& request, Json::Value& response) 
+        inline virtual void shh_postI(const Json::Value& request, Json::Value& response) 
         {
-            response = this->uninstallFilter(request[0u].asInt());
+            response = this->shh_post(request[0u]);
+        }
+
+        inline virtual void shh_uninstallFilterI(const Json::Value& request, Json::Value& response) 
+        {
+            response = this->shh_uninstallFilter(request[0u].asInt());
         }
 
 
-        virtual Json::Value accounts() = 0;
-        virtual std::string addToGroup(const std::string& param1, const std::string& param2) = 0;
-        virtual std::string balanceAt(const std::string& param1) = 0;
-        virtual Json::Value blockByHash(const std::string& param1) = 0;
-        virtual Json::Value blockByNumber(const int& param1) = 0;
-        virtual std::string call(const Json::Value& param1) = 0;
-        virtual bool changed(const int& param1) = 0;
-        virtual std::string codeAt(const std::string& param1) = 0;
-        virtual std::string coinbase() = 0;
-        virtual std::string compile(const std::string& param1) = 0;
-        virtual double countAt(const std::string& param1) = 0;
-        virtual int defaultBlock() = 0;
-        virtual std::string gasPrice() = 0;
-        virtual std::string get(const std::string& param1, const std::string& param2) = 0;
-        virtual Json::Value getMessages(const int& param1) = 0;
-        virtual std::string getString(const std::string& param1, const std::string& param2) = 0;
-        virtual bool haveIdentity(const std::string& param1) = 0;
-        virtual bool listening() = 0;
-        virtual bool mining() = 0;
-        virtual int newFilter(const Json::Value& param1) = 0;
-        virtual int newFilterString(const std::string& param1) = 0;
-        virtual std::string newGroup(const std::string& param1, const std::string& param2) = 0;
-        virtual std::string newIdentity() = 0;
-        virtual int number() = 0;
-        virtual int peerCount() = 0;
-        virtual bool post(const Json::Value& param1) = 0;
-        virtual bool put(const std::string& param1, const std::string& param2, const std::string& param3) = 0;
-        virtual bool putString(const std::string& param1, const std::string& param2, const std::string& param3) = 0;
-        virtual bool setCoinbase(const std::string& param1) = 0;
-        virtual bool setDefaultBlock(const int& param1) = 0;
-        virtual bool setListening(const bool& param1) = 0;
-        virtual bool setMining(const bool& param1) = 0;
-        virtual Json::Value shhChanged(const int& param1) = 0;
-        virtual int shhNewFilter(const Json::Value& param1) = 0;
-        virtual bool shhUninstallFilter(const int& param1) = 0;
-        virtual std::string stateAt(const std::string& param1, const std::string& param2) = 0;
-        virtual std::string transact(const Json::Value& param1) = 0;
-        virtual Json::Value transactionByHash(const std::string& param1, const int& param2) = 0;
-        virtual Json::Value transactionByNumber(const int& param1, const int& param2) = 0;
-        virtual Json::Value uncleByHash(const std::string& param1, const int& param2) = 0;
-        virtual Json::Value uncleByNumber(const int& param1, const int& param2) = 0;
-        virtual bool uninstallFilter(const int& param1) = 0;
+        virtual std::string db_get(const std::string& param1, const std::string& param2) = 0;
+        virtual std::string db_getString(const std::string& param1, const std::string& param2) = 0;
+        virtual bool db_put(const std::string& param1, const std::string& param2, const std::string& param3) = 0;
+        virtual bool db_putString(const std::string& param1, const std::string& param2, const std::string& param3) = 0;
+        virtual Json::Value eth_accounts() = 0;
+        virtual std::string eth_balanceAt(const std::string& param1) = 0;
+        virtual Json::Value eth_blockByHash(const std::string& param1) = 0;
+        virtual Json::Value eth_blockByNumber(const int& param1) = 0;
+        virtual std::string eth_call(const Json::Value& param1) = 0;
+        virtual bool eth_changed(const int& param1) = 0;
+        virtual std::string eth_codeAt(const std::string& param1) = 0;
+        virtual std::string eth_coinbase() = 0;
+        virtual std::string eth_compile(const std::string& param1) = 0;
+        virtual double eth_countAt(const std::string& param1) = 0;
+        virtual int eth_defaultBlock() = 0;
+        virtual std::string eth_gasPrice() = 0;
+        virtual Json::Value eth_getMessages(const int& param1) = 0;
+        virtual bool eth_listening() = 0;
+        virtual std::string eth_lll(const std::string& param1) = 0;
+        virtual bool eth_mining() = 0;
+        virtual int eth_newFilter(const Json::Value& param1) = 0;
+        virtual int eth_newFilterString(const std::string& param1) = 0;
+        virtual int eth_number() = 0;
+        virtual int eth_peerCount() = 0;
+        virtual bool eth_setCoinbase(const std::string& param1) = 0;
+        virtual bool eth_setDefaultBlock(const int& param1) = 0;
+        virtual bool eth_setListening(const bool& param1) = 0;
+        virtual bool eth_setMining(const bool& param1) = 0;
+        virtual std::string eth_stateAt(const std::string& param1, const std::string& param2) = 0;
+        virtual std::string eth_transact(const Json::Value& param1) = 0;
+        virtual Json::Value eth_transactionByHash(const std::string& param1, const int& param2) = 0;
+        virtual Json::Value eth_transactionByNumber(const int& param1, const int& param2) = 0;
+        virtual Json::Value eth_uncleByHash(const std::string& param1, const int& param2) = 0;
+        virtual Json::Value eth_uncleByNumber(const int& param1, const int& param2) = 0;
+        virtual bool eth_uninstallFilter(const int& param1) = 0;
+        virtual std::string shh_addToGroup(const std::string& param1, const std::string& param2) = 0;
+        virtual Json::Value shh_changed(const int& param1) = 0;
+        virtual bool shh_haveIdentity(const std::string& param1) = 0;
+        virtual int shh_newFilter(const Json::Value& param1) = 0;
+        virtual std::string shh_newGroup(const std::string& param1, const std::string& param2) = 0;
+        virtual std::string shh_newIdentity() = 0;
+        virtual bool shh_post(const Json::Value& param1) = 0;
+        virtual bool shh_uninstallFilter(const int& param1) = 0;
 
 };
 #endif //_ABSTRACTWEBTHREESTUBSERVER_H_
diff --git a/libweb3jsonrpc/spec.json b/libweb3jsonrpc/spec.json
index 591fbcfe7..47a8b26df 100644
--- a/libweb3jsonrpc/spec.json
+++ b/libweb3jsonrpc/spec.json
@@ -1,54 +1,55 @@
 [
-            { "method": "coinbase", "params": [], "order": [], "returns" : "" },
-            { "method": "setCoinbase", "params": [""], "order": [], "returns" : true },
-            { "method": "listening", "params": [], "order": [], "returns" : false },
-            { "method": "setListening", "params": [false], "order" : [], "returns" : true },
-            { "method": "mining", "params": [], "order": [], "returns" : false },
-            { "method": "setMining", "params": [false], "order" : [], "returns" : true },
-            { "method": "gasPrice", "params": [], "order": [], "returns" : "" },
-            { "method": "accounts", "params": [], "order": [], "returns" : [] },
-            { "method": "peerCount", "params": [], "order": [], "returns" : 0 },
-            { "method": "defaultBlock", "params": [], "order": [], "returns" : 0},
-            { "method": "setDefaultBlock", "params": [0], "order": [], "returns" : true},
-            { "method": "number", "params": [], "order": [], "returns" : 0},
-
-            { "method": "balanceAt", "params": [""], "order": [], "returns" : ""},
-            { "method": "stateAt", "params": ["", ""], "order": [], "returns": ""},
-            { "method": "countAt", "params": [""], "order": [], "returns" : 0.0},
-            { "method": "codeAt", "params": [""], "order": [], "returns": ""},
-
-            { "method": "transact", "params": [{}], "order": [], "returns": ""},
-            { "method": "call", "params": [{}], "order": [], "returns": ""},
-
-            { "method": "blockByHash", "params": [""],"order": [], "returns": {}},
-            { "method": "blockByNumber", "params": [0],"order": [], "returns": {}},
-            { "method": "transactionByHash", "params": ["", 0], "order": [], "returns": {}},
-            { "method": "transactionByNumber", "params": [0, 0], "order": [], "returns": {}},
-            { "method": "uncleByHash", "params": ["", 0], "order": [], "returns": {}},
-            { "method": "uncleByNumber", "params": [0, 0], "order": [], "returns": {}},
-
-            { "method": "compile", "params": [""], "order": [], "returns": ""},
-
-            { "method": "newFilter", "params": [{}], "order": [], "returns": 0},
-            { "method": "newFilterString", "params": [""], "order": [], "returns": 0},
-            { "method": "uninstallFilter", "params": [0], "order": [], "returns": true},
-            { "method": "changed", "params": [0], "order": [], "returns": false},
-            { "method": "getMessages", "params": [0], "order": [], "returns": []},
-
-            { "method": "put", "params": ["", "", ""], "order": [], "returns": true},
-            { "method": "get", "params": ["", ""], "order": [], "returns": ""},
-            { "method": "putString", "params": ["", "", ""], "order": [], "returns": true},
-            { "method": "getString", "params": ["", ""], "order": [], "returns": ""},
-
-            { "method": "post", "params": [{}], "order": [], "returns": true},
-            { "method": "newIdentity", "params": [], "order": [], "returns": ""},
-            { "method": "haveIdentity", "params": [""], "order": [], "returns": false},
-            { "method": "newGroup", "params": ["", ""], "order": [], "returns": ""},
-            { "method": "addToGroup", "params": ["", ""], "order": [], "returns": ""},
+            { "method": "eth_coinbase", "params": [], "order": [], "returns" : "" },
+            { "method": "eth_setCoinbase", "params": [""], "order": [], "returns" : true },
+            { "method": "eth_listening", "params": [], "order": [], "returns" : false },
+            { "method": "eth_setListening", "params": [false], "order" : [], "returns" : true },
+            { "method": "eth_mining", "params": [], "order": [], "returns" : false },
+            { "method": "eth_setMining", "params": [false], "order" : [], "returns" : true },
+            { "method": "eth_gasPrice", "params": [], "order": [], "returns" : "" },
+            { "method": "eth_accounts", "params": [], "order": [], "returns" : [] },
+            { "method": "eth_peerCount", "params": [], "order": [], "returns" : 0 },
+            { "method": "eth_defaultBlock", "params": [], "order": [], "returns" : 0},
+            { "method": "eth_setDefaultBlock", "params": [0], "order": [], "returns" : true},
+            { "method": "eth_number", "params": [], "order": [], "returns" : 0},
+
+            { "method": "eth_balanceAt", "params": [""], "order": [], "returns" : ""},
+            { "method": "eth_stateAt", "params": ["", ""], "order": [], "returns": ""},
+            { "method": "eth_countAt", "params": [""], "order": [], "returns" : 0.0},
+            { "method": "eth_codeAt", "params": [""], "order": [], "returns": ""},
+
+            { "method": "eth_transact", "params": [{}], "order": [], "returns": ""},
+            { "method": "eth_call", "params": [{}], "order": [], "returns": ""},
+
+            { "method": "eth_blockByHash", "params": [""],"order": [], "returns": {}},
+            { "method": "eth_blockByNumber", "params": [0],"order": [], "returns": {}},
+            { "method": "eth_transactionByHash", "params": ["", 0], "order": [], "returns": {}},
+            { "method": "eth_transactionByNumber", "params": [0, 0], "order": [], "returns": {}},
+            { "method": "eth_uncleByHash", "params": ["", 0], "order": [], "returns": {}},
+            { "method": "eth_uncleByNumber", "params": [0, 0], "order": [], "returns": {}},
+
+            { "method": "eth_lll", "params": [""], "order": [], "returns": ""},
+            { "method": "eth_compile", "params": [""], "order": [], "returns": ""},
+
+            { "method": "eth_newFilter", "params": [{}], "order": [], "returns": 0},
+            { "method": "eth_newFilterString", "params": [""], "order": [], "returns": 0},
+            { "method": "eth_uninstallFilter", "params": [0], "order": [], "returns": true},
+            { "method": "eth_changed", "params": [0], "order": [], "returns": false},
+            { "method": "eth_getMessages", "params": [0], "order": [], "returns": []},
+
+            { "method": "db_put", "params": ["", "", ""], "order": [], "returns": true},
+            { "method": "db_get", "params": ["", ""], "order": [], "returns": ""},
+            { "method": "db_putString", "params": ["", "", ""], "order": [], "returns": true},
+            { "method": "db_getString", "params": ["", ""], "order": [], "returns": ""},
+
+            { "method": "shh_post", "params": [{}], "order": [], "returns": true},
+            { "method": "shh_newIdentity", "params": [], "order": [], "returns": ""},
+            { "method": "shh_haveIdentity", "params": [""], "order": [], "returns": false},
+            { "method": "shh_newGroup", "params": ["", ""], "order": [], "returns": ""},
+            { "method": "shh_addToGroup", "params": ["", ""], "order": [], "returns": ""},
             
-            { "method": "shhNewFilter", "params": [{}], "order": [], "returns": 0},
-            { "method": "shhUninstallFilter", "params": [0], "order": [], "returns": true},
-            { "method": "shhChanged", "params": [0], "order": [], "returns": []}
+            { "method": "shh_newFilter", "params": [{}], "order": [], "returns": 0},
+            { "method": "shh_uninstallFilter", "params": [0], "order": [], "returns": true},
+            { "method": "shh_changed", "params": [0], "order": [], "returns": []}
             
 ]
 
diff --git a/libwhisper/Common.cpp b/libwhisper/Common.cpp
index 15b07e433..83f289875 100644
--- a/libwhisper/Common.cpp
+++ b/libwhisper/Common.cpp
@@ -22,11 +22,21 @@
 #include "Common.h"
 
 #include 
+#include "Message.h"
 using namespace std;
 using namespace dev;
 using namespace dev::p2p;
 using namespace dev::shh;
 
+Topic BuildTopic::toTopic() const
+{
+	Topic ret;
+	ret.reserve(m_parts.size());
+	for (auto const& h: m_parts)
+		ret.push_back(TopicPart(h));
+	return ret;
+}
+
 BuildTopic& BuildTopic::shiftBytes(bytes const& _b)
 {
 	m_parts.push_back(dev::sha3(_b));
@@ -40,19 +50,32 @@ h256 TopicFilter::sha3() const
 	return dev::sha3(s.out());
 }
 
+bool TopicFilter::matches(Envelope const& _e) const
+{
+	for (TopicMask const& t: m_topicMasks)
+	{
+		if (_e.topics().size() == t.size())
+			for (unsigned i = 0; i < t.size(); ++i)
+				if (((t[i].first ^ _e.topics()[i]) & t[i].second) != 0)
+					goto NEXT_TOPICMASK;
+		return true;
+		NEXT_TOPICMASK:;
+	}
+	return false;
+}
+
 TopicMask BuildTopicMask::toTopicMask() const
 {
 	TopicMask ret;
-	if (m_parts.size())
-		for (auto i = 0; i < 32; ++i)
-		{
-			ret.first[i] = m_parts[i * m_parts.size() / 32][i];
-			ret.second[i] = m_parts[i * m_parts.size() / 32] ? 255 : 0;
-		}
+	ret.reserve(m_parts.size());
+	for (auto const& h: m_parts)
+		ret.push_back(make_pair(TopicPart(h), h ? ~TopicPart() : TopicPart()));
 	return ret;
 }
+
 /*
 web3.shh.watch({}).arrived(function(m) { env.note("New message:\n"+JSON.stringify(m)); })
 k = web3.shh.newIdentity()
 web3.shh.post({from: k, topic: web3.fromAscii("test"), payload: web3.fromAscii("Hello world!")})
 */
+
diff --git a/libwhisper/Common.h b/libwhisper/Common.h
index 21296e193..312cbf6d3 100644
--- a/libwhisper/Common.h
+++ b/libwhisper/Common.h
@@ -59,7 +59,9 @@ enum WhisperPacket
 	PacketCount
 };
 
-using Topic = h256;
+using TopicPart = FixedHash<4>;
+
+using Topic = std::vector;
 
 class BuildTopic
 {
@@ -73,7 +75,7 @@ public:
 	BuildTopic& shiftRaw(h256 const& _part) { m_parts.push_back(_part); return *this; }
 
 	operator Topic() const { return toTopic(); }
-	Topic toTopic() const { Topic ret; for (auto i = 0; i < 32; ++i) ret[i] = m_parts[i * m_parts.size() / 32][i]; return ret; }
+	Topic toTopic() const;
 
 protected:
 	BuildTopic& shiftBytes(bytes const& _b);
@@ -81,7 +83,7 @@ protected:
 	h256s m_parts;
 };
 
-using TopicMask = std::pair;
+using TopicMask = std::vector>;
 using TopicMasks = std::vector;
 
 class TopicFilter
@@ -90,7 +92,15 @@ public:
 	TopicFilter() {}
 	TopicFilter(TopicMask const& _m): m_topicMasks(1, _m) {}
 	TopicFilter(TopicMasks const& _m): m_topicMasks(_m) {}
-	TopicFilter(RLP const& _r): m_topicMasks((TopicMasks)_r) {}
+	TopicFilter(RLP const& _r)//: m_topicMasks(_r.toVector>())
+	{
+		for (RLP i: _r)
+		{
+			m_topicMasks.push_back(TopicMask());
+			for (RLP j: i)
+				m_topicMasks.back().push_back(j.toPair, FixedHash<4>>());
+		}
+	}
 
 	void streamRLP(RLPStream& _s) const { _s << m_topicMasks; }
 	h256 sha3() const;
diff --git a/libwhisper/Interface.cpp b/libwhisper/Interface.cpp
index 9b6815f0d..c00c3ebb2 100644
--- a/libwhisper/Interface.cpp
+++ b/libwhisper/Interface.cpp
@@ -34,10 +34,7 @@ using namespace dev::shh;
 #endif
 #define clogS(X) dev::LogOutputStream(false) << "| " << std::setw(2) << session()->socketId() << "] "
 
-bool TopicFilter::matches(Envelope const& _e) const
+unsigned Interface::installWatch(TopicMask const& _mask)
 {
-	for (TopicMask const& t: m_topicMasks)
-		if (((t.first ^ _e.topic()) & t.second) == 0)
-			return true;
-	return false;
+	return installWatch(TopicFilter(_mask));
 }
diff --git a/libwhisper/Interface.h b/libwhisper/Interface.h
index 56b3be599..1af93f591 100644
--- a/libwhisper/Interface.h
+++ b/libwhisper/Interface.h
@@ -69,7 +69,7 @@ public:
 
 	virtual void inject(Envelope const& _m, WhisperPeer* _from = nullptr) = 0;
 
-	unsigned installWatch(TopicMask const& _mask) { return installWatch(TopicFilter(_mask)); }
+	unsigned installWatch(TopicMask const& _mask);
 	virtual unsigned installWatch(TopicFilter const& _filter) = 0;
 	virtual unsigned installWatchOnId(h256 _filterId) = 0;
 	virtual void uninstallWatch(unsigned _watchId) = 0;
diff --git a/libwhisper/Message.cpp b/libwhisper/Message.cpp
index 93dcaa033..65da72f9d 100644
--- a/libwhisper/Message.cpp
+++ b/libwhisper/Message.cpp
@@ -97,7 +97,7 @@ Message Envelope::open(Secret const& _s) const
 unsigned Envelope::workProved() const
 {
 	h256 d[2];
-	d[0] = sha3NoNonce();
+	d[0] = sha3(WithoutNonce);
 	d[1] = m_nonce;
 	return dev::sha3(bytesConstRef(d[0].data(), 64)).firstBitSet();
 }
@@ -106,7 +106,7 @@ void Envelope::proveWork(unsigned _ms)
 {
 	// PoW
 	h256 d[2];
-	d[0] = sha3NoNonce();
+	d[0] = sha3(WithoutNonce);
 	uint32_t& n = *(uint32_t*)&(d[1][28]);
 	unsigned bestBitSet = 0;
 	bytesConstRef chuck(d[0].data(), 64);
diff --git a/libwhisper/Message.h b/libwhisper/Message.h
index 677d16f00..954aed4a0 100644
--- a/libwhisper/Message.h
+++ b/libwhisper/Message.h
@@ -39,6 +39,12 @@ namespace shh
 
 class Message;
 
+enum IncludeNonce
+{
+	WithoutNonce = 0,
+	WithNonce = 1
+};
+
 class Envelope
 {
 	friend class Message;
@@ -49,21 +55,20 @@ public:
 	{
 		m_expiry = _m[0].toInt();
 		m_ttl = _m[1].toInt();
-		m_topic = (Topic)_m[2];
+		m_topic = _m[2].toVector>();
 		m_data = _m[3].toBytes();
 		m_nonce = _m[4].toInt();
 	}
 
 	operator bool() const { return !!m_expiry; }
 
-	void streamRLP(RLPStream& _s, bool _withNonce) const { _s.appendList(_withNonce ? 5 : 4) << m_expiry << m_ttl << m_topic << m_data; if (_withNonce) _s << m_nonce; }
-	h256 sha3() const { RLPStream s; streamRLP(s, true); return dev::sha3(s.out()); }
-	h256 sha3NoNonce() const { RLPStream s; streamRLP(s, false); return dev::sha3(s.out()); }
+	void streamRLP(RLPStream& _s, IncludeNonce _withNonce = WithNonce) const { _s.appendList(_withNonce ? 5 : 4) << m_expiry << m_ttl << m_topic << m_data; if (_withNonce) _s << m_nonce; }
+	h256 sha3(IncludeNonce _withNonce = WithNonce) const { RLPStream s; streamRLP(s, _withNonce); return dev::sha3(s.out()); }
 
 	unsigned sent() const { return m_expiry - m_ttl; }
 	unsigned expiry() const { return m_expiry; }
 	unsigned ttl() const { return m_ttl; }
-	Topic const& topic() const { return m_topic; }
+	Topic const& topics() const { return m_topic; }
 	bytes const& data() const { return m_data; }
 
 	Message open(Secret const& _s = Secret()) const;
diff --git a/libwhisper/WhisperHost.cpp b/libwhisper/WhisperHost.cpp
index 71030aae2..0fb7a206c 100644
--- a/libwhisper/WhisperHost.cpp
+++ b/libwhisper/WhisperHost.cpp
@@ -21,6 +21,7 @@
 
 #include "WhisperHost.h"
 
+#include 
 #include 
 #include 
 using namespace std;
@@ -48,14 +49,14 @@ void WhisperHost::streamMessage(h256 _m, RLPStream& _s) const
 	{
 		UpgradeGuard ll(l);
 		auto const& m = m_messages.at(_m);
-		cnote << "streamRLP: " << m.expiry() << m.ttl() << m.topic() << toHex(m.data());
-		m.streamRLP(_s, true);
+		cnote << "streamRLP: " << m.expiry() << m.ttl() << m.topics() << toHex(m.data());
+		m.streamRLP(_s);
 	}
 }
 
 void WhisperHost::inject(Envelope const& _m, WhisperPeer* _p)
 {
-	cnote << "inject: " << _m.expiry() << _m.ttl() << _m.topic() << toHex(_m.data());
+	cnote << "inject: " << _m.expiry() << _m.ttl() << _m.topics() << toHex(_m.data());
 
 	if (_m.expiry() <= time(0))
 		return;
diff --git a/libwhisper/WhisperHost.h b/libwhisper/WhisperHost.h
index 4d761919c..91934dd98 100644
--- a/libwhisper/WhisperHost.h
+++ b/libwhisper/WhisperHost.h
@@ -46,7 +46,7 @@ public:
 	WhisperHost();
 	virtual ~WhisperHost();
 
-	unsigned protocolVersion() const { return 0; }
+	unsigned protocolVersion() const { return 1; }
 
 	virtual void inject(Envelope const& _e, WhisperPeer* _from = nullptr) override;
 
diff --git a/libwhisper/WhisperPeer.cpp b/libwhisper/WhisperPeer.cpp
index 343f7ca1a..56f4e456e 100644
--- a/libwhisper/WhisperPeer.cpp
+++ b/libwhisper/WhisperPeer.cpp
@@ -37,7 +37,7 @@ using namespace dev::shh;
 WhisperPeer::WhisperPeer(Session* _s, HostCapabilityFace* _h, unsigned _i): Capability(_s, _h, _i)
 {
 	RLPStream s;
-	sealAndSend(prep(s, StatusPacket, 1) << host()->protocolVersion());
+	sealAndSend(prep(s, StatusPacket, 1) << version());
 }
 
 WhisperPeer::~WhisperPeer()
@@ -59,7 +59,7 @@ bool WhisperPeer::interpret(unsigned _id, RLP const& _r)
 
 		clogS(NetMessageSummary) << "Status: " << protocolVersion;
 
-		if (protocolVersion != host()->protocolVersion())
+		if (protocolVersion != version())
 			disable("Invalid protocol version.");
 
 		if (session()->id() < host()->host()->id())
diff --git a/libwhisper/WhisperPeer.h b/libwhisper/WhisperPeer.h
index 45d72ba89..f60de8f01 100644
--- a/libwhisper/WhisperPeer.h
+++ b/libwhisper/WhisperPeer.h
@@ -53,7 +53,7 @@ public:
 	virtual ~WhisperPeer();
 
 	static std::string name() { return "shh"; }
-	static u256 version() { return 1; }
+	static u256 version() { return 2; }
 	static unsigned messageCount() { return PacketCount; }
 
 	WhisperHost* host() const;
diff --git a/lllc/CMakeLists.txt b/lllc/CMakeLists.txt
index 9d5e8c5ff..a9b53c74c 100644
--- a/lllc/CMakeLists.txt
+++ b/lllc/CMakeLists.txt
@@ -9,7 +9,7 @@ set(EXECUTABLE lllc)
 add_executable(${EXECUTABLE} ${SRC_LIST})
 
 target_link_libraries(${EXECUTABLE} lll)
-target_link_libraries(${EXECUTABLE} evmface)
+target_link_libraries(${EXECUTABLE} evmcore)
 target_link_libraries(${EXECUTABLE} devcore)
 
 if ("${TARGET_PLATFORM}" STREQUAL "w64")
diff --git a/lllc/main.cpp b/lllc/main.cpp
index a4c9df78c..1a44ee950 100644
--- a/lllc/main.cpp
+++ b/lllc/main.cpp
@@ -25,7 +25,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include "BuildInfo.h"
 using namespace std;
 using namespace dev;
diff --git a/neth/main.cpp b/neth/main.cpp
index 06e22f963..6be555fbb 100644
--- a/neth/main.cpp
+++ b/neth/main.cpp
@@ -30,7 +30,7 @@
 #include 
 #endif
 #include 
-#include 
+#include 
 #include 
 #if ETH_JSONRPC
 #include 
diff --git a/sc/CMakeLists.txt b/sc/CMakeLists.txt
index 3cacf78e6..9aa23b03b 100644
--- a/sc/CMakeLists.txt
+++ b/sc/CMakeLists.txt
@@ -10,7 +10,7 @@ add_executable(${EXECUTABLE} ${SRC_LIST})
 
 target_link_libraries(${EXECUTABLE} serpent)
 target_link_libraries(${EXECUTABLE} lll)
-target_link_libraries(${EXECUTABLE} evmface)
+target_link_libraries(${EXECUTABLE} evmcore)
 target_link_libraries(${EXECUTABLE} devcore)
 
 if ("${TARGET_PLATFORM}" STREQUAL "w64")
diff --git a/solc/main.cpp b/solc/main.cpp
index 04fee2905..a7216e594 100644
--- a/solc/main.cpp
+++ b/solc/main.cpp
@@ -26,12 +26,13 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 
 using namespace std;
@@ -42,7 +43,8 @@ void help()
 {
 	cout << "Usage solc [OPTIONS] " << endl
 		 << "Options:" << endl
-		 << "    -h,--help  Show this help message and exit." << endl
+		 << "    -o,--optimize Optimize the bytecode for size." << endl
+		 << "    -h,--help     Show this help message and exit." << endl
 		 << "    -V,--version  Show the version and exit." << endl;
 	exit(0);
 }
@@ -58,10 +60,13 @@ void version()
 int main(int argc, char** argv)
 {
 	string infile;
+	bool optimize = false;
 	for (int i = 1; i < argc; ++i)
 	{
 		string arg = argv[i];
-		if (arg == "-h" || arg == "--help")
+		if (arg == "-o" || arg == "--optimize")
+			optimize = true;
+		else if (arg == "-h" || arg == "--help")
 			help();
 		else if (arg == "-V" || arg == "--version")
 			version();
@@ -81,48 +86,34 @@ int main(int argc, char** argv)
 	else
 		sourceCode = asString(dev::contents(infile));
 
-	ASTPointer ast;
-	shared_ptr scanner = make_shared(CharStream(sourceCode));
-	Parser parser;
-	bytes instructions;
-	Compiler compiler;
+	CompilerStack compiler;
 	try
 	{
-		ast = parser.parse(scanner);
-
-		NameAndTypeResolver resolver;
-		resolver.resolveNamesAndTypes(*ast.get());
-
-		cout << "Syntax tree for the contract:" << endl;
-		dev::solidity::ASTPrinter printer(ast, sourceCode);
-		printer.print(cout);
-
-		compiler.compileContract(*ast);
-		instructions = compiler.getAssembledBytecode();
+		compiler.compile(sourceCode, optimize);
 	}
 	catch (ParserError const& exception)
 	{
-		SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Parser error", *scanner);
+		SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Parser error", compiler.getScanner());
 		return -1;
 	}
 	catch (DeclarationError const& exception)
 	{
-		SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Declaration error", *scanner);
+		SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Declaration error", compiler.getScanner());
 		return -1;
 	}
 	catch (TypeError const& exception)
 	{
-		SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Type error", *scanner);
+		SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Type error", compiler.getScanner());
 		return -1;
 	}
 	catch (CompilerError const& exception)
 	{
-		SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Compiler error", *scanner);
+		SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Compiler error", compiler.getScanner());
 		return -1;
 	}
 	catch (InternalCompilerError const& exception)
 	{
-		cerr << "Internal compiler error: " << boost::diagnostic_information(exception) << endl;
+		SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Internal compiler error", compiler.getScanner());
 		return -1;
 	}
 	catch (Exception const& exception)
@@ -136,11 +127,15 @@ int main(int argc, char** argv)
 		return -1;
 	}
 
+	cout << "Syntax tree for the contract:" << endl;
+	ASTPrinter printer(compiler.getAST(), sourceCode);
+	printer.print(cout);
 	cout << "EVM assembly:" << endl;
 	compiler.streamAssembly(cout);
 	cout << "Opcodes:" << endl;
-	cout << eth::disassemble(instructions) << endl;
-	cout << "Binary: " << toHex(instructions) << endl;
+	cout << eth::disassemble(compiler.getBytecode()) << endl;
+	cout << "Binary: " << toHex(compiler.getBytecode()) << endl;
+	cout << "Interface specification: " << compiler.getInterface() << endl;
 
 	return 0;
 }
diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp
index ca46c2ca2..7f8c519f4 100644
--- a/test/TestHelper.cpp
+++ b/test/TestHelper.cpp
@@ -27,8 +27,6 @@
 #include 
 #include 
 
-//#define FILL_TESTS
-
 using namespace std;
 using namespace dev::eth;
 
@@ -253,7 +251,7 @@ bytes importCode(json_spirit::mObject& _o)
 		code.clear();
 		for (auto const& j: _o["code"].get_array())
 			code.push_back(toByte(j));
-	}	
+	}
 	return code;
 }
 
@@ -287,6 +285,12 @@ void checkStorage(map _expectedStore, map _resultStore,
 			BOOST_CHECK_MESSAGE(expectedStoreValue == resultStoreValue, _expectedAddr << ": store[" << expectedStoreKey << "] = " << resultStoreValue << ", expected " << expectedStoreValue);
 		}
 	}
+
+    for (auto&& resultStorePair : _resultStore)
+    {
+        if (!_expectedStore.count(resultStorePair.first))
+            BOOST_ERROR("unexpected result store key " << resultStorePair.first);
+    }
 }
 
 std::string getTestPath()
@@ -305,33 +309,79 @@ std::string getTestPath()
 	return testPath;
 }
 
+void userDefinedTest(string testTypeFlag, std::function doTests)
+{
+	for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i)
+	{
+		string arg = boost::unit_test::framework::master_test_suite().argv[i];
+		if (arg == testTypeFlag)
+		{
+			if (i + 1 >= boost::unit_test::framework::master_test_suite().argc)
+			{
+				cnote << "Missing filename\nUsage: testeth " << testTypeFlag << " \n";
+				return;
+			}
+			string filename = boost::unit_test::framework::master_test_suite().argv[i + 1];
+			int currentVerbosity = g_logVerbosity;
+			g_logVerbosity = 12;
+			try
+			{
+				cnote << "Testing user defined test: " << filename;
+				json_spirit::mValue v;
+				string s = asString(contents(filename));
+				BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + filename + " is empty. ");
+				json_spirit::read_string(s, v);
+				doTests(v, false);
+			}
+			catch (Exception const& _e)
+			{
+				BOOST_ERROR("Failed Test with Exception: " << diagnostic_information(_e));
+				g_logVerbosity = currentVerbosity;
+			}
+			catch (std::exception const& _e)
+			{
+				BOOST_ERROR("Failed Test with Exception: " << _e.what());
+				g_logVerbosity = currentVerbosity;
+			}
+			g_logVerbosity = currentVerbosity;
+		}
+		else
+			continue;
+	}
+}
+
 void executeTests(const string& _name, const string& _testPathAppendix, std::function doTests)
 {
 	string testPath = getTestPath();
 	testPath += _testPathAppendix;
 
-#ifdef FILL_TESTS
-	try
+	for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i)
 	{
-		cnote << "Populating tests...";
-		json_spirit::mValue v;
-		boost::filesystem::path p(__FILE__);
-		boost::filesystem::path dir = p.parent_path();
-		string s = asString(dev::contents(dir.string() + "/" + _name + "Filler.json"));
-		BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + dir.string() + "/" + _name + "Filler.json is empty.");
-		json_spirit::read_string(s, v);
-		doTests(v, true);
-		writeFile(testPath + "/" + _name + ".json", asBytes(json_spirit::write_string(v, true)));
-	}
-	catch (Exception const& _e)
-	{
-		BOOST_ERROR("Failed test with Exception: " << diagnostic_information(_e));
-	}
-	catch (std::exception const& _e)
-	{
-		BOOST_ERROR("Failed test with Exception: " << _e.what());
+		string arg = boost::unit_test::framework::master_test_suite().argv[i];
+		if (arg == "--filltests")
+		{
+			try
+			{
+				cnote << "Populating tests...";
+				json_spirit::mValue v;
+				boost::filesystem::path p(__FILE__);
+				boost::filesystem::path dir = p.parent_path();
+				string s = asString(dev::contents(dir.string() + "/" + _name + "Filler.json"));
+				BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + dir.string() + "/" + _name + "Filler.json is empty.");
+				json_spirit::read_string(s, v);
+				doTests(v, true);
+				writeFile(testPath + "/" + _name + ".json", asBytes(json_spirit::write_string(v, true)));
+			}
+			catch (Exception const& _e)
+			{
+				BOOST_ERROR("Failed test with Exception: " << diagnostic_information(_e));
+			}
+			catch (std::exception const& _e)
+			{
+				BOOST_ERROR("Failed test with Exception: " << _e.what());
+			}
+		}
 	}
-#endif
 
 	try
 	{
diff --git a/test/TestHelper.h b/test/TestHelper.h
index 622b83ac4..ef67d52fb 100644
--- a/test/TestHelper.h
+++ b/test/TestHelper.h
@@ -57,7 +57,6 @@ public:
 	eth::State m_statePost;
 	eth::ExtVMFace m_environment;
 	eth::Transaction m_transaction;
-	bytes code;
 
 private:
 	json_spirit::mObject& m_TestObject;
@@ -72,6 +71,7 @@ void checkOutput(bytes const& _output, json_spirit::mObject& _o);
 void checkStorage(std::map _expectedStore, std::map _resultStore, Address _expectedAddr);
 void executeTests(const std::string& _name, const std::string& _testPathAppendix, std::function doTests);
 std::string getTestPath();
+void userDefinedTest(std::string testTypeFlag, std::function doTests);
 
 template
 void checkAddresses(mapType& _expectedAddrs, mapType& _resultAddrs)
diff --git a/test/createRandomTest.cpp b/test/createRandomTest.cpp
index 29e0b7f0e..f22e5c0aa 100644
--- a/test/createRandomTest.cpp
+++ b/test/createRandomTest.cpp
@@ -31,7 +31,8 @@
 #include 
 #include 
 #include 
-#include 
+#include 
+#include 
 #include "vm.h"
 
 using namespace std;
@@ -136,18 +137,24 @@ void doMyTests(json_spirit::mValue& v)
 		o["pre"] = mValue(fev.exportState());
 
 		fev.importExec(o["exec"].get_obj());
-		if (!fev.code)
+		if (fev.code.empty())
 		{
 			fev.thisTxCode = get<3>(fev.addresses.at(fev.myAddress));
-			fev.code = &fev.thisTxCode;
+			fev.code = fev.thisTxCode;
 		}
 
 		vm.reset(fev.gas);
 		bytes output;
+		u256 gas;
 		try
 		{
 			output = vm.go(fev).toBytes();
 		}
+		catch (eth::VMException const& _e)
+		{
+			cnote << "VM did throw an exception: " << diagnostic_information(_e);
+			gas = 0;
+		}
 		catch (Exception const& _e)
 		{
 			cnote << "VM did throw an exception: " << diagnostic_information(_e);
@@ -178,6 +185,6 @@ void doMyTests(json_spirit::mValue& v)
 		o["post"] = mValue(fev.exportState());
 		o["callcreates"] = fev.exportCallCreates();
 		o["out"] = "0x" + toHex(output);
-		fev.push(o, "gas", vm.gas());
+		fev.push(o, "gas", gas);
 	}
 }
diff --git a/test/jsonrpc.cpp b/test/jsonrpc.cpp
index 68c30734a..4c748a954 100644
--- a/test/jsonrpc.cpp
+++ b/test/jsonrpc.cpp
@@ -74,14 +74,14 @@ BOOST_FIXTURE_TEST_SUITE(environment, Setup)
 BOOST_AUTO_TEST_CASE(jsonrpc_defaultBlock)
 {
 	cnote << "Testing jsonrpc defaultBlock...";
-	int defaultBlock = jsonrpcClient->defaultBlock();
+	int defaultBlock = jsonrpcClient->eth_defaultBlock();
 	BOOST_CHECK_EQUAL(defaultBlock, web3->ethereum()->getDefault());
 }
 
 BOOST_AUTO_TEST_CASE(jsonrpc_gasPrice)
 {
 	cnote << "Testing jsonrpc gasPrice...";
-	string gasPrice = jsonrpcClient->gasPrice();
+	string gasPrice = jsonrpcClient->eth_gasPrice();
 	BOOST_CHECK_EQUAL(gasPrice, toJS(10 * dev::eth::szabo));
 }
 
@@ -90,11 +90,11 @@ BOOST_AUTO_TEST_CASE(jsonrpc_isListening)
 	cnote << "Testing jsonrpc isListening...";
 
 	web3->startNetwork();
-	bool listeningOn = jsonrpcClient->listening();
+	bool listeningOn = jsonrpcClient->eth_listening();
 	BOOST_CHECK_EQUAL(listeningOn, web3->isNetworkStarted());
 	
 	web3->stopNetwork();
-	bool listeningOff = jsonrpcClient->listening();
+	bool listeningOff = jsonrpcClient->eth_listening();
 	BOOST_CHECK_EQUAL(listeningOff, web3->isNetworkStarted());
 }
 
@@ -103,11 +103,11 @@ BOOST_AUTO_TEST_CASE(jsonrpc_isMining)
 	cnote << "Testing jsonrpc isMining...";
 
 	web3->ethereum()->startMining();
-	bool miningOn = jsonrpcClient->mining();
+	bool miningOn = jsonrpcClient->eth_mining();
 	BOOST_CHECK_EQUAL(miningOn, web3->ethereum()->isMining());
 
 	web3->ethereum()->stopMining();
-	bool miningOff = jsonrpcClient->mining();
+	bool miningOff = jsonrpcClient->eth_mining();
 	BOOST_CHECK_EQUAL(miningOff, web3->ethereum()->isMining());
 }
 
@@ -116,7 +116,7 @@ BOOST_AUTO_TEST_CASE(jsonrpc_accounts)
 	cnote << "Testing jsonrpc accounts...";
 	std::vector  keys = {KeyPair::create(), KeyPair::create()};
 	jsonrpcServer->setAccounts(keys);
-	Json::Value k = jsonrpcClient->accounts();
+	Json::Value k = jsonrpcClient->eth_accounts();
 	jsonrpcServer->setAccounts({});
 	BOOST_CHECK_EQUAL(k.isArray(), true);
 	BOOST_CHECK_EQUAL(k.size(),  keys.size());
@@ -133,10 +133,10 @@ BOOST_AUTO_TEST_CASE(jsonrpc_accounts)
 BOOST_AUTO_TEST_CASE(jsonrpc_number)
 {
 	cnote << "Testing jsonrpc number2...";
-	int number = jsonrpcClient->number();
+	int number = jsonrpcClient->eth_number();
 	BOOST_CHECK_EQUAL(number, web3->ethereum()->number() + 1);
 	dev::eth::mine(*(web3->ethereum()), 1);
-	int numberAfter = jsonrpcClient->number();
+	int numberAfter = jsonrpcClient->eth_number();
 	BOOST_CHECK_EQUAL(number + 1, numberAfter);
 	BOOST_CHECK_EQUAL(numberAfter, web3->ethereum()->number() + 1);
 }
@@ -144,7 +144,7 @@ BOOST_AUTO_TEST_CASE(jsonrpc_number)
 BOOST_AUTO_TEST_CASE(jsonrpc_peerCount)
 {
 	cnote << "Testing jsonrpc peerCount...";
-	int peerCount = jsonrpcClient->peerCount();
+	int peerCount = jsonrpcClient->eth_peerCount();
 	BOOST_CHECK_EQUAL(web3->peerCount(), peerCount);
 }
 
@@ -152,10 +152,10 @@ BOOST_AUTO_TEST_CASE(jsonrpc_setListening)
 {
 	cnote << "Testing jsonrpc setListening...";
 
-	jsonrpcClient->setListening(true);
+	jsonrpcClient->eth_setListening(true);
 	BOOST_CHECK_EQUAL(web3->isNetworkStarted(), true);
 	
-	jsonrpcClient->setListening(false);
+	jsonrpcClient->eth_setListening(false);
 	BOOST_CHECK_EQUAL(web3->isNetworkStarted(), false);
 }
 
@@ -163,10 +163,10 @@ BOOST_AUTO_TEST_CASE(jsonrpc_setMining)
 {
 	cnote << "Testing jsonrpc setMining...";
 
-	jsonrpcClient->setMining(true);
+	jsonrpcClient->eth_setMining(true);
 	BOOST_CHECK_EQUAL(web3->ethereum()->isMining(), true);
 
-	jsonrpcClient->setMining(false);
+	jsonrpcClient->eth_setMining(false);
 	BOOST_CHECK_EQUAL(web3->ethereum()->isMining(), false);
 }
 
@@ -175,14 +175,14 @@ BOOST_AUTO_TEST_CASE(jsonrpc_stateAt)
 	cnote << "Testing jsonrpc stateAt...";
 	dev::KeyPair key = KeyPair::create();
 	auto address = key.address();
-	string stateAt = jsonrpcClient->stateAt(toJS(address), "0");
+	string stateAt = jsonrpcClient->eth_stateAt(toJS(address), "0");
 	BOOST_CHECK_EQUAL(toJS(web3->ethereum()->stateAt(address, jsToU256("0"), 0)), stateAt);
 }
 
 BOOST_AUTO_TEST_CASE(jsonrpc_transact)
 {
 	cnote << "Testing jsonrpc transact...";
-	string coinbase = jsonrpcClient->coinbase();
+	string coinbase = jsonrpcClient->eth_coinbase();
 	BOOST_CHECK_EQUAL(jsToAddress(coinbase), web3->ethereum()->address());
 	
 	dev::KeyPair key = KeyPair::create();
@@ -190,14 +190,14 @@ BOOST_AUTO_TEST_CASE(jsonrpc_transact)
 	auto receiver = KeyPair::create();
 	web3->ethereum()->setAddress(address);
 
-	coinbase = jsonrpcClient->coinbase();
+	coinbase = jsonrpcClient->eth_coinbase();
 	BOOST_CHECK_EQUAL(jsToAddress(coinbase), web3->ethereum()->address());
 	BOOST_CHECK_EQUAL(jsToAddress(coinbase), address);
 	
 	jsonrpcServer->setAccounts({key});
 	auto balance = web3->ethereum()->balanceAt(address, 0);
-	string balanceString = jsonrpcClient->balanceAt(toJS(address));
-	double countAt = jsonrpcClient->countAt(toJS(address));
+	string balanceString = jsonrpcClient->eth_balanceAt(toJS(address));
+	double countAt = jsonrpcClient->eth_countAt(toJS(address));
 	
 	BOOST_CHECK_EQUAL(countAt, (double)(uint64_t)web3->ethereum()->countAt(address));
 	BOOST_CHECK_EQUAL(countAt, 0);
@@ -206,7 +206,7 @@ BOOST_AUTO_TEST_CASE(jsonrpc_transact)
 	
 	dev::eth::mine(*(web3->ethereum()), 1);
 	balance = web3->ethereum()->balanceAt(address, 0);
-	balanceString = jsonrpcClient->balanceAt(toJS(address));
+	balanceString = jsonrpcClient->eth_balanceAt(toJS(address));
 	
 	BOOST_CHECK_EQUAL(toJS(balance), balanceString);
 	BOOST_CHECK_EQUAL(jsToDecimal(balanceString), "1500000000000000000");
@@ -223,13 +223,13 @@ BOOST_AUTO_TEST_CASE(jsonrpc_transact)
 	t["gas"] = toJS(gas);
 	t["gasPrice"] = toJS(gasPrice);
 	
-	jsonrpcClient->transact(t);
+	jsonrpcClient->eth_transact(t);
 	jsonrpcServer->setAccounts({});
 	dev::eth::mine(*(web3->ethereum()), 1);
 	
-	countAt = jsonrpcClient->countAt(toJS(address));
+	countAt = jsonrpcClient->eth_countAt(toJS(address));
 	auto balance2 = web3->ethereum()->balanceAt(receiver.address());
-	string balanceString2 = jsonrpcClient->balanceAt(toJS(receiver.address()));
+	string balanceString2 = jsonrpcClient->eth_balanceAt(toJS(receiver.address()));
 	
 	BOOST_CHECK_EQUAL(countAt, (double)(uint64_t)web3->ethereum()->countAt(address));
 	BOOST_CHECK_EQUAL(countAt, 1);
diff --git a/test/solidityCompiler.cpp b/test/solidityCompiler.cpp
index 69d331339..054ad3297 100644
--- a/test/solidityCompiler.cpp
+++ b/test/solidityCompiler.cpp
@@ -80,7 +80,7 @@ BOOST_AUTO_TEST_CASE(smoke_test)
 							 "}\n";
 	bytes code = compileContract(sourceCode);
 
-	unsigned boilerplateSize = 51;
+	unsigned boilerplateSize = 42;
 	bytes expectation({byte(Instruction::JUMPDEST),
 					   byte(Instruction::PUSH1), 0x0, // initialize local variable x
 					   byte(Instruction::PUSH1), 0x2,
@@ -100,8 +100,8 @@ BOOST_AUTO_TEST_CASE(different_argument_numbers)
 							 "}\n";
 	bytes code = compileContract(sourceCode);
 
-	unsigned shift = 75;
-	unsigned boilerplateSize = 88;
+	unsigned shift = 70;
+	unsigned boilerplateSize = 83;
 	bytes expectation({byte(Instruction::JUMPDEST),
 					   byte(Instruction::PUSH1), 0x0, // initialize return variable d
 					   byte(Instruction::DUP3),
@@ -119,10 +119,10 @@ BOOST_AUTO_TEST_CASE(different_argument_numbers)
 					   byte(Instruction::JUMPDEST), // beginning of g
 					   byte(Instruction::PUSH1), 0x0,
 					   byte(Instruction::DUP1), // initialized e and h
-					   byte(Instruction::PUSH1), byte(0x20 + shift), // ret address
-					   byte(Instruction::PUSH1), 0x1,
-					   byte(Instruction::PUSH1), 0x2,
-					   byte(Instruction::PUSH1), 0x3,
+					   byte(Instruction::PUSH1), byte(0x29 + shift), // ret address
+					   byte(Instruction::PUSH1), 0x1, byte(Instruction::PUSH1), 0xff, byte(Instruction::AND),
+					   byte(Instruction::PUSH1), 0x2, byte(Instruction::PUSH1), 0xff, byte(Instruction::AND),
+					   byte(Instruction::PUSH1), 0x3, byte(Instruction::PUSH1), 0xff, byte(Instruction::AND),
 					   byte(Instruction::PUSH1), byte(0x1 + shift),
 					   // stack here: ret e h 0x20 1 2 3 0x1
 					   byte(Instruction::JUMP),
@@ -153,8 +153,8 @@ BOOST_AUTO_TEST_CASE(ifStatement)
 							 "}\n";
 	bytes code = compileContract(sourceCode);
 
-	unsigned shift = 38;
-	unsigned boilerplateSize = 51;
+	unsigned shift = 29;
+	unsigned boilerplateSize = 42;
 	bytes expectation({byte(Instruction::JUMPDEST),
 					   byte(Instruction::PUSH1), 0x0,
 					   byte(Instruction::DUP1),
@@ -195,8 +195,8 @@ BOOST_AUTO_TEST_CASE(loops)
 							 "}\n";
 	bytes code = compileContract(sourceCode);
 
-	unsigned shift = 38;
-	unsigned boilerplateSize = 51;
+	unsigned shift = 29;
+	unsigned boilerplateSize = 42;
 	bytes expectation({byte(Instruction::JUMPDEST),
 					   byte(Instruction::JUMPDEST),
 					   byte(Instruction::PUSH1), 0x1,
diff --git a/test/solidityEndToEndTest.cpp b/test/solidityEndToEndTest.cpp
index 116310aed..d905646cb 100644
--- a/test/solidityEndToEndTest.cpp
+++ b/test/solidityEndToEndTest.cpp
@@ -22,6 +22,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -41,31 +42,77 @@ class ExecutionFramework
 public:
 	ExecutionFramework() { g_logVerbosity = 0; }
 
-	bytes compileAndRun(std::string const& _sourceCode)
+	bytes const& compileAndRun(string const& _sourceCode)
 	{
-		bytes code = dev::solidity::CompilerStack::compile(_sourceCode);
+		bytes code = dev::solidity::CompilerStack::staticCompile(_sourceCode);
 		sendMessage(code, true);
+		BOOST_REQUIRE(!m_output.empty());
 		return m_output;
 	}
 
-	bytes callFunction(byte _index, bytes const& _data)
+	bytes const& callContractFunction(byte _index, bytes const& _data = bytes())
 	{
 		sendMessage(bytes(1, _index) + _data, false);
 		return m_output;
 	}
 
-	bytes callFunction(byte _index, u256 const& _argument1)
+	template 
+	bytes const& callContractFunction(byte _index, Args const&... _arguments)
 	{
-		callFunction(_index, toBigEndian(_argument1));
-		return m_output;
+		return callContractFunction(_index, argsToBigEndian(_arguments...));
+	}
+
+	template 
+	void testSolidityAgainstCpp(byte _index, CppFunction const& _cppFunction, Args const&... _arguments)
+	{
+		bytes solidityResult = callContractFunction(_index, _arguments...);
+		bytes cppResult = callCppAndEncodeResult(_cppFunction, _arguments...);
+		BOOST_CHECK_MESSAGE(solidityResult == cppResult, "Computed values do not match."
+							"\nSolidity: " + toHex(solidityResult) + "\nC++:      " + toHex(cppResult));
+	}
+
+	template 
+	void testSolidityAgainstCppOnRange(byte _index, CppFunction const& _cppFunction,
+									   u256 const& _rangeStart, u256 const& _rangeEnd)
+	{
+		for (u256 argument = _rangeStart; argument < _rangeEnd; ++argument)
+		{
+			bytes solidityResult = callContractFunction(_index, argument);
+			bytes cppResult = callCppAndEncodeResult(_cppFunction, argument);
+			BOOST_CHECK_MESSAGE(solidityResult == cppResult, "Computed values do not match."
+								"\nSolidity: " + toHex(solidityResult) + "\nC++:      " + toHex(cppResult) +
+								"\nArgument: " + toHex(toBigEndian(argument)));
+		}
 	}
 
 private:
+	template 
+	bytes argsToBigEndian(FirstArg const& _firstArg, Args const&... _followingArgs) const
+	{
+		return toBigEndian(_firstArg) + argsToBigEndian(_followingArgs...);
+	}
+
+	bytes argsToBigEndian() const { return bytes(); }
+
+	template 
+	auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments)
+	-> typename enable_if::value, bytes>::type
+	{
+		_cppFunction(_arguments...);
+		return bytes();
+	}
+	template 
+	auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments)
+	-> typename enable_if::value, bytes>::type
+	{
+		return toBigEndian(_cppFunction(_arguments...));
+	}
+
 	void sendMessage(bytes const& _data, bool _isCreation)
 	{
 		eth::Executive executive(m_state);
-		eth::Transaction t = _isCreation ? eth::Transaction(0, m_gasPrice, m_gas, _data)
-										 : eth::Transaction(0, m_gasPrice, m_gas, m_contractAddress, _data);
+		eth::Transaction t = _isCreation ? eth::Transaction(0, m_gasPrice, m_gas, _data, 0, KeyPair::create().sec())
+										 : eth::Transaction(0, m_gasPrice, m_gas, m_contractAddress, _data, 0, KeyPair::create().sec());
 		bytes transactionRLP = t.rlp();
 		try
 		{
@@ -77,13 +124,17 @@ private:
 		{
 			BOOST_REQUIRE(!executive.create(Address(), 0, m_gasPrice, m_gas, &_data, Address()));
 			m_contractAddress = executive.newAddress();
+			BOOST_REQUIRE(m_contractAddress);
 			BOOST_REQUIRE(m_state.addressHasCode(m_contractAddress));
 		}
 		else
+		{
+			BOOST_REQUIRE(m_state.addressHasCode(m_contractAddress));
 			BOOST_REQUIRE(!executive.call(m_contractAddress, Address(), 0, m_gasPrice, &_data, m_gas, Address()));
+		}
 		BOOST_REQUIRE(executive.go());
 		executive.finalize();
-		m_output = executive.out().toBytes();
+		m_output = executive.out().toVector();
 	}
 
 	Address m_contractAddress;
@@ -93,27 +144,23 @@ private:
 	bytes m_output;
 };
 
-BOOST_AUTO_TEST_SUITE(SolidityCompilerEndToEndTest)
+BOOST_FIXTURE_TEST_SUITE(SolidityCompilerEndToEndTest, ExecutionFramework)
 
 BOOST_AUTO_TEST_CASE(smoke_test)
 {
 	char const* sourceCode = "contract test {\n"
 							 "  function f(uint a) returns(uint d) { return a * 7; }\n"
 							 "}\n";
-	ExecutionFramework framework;
-	framework.compileAndRun(sourceCode);
-	u256 a = 0x200030004;
-	bytes result = framework.callFunction(0, a);
-	BOOST_CHECK(result == toBigEndian(a * 7));
+	compileAndRun(sourceCode);
+	testSolidityAgainstCppOnRange(0, [](u256 const& a) -> u256 { return a * 7; }, 0, 100);
 }
 
 BOOST_AUTO_TEST_CASE(empty_contract)
 {
 	char const* sourceCode = "contract test {\n"
 							 "}\n";
-	ExecutionFramework framework;
-	framework.compileAndRun(sourceCode);
-	BOOST_CHECK(framework.callFunction(0, bytes()).empty());
+	compileAndRun(sourceCode);
+	BOOST_CHECK(callContractFunction(0, bytes()).empty());
 }
 
 BOOST_AUTO_TEST_CASE(recursive_calls)
@@ -124,13 +171,32 @@ BOOST_AUTO_TEST_CASE(recursive_calls)
 							 "    else return n * f(n - 1);\n"
 							 "  }\n"
 							 "}\n";
-	ExecutionFramework framework;
-	framework.compileAndRun(sourceCode);
-	BOOST_CHECK(framework.callFunction(0, u256(0)) == toBigEndian(u256(1)));
-	BOOST_CHECK(framework.callFunction(0, u256(1)) == toBigEndian(u256(1)));
-	BOOST_CHECK(framework.callFunction(0, u256(2)) == toBigEndian(u256(2)));
-	BOOST_CHECK(framework.callFunction(0, u256(3)) == toBigEndian(u256(6)));
-	BOOST_CHECK(framework.callFunction(0, u256(4)) == toBigEndian(u256(24)));
+	compileAndRun(sourceCode);
+	function recursive_calls_cpp = [&recursive_calls_cpp](u256 const& n) -> u256
+	{
+		if (n <= 1)
+			return 1;
+		else
+			return n * recursive_calls_cpp(n - 1);
+	};
+
+	testSolidityAgainstCppOnRange(0, recursive_calls_cpp, 0, 5);
+}
+
+BOOST_AUTO_TEST_CASE(multiple_functions)
+{
+	char const* sourceCode = "contract test {\n"
+							 "  function a() returns(uint n) { return 0; }\n"
+							 "  function b() returns(uint n) { return 1; }\n"
+							 "  function c() returns(uint n) { return 2; }\n"
+							 "  function f() returns(uint n) { return 3; }\n"
+							 "}\n";
+	compileAndRun(sourceCode);
+	BOOST_CHECK(callContractFunction(0, bytes()) == toBigEndian(u256(0)));
+	BOOST_CHECK(callContractFunction(1, bytes()) == toBigEndian(u256(1)));
+	BOOST_CHECK(callContractFunction(2, bytes()) == toBigEndian(u256(2)));
+	BOOST_CHECK(callContractFunction(3, bytes()) == toBigEndian(u256(3)));
+	BOOST_CHECK(callContractFunction(4, bytes()) == bytes());
 }
 
 BOOST_AUTO_TEST_CASE(while_loop)
@@ -142,13 +208,19 @@ BOOST_AUTO_TEST_CASE(while_loop)
 							 "    while (i <= n) nfac *= i++;\n"
 							 "  }\n"
 							 "}\n";
-	ExecutionFramework framework;
-	framework.compileAndRun(sourceCode);
-	BOOST_CHECK(framework.callFunction(0, u256(0)) == toBigEndian(u256(1)));
-	BOOST_CHECK(framework.callFunction(0, u256(1)) == toBigEndian(u256(1)));
-	BOOST_CHECK(framework.callFunction(0, u256(2)) == toBigEndian(u256(2)));
-	BOOST_CHECK(framework.callFunction(0, u256(3)) == toBigEndian(u256(6)));
-	BOOST_CHECK(framework.callFunction(0, u256(4)) == toBigEndian(u256(24)));
+	compileAndRun(sourceCode);
+
+	auto while_loop_cpp = [](u256 const& n) -> u256
+	{
+		u256 nfac = 1;
+		u256 i = 2;
+		while (i <= n)
+			nfac *= i++;
+
+		return nfac;
+	};
+
+	testSolidityAgainstCppOnRange(0, while_loop_cpp, 0, 5);
 }
 
 BOOST_AUTO_TEST_CASE(break_outside_loop)
@@ -159,9 +231,8 @@ BOOST_AUTO_TEST_CASE(break_outside_loop)
 							 "    break; continue; return 2;\n"
 							 "  }\n"
 							 "}\n";
-	ExecutionFramework framework;
-	framework.compileAndRun(sourceCode);
-	BOOST_CHECK(framework.callFunction(0, u256(0)) == toBigEndian(u256(2)));
+	compileAndRun(sourceCode);
+	testSolidityAgainstCpp(0, [](u256 const&) -> u256 { return 2; }, u256(0));
 }
 
 BOOST_AUTO_TEST_CASE(nested_loops)
@@ -184,20 +255,33 @@ BOOST_AUTO_TEST_CASE(nested_loops)
 							 "    return x;\n"
 							 "  }\n"
 							 "}\n";
-	ExecutionFramework framework;
-	framework.compileAndRun(sourceCode);
-	BOOST_CHECK(framework.callFunction(0, u256(0)) == toBigEndian(u256(0)));
-	BOOST_CHECK(framework.callFunction(0, u256(1)) == toBigEndian(u256(1)));
-	BOOST_CHECK(framework.callFunction(0, u256(2)) == toBigEndian(u256(1)));
-	BOOST_CHECK(framework.callFunction(0, u256(3)) == toBigEndian(u256(2)));
-	BOOST_CHECK(framework.callFunction(0, u256(4)) == toBigEndian(u256(2)));
-	BOOST_CHECK(framework.callFunction(0, u256(5)) == toBigEndian(u256(4)));
-	BOOST_CHECK(framework.callFunction(0, u256(6)) == toBigEndian(u256(5)));
-	BOOST_CHECK(framework.callFunction(0, u256(7)) == toBigEndian(u256(5)));
-	BOOST_CHECK(framework.callFunction(0, u256(8)) == toBigEndian(u256(7)));
-	BOOST_CHECK(framework.callFunction(0, u256(9)) == toBigEndian(u256(8)));
-	BOOST_CHECK(framework.callFunction(0, u256(10)) == toBigEndian(u256(10)));
-	BOOST_CHECK(framework.callFunction(0, u256(11)) == toBigEndian(u256(10)));
+	compileAndRun(sourceCode);
+
+	auto nested_loops_cpp = [](u256  n) -> u256
+	{
+		while (n > 1)
+		{
+			if (n == 10)
+				break;
+			while (n > 5)
+			{
+				if (n == 8)
+					break;
+				n--;
+				if (n == 6)
+					continue;
+				return n;
+			}
+			n--;
+			if (n == 3)
+				continue;
+			break;
+		}
+
+		return n;
+	};
+
+	testSolidityAgainstCppOnRange(0, nested_loops_cpp, 0, 12);
 }
 
 BOOST_AUTO_TEST_CASE(calling_other_functions)
@@ -217,13 +301,36 @@ BOOST_AUTO_TEST_CASE(calling_other_functions)
 							 "    return 3 * x + 1;\n"
 							 "  }\n"
 							 "}\n";
-	ExecutionFramework framework;
-	framework.compileAndRun(sourceCode);
-	BOOST_CHECK(framework.callFunction(2, u256(0)) == toBigEndian(u256(0)));
-	BOOST_CHECK(framework.callFunction(2, u256(1)) == toBigEndian(u256(1)));
-	BOOST_CHECK(framework.callFunction(2, u256(2)) == toBigEndian(u256(1)));
-	BOOST_CHECK(framework.callFunction(2, u256(8)) == toBigEndian(u256(1)));
-	BOOST_CHECK(framework.callFunction(2, u256(127)) == toBigEndian(u256(1)));
+	compileAndRun(sourceCode);
+
+	auto evenStep_cpp = [](u256 const& n) -> u256
+	{
+		return n / 2;
+	};
+
+	auto oddStep_cpp = [](u256 const& n) -> u256
+	{
+		return 3 * n + 1;
+	};
+
+	auto collatz_cpp = [&evenStep_cpp, &oddStep_cpp](u256 n) -> u256
+	{
+		u256 y;
+		while ((y = n) > 1)
+		{
+			if (n % 2 == 0)
+				n = evenStep_cpp(n);
+			else
+				n = oddStep_cpp(n);
+		}
+		return y;
+	};
+
+	testSolidityAgainstCpp(2, collatz_cpp, u256(0));
+	testSolidityAgainstCpp(2, collatz_cpp, u256(1));
+	testSolidityAgainstCpp(2, collatz_cpp, u256(2));
+	testSolidityAgainstCpp(2, collatz_cpp, u256(8));
+	testSolidityAgainstCpp(2, collatz_cpp, u256(127));
 }
 
 BOOST_AUTO_TEST_CASE(many_local_variables)
@@ -235,10 +342,30 @@ BOOST_AUTO_TEST_CASE(many_local_variables)
 							 "    y += b + x2;\n"
 							 "  }\n"
 							 "}\n";
-	ExecutionFramework framework;
-	framework.compileAndRun(sourceCode);
-	BOOST_CHECK(framework.callFunction(0, toBigEndian(u256(0x1000)) + toBigEndian(u256(0x10000)) + toBigEndian(u256(0x100000)))
-				== toBigEndian(u256(0x121121)));
+	compileAndRun(sourceCode);
+	auto f = [](u256 const& x1, u256 const& x2, u256 const& x3) -> u256
+	{
+		u256 a = 0x1;
+		u256 b = 0x10;
+		u256 c = 0x100;
+		u256 y = a + b + c + x1 + x2 + x3;
+		return y + b + x2;
+	};
+	testSolidityAgainstCpp(0, f, u256(0x1000), u256(0x10000), u256(0x100000));
+}
+
+BOOST_AUTO_TEST_CASE(packing_unpacking_types)
+{
+	char const* sourceCode = "contract test {\n"
+							 "  function run(bool a, uint32 b, uint64 c) returns(uint256 y) {\n"
+							 "    if (a) y = 1;\n"
+							 "    y = y * 0x100000000 | ~b;\n"
+							 "    y = y * 0x10000000000000000 | ~c;\n"
+							 "  }\n"
+							 "}\n";
+	compileAndRun(sourceCode);
+	BOOST_CHECK(callContractFunction(0, fromHex("01""0f0f0f0f""f0f0f0f0f0f0f0f0"))
+				== fromHex("00000000000000000000000000000000000000""01""f0f0f0f0""0f0f0f0f0f0f0f0f"));
 }
 
 BOOST_AUTO_TEST_CASE(multiple_return_values)
@@ -248,9 +375,8 @@ BOOST_AUTO_TEST_CASE(multiple_return_values)
 							 "    y1 = x2; y2 = x1;\n"
 							 "  }\n"
 							 "}\n";
-	ExecutionFramework framework;
-	framework.compileAndRun(sourceCode);
-	BOOST_CHECK(framework.callFunction(0, bytes(1, 1) + toBigEndian(u256(0xcd)))
+	compileAndRun(sourceCode);
+	BOOST_CHECK(callContractFunction(0, bytes(1, 1) + toBigEndian(u256(0xcd)))
 				== toBigEndian(u256(0xcd)) + bytes(1, 1) + toBigEndian(u256(0)));
 }
 
@@ -262,13 +388,113 @@ BOOST_AUTO_TEST_CASE(short_circuiting)
 							 "    return x;"
 							 "  }\n"
 							 "}\n";
-	ExecutionFramework framework;
-	framework.compileAndRun(sourceCode);
-	BOOST_CHECK(framework.callFunction(0, u256(0)) == toBigEndian(u256(0)));
-	BOOST_CHECK(framework.callFunction(0, u256(1)) == toBigEndian(u256(8)));
+	compileAndRun(sourceCode);
+
+	auto short_circuiting_cpp = [](u256 n) -> u256
+	{
+		n == 0 || (n = 8) > 0;
+		return n;
+	};
+
+	testSolidityAgainstCppOnRange(0, short_circuiting_cpp, 0, 2);
+}
+
+BOOST_AUTO_TEST_CASE(high_bits_cleaning)
+{
+	char const* sourceCode = "contract test {\n"
+							 "  function run() returns(uint256 y) {\n"
+							 "    uint32 x = uint32(0xffffffff) + 10;\n"
+							 "    if (x >= 0xffffffff) return 0;\n"
+							 "    return x;"
+							 "  }\n"
+							 "}\n";
+	compileAndRun(sourceCode);
+	auto high_bits_cleaning_cpp = []() -> u256
+	{
+		uint32_t x = uint32_t(0xffffffff) + 10;
+		if (x >= 0xffffffff)
+			return 0;
+		return x;
+	};
+	testSolidityAgainstCpp(0, high_bits_cleaning_cpp);
+}
+
+BOOST_AUTO_TEST_CASE(sign_extension)
+{
+	char const* sourceCode = "contract test {\n"
+							 "  function run() returns(uint256 y) {\n"
+							 "    int64 x = -int32(0xff);\n"
+							 "    if (x >= 0xff) return 0;\n"
+							 "    return -uint256(x);"
+							 "  }\n"
+							 "}\n";
+	compileAndRun(sourceCode);
+	auto sign_extension_cpp = []() -> u256
+	{
+		int64_t x = -int32_t(0xff);
+		if (x >= 0xff)
+			return 0;
+		return u256(x) * -1;
+	};
+	testSolidityAgainstCpp(0, sign_extension_cpp);
+}
+
+BOOST_AUTO_TEST_CASE(small_unsigned_types)
+{
+	char const* sourceCode = "contract test {\n"
+							 "  function run() returns(uint256 y) {\n"
+							 "    uint32 x = uint32(0xffffff) * 0xffffff;\n"
+							 "    return x / 0x100;"
+							 "  }\n"
+							 "}\n";
+	compileAndRun(sourceCode);
+	auto small_unsigned_types_cpp = []() -> u256
+	{
+		uint32_t x = uint32_t(0xffffff) * 0xffffff;
+		return x / 0x100;
+	};
+	testSolidityAgainstCpp(0, small_unsigned_types_cpp);
 }
 
-//@todo test smaller types
+BOOST_AUTO_TEST_CASE(small_signed_types)
+{
+	char const* sourceCode = "contract test {\n"
+							 "  function run() returns(int256 y) {\n"
+							 "    return -int32(10) * -int64(20);\n"
+							 "  }\n"
+							 "}\n";
+	compileAndRun(sourceCode);
+	auto small_signed_types_cpp = []() -> u256
+	{
+		return -int32_t(10) * -int64_t(20);
+	};
+	testSolidityAgainstCpp(0, small_signed_types_cpp);
+}
+
+BOOST_AUTO_TEST_CASE(state_smoke_test)
+{
+	char const* sourceCode = "contract test {\n"
+							 "  uint256 value1;\n"
+							 "  uint256 value2;\n"
+							 "  function get(uint8 which) returns (uint256 value) {\n"
+							 "    if (which == 0) return value1;\n"
+							 "    else return value2;\n"
+							 "  }\n"
+							 "  function set(uint8 which, uint256 value) {\n"
+							 "    if (which == 0) value1 = value;\n"
+							 "    else value2 = value;\n"
+							 "  }\n"
+							 "}\n";
+	compileAndRun(sourceCode);
+	BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0)));
+	BOOST_CHECK(callContractFunction(0, bytes(1, 0x01)) == toBigEndian(u256(0)));
+	BOOST_CHECK(callContractFunction(1, bytes(1, 0x00) + toBigEndian(u256(0x1234))) == bytes());
+	BOOST_CHECK(callContractFunction(1, bytes(1, 0x01) + toBigEndian(u256(0x8765))) == bytes());
+	BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0x1234)));
+	BOOST_CHECK(callContractFunction(0, bytes(1, 0x01)) == toBigEndian(u256(0x8765)));
+	BOOST_CHECK(callContractFunction(1, bytes(1, 0x00) + toBigEndian(u256(0x3))) == bytes());
+	BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0x3)));
+}
 
 BOOST_AUTO_TEST_SUITE_END()
 
diff --git a/test/solidityExpressionCompiler.cpp b/test/solidityExpressionCompiler.cpp
index 561cc3bda..59a9e9336 100644
--- a/test/solidityExpressionCompiler.cpp
+++ b/test/solidityExpressionCompiler.cpp
@@ -154,10 +154,10 @@ BOOST_AUTO_TEST_CASE(comparison)
 							 "}\n";
 	bytes code = compileFirstExpression(sourceCode);
 
-	bytes expectation({byte(eth::Instruction::PUSH2), 0x10, 0xaa,
-					   byte(eth::Instruction::PUSH2), 0x11, 0xaa,
-					   byte(eth::Instruction::GT),
-					   byte(eth::Instruction::PUSH1), 0x1,
+	bytes expectation({byte(eth::Instruction::PUSH1), 0x1,
+					   byte(eth::Instruction::PUSH2), 0x11, 0xaa, byte(eth::Instruction::PUSH2), 0xff, 0xff, byte(eth::Instruction::AND),
+					   byte(eth::Instruction::PUSH2), 0x10, 0xaa, byte(eth::Instruction::PUSH2), 0xff, 0xff, byte(eth::Instruction::AND),
+					   byte(eth::Instruction::LT),
 					   byte(eth::Instruction::EQ),
 					   byte(eth::Instruction::ISZERO)});
 	BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
@@ -166,22 +166,22 @@ BOOST_AUTO_TEST_CASE(comparison)
 BOOST_AUTO_TEST_CASE(short_circuiting)
 {
 	char const* sourceCode = "contract test {\n"
-							 "  function f() { var x = (10 + 8 >= 4 || 2 != 9) != true; }"
+							 "  function f() { var x = true != (4 <= 8 + 10 || 9 != 2); }"
 							 "}\n";
 	bytes code = compileFirstExpression(sourceCode);
 
 	bytes expectation({byte(eth::Instruction::PUSH1), 0xa,
 					   byte(eth::Instruction::PUSH1), 0x8,
-					   byte(eth::Instruction::ADD),
-					   byte(eth::Instruction::PUSH1), 0x4,
+					   byte(eth::Instruction::ADD), byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
+					   byte(eth::Instruction::PUSH1), 0x4, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
 					   byte(eth::Instruction::GT),
 					   byte(eth::Instruction::ISZERO), // after this we have 10 + 8 >= 4
 					   byte(eth::Instruction::DUP1),
-					   byte(eth::Instruction::PUSH1), 0x14,
+					   byte(eth::Instruction::PUSH1), 0x20,
 					   byte(eth::Instruction::JUMPI), // short-circuit if it is true
 					   byte(eth::Instruction::POP),
-					   byte(eth::Instruction::PUSH1), 0x2,
-					   byte(eth::Instruction::PUSH1), 0x9,
+					   byte(eth::Instruction::PUSH1), 0x2, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
+					   byte(eth::Instruction::PUSH1), 0x9, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
 					   byte(eth::Instruction::EQ),
 					   byte(eth::Instruction::ISZERO), // after this we have 2 != 9
 					   byte(eth::Instruction::JUMPDEST),
@@ -194,13 +194,14 @@ BOOST_AUTO_TEST_CASE(short_circuiting)
 BOOST_AUTO_TEST_CASE(arithmetics)
 {
 	char const* sourceCode = "contract test {\n"
-							 "  function f() { var x = (1 * (2 / (3 % (4 + (5 - (6 | (7 & (8 ^ 9)))))))); }"
+							 "  function f() { var x = ((((((((9 ^ 8) & 7) | 6) - 5) + 4) % 3) / 2) * 1); }"
 							 "}\n";
 	bytes code = compileFirstExpression(sourceCode);
-
 	bytes expectation({byte(eth::Instruction::PUSH1), 0x1,
 					   byte(eth::Instruction::PUSH1), 0x2,
+					   byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
 					   byte(eth::Instruction::PUSH1), 0x3,
+					   byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
 					   byte(eth::Instruction::PUSH1), 0x4,
 					   byte(eth::Instruction::PUSH1), 0x5,
 					   byte(eth::Instruction::PUSH1), 0x6,
@@ -210,12 +211,11 @@ BOOST_AUTO_TEST_CASE(arithmetics)
 					   byte(eth::Instruction::XOR),
 					   byte(eth::Instruction::AND),
 					   byte(eth::Instruction::OR),
-					   byte(eth::Instruction::SWAP1),
 					   byte(eth::Instruction::SUB),
 					   byte(eth::Instruction::ADD),
-					   byte(eth::Instruction::SWAP1),
+					   byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
 					   byte(eth::Instruction::MOD),
-					   byte(eth::Instruction::SWAP1),
+					   byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
 					   byte(eth::Instruction::DIV),
 					   byte(eth::Instruction::MUL)});
 	BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
@@ -224,15 +224,15 @@ BOOST_AUTO_TEST_CASE(arithmetics)
 BOOST_AUTO_TEST_CASE(unary_operators)
 {
 	char const* sourceCode = "contract test {\n"
-							 "  function f() { var x = !(~+-1 == 2); }"
+							 "  function f() { var x = !(~+- 1 == 2); }"
 							 "}\n";
 	bytes code = compileFirstExpression(sourceCode);
 
-	bytes expectation({byte(eth::Instruction::PUSH1), 0x1,
+	bytes expectation({byte(eth::Instruction::PUSH1), 0x2, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
+					   byte(eth::Instruction::PUSH1), 0x1,
 					   byte(eth::Instruction::PUSH1), 0x0,
 					   byte(eth::Instruction::SUB),
-					   byte(eth::Instruction::NOT),
-					   byte(eth::Instruction::PUSH1), 0x2,
+					   byte(eth::Instruction::NOT), byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
 					   byte(eth::Instruction::EQ),
 					   byte(eth::Instruction::ISZERO)});
 	BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
@@ -241,7 +241,7 @@ BOOST_AUTO_TEST_CASE(unary_operators)
 BOOST_AUTO_TEST_CASE(unary_inc_dec)
 {
 	char const* sourceCode = "contract test {\n"
-							 "  function f(uint a) { var x = ((a++ ^ ++a) ^ a--) ^ --a; }"
+							 "  function f(uint a) { var x = --a ^ (a-- ^ (++a ^ a++)); }"
 							 "}\n";
 	bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "a"}, {"test", "f", "x"}});
 
@@ -296,16 +296,15 @@ BOOST_AUTO_TEST_CASE(assignment)
 	bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "a"}, {"test", "f", "b"}});
 
 	// Stack: a, b
-	bytes expectation({byte(eth::Instruction::DUP1),
-					   byte(eth::Instruction::DUP3),
-					   byte(eth::Instruction::SWAP1),
+	bytes expectation({byte(eth::Instruction::PUSH1), 0x2, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
+					   byte(eth::Instruction::DUP2),
+					   byte(eth::Instruction::DUP4),
 					   byte(eth::Instruction::ADD),
-					   // Stack here: a b a+b
-					   byte(eth::Instruction::SWAP2),
+					   // Stack here: a b 2 a+b
+					   byte(eth::Instruction::SWAP3),
 					   byte(eth::Instruction::POP),
-					   byte(eth::Instruction::DUP2),
-					   // Stack here: a+b b a+b
-					   byte(eth::Instruction::PUSH1), 0x2,
+					   byte(eth::Instruction::DUP3),
+					   // Stack here: a+b b 2 a+b
 					   byte(eth::Instruction::MUL)});
 	BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
 }
@@ -320,21 +319,20 @@ BOOST_AUTO_TEST_CASE(function_call)
 										{{"test", "f", "a"}, {"test", "f", "b"}});
 
 	// Stack: a, b
-	bytes expectation({byte(eth::Instruction::PUSH1), 0x0a,
-					   byte(eth::Instruction::DUP3),
-					   byte(eth::Instruction::PUSH1), 0x01,
+	bytes expectation({byte(eth::Instruction::PUSH1), 0x02, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
+					   byte(eth::Instruction::PUSH1), 0x12,
+					   byte(eth::Instruction::PUSH1), 0x01, byte(eth::Instruction::PUSH1), 0xff, byte(eth::Instruction::AND),
+					   byte(eth::Instruction::DUP5),
 					   byte(eth::Instruction::ADD),
-					   // Stack here: a b  (a+1)
-					   byte(eth::Instruction::DUP3),
-					   byte(eth::Instruction::PUSH1), 0x14,
+					   // Stack here: a b 2  (a+1)
+					   byte(eth::Instruction::DUP4),
+					   byte(eth::Instruction::PUSH1), 0x19,
 					   byte(eth::Instruction::JUMP),
 					   byte(eth::Instruction::JUMPDEST),
-					   // Stack here: a b g(a+1, b)
-					   byte(eth::Instruction::PUSH1), 0x02,
+					   // Stack here: a b 2 g(a+1, b)
 					   byte(eth::Instruction::MUL),
 					   // Stack here: a b g(a+1, b)*2
 					   byte(eth::Instruction::DUP3),
-					   byte(eth::Instruction::SWAP1),
 					   byte(eth::Instruction::ADD),
 					   // Stack here: a b a+g(a+1, b)*2
 					   byte(eth::Instruction::SWAP2),
@@ -344,6 +342,45 @@ BOOST_AUTO_TEST_CASE(function_call)
 	BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
 }
 
+BOOST_AUTO_TEST_CASE(negative_literals_8bits)
+{
+	// these all fit in 8 bits
+	char const* sourceCode = "contract test {\n"
+							 "  function f() { int8 x = -0 + -1 + -0x01 + -127 + -128; }\n"
+							 "}\n";
+	bytes code = compileFirstExpression(sourceCode);
+
+	bytes expectation(bytes({byte(eth::Instruction::PUSH32)}) + bytes(31, 0xff) + bytes(1, 0x80) +
+					  bytes({byte(eth::Instruction::PUSH32)}) + bytes(31, 0xff) + bytes(1, 0x81) +
+					  bytes({byte(eth::Instruction::PUSH32)}) + bytes(32, 0xff) +
+					  bytes({byte(eth::Instruction::PUSH32)}) + bytes(32, 0xff) +
+					  bytes({byte(eth::Instruction::PUSH1), 0x00,
+							 byte(eth::Instruction::ADD),
+							 byte(eth::Instruction::ADD),
+							 byte(eth::Instruction::ADD),
+							 byte(eth::Instruction::ADD)}));
+	BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
+}
+
+BOOST_AUTO_TEST_CASE(negative_literals_16bits)
+{
+	// -1 should need 8 bits, -129 should need 16 bits, how many bits are used is visible
+	// from the SIGNEXTEND opcodes
+	char const* sourceCode = "contract test {\n"
+							 "  function f() { int64 x = int64(-1 + -129); }\n"
+							 "}\n";
+	bytes code = compileFirstExpression(sourceCode);
+
+	bytes expectation(bytes({byte(eth::Instruction::PUSH32)}) + bytes(31, 0xff) + bytes(1, 0x7f) +
+					  bytes({byte(eth::Instruction::PUSH32)}) + bytes(32, 0xff) +
+					  bytes({byte(eth::Instruction::PUSH1), 0x00,
+							 byte(eth::Instruction::SIGNEXTEND),
+							 byte(eth::Instruction::ADD),
+							 byte(eth::Instruction::PUSH1), 0x01,
+							 byte(eth::Instruction::SIGNEXTEND)}));
+	BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
+}
+
 BOOST_AUTO_TEST_SUITE_END()
 
 }
diff --git a/test/solidityJSONInterfaceTest.cpp b/test/solidityJSONInterfaceTest.cpp
new file mode 100644
index 000000000..1a443087f
--- /dev/null
+++ b/test/solidityJSONInterfaceTest.cpp
@@ -0,0 +1,214 @@
+/*
+	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 .
+ */
+/**
+ * @author Marek Kotewicz 
+ * @date 2014
+ * Unit tests for the solidity compiler JSON Interface output.
+ */
+
+#include 
+#include 
+#include 
+
+namespace dev
+{
+namespace solidity
+{
+namespace test
+{
+
+class InterfaceChecker
+{
+public:
+	bool checkInterface(std::string const& _code, std::string const& _expectedInterfaceString)
+	{
+		m_compilerStack.parse(_code);
+		std::string generatedInterfaceString = m_compilerStack.getInterface();
+		Json::Value generatedInterface;
+		m_reader.parse(generatedInterfaceString, generatedInterface);
+		Json::Value expectedInterface;
+		m_reader.parse(_expectedInterfaceString, expectedInterface);
+		return expectedInterface == generatedInterface;
+	}
+	
+private:
+	CompilerStack m_compilerStack;
+	Json::Reader m_reader;
+};
+
+BOOST_FIXTURE_TEST_SUITE(SolidityCompilerJSONInterfaceOutput, InterfaceChecker)
+
+BOOST_AUTO_TEST_CASE(basic_test)
+{
+	char const* sourceCode = "contract test {\n"
+	"  function f(uint a) returns(uint d) { return a * 7; }\n"
+	"}\n";
+
+	char const* interface = R"([
+	{
+		"name": "f",
+		"inputs": [
+		{
+			"name": "a",
+			"type": "uint256"
+		}
+		],
+		"outputs": [
+		{
+			"name": "d",
+			"type": "uint256"
+		}
+		]
+	}
+	])";
+
+	BOOST_CHECK(checkInterface(sourceCode, interface));
+}
+
+BOOST_AUTO_TEST_CASE(empty_contract)
+{
+	char const* sourceCode = "contract test {\n"
+	"}\n";
+
+	char const* interface = "[]";
+
+	BOOST_CHECK(checkInterface(sourceCode, interface));
+}
+
+BOOST_AUTO_TEST_CASE(multiple_methods)
+{
+	char const* sourceCode = "contract test {\n"
+	"  function f(uint a) returns(uint d) { return a * 7; }\n"
+	"  function g(uint b) returns(uint e) { return b * 8; }\n"
+	"}\n";
+	
+	char const* interface = R"([
+	{
+		"name": "f",
+		"inputs": [
+		{
+			"name": "a",
+			"type": "uint256"
+		}
+		],
+		"outputs": [
+		{
+			"name": "d",
+			"type": "uint256"
+		}
+		]
+	},
+	{
+		"name": "g",
+		"inputs": [
+		{
+			"name": "b",
+			"type": "uint256"
+		}
+		],
+		"outputs": [
+		{
+			"name": "e",
+			"type": "uint256"
+		}
+		]
+	}
+	])";
+
+	BOOST_CHECK(checkInterface(sourceCode, interface));
+}
+
+BOOST_AUTO_TEST_CASE(multiple_params)
+{
+	char const* sourceCode = "contract test {\n"
+	"  function f(uint a, uint b) returns(uint d) { return a + b; }\n"
+	"}\n";
+
+	char const* interface = R"([
+	{
+		"name": "f",
+		"inputs": [
+		{
+			"name": "a",
+			"type": "uint256"
+		},
+		{
+			"name": "b",
+			"type": "uint256"
+		}
+		],
+		"outputs": [
+		{
+			"name": "d",
+			"type": "uint256"
+		}
+		]
+	}
+	])";
+
+	BOOST_CHECK(checkInterface(sourceCode, interface));
+}
+
+BOOST_AUTO_TEST_CASE(multiple_methods_order)
+{
+	// methods are expected to be in alpabetical order
+	char const* sourceCode = "contract test {\n"
+	"  function f(uint a) returns(uint d) { return a * 7; }\n"
+	"  function c(uint b) returns(uint e) { return b * 8; }\n"
+	"}\n";
+		
+	char const* interface = R"([
+	{
+		"name": "c",
+		"inputs": [
+		{
+			"name": "b",
+			"type": "uint256"
+		}
+		],
+		"outputs": [
+		{
+			"name": "e",
+			"type": "uint256"
+		}
+		]
+	},
+	{
+		"name": "f",
+		"inputs": [
+		{
+			"name": "a",
+			"type": "uint256"
+		}
+		],
+		"outputs": [
+		{
+			"name": "d",
+			"type": "uint256"
+		}
+		]
+	}
+	])";
+	
+	BOOST_CHECK(checkInterface(sourceCode, interface));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+}
+}
+}
diff --git a/test/solidityNameAndTypeResolution.cpp b/test/solidityNameAndTypeResolution.cpp
index 9e34e6d0e..f46ad6733 100644
--- a/test/solidityNameAndTypeResolution.cpp
+++ b/test/solidityNameAndTypeResolution.cpp
@@ -162,6 +162,22 @@ BOOST_AUTO_TEST_CASE(type_checking_function_call)
 	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
 }
 
+BOOST_AUTO_TEST_CASE(type_conversion_for_comparison)
+{
+	char const* text = "contract test {\n"
+					   "  function f() { uint32(2) == int64(2); }"
+					   "}\n";
+	BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
+}
+
+BOOST_AUTO_TEST_CASE(type_conversion_for_comparison_invalid)
+{
+	char const* text = "contract test {\n"
+					   "  function f() { int32(2) == uint64(2); }"
+					   "}\n";
+	BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
+}
+
 BOOST_AUTO_TEST_CASE(type_inference_explicit_conversion)
 {
 	char const* text = "contract test {\n"
diff --git a/test/solidityScanner.cpp b/test/solidityScanner.cpp
index d2a960cfb..d714699a0 100644
--- a/test/solidityScanner.cpp
+++ b/test/solidityScanner.cpp
@@ -97,6 +97,27 @@ BOOST_AUTO_TEST_CASE(hex_numbers)
 	BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
 }
 
+BOOST_AUTO_TEST_CASE(negative_numbers)
+{
+	Scanner scanner(CharStream("var x = -.2 + -0x78 + -7.3 + 8.9;"));
+	BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::VAR);
+	BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
+	BOOST_CHECK_EQUAL(scanner.next(), Token::ASSIGN);
+	BOOST_CHECK_EQUAL(scanner.next(), Token::NUMBER);
+	BOOST_CHECK_EQUAL(scanner.getCurrentLiteral(), "-.2");
+	BOOST_CHECK_EQUAL(scanner.next(), Token::ADD);
+	BOOST_CHECK_EQUAL(scanner.next(), Token::NUMBER);
+	BOOST_CHECK_EQUAL(scanner.getCurrentLiteral(), "-0x78");
+	BOOST_CHECK_EQUAL(scanner.next(), Token::ADD);
+	BOOST_CHECK_EQUAL(scanner.next(), Token::NUMBER);
+	BOOST_CHECK_EQUAL(scanner.getCurrentLiteral(), "-7.3");
+	BOOST_CHECK_EQUAL(scanner.next(), Token::ADD);
+	BOOST_CHECK_EQUAL(scanner.next(), Token::NUMBER);
+	BOOST_CHECK_EQUAL(scanner.getCurrentLiteral(), "8.9");
+	BOOST_CHECK_EQUAL(scanner.next(), Token::SEMICOLON);
+	BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
+}
+
 BOOST_AUTO_TEST_CASE(locations)
 {
 	Scanner scanner(CharStream("function_identifier has ; -0x743/*comment*/\n ident //comment"));
@@ -109,11 +130,8 @@ BOOST_AUTO_TEST_CASE(locations)
 	BOOST_CHECK_EQUAL(scanner.next(), Token::SEMICOLON);
 	BOOST_CHECK_EQUAL(scanner.getCurrentLocation().start, 24);
 	BOOST_CHECK_EQUAL(scanner.getCurrentLocation().end, 25);
-	BOOST_CHECK_EQUAL(scanner.next(), Token::SUB);
-	BOOST_CHECK_EQUAL(scanner.getCurrentLocation().start, 26);
-	BOOST_CHECK_EQUAL(scanner.getCurrentLocation().end, 27);
 	BOOST_CHECK_EQUAL(scanner.next(), Token::NUMBER);
-	BOOST_CHECK_EQUAL(scanner.getCurrentLocation().start, 27);
+	BOOST_CHECK_EQUAL(scanner.getCurrentLocation().start, 26);
 	BOOST_CHECK_EQUAL(scanner.getCurrentLocation().end, 32);
 	BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
 	BOOST_CHECK_EQUAL(scanner.getCurrentLocation().start, 45);
diff --git a/test/stPreCompiledContractsFiller.json b/test/stPreCompiledContractsFiller.json
new file mode 100644
index 000000000..bb2b35756
--- /dev/null
+++ b/test/stPreCompiledContractsFiller.json
@@ -0,0 +1,717 @@
+{
+    "CallEcrecover0": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 1000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0))  }",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallEcrecover0_gas500": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 500 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0))  }",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallEcrecover0_Gas499": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 499 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0))  }",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallEcrecover0_0input": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code": "{ [[ 2 ]] (CALL 1000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) }",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallEcrecover1": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 1) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 1000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0))  }",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallEcrecover2": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 33 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 65 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 1000 1 0 0 97 97 32) [[ 0 ]] (MOD (MLOAD 97) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0))  }",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallEcrecover3": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code": "{ (MSTORE 0 0x2f380a2dea7e778d81affc2443403b8fe4644db442ae4862ff5bb3732829cdb9) (MSTORE 32 27) (MSTORE 64 0x6b65ccb0558806e9b097f27a396d08f964e37b8b7af6ceeb516ff86739fbea0a) (MSTORE 96 0x37cbc8d883e129a4b1ef9d5f1df53c4f21a3ef147cf2a50a4ede0eb06ce092d4) [[ 2 ]] (CALL 1000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0))  }",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallSha256_0": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code" : "0x600160005260206000602060006000600260fff1600051600055",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallSha256_1": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code" : "{ [[ 2 ]] (CALL 500 2 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallSha256_2": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code" : "{ (MSTORE 5 0xf34578907f) [[ 2 ]] (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallSha256_3": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallSha256_4": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 100 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallSha256_4_gas99": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 99 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallSha256_5": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 500 2 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "10000000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallRipemd160_0": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code" : "0x600160005260206000602060006000600360fff1600051600055",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallRipemd160_1": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code" : "{ [[ 2 ]] (CALL 500 3 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallRipemd160_2": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code" : "{ (MSTORE 5 0xf34578907f) [[ 2 ]] (CALL 500 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallRipemd160_3": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALL 500 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallRipemd160_4": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 100 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallRipemd160_4_gas99": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 99 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallRipemd160_5": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 500 3 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "10000000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+}
+
diff --git a/test/stSystemOperationsTestFiller.json b/test/stSystemOperationsTestFiller.json
new file mode 100644
index 000000000..e62753089
--- /dev/null
+++ b/test/stSystemOperationsTestFiller.json
@@ -0,0 +1,1334 @@
+{
+    "createNameRegistrator": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "1000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ (MSTORE 0 0x601080600c6000396000f20060003554156009570060203560003555) [[ 0 ]] (CREATE 23 4 28) }",
+                "storage": {}
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "10000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "createNameRegistratorValueTooHigh": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "1000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ (MSTORE 0 0x601080600c6000396000f20060003554156009570060203560003555) [[ 0 ]] (CREATE 1000 4 28) }",
+                "storage": {}
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "10000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "createNameRegistratorOutOfMemoryBonds0": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "1000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ (MSTORE 0 0x601080600c6000396000f20060003554156009570060203560003555) [[ 0 ]] (CREATE 23 0xfffffffffff 28) }",
+                "storage": {}
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "10000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "createNameRegistratorOutOfMemoryBonds1": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "1000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ (MSTORE 0 0x601080600c6000396000f20060003554156009570060203560003555) [[ 0 ]] (CREATE 23 4 0xfffffffffff) }",
+                "storage": {}
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "10000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "CallToNameRegistrator0": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0) }",
+                "storage": {}
+            },
+            "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+                "balance" : "23",
+                "code" : "0x60003554156009570060203560003555",
+                "nonce" : "0",
+                "storage" : {
+                }
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "10000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "CallToReturn1": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 0 2) }",
+                "storage": {}
+            },
+            "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+                "balance" : "23",
+                "code" : "0x6001600155603760005360026000f2",
+                "nonce" : "0",
+                "storage" : {
+                }
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "10000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "PostToReturn1": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) (POST 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 ) }",
+                "storage": {}
+            },
+            "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+                "balance" : "23",
+                "code" : "0x603760005360026000f2",
+                "nonce" : "0",
+                "storage" : {
+                }
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "10000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "callstatelessToReturn1": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLSTATELESS 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 0 2 ) }",
+                "storage": {}
+            },
+            "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+                "balance" : "23",
+                "code" : "0x6001600155603760005360026000f2",
+                "nonce" : "0",
+                "storage" : {
+                }
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "10000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "callcodeToReturn1": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLCODE 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 0 2 ) }",
+                "storage": {}
+            },
+            "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+                "balance" : "23",
+                "code" : "0x6001600155603760005360026000f2",
+                "nonce" : "0",
+                "storage" : {
+                }
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "10000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+
+    "CallToNameRegistratorOutOfGas": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 100 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0) }",
+                "storage": {}
+            },
+            "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+                "balance" : "23",
+                "code" : "0x60003554156009570060203560003555",
+                "nonce" : "0",
+                "storage" : {
+                }
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "10000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "CallToNameRegistratorTooMuchMemory0": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 987654321 64 64 0) }",
+                "storage": {}
+            },
+            "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+                "balance" : "23",
+                "code" : "0x60003554156009570060203560003555",
+                "nonce" : "0",
+                "storage" : {
+                }
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "10000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "CallToNameRegistratorTooMuchMemory1": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 9865432 64 0) }",
+                "storage": {}
+            },
+            "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+                "balance" : "23",
+                "code" : "0x60003554156009570060203560003555",
+                "nonce" : "0",
+                "storage" : {
+                }
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "10000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "CallToNameRegistratorTooMuchMemory2": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 987654 1) }",
+                "storage": {}
+            },
+            "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+                "balance" : "23",
+                "code" : "0x60003554156009570060203560003555",
+                "nonce" : "0",
+                "storage" : {
+                }
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "10000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+
+    "CallToNameRegistratorNotMuchMemory0": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 987654 0) }",
+                "storage": {}
+            },
+            "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+                "balance" : "23",
+                "code" : "0x60003554156009570060203560003555",
+                "nonce" : "0",
+                "storage" : {
+                }
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "10000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "CallToNameRegistratorNotMuchMemory1": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ (MSTORE 0 0xeeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 500 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 987654 0 64 0) }",
+                "storage": {}
+            },
+            "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+                "balance" : "23",
+                "code" : "0x60003554156009570060203560003555",
+                "nonce" : "0",
+                "storage" : {
+                }
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "10000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "CallRecursiveBomb0": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code" : "{  (CALL 100000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 0 0 0)  }",
+                 "storage": {}
+             },
+             "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+                 "balance" : "1000000000000000000",
+                 "nonce" : 0,
+                 "code" : "{ [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224) (ADDRESS) 0 0 0 0 0) } ",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "1000000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallRecursiveBomb1": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code" : "{  [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224) (ADDRESS) 0 0 0 0 0)  }",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365223",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallRecursiveBomb2": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code" : "{  [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224) (ADDRESS) 0 0 0 0 0)  }",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "365224",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "CallRecursiveBomb3": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "20000000",
+                 "nonce" : 0,
+                 "code" : "{  [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224) (ADDRESS) 0 0 0 0 0)  }",
+                 "storage": {}
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "1000000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "suicideCaller": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ [[0]] (CALLER) (SUICIDE (CALLER))}",
+                "storage": {}
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "1000000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "suicideOrigin": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ [[0]] (ORIGIN) (SUICIDE (ORIGIN))}",
+                "storage": {}
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "1000000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "suicideAddress": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ [[0]] (ADDRESS) (SUICIDE (ADDRESS))}",
+                "storage": {}
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "1000000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "suicideNotExistingAccount": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ (SUICIDE 0xaa1722f3947def4cf144679da39c4c32bdc35681 )}",
+                "storage": {}
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "1000000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "suicideSendEtherToMe": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ (SUICIDE (ADDRESS) )}",
+                "storage": {}
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "1000000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "return0": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+           "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "23",
+                "code" : "{ (MSTORE8 0 55) (RETURN 0 1)}",
+                "nonce" : "0",
+                "storage" : {
+                }
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "1000000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "return1": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+           "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "23",
+                "code" : "{ (MSTORE8 0 55) (RETURN 0 2)}",
+                "nonce" : "0",
+                "storage" : {
+                }
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "1000000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "return2": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+           "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "23",
+                "code" : "{ (MSTORE8 0 55) (RETURN 0 33)}",
+                "nonce" : "0",
+                "storage" : {
+                }
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "1000000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+   "callcodeToNameRegistrator0": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALLCODE 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0) }",
+                "storage": {}
+            },
+            "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+                "balance" : "23",
+                "code" : "0x60003554156009570060203560003555",
+                "nonce" : "0",
+                "storage" : {
+                }
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "1000000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "TestNameRegistrator": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "1000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "0x60003554156009570060203560003555",
+                "storage": {}
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "1000000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
+        }
+    },
+
+    "ABAcalls0": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{  [[ (PC) ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }",
+                "storage": {}
+            },
+            "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+                "balance" : "23",
+                "code" : " { [[ (PC) ]] (ADD 1 (CALL 500 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) } ",
+                "nonce" : "0",
+                "storage" : {
+                }
+            },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "1000000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+    },
+
+    "ABAcalls1": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "1000000000000000000",
+                 "nonce" : 0,
+                 "code" : "{  [[ (PC) ]] (CALL (- (GAS) 1000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }",
+                 "storage": {}
+             },
+             "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+                 "balance" : "23",
+                 "code" : " { [[ (PC) ]] (ADD 1 (CALL (- (GAS) 1000) 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) } ",
+                 "nonce" : "0",
+                 "storage" : {
+                 }
+             },
+            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "",
+                "storage": {}
+            }
+        },
+        "transaction" : {
+            "nonce" : "0",
+            "gasPrice" : "1",
+            "gasLimit" : "1000000",
+            "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+            "value" : "100000",
+            "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+            "data" : ""
+        }
+     },
+
+    "ABAcalls2": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "1000000000000000000",
+                 "nonce" : 0,
+                 "code" : "{  [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 1 0 0 0 0) }",
+                 "storage": {}
+             },
+             "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+                 "balance" : "0",
+                 "code" : " { [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 0 0 0 0 0) } ",
+                 "nonce" : "0",
+                 "storage" : {
+                 }
+            },
+           "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+               "balance" : "1000000000000000000",
+               "nonce" : 0,
+               "code" : "",
+               "storage": {}
+           }
+       },
+       "transaction" : {
+           "nonce" : "0",
+           "gasPrice" : "1",
+           "gasLimit" : "10000000",
+           "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+           "value" : "100000",
+           "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+           "data" : ""
+       }
+     },
+
+    "ABAcalls3": {
+         "env" : {
+             "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+             "currentNumber" : "0",
+             "currentGasLimit" : "10000000",
+             "currentDifficulty" : "256",
+             "currentTimestamp" : 1,
+             "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+         },
+         "pre" : {
+             "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                 "balance" : "1025000",
+                 "nonce" : 0,
+                 "code" : "{  [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 1 0 0 0 0) }",
+                 "storage": {}
+             },
+             "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+                 "balance" : "0",
+                 "code" : " { [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 0 0 0 0 0) } ",
+                 "nonce" : "0",
+                 "storage" : {
+                 }
+            },
+           "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+               "balance" : "1000000000000000000",
+               "nonce" : 0,
+               "code" : "",
+               "storage": {}
+           }
+       },
+       "transaction" : {
+           "nonce" : "0",
+           "gasPrice" : "1",
+           "gasLimit" : "10000000",
+           "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+           "value" : "100000",
+           "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+           "data" : ""
+       }
+     },
+
+    "ABAcallsSuicide0": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{  [[ (PC) ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) (SUICIDE 0x945304eb96065b2a98b57a48a06ae28d285a71b5)  }",
+                "storage": {}
+            },
+            "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+                "balance" : "23",
+                "code" : "{ [[ (PC) ]] (ADD 1 (CALL 500 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) } ",
+                "nonce" : "0",
+                "storage" : {
+                }
+            },
+           "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+               "balance" : "1000000000000000000",
+               "nonce" : 0,
+               "code" : "",
+               "storage": {}
+           }
+       },
+       "transaction" : {
+           "nonce" : "0",
+           "gasPrice" : "1",
+           "gasLimit" : "10000000",
+           "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+           "value" : "100000",
+           "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+           "data" : ""
+       }
+    },
+
+    "ABAcallsSuicide1": {
+        "env" : {
+            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
+            "currentNumber" : "0",
+            "currentGasLimit" : "10000000",
+            "currentDifficulty" : "256",
+            "currentTimestamp" : 1,
+            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
+        },
+        "pre" : {
+            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
+                "balance" : "1000000000000000000",
+                "nonce" : 0,
+                "code" : "{  [[ (PC) ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0)   }",
+                "storage": {}
+            },
+            "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
+                "balance" : "23",
+                "code" : "{ [[ (PC) ]] (ADD 1 (CALL 500 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) (SUICIDE 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6) } ",
+                "nonce" : "0",
+                "storage" : {
+                }
+            },
+           "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
+               "balance" : "1000000000000000000",
+               "nonce" : 0,
+               "code" : "",
+               "storage": {}
+           }
+       },
+       "transaction" : {
+           "nonce" : "0",
+           "gasPrice" : "1",
+           "gasLimit" : "10000000",
+           "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
+           "value" : "100000",
+           "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
+           "data" : ""
+       }
+    }
+}
diff --git a/test/state.cpp b/test/state.cpp
index 9c0a7188b..b5b238299 100644
--- a/test/state.cpp
+++ b/test/state.cpp
@@ -43,7 +43,6 @@ namespace dev {  namespace test {
 
 void doStateTests(json_spirit::mValue& v, bool _fillin)
 {
-	cout << "start state test\n";
 	for (auto& i: v.get_obj())
 	{
 		cnote << i.first;
@@ -55,12 +54,6 @@ void doStateTests(json_spirit::mValue& v, bool _fillin)
 
 		ImportTest importer(o, _fillin);
 
-		if (_fillin)
-		{
-			importer.code = importer.m_statePre.code(importer.m_environment.myAddress);
-			importer.m_environment.code = &importer.code;
-		}
-
 		State theState = importer.m_statePre;
 		bytes tx = importer.m_transaction.rlp();
 		bytes output;
@@ -124,12 +117,48 @@ BOOST_AUTO_TEST_CASE(stSystemOperationsTest)
 	dev::test::executeTests("stSystemOperationsTest", "/StateTests", dev::test::doStateTests);
 }
 
-BOOST_AUTO_TEST_CASE(tmp)
+BOOST_AUTO_TEST_CASE(stPreCompiledContracts)
+{
+	dev::test::executeTests("stPreCompiledContracts", "/StateTests", dev::test::doStateTests);
+}
+
+BOOST_AUTO_TEST_CASE(stCreateTest)
+{
+	for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i)
+	{
+		string arg = boost::unit_test::framework::master_test_suite().argv[i];
+		if (arg == "--createtest")
+		{
+			if (boost::unit_test::framework::master_test_suite().argc <= i + 2)
+			{
+				cnote << "usage: ./testeth --createtest  \n";
+				return;
+			}
+			try
+			{
+				cnote << "Populating tests...";
+				json_spirit::mValue v;
+				string s = asString(dev::contents(boost::unit_test::framework::master_test_suite().argv[i + 1]));
+				BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + (string)boost::unit_test::framework::master_test_suite().argv[i + 1] + " is empty.");
+				json_spirit::read_string(s, v);
+				dev::test::doStateTests(v, true);
+				writeFile(boost::unit_test::framework::master_test_suite().argv[i + 2], asBytes(json_spirit::write_string(v, true)));
+			}
+			catch (Exception const& _e)
+			{
+				BOOST_ERROR("Failed state test with Exception: " << diagnostic_information(_e));
+			}
+			catch (std::exception const& _e)
+			{
+				BOOST_ERROR("Failed state test with Exception: " << _e.what());
+			}
+		}
+	}
+}
+
+BOOST_AUTO_TEST_CASE(userDefinedFileState)
 {
-	int currentVerbosity = g_logVerbosity;
-	g_logVerbosity = 12;
-	dev::test::executeTests("tmp", "/StateTests", dev::test::doStateTests);
-	g_logVerbosity = currentVerbosity;
+	dev::test::userDefinedTest("--statetest", dev::test::doStateTests);
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/tmpFiller.json b/test/tmpFiller.json
deleted file mode 100644
index bd27b8907..000000000
--- a/test/tmpFiller.json
+++ /dev/null
@@ -1,44 +0,0 @@
-{
- "ABAcalls0": {
-        "env" : {
-            "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
-            "currentNumber" : "0",
-            "currentGasLimit" : "10000000",
-            "currentDifficulty" : "256",
-            "currentTimestamp" : 1,
-            "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
-        },
-        "pre" : {
-            "095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
-                "balance" : "1000000000000000000",
-                "nonce" : 0,
-                "code" : "{  [[ (PC) ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }",
-                "storage": {}
-            },
-            "945304eb96065b2a98b57a48a06ae28d285a71b5" : {
-                "balance" : "23",
-                "code" : " { [[ (PC) ]] (ADD 1 (CALL 500 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) } ",
-                "nonce" : "0",
-                "storage" : {
-                }
-            },
-            "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
-                "balance" : "1000000000000000000",
-                "nonce" : 0,
-                "code" : "",
-                "storage": {}
-            }
-
-        },
-	"transaction" : {
-		"nonce" : "0",
-		"gasPrice" : "1",
-		"gasLimit" : "10000",
-		"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
-		"value" : "100000",
-		"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
-		"data" : ""		
-	}
-    }
-
-}
diff --git a/test/vm.cpp b/test/vm.cpp
index fe37d67c3..67f088376 100644
--- a/test/vm.cpp
+++ b/test/vm.cpp
@@ -21,6 +21,7 @@
  */
 
 #include 
+#include 
 #include "vm.h"
 using namespace std;
 using namespace json_spirit;
@@ -29,7 +30,7 @@ using namespace dev::eth;
 using namespace dev::test;
 
 FakeExtVM::FakeExtVM(eth::BlockInfo const& _previousBlock, eth::BlockInfo const& _currentBlock, unsigned _depth):			/// TODO: XXX: remove the default argument & fix.
-	ExtVMFace(Address(), Address(), Address(), 0, 1, bytesConstRef(), bytesConstRef(), _previousBlock, _currentBlock, _depth) {}
+	ExtVMFace(Address(), Address(), Address(), 0, 1, bytesConstRef(), bytes(), _previousBlock, _currentBlock, _depth) {}
 
 h160 FakeExtVM::create(u256 _endowment, u256* _gas, bytesConstRef _init, OnOpFunc const&)
 {
@@ -195,11 +196,11 @@ void FakeExtVM::importExec(mObject& _o)
 	gas = toInt(_o["gas"]);
 
 	thisTxCode.clear();
-	code = &thisTxCode;
+	code = thisTxCode;
 
 	thisTxCode = importCode(_o);
 	if (_o["code"].type() != str_type && _o["code"].type() != array_type)
-		code.reset();
+		code.clear();
 
 	thisTxData.clear();
 	thisTxData = importData(_o);
@@ -297,10 +298,10 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
 			o["pre"] = mValue(fev.exportState());
 
 		fev.importExec(o["exec"].get_obj());
-		if (!fev.code)
+		if (fev.code.empty())
 		{
 			fev.thisTxCode = get<3>(fev.addresses.at(fev.myAddress));
-			fev.code = &fev.thisTxCode;
+			fev.code = fev.thisTxCode;
 		}
 
 		auto vm = VMFace::create(vmKind, fev.gas);
@@ -308,21 +309,31 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
 		auto outOfGas = false;
 
 		auto startTime = std::chrono::high_resolution_clock::now();
+		u256 gas;
 		try
 		{
 			output = vm->go(fev, fev.simpleTrace()).toVector();
+			gas = vm->gas();
 		}
 		catch (OutOfGas const&)
 		{
 			outOfGas = true;
+			gas = 0;
+		}
+		catch (VMException const& _e)
+		{
+			cnote << "VM did throw an exception: " << diagnostic_information(_e);
+			gas = 0;
 		}
 		catch (Exception const& _e)
 		{
 			cnote << "VM did throw an exception: " << diagnostic_information(_e);
+			BOOST_ERROR("Failed VM Test with Exception: " << _e.what());
 		}
 		catch (std::exception const& _e)
 		{
 			cnote << "VM did throw an exception: " << _e.what();
+			BOOST_ERROR("Failed VM Test with Exception: " << _e.what());
 		}
 
 		auto endTime = std::chrono::high_resolution_clock::now();
@@ -338,8 +349,6 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
 			}
 		}
 
-		auto gas = vm->gas();
-
 		// delete null entries in storage for the sake of comparison
 
 		for (auto  &a: fev.addresses)
@@ -380,7 +389,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
 			checkOutput(output, o);
 
             BOOST_CHECK_EQUAL(toInt(o["gas"]), gas);
-		
+
 			if (outOfGas)
 				BOOST_CHECK_MESSAGE(gas == 0, "Remaining gas not 0 in out-of-gas state");
 
@@ -454,32 +463,42 @@ BOOST_AUTO_TEST_CASE(vmPushDupSwapTest)
 	dev::test::executeTests("vmPushDupSwapTest", "/VMTests", dev::test::doVMTests);
 }
 
-BOOST_AUTO_TEST_CASE(userDefinedFile)
+BOOST_AUTO_TEST_CASE(vmRandom)
 {
-	if (boost::unit_test::framework::master_test_suite().argc >= 2)
+	string testPath = getTestPath();
+	testPath += "/VMTests/RandomTests";
+
+	vector testFiles;
+	boost::filesystem::directory_iterator iterator(testPath);
+	for(; iterator != boost::filesystem::directory_iterator(); ++iterator)
+		if (boost::filesystem::is_regular_file(iterator->path()) && iterator->path().extension() == ".json")
+			testFiles.push_back(iterator->path());
+
+	for (auto& path: testFiles)
 	{
-		string filename = boost::unit_test::framework::master_test_suite().argv[1];
-		int currentVerbosity = g_logVerbosity;
-		g_logVerbosity = 12;
 		try
 		{
-			cnote << "Testing VM..." << "user defined test";
+			cnote << "Testing ..." << path.filename();
 			json_spirit::mValue v;
-			string s = asString(contents(filename));
-			BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + filename + " is empty. ");
+			string s = asString(dev::contents(path.string()));
+			BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + path.string() + " is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path?");
 			json_spirit::read_string(s, v);
-			dev::test::doVMTests(v, false);
+			doVMTests(v, false);
 		}
 		catch (Exception const& _e)
 		{
-			BOOST_ERROR("Failed VM Test with Exception: " << diagnostic_information(_e));
+			BOOST_ERROR("Failed test with Exception: " << diagnostic_information(_e));
 		}
 		catch (std::exception const& _e)
 		{
-			BOOST_ERROR("Failed VM Test with Exception: " << _e.what());
+			BOOST_ERROR("Failed test with Exception: " << _e.what());
 		}
-		g_logVerbosity = currentVerbosity;
 	}
 }
 
+BOOST_AUTO_TEST_CASE(userDefinedFileVM)
+{
+	dev::test::userDefinedTest("--vmtest", dev::test::doVMTests);
+}
+
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/vm.h b/test/vm.h
index 1ed33e5fa..a52a02e31 100644
--- a/test/vm.h
+++ b/test/vm.h
@@ -29,7 +29,7 @@ along with cpp-ethereum.  If not, see .
 #include "JsonSpiritHeaders.h"
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
diff --git a/test/vmArithmeticTestFiller.json b/test/vmArithmeticTestFiller.json
index 29d523a36..b93694575 100644
--- a/test/vmArithmeticTestFiller.json
+++ b/test/vmArithmeticTestFiller.json
@@ -1725,7 +1725,7 @@
             "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
                 "balance" : "1000000000000000000",
                 "nonce" : 0,
-                "code" : "0x62122ff4600016600057",
+                "code" : "0x62122ff460000b600055",
                 "storage": {}
             }
         },
@@ -1753,7 +1753,7 @@
             "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
                 "balance" : "1000000000000000000",
                 "nonce" : 0,
-                "code" : "0x62122f6a600016600057",
+                "code" : "0x62122f6a60000b600055",
                 "storage": {}
             }
         },
@@ -1781,7 +1781,7 @@
             "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
                 "balance" : "1000000000000000000",
                 "nonce" : 0,
-                "code" : "0x6212faf4600116600057",
+                "code" : "0x6212faf460010b600055",
                 "storage": {}
             }
         },
@@ -1809,7 +1809,7 @@
             "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
                 "balance" : "1000000000000000000",
                 "nonce" : 0,
-                "code" : "0x62126af4600116600057",
+                "code" : "0x62126af460010b600055",
                 "storage": {}
             }
         },
@@ -1837,7 +1837,7 @@
             "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
                 "balance" : "1000000000000000000",
                 "nonce" : 0,
-                "code" : "0x62126af4605016600057",
+                "code" : "0x62126af460500b600055",
                 "storage": {}
             }
         },
@@ -2005,7 +2005,7 @@
             "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
                 "balance" : "1000000000000000000",
                 "nonce" : 0,
-                "code" : "0x66f000000000000161ffff16600057",
+                "code" : "0x66f000000000000161ffff0b600055",
                 "storage": {}
             }
         },
@@ -2033,7 +2033,7 @@
             "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
                 "balance" : "1000000000000000000",
                 "nonce" : 0,
-                "code" : "0x60ff68f0000000000000000116600057",
+                "code" : "0x60ff68f000000000000000010b600055",
                 "storage": {}
             }
         },
diff --git a/test/webthreestubclient.h b/test/webthreestubclient.h
index 6beee5bb6..179c620a7 100644
--- a/test/webthreestubclient.h
+++ b/test/webthreestubclient.h
@@ -19,11 +19,13 @@ class WebThreeStubClient
             delete this->client;
         }
 
-        std::string account() throw (jsonrpc::JsonRpcException)
+        std::string db_get(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
-            p = Json::nullValue;
-            Json::Value result = this->client->CallMethod("account",p);
+            p.append(param1);
+p.append(param2);
+
+            Json::Value result = this->client->CallMethod("db_get",p);
     if (result.isString())
         return result.asString();
      else 
@@ -31,38 +33,68 @@ class WebThreeStubClient
 
         }
 
-        Json::Value accounts() throw (jsonrpc::JsonRpcException)
+        std::string db_getString(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
-            p = Json::nullValue;
-            Json::Value result = this->client->CallMethod("accounts",p);
-    if (result.isArray())
-        return result;
+            p.append(param1);
+p.append(param2);
+
+            Json::Value result = this->client->CallMethod("db_getString",p);
+    if (result.isString())
+        return result.asString();
      else 
          throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
 
         }
 
-        std::string addToGroup(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
+        bool db_put(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
 p.append(param2);
+p.append(param3);
 
-            Json::Value result = this->client->CallMethod("addToGroup",p);
-    if (result.isString())
-        return result.asString();
+            Json::Value result = this->client->CallMethod("db_put",p);
+    if (result.isBool())
+        return result.asBool();
      else 
          throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
 
         }
 
-        std::string balanceAt(const std::string& param1) throw (jsonrpc::JsonRpcException)
+        bool db_putString(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
+p.append(param2);
+p.append(param3);
 
-            Json::Value result = this->client->CallMethod("balanceAt",p);
+            Json::Value result = this->client->CallMethod("db_putString",p);
+    if (result.isBool())
+        return result.asBool();
+     else 
+         throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
+
+        }
+
+        Json::Value eth_accounts() throw (jsonrpc::JsonRpcException)
+        {
+            Json::Value p;
+            p = Json::nullValue;
+            Json::Value result = this->client->CallMethod("eth_accounts",p);
+    if (result.isArray())
+        return result;
+     else 
+         throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
+
+        }
+
+        std::string eth_balanceAt(const std::string& param1) throw (jsonrpc::JsonRpcException)
+        {
+            Json::Value p;
+            p.append(param1);
+
+            Json::Value result = this->client->CallMethod("eth_balanceAt",p);
     if (result.isString())
         return result.asString();
      else 
@@ -70,12 +102,12 @@ p.append(param2);
 
         }
 
-        Json::Value blockByHash(const std::string& param1) throw (jsonrpc::JsonRpcException)
+        Json::Value eth_blockByHash(const std::string& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
 
-            Json::Value result = this->client->CallMethod("blockByHash",p);
+            Json::Value result = this->client->CallMethod("eth_blockByHash",p);
     if (result.isObject())
         return result;
      else 
@@ -83,12 +115,12 @@ p.append(param2);
 
         }
 
-        Json::Value blockByNumber(const int& param1) throw (jsonrpc::JsonRpcException)
+        Json::Value eth_blockByNumber(const int& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
 
-            Json::Value result = this->client->CallMethod("blockByNumber",p);
+            Json::Value result = this->client->CallMethod("eth_blockByNumber",p);
     if (result.isObject())
         return result;
      else 
@@ -96,12 +128,12 @@ p.append(param2);
 
         }
 
-        std::string call(const Json::Value& param1) throw (jsonrpc::JsonRpcException)
+        std::string eth_call(const Json::Value& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
 
-            Json::Value result = this->client->CallMethod("call",p);
+            Json::Value result = this->client->CallMethod("eth_call",p);
     if (result.isString())
         return result.asString();
      else 
@@ -109,12 +141,12 @@ p.append(param2);
 
         }
 
-        bool changed(const int& param1) throw (jsonrpc::JsonRpcException)
+        bool eth_changed(const int& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
 
-            Json::Value result = this->client->CallMethod("changed",p);
+            Json::Value result = this->client->CallMethod("eth_changed",p);
     if (result.isBool())
         return result.asBool();
      else 
@@ -122,12 +154,12 @@ p.append(param2);
 
         }
 
-        std::string codeAt(const std::string& param1) throw (jsonrpc::JsonRpcException)
+        std::string eth_codeAt(const std::string& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
 
-            Json::Value result = this->client->CallMethod("codeAt",p);
+            Json::Value result = this->client->CallMethod("eth_codeAt",p);
     if (result.isString())
         return result.asString();
      else 
@@ -135,11 +167,11 @@ p.append(param2);
 
         }
 
-        std::string coinbase() throw (jsonrpc::JsonRpcException)
+        std::string eth_coinbase() throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p = Json::nullValue;
-            Json::Value result = this->client->CallMethod("coinbase",p);
+            Json::Value result = this->client->CallMethod("eth_coinbase",p);
     if (result.isString())
         return result.asString();
      else 
@@ -147,12 +179,12 @@ p.append(param2);
 
         }
 
-        std::string compile(const std::string& param1) throw (jsonrpc::JsonRpcException)
+        std::string eth_compile(const std::string& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
 
-            Json::Value result = this->client->CallMethod("compile",p);
+            Json::Value result = this->client->CallMethod("eth_compile",p);
     if (result.isString())
         return result.asString();
      else 
@@ -160,12 +192,12 @@ p.append(param2);
 
         }
 
-        double countAt(const std::string& param1) throw (jsonrpc::JsonRpcException)
+        double eth_countAt(const std::string& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
 
-            Json::Value result = this->client->CallMethod("countAt",p);
+            Json::Value result = this->client->CallMethod("eth_countAt",p);
     if (result.isDouble())
         return result.asDouble();
      else 
@@ -173,11 +205,11 @@ p.append(param2);
 
         }
 
-        int defaultBlock() throw (jsonrpc::JsonRpcException)
+        int eth_defaultBlock() throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p = Json::nullValue;
-            Json::Value result = this->client->CallMethod("defaultBlock",p);
+            Json::Value result = this->client->CallMethod("eth_defaultBlock",p);
     if (result.isInt())
         return result.asInt();
      else 
@@ -185,11 +217,11 @@ p.append(param2);
 
         }
 
-        std::string gasPrice() throw (jsonrpc::JsonRpcException)
+        std::string eth_gasPrice() throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p = Json::nullValue;
-            Json::Value result = this->client->CallMethod("gasPrice",p);
+            Json::Value result = this->client->CallMethod("eth_gasPrice",p);
     if (result.isString())
         return result.asString();
      else 
@@ -197,26 +229,12 @@ p.append(param2);
 
         }
 
-        std::string get(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
+        Json::Value eth_getMessages(const int& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
-p.append(param2);
 
-            Json::Value result = this->client->CallMethod("get",p);
-    if (result.isString())
-        return result.asString();
-     else 
-         throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
-
-        }
-
-        Json::Value getMessages(const int& param1) throw (jsonrpc::JsonRpcException)
-        {
-            Json::Value p;
-            p.append(param1);
-
-            Json::Value result = this->client->CallMethod("getMessages",p);
+            Json::Value result = this->client->CallMethod("eth_getMessages",p);
     if (result.isArray())
         return result;
      else 
@@ -224,26 +242,11 @@ p.append(param2);
 
         }
 
-        std::string getString(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
-        {
-            Json::Value p;
-            p.append(param1);
-p.append(param2);
-
-            Json::Value result = this->client->CallMethod("getString",p);
-    if (result.isString())
-        return result.asString();
-     else 
-         throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
-
-        }
-
-        bool haveIdentity(const std::string& param1) throw (jsonrpc::JsonRpcException)
+        bool eth_listening() throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
-            p.append(param1);
-
-            Json::Value result = this->client->CallMethod("haveIdentity",p);
+            p = Json::nullValue;
+            Json::Value result = this->client->CallMethod("eth_listening",p);
     if (result.isBool())
         return result.asBool();
      else 
@@ -251,23 +254,24 @@ p.append(param2);
 
         }
 
-        bool listening() throw (jsonrpc::JsonRpcException)
+        std::string eth_lll(const std::string& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
-            p = Json::nullValue;
-            Json::Value result = this->client->CallMethod("listening",p);
-    if (result.isBool())
-        return result.asBool();
+            p.append(param1);
+
+            Json::Value result = this->client->CallMethod("eth_lll",p);
+    if (result.isString())
+        return result.asString();
      else 
          throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
 
         }
 
-        bool mining() throw (jsonrpc::JsonRpcException)
+        bool eth_mining() throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p = Json::nullValue;
-            Json::Value result = this->client->CallMethod("mining",p);
+            Json::Value result = this->client->CallMethod("eth_mining",p);
     if (result.isBool())
         return result.asBool();
      else 
@@ -275,12 +279,12 @@ p.append(param2);
 
         }
 
-        int newFilter(const Json::Value& param1) throw (jsonrpc::JsonRpcException)
+        int eth_newFilter(const Json::Value& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
 
-            Json::Value result = this->client->CallMethod("newFilter",p);
+            Json::Value result = this->client->CallMethod("eth_newFilter",p);
     if (result.isInt())
         return result.asInt();
      else 
@@ -288,12 +292,12 @@ p.append(param2);
 
         }
 
-        int newFilterString(const std::string& param1) throw (jsonrpc::JsonRpcException)
+        int eth_newFilterString(const std::string& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
 
-            Json::Value result = this->client->CallMethod("newFilterString",p);
+            Json::Value result = this->client->CallMethod("eth_newFilterString",p);
     if (result.isInt())
         return result.asInt();
      else 
@@ -301,37 +305,23 @@ p.append(param2);
 
         }
 
-        std::string newGroup(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
-        {
-            Json::Value p;
-            p.append(param1);
-p.append(param2);
-
-            Json::Value result = this->client->CallMethod("newGroup",p);
-    if (result.isString())
-        return result.asString();
-     else 
-         throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
-
-        }
-
-        std::string newIdentity() throw (jsonrpc::JsonRpcException)
+        int eth_number() throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p = Json::nullValue;
-            Json::Value result = this->client->CallMethod("newIdentity",p);
-    if (result.isString())
-        return result.asString();
+            Json::Value result = this->client->CallMethod("eth_number",p);
+    if (result.isInt())
+        return result.asInt();
      else 
          throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
 
         }
 
-        int number() throw (jsonrpc::JsonRpcException)
+        int eth_peerCount() throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p = Json::nullValue;
-            Json::Value result = this->client->CallMethod("number",p);
+            Json::Value result = this->client->CallMethod("eth_peerCount",p);
     if (result.isInt())
         return result.asInt();
      else 
@@ -339,24 +329,25 @@ p.append(param2);
 
         }
 
-        int peerCount() throw (jsonrpc::JsonRpcException)
+        bool eth_setCoinbase(const std::string& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
-            p = Json::nullValue;
-            Json::Value result = this->client->CallMethod("peerCount",p);
-    if (result.isInt())
-        return result.asInt();
+            p.append(param1);
+
+            Json::Value result = this->client->CallMethod("eth_setCoinbase",p);
+    if (result.isBool())
+        return result.asBool();
      else 
          throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
 
         }
 
-        bool post(const Json::Value& param1) throw (jsonrpc::JsonRpcException)
+        bool eth_setDefaultBlock(const int& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
 
-            Json::Value result = this->client->CallMethod("post",p);
+            Json::Value result = this->client->CallMethod("eth_setDefaultBlock",p);
     if (result.isBool())
         return result.asBool();
      else 
@@ -364,14 +355,12 @@ p.append(param2);
 
         }
 
-        bool put(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException)
+        bool eth_setListening(const bool& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
-p.append(param2);
-p.append(param3);
 
-            Json::Value result = this->client->CallMethod("put",p);
+            Json::Value result = this->client->CallMethod("eth_setListening",p);
     if (result.isBool())
         return result.asBool();
      else 
@@ -379,14 +368,12 @@ p.append(param3);
 
         }
 
-        bool putString(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException)
+        bool eth_setMining(const bool& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
-p.append(param2);
-p.append(param3);
 
-            Json::Value result = this->client->CallMethod("putString",p);
+            Json::Value result = this->client->CallMethod("eth_setMining",p);
     if (result.isBool())
         return result.asBool();
      else 
@@ -394,90 +381,95 @@ p.append(param3);
 
         }
 
-        bool setCoinbase(const std::string& param1) throw (jsonrpc::JsonRpcException)
+        std::string eth_stateAt(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
+p.append(param2);
 
-            Json::Value result = this->client->CallMethod("setCoinbase",p);
-    if (result.isBool())
-        return result.asBool();
+            Json::Value result = this->client->CallMethod("eth_stateAt",p);
+    if (result.isString())
+        return result.asString();
      else 
          throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
 
         }
 
-        bool setDefaultBlock(const int& param1) throw (jsonrpc::JsonRpcException)
+        std::string eth_transact(const Json::Value& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
 
-            Json::Value result = this->client->CallMethod("setDefaultBlock",p);
-    if (result.isBool())
-        return result.asBool();
+            Json::Value result = this->client->CallMethod("eth_transact",p);
+    if (result.isString())
+        return result.asString();
      else 
          throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
 
         }
 
-        bool setListening(const bool& param1) throw (jsonrpc::JsonRpcException)
+        Json::Value eth_transactionByHash(const std::string& param1, const int& param2) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
+p.append(param2);
 
-            Json::Value result = this->client->CallMethod("setListening",p);
-    if (result.isBool())
-        return result.asBool();
+            Json::Value result = this->client->CallMethod("eth_transactionByHash",p);
+    if (result.isObject())
+        return result;
      else 
          throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
 
         }
 
-        bool setMining(const bool& param1) throw (jsonrpc::JsonRpcException)
+        Json::Value eth_transactionByNumber(const int& param1, const int& param2) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
+p.append(param2);
 
-            Json::Value result = this->client->CallMethod("setMining",p);
-    if (result.isBool())
-        return result.asBool();
+            Json::Value result = this->client->CallMethod("eth_transactionByNumber",p);
+    if (result.isObject())
+        return result;
      else 
          throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
 
         }
 
-        Json::Value shhChanged(const int& param1) throw (jsonrpc::JsonRpcException)
+        Json::Value eth_uncleByHash(const std::string& param1, const int& param2) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
+p.append(param2);
 
-            Json::Value result = this->client->CallMethod("shhChanged",p);
-    if (result.isArray())
+            Json::Value result = this->client->CallMethod("eth_uncleByHash",p);
+    if (result.isObject())
         return result;
      else 
          throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
 
         }
 
-        int shhNewFilter(const Json::Value& param1) throw (jsonrpc::JsonRpcException)
+        Json::Value eth_uncleByNumber(const int& param1, const int& param2) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
+p.append(param2);
 
-            Json::Value result = this->client->CallMethod("shhNewFilter",p);
-    if (result.isInt())
-        return result.asInt();
+            Json::Value result = this->client->CallMethod("eth_uncleByNumber",p);
+    if (result.isObject())
+        return result;
      else 
          throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
 
         }
 
-        bool shhUninstallFilter(const int& param1) throw (jsonrpc::JsonRpcException)
+        bool eth_uninstallFilter(const int& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
 
-            Json::Value result = this->client->CallMethod("shhUninstallFilter",p);
+            Json::Value result = this->client->CallMethod("eth_uninstallFilter",p);
     if (result.isBool())
         return result.asBool();
      else 
@@ -485,13 +477,13 @@ p.append(param3);
 
         }
 
-        std::string stateAt(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
+        std::string shh_addToGroup(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
 p.append(param2);
 
-            Json::Value result = this->client->CallMethod("stateAt",p);
+            Json::Value result = this->client->CallMethod("shh_addToGroup",p);
     if (result.isString())
         return result.asString();
      else 
@@ -499,81 +491,90 @@ p.append(param2);
 
         }
 
-        std::string transact(const Json::Value& param1) throw (jsonrpc::JsonRpcException)
+        Json::Value shh_changed(const int& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
 
-            Json::Value result = this->client->CallMethod("transact",p);
-    if (result.isString())
-        return result.asString();
+            Json::Value result = this->client->CallMethod("shh_changed",p);
+    if (result.isArray())
+        return result;
      else 
          throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
 
         }
 
-        Json::Value transactionByHash(const std::string& param1, const int& param2) throw (jsonrpc::JsonRpcException)
+        bool shh_haveIdentity(const std::string& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
-p.append(param2);
 
-            Json::Value result = this->client->CallMethod("transactionByHash",p);
-    if (result.isObject())
-        return result;
+            Json::Value result = this->client->CallMethod("shh_haveIdentity",p);
+    if (result.isBool())
+        return result.asBool();
      else 
          throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
 
         }
 
-        Json::Value transactionByNumber(const int& param1, const int& param2) throw (jsonrpc::JsonRpcException)
+        int shh_newFilter(const Json::Value& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
-p.append(param2);
 
-            Json::Value result = this->client->CallMethod("transactionByNumber",p);
-    if (result.isObject())
-        return result;
+            Json::Value result = this->client->CallMethod("shh_newFilter",p);
+    if (result.isInt())
+        return result.asInt();
      else 
          throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
 
         }
 
-        Json::Value uncleByHash(const std::string& param1, const int& param2) throw (jsonrpc::JsonRpcException)
+        std::string shh_newGroup(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
 p.append(param2);
 
-            Json::Value result = this->client->CallMethod("uncleByHash",p);
-    if (result.isObject())
-        return result;
+            Json::Value result = this->client->CallMethod("shh_newGroup",p);
+    if (result.isString())
+        return result.asString();
+     else 
+         throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
+
+        }
+
+        std::string shh_newIdentity() throw (jsonrpc::JsonRpcException)
+        {
+            Json::Value p;
+            p = Json::nullValue;
+            Json::Value result = this->client->CallMethod("shh_newIdentity",p);
+    if (result.isString())
+        return result.asString();
      else 
          throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
 
         }
 
-        Json::Value uncleByNumber(const int& param1, const int& param2) throw (jsonrpc::JsonRpcException)
+        bool shh_post(const Json::Value& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
-p.append(param2);
 
-            Json::Value result = this->client->CallMethod("uncleByNumber",p);
-    if (result.isObject())
-        return result;
+            Json::Value result = this->client->CallMethod("shh_post",p);
+    if (result.isBool())
+        return result.asBool();
      else 
          throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString());
 
         }
 
-        bool uninstallFilter(const int& param1) throw (jsonrpc::JsonRpcException)
+        bool shh_uninstallFilter(const int& param1) throw (jsonrpc::JsonRpcException)
         {
             Json::Value p;
             p.append(param1);
 
-            Json::Value result = this->client->CallMethod("uninstallFilter",p);
+            Json::Value result = this->client->CallMethod("shh_uninstallFilter",p);
     if (result.isBool())
         return result.asBool();
      else 
diff --git a/test/whisperTopic.cpp b/test/whisperTopic.cpp
new file mode 100644
index 000000000..493b37bc2
--- /dev/null
+++ b/test/whisperTopic.cpp
@@ -0,0 +1,84 @@
+/*
+	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 .
+*/
+/** @file whisperTopic.cpp
+ * @author Gav Wood 
+ * @date 2014
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+using namespace std;
+using namespace dev;
+using namespace dev::p2p;
+using namespace dev::shh;
+
+BOOST_AUTO_TEST_SUITE(whisper)
+
+BOOST_AUTO_TEST_CASE(topic)
+{
+	g_logVerbosity = 0;
+
+	bool started = false;
+	unsigned result = 0;
+	std::thread listener([&]()
+	{
+		setThreadName("other");
+
+		Host ph("Test", NetworkPreferences(30303, "", false, true));
+		auto wh = ph.registerCapability(new WhisperHost());
+		ph.start();
+
+		started = true;
+
+		/// Only interested in odd packets
+		auto w = wh->installWatch(BuildTopicMask()("odd"));
+
+		for (int i = 0, last = 0; i < 100 && last < 81; ++i)
+		{
+			for (auto i: wh->checkWatch(w))
+			{
+				Message msg = wh->envelope(i).open();
+				last = RLP(msg.payload()).toInt();
+				cnote << "New message from:" << msg.from().abridged() << RLP(msg.payload()).toInt();
+				result += last;
+			}
+			this_thread::sleep_for(chrono::milliseconds(50));
+		}
+	});
+
+	while (!started)
+		this_thread::sleep_for(chrono::milliseconds(50));
+
+	Host ph("Test", NetworkPreferences(30300, "", false, true));
+	auto wh = ph.registerCapability(new WhisperHost());
+	ph.start();
+	ph.connect("127.0.0.1", 30303);
+
+	KeyPair us = KeyPair::create();
+	for (int i = 0; i < 10; ++i)
+	{
+		wh->post(us.sec(), RLPStream().append(i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even"));
+		this_thread::sleep_for(chrono::milliseconds(250));
+	}
+
+	listener.join();
+	BOOST_REQUIRE_EQUAL(result, 1 + 9 + 25 + 49 + 81);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/third/CMakeLists.txt b/third/CMakeLists.txt
index 6edea7456..d5371b666 100644
--- a/third/CMakeLists.txt
+++ b/third/CMakeLists.txt
@@ -53,7 +53,7 @@ else ()
 endif ()
 
 qt5_use_modules(${EXECUTEABLE} Core)# Gui Widgets Network WebKit WebKitWidgets)
-target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore secp256k1 gmp ${CRYPTOPP_LS} serpent lll evmface devcore web3jsonrpc jsqrc)
+target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore secp256k1 gmp ${CRYPTOPP_LS} serpent lll evmcore devcore web3jsonrpc jsqrc)
 
 if (APPLE)
 	# First have qt5 install plugins and frameworks
diff --git a/walleth/MainWin.cpp b/walleth/MainWin.cpp
index 3fa5a9388..f56cad65d 100644
--- a/walleth/MainWin.cpp
+++ b/walleth/MainWin.cpp
@@ -9,7 +9,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include "BuildInfo.h"
diff --git a/windows/LibEthereum.vcxproj b/windows/LibEthereum.vcxproj
index 9faae62c3..77b8f7e1a 100644
--- a/windows/LibEthereum.vcxproj
+++ b/windows/LibEthereum.vcxproj
@@ -125,7 +125,8 @@
     
     
     
-    
+    
+    
     
       true
       true
@@ -146,7 +147,6 @@
     
     
     
-    
     
     
     
@@ -342,7 +342,9 @@
     
     
     
-    
+    
+    
+    
     
       true
       true
@@ -369,7 +371,6 @@
     
     
     
-    
     
     
     
diff --git a/windows/LibEthereum.vcxproj.filters b/windows/LibEthereum.vcxproj.filters
index 5e1497b86..9d32fd9f6 100644
--- a/windows/LibEthereum.vcxproj.filters
+++ b/windows/LibEthereum.vcxproj.filters
@@ -37,11 +37,8 @@
     
       libevm
     
-    
-      libevmface
-    
-    
-      liblll
+    
+      libevmcore
     
     
       liblll
@@ -190,9 +187,6 @@
     
       libethcore
     
-    
-      libevm
-    
     
       libdevcrypto
     
@@ -205,6 +199,12 @@
     
       libethereum
     
+    
+      libevmcore
+    
+    
+      libevm
+    
   
   
     
@@ -246,15 +246,12 @@
     
       libevm
     
-    
-      libevmface
+    
+      libevmcore
     
     
       liblll
     
-    
-      liblll
-    
     
       liblll
     
@@ -426,9 +423,6 @@
     
       libwebthree
     
-    
-      libevm
-    
     
       libdevcrypto
     
@@ -441,6 +435,15 @@
     
       libethereum
     
+    
+      libevmcore
+    
+    
+      libevmcore
+    
+    
+      libevm
+    
   
   
     
@@ -455,7 +458,7 @@
     
       {37c37803-1515-47c1-b7e6-3879f4429ab3}
     
-    
+    
       {ed9ad1b3-700c-47f9-8548-a90b5ef179ac}