diff --git a/README.md b/README.md
index c54a555cb50e529323045bd152a565f9bf37f971..4830d9303248a1c953833ea4a2808aeacaafe434 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20develop%20
 
 Ethereum Go Client © 2014 Jeffrey Wilcke.
 
-Current state: Proof of Concept 0.7
+Current state: Proof of Concept 0.8
 
 Ethereum is currently in its testing phase. 
 
diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go
index 7efee31e78ba1ac765eeb16ecd5575c5c1c1f879..b238522820cecaf345a126bfed7ed71ce3cba4bd 100644
--- a/cmd/ethereum/main.go
+++ b/cmd/ethereum/main.go
@@ -25,13 +25,14 @@ import (
 
 	"github.com/ethereum/go-ethereum/cmd/utils"
 	"github.com/ethereum/go-ethereum/core/types"
+	"github.com/ethereum/go-ethereum/eth"
 	"github.com/ethereum/go-ethereum/ethutil"
 	"github.com/ethereum/go-ethereum/logger"
 )
 
 const (
 	ClientIdentifier = "Ethereum(G)"
-	Version          = "0.7.11"
+	Version          = "0.8.0"
 )
 
 var clilogger = logger.NewLogger("CLI")
@@ -48,35 +49,26 @@ func main() {
 	// precedence: code-internal flag default < config file < environment variables < command line
 	Init() // parsing command line
 
-	// If the difftool option is selected ignore all other log output
-	if DiffTool || Dump {
-		LogLevel = 0
-	}
-
 	utils.InitConfig(VmType, ConfigFile, Datadir, "ETH")
-	ethutil.Config.Diff = DiffTool
-	ethutil.Config.DiffType = DiffType
-
-	utils.InitDataDir(Datadir)
 
-	utils.InitLogging(Datadir, LogFile, LogLevel, DebugFile)
-
-	db := utils.NewDatabase()
-	err := utils.DBSanityCheck(db)
+	ethereum, err := eth.New(&eth.Config{
+		Name:       ClientIdentifier,
+		Version:    Version,
+		KeyStore:   KeyStore,
+		DataDir:    Datadir,
+		LogFile:    LogFile,
+		LogLevel:   LogLevel,
+		Identifier: Identifier,
+		MaxPeers:   MaxPeer,
+		Port:       OutboundPort,
+		NATType:    PMPGateway,
+		PMPGateway: PMPGateway,
+		KeyRing:    KeyRing,
+	})
 	if err != nil {
-		fmt.Println(err)
-
-		os.Exit(1)
+		clilogger.Fatalln(err)
 	}
-
-	keyManager := utils.NewKeyManager(KeyStore, Datadir, db)
-
-	// create, import, export keys
-	utils.KeyTasks(keyManager, KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive)
-
-	clientIdentity := utils.NewClientIdentity(ClientIdentifier, Version, Identifier, string(keyManager.PublicKey()))
-
-	ethereum := utils.NewEthereum(db, clientIdentity, keyManager, utils.NatType(NatType, PMPGateway), OutboundPort, MaxPeer)
+	utils.KeyTasks(ethereum.KeyManager(), KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive)
 
 	if Dump {
 		var block *types.Block
@@ -103,11 +95,7 @@ func main() {
 
 		fmt.Println(block)
 
-		os.Exit(0)
-	}
-
-	if ShowGenesis {
-		utils.ShowGenesis(ethereum)
+		return
 	}
 
 	if StartMining {
diff --git a/cmd/ethtest/LICENSE b/cmd/ethtest/LICENSE
deleted file mode 100644
index 0f187b873618b23c209f7b599d1c2907c0eaa6ea..0000000000000000000000000000000000000000
--- a/cmd/ethtest/LICENSE
+++ /dev/null
@@ -1,14 +0,0 @@
-This file is part of ethereum.js.
-
-ethereum.js is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-ethereum.js is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with ethereum.js.  If not, see <http://www.gnu.org/licenses/>.
\ No newline at end of file
diff --git a/cmd/ethtest/README.md b/cmd/ethtest/README.md
deleted file mode 100644
index 865b62c6b1a15e0b969d024abc5d69613abec935..0000000000000000000000000000000000000000
--- a/cmd/ethtest/README.md
+++ /dev/null
@@ -1,79 +0,0 @@
-# Ethereum JavaScript API
-
-This is the Ethereum compatible JavaScript API using `Promise`s
-which implements the [Generic JSON RPC](https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC) spec. It's available on npm as a node module and also for bower and component as an embeddable js
-
-[![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![dependency status][dep-image]][dep-url] [![dev dependency status][dep-dev-image]][dep-dev-url]
-
-<!-- [![browser support](https://ci.testling.com/ethereum/ethereum.js.png)](https://ci.testling.com/ethereum/ethereum.js) -->
-
-## Installation
-
-### Node.js
-
-    npm install ethereum.js
-
-### For browser
-Bower
-
-	bower install ethereum.js
-
-Component
-
-	component install ethereum/ethereum.js
-
-* Include `ethereum.min.js` in your html file.
-* Include [es6-promise](https://github.com/jakearchibald/es6-promise) or another ES6-Shim if your browser doesn't support ECMAScript 6.
-
-## Usage
-Require the library:
-
-	var web3 = require('web3');
-
-Set a provider (QtProvider, WebSocketProvider, HttpRpcProvider)
-
-	var web3.setProvider(new web3.providers.WebSocketProvider('ws://localhost:40404/eth'));
-
-There you go, now you can use it:
-
-```
-web3.eth.coinbase.then(function(result){
-  console.log(result);
-  return web3.eth.balanceAt(result);
-}).then(function(balance){
-  console.log(web3.toDecimal(balance));
-}).catch(function(err){
-  console.log(err);
-});
-```
-
-
-For another example see `example/index.html`.
-
-## Building
-
-* `gulp build`
-
-
-### Testing
-
-**Please note this repo is in it's early stage.**
-
-If you'd like to run a WebSocket ethereum node check out
-[go-ethereum](https://github.com/ethereum/go-ethereum).
-
-To install ethereum and spawn a node:
-
-```
-go get github.com/ethereum/go-ethereum/ethereum
-ethereum -ws -loglevel=4
-```
-
-[npm-image]: https://badge.fury.io/js/ethereum.js.png
-[npm-url]: https://npmjs.org/package/ethereum.js
-[travis-image]: https://travis-ci.org/ethereum/ethereum.js.svg
-[travis-url]: https://travis-ci.org/ethereum/ethereum.js
-[dep-image]: https://david-dm.org/ethereum/ethereum.js.svg
-[dep-url]: https://david-dm.org/ethereum/ethereum.js
-[dep-dev-image]: https://david-dm.org/ethereum/ethereum.js/dev-status.svg
-[dep-dev-url]: https://david-dm.org/ethereum/ethereum.js#info=devDependencies
\ No newline at end of file
diff --git a/cmd/ethtest/bower.json b/cmd/ethtest/bower.json
deleted file mode 100644
index cedae9023d44aaa240e4d9750dbe7244cc85a3a9..0000000000000000000000000000000000000000
--- a/cmd/ethtest/bower.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "ethereum.js",
-  "namespace": "ethereum",
-  "version": "0.0.3",
-  "description": "Ethereum Compatible JavaScript API",
-  "main": ["./dist/ethereum.js", "./dist/ethereum.min.js"],
-  "dependencies": {
-    "es6-promise": "#master"
-  },
-  "repository": {
-    "type": "git",
-    "url": "https://github.com/ethereum/ethereum.js.git"
-  },
-  "homepage": "https://github.com/ethereum/ethereum.js",
-  "bugs": {
-    "url": "https://github.com/ethereum/ethereum.js/issues"
-  },
-  "keywords": [
-    "ethereum",
-    "javascript",
-    "API"
-  ],
-  "authors": [
-    {
-      "name": "Marek Kotewicz",
-      "email": "marek@ethdev.com",
-      "homepage": "https://github.com/debris"
-    },
-    {
-      "name": "Marian Oancea",
-      "email": "marian@ethdev.com",
-      "homepage": "https://github.com/cubedro"
-    }
-  ],
-  "license": "LGPL-3.0",
-  "ignore": [
-    "example",
-    "lib",
-    "node_modules",
-    "package.json",
-    ".bowerrc",
-    ".editorconfig",
-    ".gitignore",
-    ".jshintrc",
-    ".npmignore",
-    ".travis.yml",
-    "gulpfile.js",
-    "index.js",
-    "**/*.txt"
-  ]
-}
\ No newline at end of file
diff --git a/cmd/ethtest/dist/ethereum.js b/cmd/ethtest/dist/ethereum.js
deleted file mode 100644
index b64c15b9e27bd832e04c3a1c88bdba80ad62499a..0000000000000000000000000000000000000000
--- a/cmd/ethtest/dist/ethereum.js
+++ /dev/null
@@ -1,20 +0,0 @@
-require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-var findIndex=function(array,callback){for(var end=!1,i=0;i<array.length&&!end;i++)end=callback(array[i]);return end?i-1:-1},findMethodIndex=function(json,methodName){return findIndex(json,function(method){return method.name===methodName})},padLeft=function(number,n){return new Array(2*n-number.toString().length+1).join("0")+number},setupInputTypes=function(){var prefixedType=function(prefix){return function(type,value){var padding,expected=prefix;return 0!==type.indexOf(expected)?!1:(padding=parseInt(type.slice(expected.length))/8,padLeft(value,padding))}},namedType=function(name,padding,formatter){return function(type,value){return type!==name?!1:padLeft(formatter?value:formatter(value),padding)}},formatBool=function(value){return value?"1":"0"};return[prefixedType("uint"),prefixedType("int"),namedType("address",20),namedType("bool",1,formatBool)]},inputTypes=setupInputTypes(),toAbiInput=function(json,methodName,params){var method,i,found,j,val,bytes="",index=findMethodIndex(json,methodName);if(-1!==index){for(bytes=bytes+index+"x0",method=json[index],i=0;i<method.inputs.length;i++){for(found=!1,j=0;j<inputTypes.length&&!found;j++)val=parseInt(params[i]).toString(16),found=inputTypes[j](method.inputs[i].type,val);found||console.error("unsupported json type: "+method.inputs[i].type),bytes+=found}return bytes}},setupOutputTypes=function(){var prefixedType=function(prefix){return function(type){var padding,expected=prefix;return 0!==type.indexOf(expected)?-1:(padding=parseInt(type.slice(expected.length))/8,2*padding)}},namedType=function(name,padding){return function(type){return name===type?2*padding:-1}},formatInt=function(value){return parseInt(value,16)},formatBool=function(value){return"1"===value?!0:!1};return[{padding:prefixedType("uint"),format:formatInt},{padding:prefixedType("int"),format:formatInt},{padding:namedType("address",20)},{padding:namedType("bool",1),format:formatBool}]},outputTypes=setupOutputTypes(),fromAbiOutput=function(json,methodName,output){var result,method,i,padding,j,res,formatter,index=findMethodIndex(json,methodName);if(-1!==index){for(output=output.slice(2),result=[],method=json[index],i=0;i<method.outputs.length;i++){for(padding=-1,j=0;j<outputTypes.length&&-1===padding;j++)padding=outputTypes[j].padding(method.outputs[i].type);-1!==padding&&(res=output.slice(0,padding),formatter=outputTypes[j-1].format,result.push(formatter?formatter(res):res),output=output.slice(padding))}return result}},inputParser=function(json){var parser={};return json.forEach(function(method){parser[method.name]=function(){var params=Array.prototype.slice.call(arguments);return toAbiInput(json,method.name,params)}}),parser},outputParser=function(json){var parser={};return json.forEach(function(method){parser[method.name]=function(output){return fromAbiOutput(json,method.name,output)}}),parser};module.exports={inputParser:inputParser,outputParser:outputParser};
-},{}],2:[function(require,module,exports){
-var AutoProvider=function(userOptions){var options,self,closeWithSuccess,ws;if(!web3.haveProvider()){if(this.sendQueue=[],this.onmessageQueue=[],navigator.qt)return void(this.provider=new web3.providers.QtProvider);userOptions=userOptions||{},options={httprpc:userOptions.httprpc||"http://localhost:8080",websockets:userOptions.websockets||"ws://localhost:40404/eth"},self=this,closeWithSuccess=function(success){ws.close(),success?self.provider=new web3.providers.WebSocketProvider(options.websockets):(self.provider=new web3.providers.HttpRpcProvider(options.httprpc),self.poll=self.provider.poll.bind(self.provider)),self.sendQueue.forEach(function(payload){self.provider(payload)}),self.onmessageQueue.forEach(function(handler){self.provider.onmessage=handler})},ws=new WebSocket(options.websockets),ws.onopen=function(){closeWithSuccess(!0)},ws.onerror=function(){closeWithSuccess(!1)}}};AutoProvider.prototype.send=function(payload){return this.provider?void this.provider.send(payload):void this.sendQueue.push(payload)},Object.defineProperty(AutoProvider.prototype,"onmessage",{set:function(handler){return this.provider?void(this.provider.onmessage=handler):void this.onmessageQueue.push(handler)}}),module.exports=AutoProvider;
-},{}],3:[function(require,module,exports){
-var abi,contract;abi=require("./abi"),contract=function(address,desc){var inputParser=abi.inputParser(desc),outputParser=abi.outputParser(desc),contract={};return desc.forEach(function(method){contract[method.name]=function(){var params=Array.prototype.slice.call(arguments),parsed=inputParser[method.name].apply(null,params),onSuccess=function(result){return outputParser[method.name](result)};return{call:function(extra){return extra=extra||{},extra.to=address,extra.data=parsed,web3.eth.call(extra).then(onSuccess)},transact:function(extra){return extra=extra||{},extra.to=address,extra.data=parsed,web3.eth.transact(extra).then(onSuccess)}}}}),contract},module.exports=contract;
-},{"./abi":1}],4:[function(require,module,exports){
-function formatJsonRpcObject(object){return{jsonrpc:"2.0",method:object.call,params:object.args,id:object._id}}function formatJsonRpcMessage(message){var object=JSON.parse(message);return{_id:object.id,data:object.result,error:object.error}}var HttpRpcProvider=function(host){this.handlers=[],this.host=host};HttpRpcProvider.prototype.sendRequest=function(payload,cb){var data=formatJsonRpcObject(payload),request=new XMLHttpRequest;request.open("POST",this.host,!0),request.send(JSON.stringify(data)),request.onreadystatechange=function(){4===request.readyState&&cb&&cb(request)}},HttpRpcProvider.prototype.send=function(payload){var self=this;this.sendRequest(payload,function(request){self.handlers.forEach(function(handler){handler.call(self,formatJsonRpcMessage(request.responseText))})})},HttpRpcProvider.prototype.poll=function(payload,id){var self=this;this.sendRequest(payload,function(request){var parsed=JSON.parse(request.responseText);!parsed.error&&(parsed.result instanceof Array?0!==parsed.result.length:parsed.result)&&self.handlers.forEach(function(handler){handler.call(self,{_event:payload.call,_id:id,data:parsed.result})})})},Object.defineProperty(HttpRpcProvider.prototype,"onmessage",{set:function(handler){this.handlers.push(handler)}}),module.exports=HttpRpcProvider;
-},{}],5:[function(require,module,exports){
-function flattenPromise(obj){return obj instanceof Promise?Promise.resolve(obj):obj instanceof Array?new Promise(function(resolve){var promises=obj.map(function(o){return flattenPromise(o)});return Promise.all(promises).then(function(res){for(var i=0;i<obj.length;i++)obj[i]=res[i];resolve(obj)})}):obj instanceof Object?new Promise(function(resolve){var keys=Object.keys(obj),promises=keys.map(function(key){return flattenPromise(obj[key])});return Promise.all(promises).then(function(res){for(var i=0;i<keys.length;i++)obj[keys[i]]=res[i];resolve(obj)})}):Promise.resolve(obj)}function messageHandler(data){if(void 0!==data._event)return void web3.trigger(data._event,data._id,data.data);if(data._id){var cb=web3._callbacks[data._id];cb&&(cb.call(this,data.error,data.data),delete web3._callbacks[data._id])}}var ethWatch,shhWatch,ProviderManager,Filter,ethMethods=function(){var blockCall=function(args){return"string"==typeof args[0]?"eth_blockByHash":"eth_blockByNumber"},transactionCall=function(args){return"string"==typeof args[0]?"eth_transactionByHash":"eth_transactionByNumber"},uncleCall=function(args){return"string"==typeof args[0]?"eth_uncleByHash":"eth_uncleByNumber"},methods=[{name:"balanceAt",call:"eth_balanceAt"},{name:"stateAt",call:"eth_stateAt"},{name:"storageAt",call:"eth_storageAt"},{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:"compilers",call:"eth_compilers"},{name:"lll",call:"eth_lll"},{name:"solidity",call:"eth_solidity"},{name:"serpent",call:"eth_serpent"},{name:"logs",call:"eth_logs"}];return methods},ethProperties=function(){return[{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"}]},dbMethods=function(){return[{name:"put",call:"db_put"},{name:"get",call:"db_get"},{name:"putString",call:"db_putString"},{name:"getString",call:"db_getString"}]},shhMethods=function(){return[{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"}]},ethWatchMethods=function(){var newFilter=function(args){return"string"==typeof args[0]?"eth_newFilterString":"eth_newFilter"};return[{name:"newFilter",call:newFilter},{name:"uninstallFilter",call:"eth_uninstallFilter"},{name:"getMessages",call:"eth_filterLogs"}]},shhWatchMethods=function(){return[{name:"newFilter",call:"shh_newFilter"},{name:"uninstallFilter",call:"shh_uninstallFilter"},{name:"getMessage",call:"shh_getMessages"}]},setupMethods=function(obj,methods){methods.forEach(function(method){obj[method.name]=function(){return flattenPromise(Array.prototype.slice.call(arguments)).then(function(args){var call="function"==typeof method.call?method.call(args):method.call;return{call:call,args:args}}).then(function(request){return new Promise(function(resolve,reject){web3.provider.send(request,function(err,result){return err?void reject(err):void resolve(result)})})}).catch(function(err){console.error(err)})}})},setupProperties=function(obj,properties){properties.forEach(function(property){var proto={};proto.get=function(){return new Promise(function(resolve,reject){web3.provider.send({call:property.getter},function(err,result){return err?void reject(err):void resolve(result)})})},property.setter&&(proto.set=function(val){return flattenPromise([val]).then(function(args){return new Promise(function(resolve){web3.provider.send({call:property.setter,args:args},function(err,result){return err?void reject(err):void resolve(result)})})}).catch(function(err){console.error(err)})}),Object.defineProperty(obj,property.name,proto)})},web3={_callbacks:{},_events:{},providers:{},toHex:function(str){var i,n,hex="";for(i=0;i<str.length;i++)n=str.charCodeAt(i).toString(16),hex+=n.length<2?"0"+n:n;return hex},toAscii:function(hex){var code,str="",i=0,l=hex.length;for("0x"===hex.substring(0,2)&&(i=2);l>i&&(code=hex.charCodeAt(i),0!==code);i+=2)str+=String.fromCharCode(parseInt(hex.substr(i,2),16));return str},toDecimal:function(val){return parseInt(val,16)},fromAscii:function(str,pad){pad=void 0===pad?32:pad;for(var hex=this.toHex(str);hex.length<2*pad;)hex+="00";return"0x"+hex},eth:{prototype:Object(),watch:function(params){return new Filter(params,ethWatch)}},db:{prototype:Object()},shh:{prototype:Object(),watch:function(params){return new Filter(params,shhWatch)}},on:function(event,id,cb){return void 0===web3._events[event]&&(web3._events[event]={}),web3._events[event][id]=cb,this},off:function(event,id){return void 0!==web3._events[event]&&delete web3._events[event][id],this},trigger:function(event,id,data){var cb,callbacks=web3._events[event];callbacks&&callbacks[id]&&(cb=callbacks[id])(data)}};setupMethods(web3.eth,ethMethods()),setupProperties(web3.eth,ethProperties()),setupMethods(web3.db,dbMethods()),setupMethods(web3.shh,shhMethods()),ethWatch={changed:"eth_changed"},setupMethods(ethWatch,ethWatchMethods()),shhWatch={changed:"shh_changed"},setupMethods(shhWatch,shhWatchMethods()),ProviderManager=function(){var self,poll;this.queued=[],this.polls=[],this.ready=!1,this.provider=void 0,this.id=1,self=this,(poll=function(){self.provider&&self.provider.poll&&self.polls.forEach(function(data){data.data._id=self.id,self.id++,self.provider.poll(data.data,data.id)}),setTimeout(poll,12e3)})()},ProviderManager.prototype.send=function(data,cb){data._id=this.id,cb&&(web3._callbacks[data._id]=cb),data.args=data.args||[],this.id++,void 0!==this.provider?this.provider.send(data):(console.warn("provider is not set"),this.queued.push(data))},ProviderManager.prototype.set=function(provider){void 0!==this.provider&&void 0!==this.provider.unload&&this.provider.unload(),this.provider=provider,this.ready=!0},ProviderManager.prototype.sendQueued=function(){for(var i=0;this.queued.length;i++)this.send(this.queued[i])},ProviderManager.prototype.installed=function(){return void 0!==this.provider},ProviderManager.prototype.startPolling=function(data,pollId){this.provider&&this.provider.poll&&this.polls.push({data:data,id:pollId})},ProviderManager.prototype.stopPolling=function(pollId){var i,poll;for(i=this.polls.length;i--;)poll=this.polls[i],poll.id===pollId&&this.polls.splice(i,1)},web3.provider=new ProviderManager,web3.setProvider=function(provider){provider.onmessage=messageHandler,web3.provider.set(provider),web3.provider.sendQueued()},web3.haveProvider=function(){return!!web3.provider.provider},Filter=function(options,impl){this.impl=impl,this.callbacks=[];var self=this;this.promise=impl.newFilter(options),this.promise.then(function(id){self.id=id,web3.on(impl.changed,id,self.trigger.bind(self)),web3.provider.startPolling({call:impl.changed,args:[id]},id)})},Filter.prototype.arrived=function(callback){this.changed(callback)},Filter.prototype.changed=function(callback){var self=this;this.promise.then(function(id){self.callbacks.push(callback)})},Filter.prototype.trigger=function(messages){for(var i=0;i<this.callbacks.length;i++)this.callbacks[i].call(this,messages)},Filter.prototype.uninstall=function(){var self=this;this.promise.then(function(id){self.impl.uninstallFilter(id),web3.provider.stopPolling(id),web3.off(impl.changed,id)})},Filter.prototype.messages=function(){var self=this;return this.promise.then(function(id){return self.impl.getMessages(id)})},Filter.prototype.logs=function(){return this.messages()},module.exports=web3;
-},{}],6:[function(require,module,exports){
-var QtProvider=function(){this.handlers=[];var self=this;navigator.qt.onmessage=function(message){self.handlers.forEach(function(handler){handler.call(self,JSON.parse(message.data))})}};QtProvider.prototype.send=function(payload){navigator.qt.postMessage(JSON.stringify(payload))},Object.defineProperty(QtProvider.prototype,"onmessage",{set:function(handler){this.handlers.push(handler)}}),module.exports=QtProvider;
-},{}],7:[function(require,module,exports){
-var WebSocketProvider=function(host){this.handlers=[],this.queued=[],this.ready=!1,this.ws=new WebSocket(host);var self=this;this.ws.onmessage=function(event){for(var i=0;i<self.handlers.length;i++)self.handlers[i].call(self,JSON.parse(event.data),event)},this.ws.onopen=function(){self.ready=!0;for(var i=0;i<self.queued.length;i++)self.send(self.queued[i])}};WebSocketProvider.prototype.send=function(payload){if(this.ready){var data=JSON.stringify(payload);this.ws.send(data)}else this.queued.push(payload)},WebSocketProvider.prototype.onMessage=function(handler){this.handlers.push(handler)},WebSocketProvider.prototype.unload=function(){this.ws.close()},Object.defineProperty(WebSocketProvider.prototype,"onmessage",{set:function(provider){this.onMessage(provider)}}),module.exports=WebSocketProvider;
-},{}],"web3":[function(require,module,exports){
-var web3=require("./lib/main");web3.providers.WebSocketProvider=require("./lib/websocket"),web3.providers.HttpRpcProvider=require("./lib/httprpc"),web3.providers.QtProvider=require("./lib/qt"),web3.providers.AutoProvider=require("./lib/autoprovider"),web3.contract=require("./lib/contract"),module.exports=web3;
-},{"./lib/autoprovider":2,"./lib/contract":3,"./lib/httprpc":4,"./lib/main":5,"./lib/qt":6,"./lib/websocket":7}]},{},[])
-
-
-//# sourceMappingURL=ethereum.js.map
\ No newline at end of file
diff --git a/cmd/ethtest/dist/ethereum.js.map b/cmd/ethtest/dist/ethereum.js.map
deleted file mode 100644
index b544cab530c1c7cc08b73d7667722f98bc90cf61..0000000000000000000000000000000000000000
--- a/cmd/ethtest/dist/ethereum.js.map
+++ /dev/null
@@ -1,29 +0,0 @@
-{
-  "version": 3,
-  "sources": [
-    "node_modules/browserify/node_modules/browser-pack/_prelude.js",
-    "lib/abi.js",
-    "lib/autoprovider.js",
-    "lib/contract.js",
-    "lib/httprpc.js",
-    "lib/main.js",
-    "lib/qt.js",
-    "lib/websocket.js",
-    "index.js"
-  ],
-  "names": [],
-  "mappings": "AAAA;ACAA;;ACAA;;ACAA;;ACAA;;ACAA;;ACAA;;ACAA;;ACAA",
-  "file": "generated.js",
-  "sourceRoot": "",
-  "sourcesContent": [
-    "(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})",
-    "var findIndex=function(array,callback){for(var end=!1,i=0;i<array.length&&!end;i++)end=callback(array[i]);return end?i-1:-1},findMethodIndex=function(json,methodName){return findIndex(json,function(method){return method.name===methodName})},padLeft=function(number,n){return new Array(2*n-number.toString().length+1).join(\"0\")+number},setupInputTypes=function(){var prefixedType=function(prefix){return function(type,value){var padding,expected=prefix;return 0!==type.indexOf(expected)?!1:(padding=parseInt(type.slice(expected.length))/8,padLeft(value,padding))}},namedType=function(name,padding,formatter){return function(type,value){return type!==name?!1:padLeft(formatter?value:formatter(value),padding)}},formatBool=function(value){return value?\"1\":\"0\"};return[prefixedType(\"uint\"),prefixedType(\"int\"),namedType(\"address\",20),namedType(\"bool\",1,formatBool)]},inputTypes=setupInputTypes(),toAbiInput=function(json,methodName,params){var method,i,found,j,val,bytes=\"\",index=findMethodIndex(json,methodName);if(-1!==index){for(bytes=bytes+index+\"x0\",method=json[index],i=0;i<method.inputs.length;i++){for(found=!1,j=0;j<inputTypes.length&&!found;j++)val=parseInt(params[i]).toString(16),found=inputTypes[j](method.inputs[i].type,val);found||console.error(\"unsupported json type: \"+method.inputs[i].type),bytes+=found}return bytes}},setupOutputTypes=function(){var prefixedType=function(prefix){return function(type){var padding,expected=prefix;return 0!==type.indexOf(expected)?-1:(padding=parseInt(type.slice(expected.length))/8,2*padding)}},namedType=function(name,padding){return function(type){return name===type?2*padding:-1}},formatInt=function(value){return parseInt(value,16)},formatBool=function(value){return\"1\"===value?!0:!1};return[{padding:prefixedType(\"uint\"),format:formatInt},{padding:prefixedType(\"int\"),format:formatInt},{padding:namedType(\"address\",20)},{padding:namedType(\"bool\",1),format:formatBool}]},outputTypes=setupOutputTypes(),fromAbiOutput=function(json,methodName,output){var result,method,i,padding,j,res,formatter,index=findMethodIndex(json,methodName);if(-1!==index){for(output=output.slice(2),result=[],method=json[index],i=0;i<method.outputs.length;i++){for(padding=-1,j=0;j<outputTypes.length&&-1===padding;j++)padding=outputTypes[j].padding(method.outputs[i].type);-1!==padding&&(res=output.slice(0,padding),formatter=outputTypes[j-1].format,result.push(formatter?formatter(res):res),output=output.slice(padding))}return result}},inputParser=function(json){var parser={};return json.forEach(function(method){parser[method.name]=function(){var params=Array.prototype.slice.call(arguments);return toAbiInput(json,method.name,params)}}),parser},outputParser=function(json){var parser={};return json.forEach(function(method){parser[method.name]=function(output){return fromAbiOutput(json,method.name,output)}}),parser};module.exports={inputParser:inputParser,outputParser:outputParser};",
-    "var AutoProvider=function(userOptions){var options,self,closeWithSuccess,ws;if(!web3.haveProvider()){if(this.sendQueue=[],this.onmessageQueue=[],navigator.qt)return void(this.provider=new web3.providers.QtProvider);userOptions=userOptions||{},options={httprpc:userOptions.httprpc||\"http://localhost:8080\",websockets:userOptions.websockets||\"ws://localhost:40404/eth\"},self=this,closeWithSuccess=function(success){ws.close(),success?self.provider=new web3.providers.WebSocketProvider(options.websockets):(self.provider=new web3.providers.HttpRpcProvider(options.httprpc),self.poll=self.provider.poll.bind(self.provider)),self.sendQueue.forEach(function(payload){self.provider(payload)}),self.onmessageQueue.forEach(function(handler){self.provider.onmessage=handler})},ws=new WebSocket(options.websockets),ws.onopen=function(){closeWithSuccess(!0)},ws.onerror=function(){closeWithSuccess(!1)}}};AutoProvider.prototype.send=function(payload){return this.provider?void this.provider.send(payload):void this.sendQueue.push(payload)},Object.defineProperty(AutoProvider.prototype,\"onmessage\",{set:function(handler){return this.provider?void(this.provider.onmessage=handler):void this.onmessageQueue.push(handler)}}),module.exports=AutoProvider;",
-    "var abi,contract;abi=require(\"./abi\"),contract=function(address,desc){var inputParser=abi.inputParser(desc),outputParser=abi.outputParser(desc),contract={};return desc.forEach(function(method){contract[method.name]=function(){var params=Array.prototype.slice.call(arguments),parsed=inputParser[method.name].apply(null,params),onSuccess=function(result){return outputParser[method.name](result)};return{call:function(extra){return extra=extra||{},extra.to=address,extra.data=parsed,web3.eth.call(extra).then(onSuccess)},transact:function(extra){return extra=extra||{},extra.to=address,extra.data=parsed,web3.eth.transact(extra).then(onSuccess)}}}}),contract},module.exports=contract;",
-    "function formatJsonRpcObject(object){return{jsonrpc:\"2.0\",method:object.call,params:object.args,id:object._id}}function formatJsonRpcMessage(message){var object=JSON.parse(message);return{_id:object.id,data:object.result,error:object.error}}var HttpRpcProvider=function(host){this.handlers=[],this.host=host};HttpRpcProvider.prototype.sendRequest=function(payload,cb){var data=formatJsonRpcObject(payload),request=new XMLHttpRequest;request.open(\"POST\",this.host,!0),request.send(JSON.stringify(data)),request.onreadystatechange=function(){4===request.readyState&&cb&&cb(request)}},HttpRpcProvider.prototype.send=function(payload){var self=this;this.sendRequest(payload,function(request){self.handlers.forEach(function(handler){handler.call(self,formatJsonRpcMessage(request.responseText))})})},HttpRpcProvider.prototype.poll=function(payload,id){var self=this;this.sendRequest(payload,function(request){var parsed=JSON.parse(request.responseText);!parsed.error&&(parsed.result instanceof Array?0!==parsed.result.length:parsed.result)&&self.handlers.forEach(function(handler){handler.call(self,{_event:payload.call,_id:id,data:parsed.result})})})},Object.defineProperty(HttpRpcProvider.prototype,\"onmessage\",{set:function(handler){this.handlers.push(handler)}}),module.exports=HttpRpcProvider;",
-    "function flattenPromise(obj){return obj instanceof Promise?Promise.resolve(obj):obj instanceof Array?new Promise(function(resolve){var promises=obj.map(function(o){return flattenPromise(o)});return Promise.all(promises).then(function(res){for(var i=0;i<obj.length;i++)obj[i]=res[i];resolve(obj)})}):obj instanceof Object?new Promise(function(resolve){var keys=Object.keys(obj),promises=keys.map(function(key){return flattenPromise(obj[key])});return Promise.all(promises).then(function(res){for(var i=0;i<keys.length;i++)obj[keys[i]]=res[i];resolve(obj)})}):Promise.resolve(obj)}function messageHandler(data){if(void 0!==data._event)return void web3.trigger(data._event,data._id,data.data);if(data._id){var cb=web3._callbacks[data._id];cb&&(cb.call(this,data.error,data.data),delete web3._callbacks[data._id])}}var ethWatch,shhWatch,ProviderManager,Filter,ethMethods=function(){var blockCall=function(args){return\"string\"==typeof args[0]?\"eth_blockByHash\":\"eth_blockByNumber\"},transactionCall=function(args){return\"string\"==typeof args[0]?\"eth_transactionByHash\":\"eth_transactionByNumber\"},uncleCall=function(args){return\"string\"==typeof args[0]?\"eth_uncleByHash\":\"eth_uncleByNumber\"},methods=[{name:\"balanceAt\",call:\"eth_balanceAt\"},{name:\"stateAt\",call:\"eth_stateAt\"},{name:\"storageAt\",call:\"eth_storageAt\"},{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:\"compilers\",call:\"eth_compilers\"},{name:\"lll\",call:\"eth_lll\"},{name:\"solidity\",call:\"eth_solidity\"},{name:\"serpent\",call:\"eth_serpent\"},{name:\"logs\",call:\"eth_logs\"}];return methods},ethProperties=function(){return[{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\"}]},dbMethods=function(){return[{name:\"put\",call:\"db_put\"},{name:\"get\",call:\"db_get\"},{name:\"putString\",call:\"db_putString\"},{name:\"getString\",call:\"db_getString\"}]},shhMethods=function(){return[{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\"}]},ethWatchMethods=function(){var newFilter=function(args){return\"string\"==typeof args[0]?\"eth_newFilterString\":\"eth_newFilter\"};return[{name:\"newFilter\",call:newFilter},{name:\"uninstallFilter\",call:\"eth_uninstallFilter\"},{name:\"getMessages\",call:\"eth_filterLogs\"}]},shhWatchMethods=function(){return[{name:\"newFilter\",call:\"shh_newFilter\"},{name:\"uninstallFilter\",call:\"shh_uninstallFilter\"},{name:\"getMessage\",call:\"shh_getMessages\"}]},setupMethods=function(obj,methods){methods.forEach(function(method){obj[method.name]=function(){return flattenPromise(Array.prototype.slice.call(arguments)).then(function(args){var call=\"function\"==typeof method.call?method.call(args):method.call;return{call:call,args:args}}).then(function(request){return new Promise(function(resolve,reject){web3.provider.send(request,function(err,result){return err?void reject(err):void resolve(result)})})}).catch(function(err){console.error(err)})}})},setupProperties=function(obj,properties){properties.forEach(function(property){var proto={};proto.get=function(){return new Promise(function(resolve,reject){web3.provider.send({call:property.getter},function(err,result){return err?void reject(err):void resolve(result)})})},property.setter&&(proto.set=function(val){return flattenPromise([val]).then(function(args){return new Promise(function(resolve){web3.provider.send({call:property.setter,args:args},function(err,result){return err?void reject(err):void resolve(result)})})}).catch(function(err){console.error(err)})}),Object.defineProperty(obj,property.name,proto)})},web3={_callbacks:{},_events:{},providers:{},toHex:function(str){var i,n,hex=\"\";for(i=0;i<str.length;i++)n=str.charCodeAt(i).toString(16),hex+=n.length<2?\"0\"+n:n;return hex},toAscii:function(hex){var code,str=\"\",i=0,l=hex.length;for(\"0x\"===hex.substring(0,2)&&(i=2);l>i&&(code=hex.charCodeAt(i),0!==code);i+=2)str+=String.fromCharCode(parseInt(hex.substr(i,2),16));return str},toDecimal:function(val){return parseInt(val,16)},fromAscii:function(str,pad){pad=void 0===pad?32:pad;for(var hex=this.toHex(str);hex.length<2*pad;)hex+=\"00\";return\"0x\"+hex},eth:{prototype:Object(),watch:function(params){return new Filter(params,ethWatch)}},db:{prototype:Object()},shh:{prototype:Object(),watch:function(params){return new Filter(params,shhWatch)}},on:function(event,id,cb){return void 0===web3._events[event]&&(web3._events[event]={}),web3._events[event][id]=cb,this},off:function(event,id){return void 0!==web3._events[event]&&delete web3._events[event][id],this},trigger:function(event,id,data){var cb,callbacks=web3._events[event];callbacks&&callbacks[id]&&(cb=callbacks[id])(data)}};setupMethods(web3.eth,ethMethods()),setupProperties(web3.eth,ethProperties()),setupMethods(web3.db,dbMethods()),setupMethods(web3.shh,shhMethods()),ethWatch={changed:\"eth_changed\"},setupMethods(ethWatch,ethWatchMethods()),shhWatch={changed:\"shh_changed\"},setupMethods(shhWatch,shhWatchMethods()),ProviderManager=function(){var self,poll;this.queued=[],this.polls=[],this.ready=!1,this.provider=void 0,this.id=1,self=this,(poll=function(){self.provider&&self.provider.poll&&self.polls.forEach(function(data){data.data._id=self.id,self.id++,self.provider.poll(data.data,data.id)}),setTimeout(poll,12e3)})()},ProviderManager.prototype.send=function(data,cb){data._id=this.id,cb&&(web3._callbacks[data._id]=cb),data.args=data.args||[],this.id++,void 0!==this.provider?this.provider.send(data):(console.warn(\"provider is not set\"),this.queued.push(data))},ProviderManager.prototype.set=function(provider){void 0!==this.provider&&void 0!==this.provider.unload&&this.provider.unload(),this.provider=provider,this.ready=!0},ProviderManager.prototype.sendQueued=function(){for(var i=0;this.queued.length;i++)this.send(this.queued[i])},ProviderManager.prototype.installed=function(){return void 0!==this.provider},ProviderManager.prototype.startPolling=function(data,pollId){this.provider&&this.provider.poll&&this.polls.push({data:data,id:pollId})},ProviderManager.prototype.stopPolling=function(pollId){var i,poll;for(i=this.polls.length;i--;)poll=this.polls[i],poll.id===pollId&&this.polls.splice(i,1)},web3.provider=new ProviderManager,web3.setProvider=function(provider){provider.onmessage=messageHandler,web3.provider.set(provider),web3.provider.sendQueued()},web3.haveProvider=function(){return!!web3.provider.provider},Filter=function(options,impl){this.impl=impl,this.callbacks=[];var self=this;this.promise=impl.newFilter(options),this.promise.then(function(id){self.id=id,web3.on(impl.changed,id,self.trigger.bind(self)),web3.provider.startPolling({call:impl.changed,args:[id]},id)})},Filter.prototype.arrived=function(callback){this.changed(callback)},Filter.prototype.changed=function(callback){var self=this;this.promise.then(function(id){self.callbacks.push(callback)})},Filter.prototype.trigger=function(messages){for(var i=0;i<this.callbacks.length;i++)this.callbacks[i].call(this,messages)},Filter.prototype.uninstall=function(){var self=this;this.promise.then(function(id){self.impl.uninstallFilter(id),web3.provider.stopPolling(id),web3.off(impl.changed,id)})},Filter.prototype.messages=function(){var self=this;return this.promise.then(function(id){return self.impl.getMessages(id)})},Filter.prototype.logs=function(){return this.messages()},module.exports=web3;",
-    "var QtProvider=function(){this.handlers=[];var self=this;navigator.qt.onmessage=function(message){self.handlers.forEach(function(handler){handler.call(self,JSON.parse(message.data))})}};QtProvider.prototype.send=function(payload){navigator.qt.postMessage(JSON.stringify(payload))},Object.defineProperty(QtProvider.prototype,\"onmessage\",{set:function(handler){this.handlers.push(handler)}}),module.exports=QtProvider;",
-    "var WebSocketProvider=function(host){this.handlers=[],this.queued=[],this.ready=!1,this.ws=new WebSocket(host);var self=this;this.ws.onmessage=function(event){for(var i=0;i<self.handlers.length;i++)self.handlers[i].call(self,JSON.parse(event.data),event)},this.ws.onopen=function(){self.ready=!0;for(var i=0;i<self.queued.length;i++)self.send(self.queued[i])}};WebSocketProvider.prototype.send=function(payload){if(this.ready){var data=JSON.stringify(payload);this.ws.send(data)}else this.queued.push(payload)},WebSocketProvider.prototype.onMessage=function(handler){this.handlers.push(handler)},WebSocketProvider.prototype.unload=function(){this.ws.close()},Object.defineProperty(WebSocketProvider.prototype,\"onmessage\",{set:function(provider){this.onMessage(provider)}}),module.exports=WebSocketProvider;",
-    "var web3=require(\"./lib/main\");web3.providers.WebSocketProvider=require(\"./lib/websocket\"),web3.providers.HttpRpcProvider=require(\"./lib/httprpc\"),web3.providers.QtProvider=require(\"./lib/qt\"),web3.providers.AutoProvider=require(\"./lib/autoprovider\"),web3.contract=require(\"./lib/contract\"),module.exports=web3;"
-  ]
-}
\ No newline at end of file
diff --git a/cmd/ethtest/dist/ethereum.min.js b/cmd/ethtest/dist/ethereum.min.js
deleted file mode 100644
index 38ce01aa846934cd9f259c9b5dc105dce1a3983a..0000000000000000000000000000000000000000
--- a/cmd/ethtest/dist/ethereum.min.js
+++ /dev/null
@@ -1 +0,0 @@
-require=function t(e,n,r){function o(s,a){if(!n[s]){if(!e[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[s]={exports:{}};e[s][0].call(l.exports,function(t){var n=e[s][1][t];return o(n?n:t)},l,l.exports,t,e,n,r)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;s<r.length;s++)o(r[s]);return o}({1:[function(t,e){var n=function(t,e){for(var n=!1,r=0;r<t.length&&!n;r++)n=e(t[r]);return n?r-1:-1},r=function(t,e){return n(t,function(t){return t.name===e})},o=function(t,e){return new Array(2*e-t.toString().length+1).join("0")+t},i=function(){var t=function(t){return function(e,n){var r,i=t;return 0!==e.indexOf(i)?!1:(r=parseInt(e.slice(i.length))/8,o(n,r))}},e=function(t,e,n){return function(r,i){return r!==t?!1:o(n?i:n(i),e)}},n=function(t){return t?"1":"0"};return[t("uint"),t("int"),e("address",20),e("bool",1,n)]},s=i(),a=function(t,e,n){var o,i,a,u,c,l="",h=r(t,e);if(-1!==h){for(l=l+h+"x0",o=t[h],i=0;i<o.inputs.length;i++){for(a=!1,u=0;u<s.length&&!a;u++)c=parseInt(n[i]).toString(16),a=s[u](o.inputs[i].type,c);a||console.error("unsupported json type: "+o.inputs[i].type),l+=a}return l}},u=function(){var t=function(t){return function(e){var n,r=t;return 0!==e.indexOf(r)?-1:(n=parseInt(e.slice(r.length))/8,2*n)}},e=function(t,e){return function(n){return t===n?2*e:-1}},n=function(t){return parseInt(t,16)},r=function(t){return"1"===t?!0:!1};return[{padding:t("uint"),format:n},{padding:t("int"),format:n},{padding:e("address",20)},{padding:e("bool",1),format:r}]},c=u(),l=function(t,e,n){var o,i,s,a,u,l,h,p=r(t,e);if(-1!==p){for(n=n.slice(2),o=[],i=t[p],s=0;s<i.outputs.length;s++){for(a=-1,u=0;u<c.length&&-1===a;u++)a=c[u].padding(i.outputs[s].type);-1!==a&&(l=n.slice(0,a),h=c[u-1].format,o.push(h?h(l):l),n=n.slice(a))}return o}},h=function(t){var e={};return t.forEach(function(n){e[n.name]=function(){var e=Array.prototype.slice.call(arguments);return a(t,n.name,e)}}),e},p=function(t){var e={};return t.forEach(function(n){e[n.name]=function(e){return l(t,n.name,e)}}),e};e.exports={inputParser:h,outputParser:p}},{}],2:[function(t,e){var n=function(t){var e,n,r,o;if(!web3.haveProvider()){if(this.sendQueue=[],this.onmessageQueue=[],navigator.qt)return void(this.provider=new web3.providers.QtProvider);t=t||{},e={httprpc:t.httprpc||"http://localhost:8080",websockets:t.websockets||"ws://localhost:40404/eth"},n=this,r=function(t){o.close(),t?n.provider=new web3.providers.WebSocketProvider(e.websockets):(n.provider=new web3.providers.HttpRpcProvider(e.httprpc),n.poll=n.provider.poll.bind(n.provider)),n.sendQueue.forEach(function(t){n.provider(t)}),n.onmessageQueue.forEach(function(t){n.provider.onmessage=t})},o=new WebSocket(e.websockets),o.onopen=function(){r(!0)},o.onerror=function(){r(!1)}}};n.prototype.send=function(t){return this.provider?void this.provider.send(t):void this.sendQueue.push(t)},Object.defineProperty(n.prototype,"onmessage",{set:function(t){return this.provider?void(this.provider.onmessage=t):void this.onmessageQueue.push(t)}}),e.exports=n},{}],3:[function(t,e){var n,r;n=t("./abi"),r=function(t,e){var r=n.inputParser(e),o=n.outputParser(e),i={};return e.forEach(function(e){i[e.name]=function(){var n=Array.prototype.slice.call(arguments),i=r[e.name].apply(null,n),s=function(t){return o[e.name](t)};return{call:function(e){return e=e||{},e.to=t,e.data=i,web3.eth.call(e).then(s)},transact:function(e){return e=e||{},e.to=t,e.data=i,web3.eth.transact(e).then(s)}}}}),i},e.exports=r},{"./abi":1}],4:[function(t,e){function n(t){return{jsonrpc:"2.0",method:t.call,params:t.args,id:t._id}}function r(t){var e=JSON.parse(t);return{_id:e.id,data:e.result,error:e.error}}var o=function(t){this.handlers=[],this.host=t};o.prototype.sendRequest=function(t,e){var r=n(t),o=new XMLHttpRequest;o.open("POST",this.host,!0),o.send(JSON.stringify(r)),o.onreadystatechange=function(){4===o.readyState&&e&&e(o)}},o.prototype.send=function(t){var e=this;this.sendRequest(t,function(t){e.handlers.forEach(function(n){n.call(e,r(t.responseText))})})},o.prototype.poll=function(t,e){var n=this;this.sendRequest(t,function(r){var o=JSON.parse(r.responseText);!o.error&&(o.result instanceof Array?0!==o.result.length:o.result)&&n.handlers.forEach(function(r){r.call(n,{_event:t.call,_id:e,data:o.result})})})},Object.defineProperty(o.prototype,"onmessage",{set:function(t){this.handlers.push(t)}}),e.exports=o},{}],5:[function(t,e){function n(t){return t instanceof Promise?Promise.resolve(t):t instanceof Array?new Promise(function(e){var r=t.map(function(t){return n(t)});return Promise.all(r).then(function(n){for(var r=0;r<t.length;r++)t[r]=n[r];e(t)})}):t instanceof Object?new Promise(function(e){var r=Object.keys(t),o=r.map(function(e){return n(t[e])});return Promise.all(o).then(function(n){for(var o=0;o<r.length;o++)t[r[o]]=n[o];e(t)})}):Promise.resolve(t)}function r(t){if(void 0!==t._event)return void g.trigger(t._event,t._id,t.data);if(t._id){var e=g._callbacks[t._id];e&&(e.call(this,t.error,t.data),delete g._callbacks[t._id])}}var o,i,s,a,u=function(){var t=function(t){return"string"==typeof t[0]?"eth_blockByHash":"eth_blockByNumber"},e=function(t){return"string"==typeof t[0]?"eth_transactionByHash":"eth_transactionByNumber"},n=function(t){return"string"==typeof t[0]?"eth_uncleByHash":"eth_uncleByNumber"},r=[{name:"balanceAt",call:"eth_balanceAt"},{name:"stateAt",call:"eth_stateAt"},{name:"storageAt",call:"eth_storageAt"},{name:"countAt",call:"eth_countAt"},{name:"codeAt",call:"eth_codeAt"},{name:"transact",call:"eth_transact"},{name:"call",call:"eth_call"},{name:"block",call:t},{name:"transaction",call:e},{name:"uncle",call:n},{name:"compilers",call:"eth_compilers"},{name:"lll",call:"eth_lll"},{name:"solidity",call:"eth_solidity"},{name:"serpent",call:"eth_serpent"},{name:"logs",call:"eth_logs"}];return r},c=function(){return[{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"}]},l=function(){return[{name:"put",call:"db_put"},{name:"get",call:"db_get"},{name:"putString",call:"db_putString"},{name:"getString",call:"db_getString"}]},h=function(){return[{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"}]},p=function(){var t=function(t){return"string"==typeof t[0]?"eth_newFilterString":"eth_newFilter"};return[{name:"newFilter",call:t},{name:"uninstallFilter",call:"eth_uninstallFilter"},{name:"getMessages",call:"eth_filterLogs"}]},d=function(){return[{name:"newFilter",call:"shh_newFilter"},{name:"uninstallFilter",call:"shh_uninstallFilter"},{name:"getMessage",call:"shh_getMessages"}]},f=function(t,e){e.forEach(function(e){t[e.name]=function(){return n(Array.prototype.slice.call(arguments)).then(function(t){var n="function"==typeof e.call?e.call(t):e.call;return{call:n,args:t}}).then(function(t){return new Promise(function(e,n){g.provider.send(t,function(t,r){return t?void n(t):void e(r)})})}).catch(function(t){console.error(t)})}})},v=function(t,e){e.forEach(function(e){var r={};r.get=function(){return new Promise(function(t,n){g.provider.send({call:e.getter},function(e,r){return e?void n(e):void t(r)})})},e.setter&&(r.set=function(t){return n([t]).then(function(t){return new Promise(function(n){g.provider.send({call:e.setter,args:t},function(t,e){return t?void reject(t):void n(e)})})}).catch(function(t){console.error(t)})}),Object.defineProperty(t,e.name,r)})},g={_callbacks:{},_events:{},providers:{},toHex:function(t){var e,n,r="";for(e=0;e<t.length;e++)n=t.charCodeAt(e).toString(16),r+=n.length<2?"0"+n:n;return r},toAscii:function(t){var e,n="",r=0,o=t.length;for("0x"===t.substring(0,2)&&(r=2);o>r&&(e=t.charCodeAt(r),0!==e);r+=2)n+=String.fromCharCode(parseInt(t.substr(r,2),16));return n},toDecimal:function(t){return parseInt(t,16)},fromAscii:function(t,e){e=void 0===e?32:e;for(var n=this.toHex(t);n.length<2*e;)n+="00";return"0x"+n},eth:{prototype:Object(),watch:function(t){return new a(t,o)}},db:{prototype:Object()},shh:{prototype:Object(),watch:function(t){return new a(t,i)}},on:function(t,e,n){return void 0===g._events[t]&&(g._events[t]={}),g._events[t][e]=n,this},off:function(t,e){return void 0!==g._events[t]&&delete g._events[t][e],this},trigger:function(t,e,n){var r,o=g._events[t];o&&o[e]&&(r=o[e])(n)}};f(g.eth,u()),v(g.eth,c()),f(g.db,l()),f(g.shh,h()),o={changed:"eth_changed"},f(o,p()),i={changed:"shh_changed"},f(i,d()),s=function(){var t,e;this.queued=[],this.polls=[],this.ready=!1,this.provider=void 0,this.id=1,t=this,(e=function(){t.provider&&t.provider.poll&&t.polls.forEach(function(e){e.data._id=t.id,t.id++,t.provider.poll(e.data,e.id)}),setTimeout(e,12e3)})()},s.prototype.send=function(t,e){t._id=this.id,e&&(g._callbacks[t._id]=e),t.args=t.args||[],this.id++,void 0!==this.provider?this.provider.send(t):(console.warn("provider is not set"),this.queued.push(t))},s.prototype.set=function(t){void 0!==this.provider&&void 0!==this.provider.unload&&this.provider.unload(),this.provider=t,this.ready=!0},s.prototype.sendQueued=function(){for(var t=0;this.queued.length;t++)this.send(this.queued[t])},s.prototype.installed=function(){return void 0!==this.provider},s.prototype.startPolling=function(t,e){this.provider&&this.provider.poll&&this.polls.push({data:t,id:e})},s.prototype.stopPolling=function(t){var e,n;for(e=this.polls.length;e--;)n=this.polls[e],n.id===t&&this.polls.splice(e,1)},g.provider=new s,g.setProvider=function(t){t.onmessage=r,g.provider.set(t),g.provider.sendQueued()},g.haveProvider=function(){return!!g.provider.provider},a=function(t,e){this.impl=e,this.callbacks=[];var n=this;this.promise=e.newFilter(t),this.promise.then(function(t){n.id=t,g.on(e.changed,t,n.trigger.bind(n)),g.provider.startPolling({call:e.changed,args:[t]},t)})},a.prototype.arrived=function(t){this.changed(t)},a.prototype.changed=function(t){var e=this;this.promise.then(function(){e.callbacks.push(t)})},a.prototype.trigger=function(t){for(var e=0;e<this.callbacks.length;e++)this.callbacks[e].call(this,t)},a.prototype.uninstall=function(){var t=this;this.promise.then(function(e){t.impl.uninstallFilter(e),g.provider.stopPolling(e),g.off(impl.changed,e)})},a.prototype.messages=function(){var t=this;return this.promise.then(function(e){return t.impl.getMessages(e)})},a.prototype.logs=function(){return this.messages()},e.exports=g},{}],6:[function(t,e){var n=function(){this.handlers=[];var t=this;navigator.qt.onmessage=function(e){t.handlers.forEach(function(n){n.call(t,JSON.parse(e.data))})}};n.prototype.send=function(t){navigator.qt.postMessage(JSON.stringify(t))},Object.defineProperty(n.prototype,"onmessage",{set:function(t){this.handlers.push(t)}}),e.exports=n},{}],7:[function(t,e){var n=function(t){this.handlers=[],this.queued=[],this.ready=!1,this.ws=new WebSocket(t);var e=this;this.ws.onmessage=function(t){for(var n=0;n<e.handlers.length;n++)e.handlers[n].call(e,JSON.parse(t.data),t)},this.ws.onopen=function(){e.ready=!0;for(var t=0;t<e.queued.length;t++)e.send(e.queued[t])}};n.prototype.send=function(t){if(this.ready){var e=JSON.stringify(t);this.ws.send(e)}else this.queued.push(t)},n.prototype.onMessage=function(t){this.handlers.push(t)},n.prototype.unload=function(){this.ws.close()},Object.defineProperty(n.prototype,"onmessage",{set:function(t){this.onMessage(t)}}),e.exports=n},{}],web3:[function(t,e){var n=t("./lib/main");n.providers.WebSocketProvider=t("./lib/websocket"),n.providers.HttpRpcProvider=t("./lib/httprpc"),n.providers.QtProvider=t("./lib/qt"),n.providers.AutoProvider=t("./lib/autoprovider"),n.contract=t("./lib/contract"),e.exports=n},{"./lib/autoprovider":2,"./lib/contract":3,"./lib/httprpc":4,"./lib/main":5,"./lib/qt":6,"./lib/websocket":7}]},{},[]);
\ No newline at end of file
diff --git a/cmd/ethtest/example/contract.html b/cmd/ethtest/example/contract.html
deleted file mode 100644
index 44f0b03a1986317f232cdb8e0b90d567fb166e16..0000000000000000000000000000000000000000
--- a/cmd/ethtest/example/contract.html
+++ /dev/null
@@ -1,75 +0,0 @@
-<!doctype>
-<html>
-
-<head>
-<script type="text/javascript" src="js/es6-promise/promise.min.js"></script>
-<script type="text/javascript" src="../dist/ethereum.js"></script>
-<script type="text/javascript">
-
-    var web3 = require('web3');
-    web3.setProvider(new web3.providers.AutoProvider());
-
-    // solidity source code
-    var source = "" + 
-    "contract test {\n" +
-    "   function multiply(uint a) returns(uint d) {\n" +
-    "       return a * 7;\n" +
-    "   }\n" +
-    "}\n";
-
-    // contract description, this will be autogenerated somehow
-    var desc =  [{
-        "name": "multiply",
-        "inputs": [
-        {
-            "name": "a",
-            "type": "uint256"
-        }
-        ],
-        "outputs": [
-        {
-            "name": "d",
-            "type": "uint256"
-        }
-        ]
-    }];
-
-    var contract;
-
-    function createExampleContract() {
-        // hide create button
-        document.getElementById('create').style.visibility = 'hidden'; 
-        document.getElementById('source').innerText = source;
-
-        // create contract
-        web3.eth.transact({code: web3.eth.solidity(source)}).then(function (address) {
-            contract = web3.contract(address, desc);
-            document.getElementById('call').style.visibility = 'visible';
-        });
-    }
-
-    function callExampleContract() {
-        // this should be generated by ethereum
-        var param = document.getElementById('value').value;
-
-        // call the contract
-        contract.multiply(param).call().then(function(res) {
-            document.getElementById('result').innerText = res[0];
-        });
-    }
-
-</script>
-</head>
-<body>
-    <h1>contract</h1>
-    <div id="source"></div> 
-    <div id='create'>
-        <button type="button" onClick="createExampleContract();">create example contract</button>
-    </div>
-    <div id='call' style='visibility: hidden;'>
-        <input type="number" id="value" onkeyup='callExampleContract()'></input>
-    </div>
-    <div id="result"></div>
-</body>
-</html>
-
diff --git a/cmd/ethtest/example/index.html b/cmd/ethtest/example/index.html
deleted file mode 100644
index d0bf094ef2f23156d9580cb6a4098c44c9242704..0000000000000000000000000000000000000000
--- a/cmd/ethtest/example/index.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!doctype>
-<html>
-
-<head>
-<script type="text/javascript" src="js/es6-promise/promise.min.js"></script>
-<script type="text/javascript" src="../dist/ethereum.js"></script>
-<script type="text/javascript">
-   
-    var web3 = require('web3');
-    web3.setProvider(new web3.providers.AutoProvider());
-
-    function watchBalance() {
-        var coinbase = web3.eth.coinbase;
-        var originalBalance = 0;
-
-        web3.eth.balanceAt(coinbase).then(function (balance) {
-            originalBalance = web3.toDecimal(balance);
-            document.getElementById('original').innerText = 'original balance: ' + originalBalance + '    watching...';
-        });
-
-        web3.eth.watch({altered: coinbase}).changed(function() {
-            web3.eth.balanceAt(coinbase).then(function (balance) {
-                var currentBalance = web3.toDecimal(balance);
-                document.getElementById("current").innerText = 'current: ' + currentBalance;
-                document.getElementById("diff").innerText = 'diff:    ' + (currentBalance - originalBalance);
-            });
-        });
-    }
-
-</script>
-</head>
-<body>
-    <h1>coinbase balance</h1>
-    <button type="button" onClick="watchBalance();">watch balance</button>
-    <div></div>
-    <div id="original"></div>
-    <div id="current"></div>
-    <div id="diff"></div>
-</body>
-</html>
-
diff --git a/cmd/ethtest/example/node-app.js b/cmd/ethtest/example/node-app.js
deleted file mode 100644
index f63fa9115ff439525848a38f54eca94b41076adb..0000000000000000000000000000000000000000
--- a/cmd/ethtest/example/node-app.js
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env node
-
-require('es6-promise').polyfill();
-
-var web3 = require("../index.js");
-
-web3.setProvider(new web3.providers.HttpRpcProvider('http://localhost:8080'));
-
-web3.eth.coinbase.then(function(result){
-  console.log(result);
-  return web3.eth.balanceAt(result);
-}).then(function(balance){
-  console.log(web3.toDecimal(balance));
-}).catch(function(err){
-  console.log(err);
-});
\ No newline at end of file
diff --git a/cmd/ethtest/gulpfile.js b/cmd/ethtest/gulpfile.js
deleted file mode 100644
index 9e0717d8b123992b82ce4b9ebfd813669f0fbac2..0000000000000000000000000000000000000000
--- a/cmd/ethtest/gulpfile.js
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/usr/bin/env node
-
-'use strict';
-
-var path = require('path');
-
-var del = require('del');
-var gulp = require('gulp');
-var browserify = require('browserify');
-var jshint = require('gulp-jshint');
-var uglify = require('gulp-uglify');
-var rename = require('gulp-rename');
-var envify = require('envify/custom');
-var unreach = require('unreachable-branch-transform');
-var source = require('vinyl-source-stream');
-var exorcist = require('exorcist');
-var bower = require('bower');
-
-var DEST = './dist/';
-
-var build = function(src, dst) {
-  return browserify({
-      debug: true,
-      insert_global_vars: false,
-      detectGlobals: false,
-      bundleExternal: false
-    })
-    .require('./' + src + '.js', {expose: 'web3'})
-    .add('./' + src + '.js')
-    .transform('envify', {
-      NODE_ENV: 'build'
-    })
-    .transform('unreachable-branch-transform')
-    .transform('uglifyify', {
-      mangle: false,
-      compress: {
-        dead_code: false,
-        conditionals: true,
-        unused: false,
-        hoist_funs: true,
-        hoist_vars: true,
-        negate_iife: false
-      },
-      beautify: true,
-      warnings: true
-    })
-    .bundle()
-    .pipe(exorcist(path.join( DEST, dst + '.js.map')))
-    .pipe(source(dst + '.js'))
-    .pipe(gulp.dest( DEST ));
-};
-
-var buildDev = function(src, dst) {
-  return browserify({
-      debug: true,
-      insert_global_vars: false,
-      detectGlobals: false,
-      bundleExternal: false
-    })
-    .require('./' + src + '.js', {expose: 'web3'})
-    .add('./' + src + '.js')
-    .transform('envify', {
-      NODE_ENV: 'build'
-    })
-    .transform('unreachable-branch-transform')
-    .bundle()
-    .pipe(exorcist(path.join( DEST, dst + '.js.map')))
-    .pipe(source(dst + '.js'))
-    .pipe(gulp.dest( DEST ));
-};
-
-var uglifyFile = function(file) {
-  return gulp.src( DEST + file + '.js')
-    .pipe(uglify())
-    .pipe(rename(file + '.min.js'))
-    .pipe(gulp.dest( DEST ));
-};
-
-gulp.task('bower', function(cb){
-  bower.commands.install().on('end', function (installed){
-    console.log(installed);
-    cb();
-  });
-});
-
-gulp.task('lint', function(){
-  return gulp.src(['./*.js', './lib/*.js'])
-    .pipe(jshint())
-    .pipe(jshint.reporter('default'));
-});
-
-gulp.task('clean', ['lint'], function(cb) {
-  del([ DEST ], cb);
-});
-
-gulp.task('build', ['clean'], function () {
-    return build('index', 'ethereum');
-});
-
-gulp.task('buildQt', ['clean'], function () {
-    return build('index_qt', 'ethereum');
-});
-
-gulp.task('buildDev', ['clean'], function () {
-    return buildDev('index', 'ethereum');
-});
-
-gulp.task('uglify', ['build'], function(){
-    return uglifyFile('ethereum');
-});
-
-gulp.task('uglifyQt', ['buildQt'], function () {
-    return uglifyFile('ethereum');
-});
-
-gulp.task('watch', function() {
-  gulp.watch(['./lib/*.js'], ['lint', 'prepare', 'build']);
-});
-
-gulp.task('default', ['bower', 'lint', 'build', 'uglify']);
-gulp.task('qt', ['bower', 'lint', 'buildQt', 'uglifyQt']);
-gulp.task('dev', ['bower', 'lint', 'buildDev']);
-
diff --git a/cmd/ethtest/index.js b/cmd/ethtest/index.js
deleted file mode 100644
index c2de7e735e116903c0cbb97ba7f0ae45ef5d70b6..0000000000000000000000000000000000000000
--- a/cmd/ethtest/index.js
+++ /dev/null
@@ -1,8 +0,0 @@
-var web3 = require('./lib/main');
-web3.providers.WebSocketProvider = require('./lib/websocket');
-web3.providers.HttpRpcProvider = require('./lib/httprpc');
-web3.providers.QtProvider = require('./lib/qt');
-web3.providers.AutoProvider = require('./lib/autoprovider');
-web3.contract = require('./lib/contract');
-
-module.exports = web3;
diff --git a/cmd/ethtest/index_qt.js b/cmd/ethtest/index_qt.js
deleted file mode 100644
index d5e47597e49ba87b4632a647a1eea43ca6656f37..0000000000000000000000000000000000000000
--- a/cmd/ethtest/index_qt.js
+++ /dev/null
@@ -1,5 +0,0 @@
-var web3 = require('./lib/main');
-web3.providers.QtProvider = require('./lib/qt');
-web3.contract = require('./lib/contract');
-
-module.exports = web3;
diff --git a/cmd/ethtest/lib/abi.js b/cmd/ethtest/lib/abi.js
deleted file mode 100644
index 2cff503d3840d6fe599fac86d3cfac600acc8e34..0000000000000000000000000000000000000000
--- a/cmd/ethtest/lib/abi.js
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
-    This file is part of ethereum.js.
-
-    ethereum.js is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    ethereum.js is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public License
-    along with ethereum.js.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file abi.js
- * @authors:
- *   Marek Kotewicz <marek@ethdev.com>
- *   Gav Wood <g@ethdev.com>
- * @date 2014
- */
-
-// TODO: make these be actually accurate instead of falling back onto JS's doubles.
-var hexToDec = function (hex) {
-    return parseInt(hex, 16).toString();
-};
-
-var decToHex = function (dec) {
-    return parseInt(dec).toString(16);
-};
-
-var findIndex = function (array, callback) {
-    var end = false;
-    var i = 0;
-    for (; i < array.length && !end; i++) {
-        end = callback(array[i]);
-    }
-    return end ? i - 1 : -1;
-};
-
-var findMethodIndex = function (json, methodName) {
-    return findIndex(json, function (method) {
-        return method.name === methodName;
-    });
-};
-
-var padLeft = function (string, chars) {
-    return Array(chars - string.length + 1).join("0") + string;
-};
-
-var setupInputTypes = function () {
-    var prefixedType = function (prefix) {
-        return function (type, value) {
-            var expected = prefix;
-            if (type.indexOf(expected) !== 0) {
-                return false;
-            }
-
-            var padding = parseInt(type.slice(expected.length)) / 8;
-            if (typeof value === "number")
-                value = value.toString(16);
-            else if (value.indexOf('0x') === 0)
-                value = value.substr(2);
-            else
-                value = (+value).toString(16);
-            return padLeft(value, padding * 2);
-        };
-    };
-
-    var namedType = function (name, padding, formatter) {
-        return function (type, value) {
-            if (type !== name) {
-                return false;
-            }
-
-            return padLeft(formatter ? formatter(value) : value, padding * 2);
-        };
-    };
-
-    var formatBool = function (value) {
-        return value ? '0x1' : '0x0';
-    };
-
-    return [
-        prefixedType('uint'),
-        prefixedType('int'),
-        prefixedType('hash'),
-        namedType('address', 20),
-        namedType('bool', 1, formatBool),
-    ];
-};
-
-var inputTypes = setupInputTypes();
-
-var toAbiInput = function (json, methodName, params) {
-    var bytes = "";
-    var index = findMethodIndex(json, methodName);
-
-    if (index === -1) {
-        return;
-    }
-
-    bytes = "0x" + padLeft(index.toString(16), 2);
-    var method = json[index];
-
-    for (var i = 0; i < method.inputs.length; i++) {
-        var found = false;
-        for (var j = 0; j < inputTypes.length && !found; j++) {
-            found = inputTypes[j](method.inputs[i].type, params[i]);
-        }
-        if (!found) {
-            console.error('unsupported json type: ' + method.inputs[i].type);
-        }
-        bytes += found;
-    }
-    return bytes;
-};
-
-var setupOutputTypes = function () {
-    var prefixedType = function (prefix) {
-        return function (type) {
-            var expected = prefix;
-            if (type.indexOf(expected) !== 0) {
-                return -1;
-            }
-
-            var padding = parseInt(type.slice(expected.length)) / 8;
-            return padding * 2;
-        };
-    };
-
-    var namedType = function (name, padding) {
-        return function (type) {
-            return name === type ? padding * 2 : -1;
-        };
-    };
-
-    var formatInt = function (value) {
-        return value.length <= 8 ? +parseInt(value, 16) : hexToDec(value);
-    };
-
-    var formatHash = function (value) {
-        return "0x" + value;
-    };
-
-    var formatBool = function (value) {
-        return value === '1' ? true : false;
-    };
-
-    return [
-    { padding: prefixedType('uint'), format: formatInt },
-    { padding: prefixedType('int'), format: formatInt },
-    { padding: prefixedType('hash'), format: formatHash },
-    { padding: namedType('address', 20) },
-    { padding: namedType('bool', 1), format: formatBool }
-    ];
-};
-
-var outputTypes = setupOutputTypes();
-
-var fromAbiOutput = function (json, methodName, output) {
-    var index = findMethodIndex(json, methodName);
-
-    if (index === -1) {
-        return;
-    }
-
-    output = output.slice(2);
-
-    var result = [];
-    var method = json[index];
-    for (var i = 0; i < method.outputs.length; i++) {
-        var padding = -1;
-        for (var j = 0; j < outputTypes.length && padding === -1; j++) {
-            padding = outputTypes[j].padding(method.outputs[i].type);
-        }
-
-        if (padding === -1) {
-            // not found output parsing
-            continue;
-        }
-        var res = output.slice(0, padding);
-        var formatter = outputTypes[j - 1].format;
-        result.push(formatter ? formatter(res) : ("0x" + res));
-        output = output.slice(padding);
-    }
-
-    return result;
-};
-
-var inputParser = function (json) {
-    var parser = {};
-    json.forEach(function (method) {
-        parser[method.name] = function () {
-            var params = Array.prototype.slice.call(arguments);
-            return toAbiInput(json, method.name, params);
-        };
-    });
-
-    return parser;
-};
-
-var outputParser = function (json) {
-    var parser = {};
-    json.forEach(function (method) {
-        parser[method.name] = function (output) {
-            return fromAbiOutput(json, method.name, output);
-        };
-    });
-
-    return parser;
-};
-
-module.exports = {
-    inputParser: inputParser,
-    outputParser: outputParser
-};
diff --git a/cmd/ethtest/lib/autoprovider.js b/cmd/ethtest/lib/autoprovider.js
deleted file mode 100644
index bfbc3ab6e1ef3d983f0f7c12c400d0ddb4d67a4e..0000000000000000000000000000000000000000
--- a/cmd/ethtest/lib/autoprovider.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-    This file is part of ethereum.js.
-
-    ethereum.js is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    ethereum.js is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public License
-    along with ethereum.js.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file autoprovider.js
- * @authors:
- *   Marek Kotewicz <marek@ethdev.com>
- *   Marian Oancea <marian@ethdev.com>
- * @date 2014
- */
-
-/*
- * @brief if qt object is available, uses QtProvider,
- * if not tries to connect over websockets
- * if it fails, it uses HttpRpcProvider
- */
-
-// TODO: work out which of the following two lines it is supposed to be...
-//if (process.env.NODE_ENV !== 'build') {
-if ("build" !== 'build') {/*
-    var WebSocket = require('ws'); // jshint ignore:line
-    var web3 = require('./main.js'); // jshint ignore:line
-*/}
-
-var AutoProvider = function (userOptions) {
-    if (web3.haveProvider()) {
-        return;
-    }
-
-    // before we determine what provider we are, we have to cache request
-    this.sendQueue = [];
-    this.onmessageQueue = [];
-
-    if (navigator.qt) {
-        this.provider = new web3.providers.QtProvider();
-        return;
-    }
-
-    userOptions = userOptions || {};
-    var options = {
-        httprpc: userOptions.httprpc || 'http://localhost:8080',
-        websockets: userOptions.websockets || 'ws://localhost:40404/eth'
-    };
-
-    var self = this;
-    var closeWithSuccess = function (success) {
-        ws.close();
-        if (success) {
-            self.provider = new web3.providers.WebSocketProvider(options.websockets);
-        } else {
-            self.provider = new web3.providers.HttpRpcProvider(options.httprpc);
-            self.poll = self.provider.poll.bind(self.provider);
-        }
-        self.sendQueue.forEach(function (payload) {
-            self.provider(payload);
-        });
-        self.onmessageQueue.forEach(function (handler) {
-            self.provider.onmessage = handler;
-        });
-    };
-
-    var ws = new WebSocket(options.websockets);
-
-    ws.onopen = function() {
-        closeWithSuccess(true);
-    };
-
-    ws.onerror = function() {
-        closeWithSuccess(false);
-    };
-};
-
-AutoProvider.prototype.send = function (payload) {
-    if (this.provider) {
-        this.provider.send(payload);
-        return;
-    }
-    this.sendQueue.push(payload);
-};
-
-Object.defineProperty(AutoProvider.prototype, 'onmessage', {
-    set: function (handler) {
-        if (this.provider) {
-            this.provider.onmessage = handler;
-            return;
-        }
-        this.onmessageQueue.push(handler);
-    }
-});
-
-module.exports = AutoProvider;
diff --git a/cmd/ethtest/lib/contract.js b/cmd/ethtest/lib/contract.js
deleted file mode 100644
index 17b077484bae50237848aa5754de35eef07a7c34..0000000000000000000000000000000000000000
--- a/cmd/ethtest/lib/contract.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-    This file is part of ethereum.js.
-
-    ethereum.js is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    ethereum.js is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public License
-    along with ethereum.js.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file contract.js
- * @authors:
- *   Marek Kotewicz <marek@ethdev.com>
- * @date 2014
- */
-
-// TODO: work out which of the following two lines it is supposed to be...
-//if (process.env.NODE_ENV !== 'build') {
-if ("build" !== 'build') {/*
-    var web3 = require('./web3'); // jshint ignore:line
-*/}
-var abi = require('./abi');
-
-var contract = function (address, desc) {
-    var inputParser = abi.inputParser(desc);
-    var outputParser = abi.outputParser(desc);
-
-    var contract = {};
-
-    desc.forEach(function (method) {
-        contract[method.name] = function () {
-            var params = Array.prototype.slice.call(arguments);
-            var parsed = inputParser[method.name].apply(null, params);
-
-            var onSuccess = function (result) {
-                return outputParser[method.name](result);
-            };
-
-            return {
-                call: function (extra) {
-                    extra = extra || {};
-                    extra.to = address;
-                    extra.data = parsed;
-                    return web3.eth.call(extra).then(onSuccess);
-                },
-                transact: function (extra) {
-                    extra = extra || {};
-                    extra.to = address;
-                    extra.data = parsed;
-                    return web3.eth.transact(extra).then(onSuccess);
-                }
-            };
-        };
-    });
-
-    return contract;
-};
-
-module.exports = contract;
diff --git a/cmd/ethtest/lib/httprpc.js b/cmd/ethtest/lib/httprpc.js
deleted file mode 100644
index ee6b5c30705f3391a91b64f1450f4a9b50fb71dc..0000000000000000000000000000000000000000
--- a/cmd/ethtest/lib/httprpc.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-    This file is part of ethereum.js.
-
-    ethereum.js is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    ethereum.js is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public License
-    along with ethereum.js.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file httprpc.js
- * @authors:
- *   Marek Kotewicz <marek@ethdev.com>
- *   Marian Oancea <marian@ethdev.com>
- * @date 2014
- */
-
-// TODO: work out which of the following two lines it is supposed to be...
-//if (process.env.NODE_ENV !== 'build') {
-if ("build" !== "build") {/*
-    var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line
-*/}
-
-var HttpRpcProvider = function (host) {
-    this.handlers = [];
-    this.host = host;
-};
-
-function formatJsonRpcObject(object) {
-    return {
-        jsonrpc: '2.0',
-        method: object.call,
-        params: object.args,
-        id: object._id
-    };
-}
-
-function formatJsonRpcMessage(message) {
-    var object = JSON.parse(message);
-
-    return {
-        _id: object.id,
-        data: object.result,
-        error: object.error
-    };
-}
-
-HttpRpcProvider.prototype.sendRequest = function (payload, cb) {
-    var data = formatJsonRpcObject(payload);
-
-    var request = new XMLHttpRequest();
-    request.open("POST", this.host, true);
-    request.send(JSON.stringify(data));
-    request.onreadystatechange = function () {
-        if (request.readyState === 4 && cb) {
-            cb(request);
-        }
-    };
-};
-
-HttpRpcProvider.prototype.send = function (payload) {
-    var self = this;
-    this.sendRequest(payload, function (request) {
-        self.handlers.forEach(function (handler) {
-            handler.call(self, formatJsonRpcMessage(request.responseText));
-        });
-    });
-};
-
-HttpRpcProvider.prototype.poll = function (payload, id) {
-    var self = this;
-    this.sendRequest(payload, function (request) {
-        var parsed = JSON.parse(request.responseText);
-        if (parsed.error || (parsed.result instanceof Array ? parsed.result.length === 0 : !parsed.result)) {
-            return;
-        }
-        self.handlers.forEach(function (handler) {
-            handler.call(self, {_event: payload.call, _id: id, data: parsed.result});
-        });
-    });
-};
-
-Object.defineProperty(HttpRpcProvider.prototype, "onmessage", {
-    set: function (handler) {
-        this.handlers.push(handler);
-    }
-});
-
-module.exports = HttpRpcProvider;
diff --git a/cmd/ethtest/lib/main.js b/cmd/ethtest/lib/main.js
deleted file mode 100644
index 59c60cfa816cec77ba05d75ce32cd2f9ea342491..0000000000000000000000000000000000000000
--- a/cmd/ethtest/lib/main.js
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
-    This file is part of ethereum.js.
-
-    ethereum.js is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    ethereum.js is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public License
-    along with ethereum.js.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file main.js
- * @authors:
- *   Jeffrey Wilcke <jeff@ethdev.com>
- *   Marek Kotewicz <marek@ethdev.com>
- *   Marian Oancea <marian@ethdev.com>
- *   Gav Wood <g@ethdev.com>
- * @date 2014
- */
-
-function flattenPromise (obj) {
-    if (obj instanceof Promise) {
-        return Promise.resolve(obj);
-    }
-
-    if (obj instanceof Array) {
-        return new Promise(function (resolve) {
-            var promises = obj.map(function (o) {
-                return flattenPromise(o);
-            });
-
-            return Promise.all(promises).then(function (res) {
-                for (var i = 0; i < obj.length; i++) {
-                    obj[i] = res[i];
-                }
-                resolve(obj);
-            });
-        });
-    }
-
-    if (obj instanceof Object) {
-        return new Promise(function (resolve) {
-            var keys = Object.keys(obj);
-            var promises = keys.map(function (key) {
-                return flattenPromise(obj[key]);
-            });
-
-            return Promise.all(promises).then(function (res) {
-                for (var i = 0; i < keys.length; i++) {
-                    obj[keys[i]] = res[i];
-                }
-                resolve(obj);
-            });
-        });
-    }
-
-    return Promise.resolve(obj);
-}
-
-var web3Methods = function () {
-    return [
-    { name: 'sha3', call: 'web3_sha3' }
-    ];
-};
-
-var ethMethods = function () {
-    var blockCall = function (args) {
-        return typeof args[0] === "string" ? "eth_blockByHash" : "eth_blockByNumber";
-    };
-
-    var transactionCall = function (args) {
-        return typeof args[0] === "string" ? 'eth_transactionByHash' : 'eth_transactionByNumber';
-    };
-
-    var uncleCall = function (args) {
-        return typeof args[0] === "string" ? 'eth_uncleByHash' : 'eth_uncleByNumber';
-    };
-
-    var methods = [
-    { name: 'balanceAt', call: 'eth_balanceAt' },
-    { name: 'stateAt', call: 'eth_stateAt' },
-    { name: 'storageAt', call: 'eth_storageAt' },
-    { 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: 'compilers', call: 'eth_compilers' },
-    { name: 'lll', call: 'eth_lll' },
-    { name: 'solidity', call: 'eth_solidity' },
-    { name: 'serpent', call: 'eth_serpent' },
-    { name: 'logs', call: 'eth_logs' }
-    ];
-    return methods;
-};
-
-var ethProperties = function () {
-    return [
-    { 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: 'db_put' },
-    { name: 'get', call: 'db_get' },
-    { name: 'putString', call: 'db_putString' },
-    { name: 'getString', call: 'db_getString' }
-    ];
-};
-
-var shhMethods = function () {
-    return [
-    { 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' ? 'eth_newFilterString' : 'eth_newFilter';
-    };
-
-    return [
-    { name: 'newFilter', call: newFilter },
-    { name: 'uninstallFilter', call: 'eth_uninstallFilter' },
-    { name: 'getMessages', call: 'eth_filterLogs' }
-    ];
-};
-
-var shhWatchMethods = function () {
-    return [
-    { name: 'newFilter', call: 'shh_newFilter' },
-    { name: 'uninstallFilter', call: 'shh_uninstallFilter' },
-    { name: 'getMessage', call: 'shh_getMessages' }
-    ];
-};
-
-var setupMethods = function (obj, methods) {
-    methods.forEach(function (method) {
-        obj[method.name] = function () {
-            return flattenPromise(Array.prototype.slice.call(arguments)).then(function (args) {
-                var call = typeof method.call === "function" ? method.call(args) : method.call;
-                return {call: call, args: args};
-            }).then(function (request) {
-                return new Promise(function (resolve, reject) {
-                    web3.provider.send(request, function (err, result) {
-                        if (!err) {
-                            resolve(result);
-                            return;
-                        }
-                        reject(err);
-                    });
-                });
-            }).catch(function(err) {
-                console.error(err);
-            });
-        };
-    });
-};
-
-var setupProperties = function (obj, properties) {
-    properties.forEach(function (property) {
-        var proto = {};
-        proto.get = function () {
-            return new Promise(function(resolve, reject) {
-                web3.provider.send({call: property.getter}, function(err, result) {
-                    if (!err) {
-                        resolve(result);
-                        return;
-                    }
-                    reject(err);
-                });
-            });
-        };
-        if (property.setter) {
-            proto.set = function (val) {
-                return flattenPromise([val]).then(function (args) {
-                    return new Promise(function (resolve) {
-                        web3.provider.send({call: property.setter, args: args}, function (err, result) {
-                            if (!err) {
-                                resolve(result);
-                                return;
-                            }
-                            reject(err);
-                        });
-                    });
-                }).catch(function (err) {
-                    console.error(err);
-                });
-            };
-        }
-        Object.defineProperty(obj, property.name, proto);
-    });
-};
-
-// TODO: import from a dependency, don't duplicate.
-var hexToDec = function (hex) {
-    return parseInt(hex, 16).toString();
-};
-
-var decToHex = function (dec) {
-    return parseInt(dec).toString(16);
-};
-
-
-var web3 = {
-    _callbacks: {},
-    _events: {},
-    providers: {},
-
-    toAscii: function(hex) {
-        // Find termination
-        var str = "";
-        var i = 0, l = hex.length;
-        if (hex.substring(0, 2) === '0x')
-            i = 2;
-        for(; i < l; i+=2) {
-            var code = hex.charCodeAt(i);
-            if(code === 0) {
-                break;
-            }
-
-            str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
-        }
-
-        return str;
-    },
-
-    fromAscii: function(str, pad) {
-        pad = pad === undefined ? 32 : pad;
-        var hex = this.toHex(str);
-        while(hex.length < pad*2)
-            hex += "00";
-        return "0x" + hex;
-    },
-
-    toDecimal: function (val) {
-        return hexToDec(val.substring(2));
-    },
-
-    fromDecimal: function (val) {
-        return "0x" + decToHex(val);
-    },
-
-    toEth: function(str) {
-        var val = typeof str === "string" ? str.indexOf('0x') == 0 ? parseInt(str.substr(2), 16) : parseInt(str) : str;
-        var unit = 0;
-        var units = [ 'wei', 'Kwei', 'Mwei', 'Gwei', 'szabo', 'finney', 'ether', 'grand', 'Mether', 'Gether', 'Tether', 'Pether', 'Eether', 'Zether', 'Yether', 'Nether', 'Dether', 'Vether', 'Uether' ];
-        while (val > 3000 && unit < units.length - 1)
-        {
-            val /= 1000;
-            unit++;
-        }
-        var s = val.toString().length < val.toFixed(2).length ? val.toString() : val.toFixed(2);
-        while (true) {
-            var o = s;
-            s = s.replace(/(\d)(\d\d\d[\.\,])/, function($0, $1, $2) { return $1 + ',' + $2; });
-            if (o == s)
-                break;
-        }
-        return s + ' ' + units[unit];
-    },
-
-    eth: {
-        prototype: Object(), // jshint ignore:line
-        watch: function (params) {
-            return new Filter(params, ethWatch);
-        }
-    },
-
-    db: {
-        prototype: Object() // jshint ignore:line
-    },
-
-    shh: {
-        prototype: Object(), // jshint ignore:line
-        watch: function (params) {
-            return new Filter(params, shhWatch);
-        }
-    },
-
-    on: function(event, id, cb) {
-        if(web3._events[event] === undefined) {
-            web3._events[event] = {};
-        }
-
-        web3._events[event][id] = cb;
-        return this;
-    },
-
-    off: function(event, id) {
-        if(web3._events[event] !== undefined) {
-            delete web3._events[event][id];
-        }
-
-        return this;
-    },
-
-    trigger: function(event, id, data) {
-        var callbacks = web3._events[event];
-        if (!callbacks || !callbacks[id]) {
-            return;
-        }
-        var cb = callbacks[id];
-        cb(data);
-    }
-};
-
-setupMethods(web3, web3Methods());
-setupMethods(web3.eth, ethMethods());
-setupProperties(web3.eth, ethProperties());
-setupMethods(web3.db, dbMethods());
-setupMethods(web3.shh, shhMethods());
-
-var ethWatch = {
-    changed: 'eth_changed'
-};
-setupMethods(ethWatch, ethWatchMethods());
-var shhWatch = {
-    changed: 'shh_changed'
-};
-setupMethods(shhWatch, shhWatchMethods());
-
-var ProviderManager = function() {
-    this.queued = [];
-    this.polls = [];
-    this.ready = false;
-    this.provider = undefined;
-    this.id = 1;
-
-    var self = this;
-    var poll = function () {
-        if (self.provider && self.provider.poll) {
-            self.polls.forEach(function (data) {
-                data.data._id = self.id;
-                self.id++;
-                self.provider.poll(data.data, data.id);
-            });
-        }
-        setTimeout(poll, 12000);
-    };
-    poll();
-};
-
-ProviderManager.prototype.send = function(data, cb) {
-    data._id = this.id;
-    if (cb) {
-        web3._callbacks[data._id] = cb;
-    }
-
-    data.args = data.args || [];
-    this.id++;
-
-    if(this.provider !== undefined) {
-        this.provider.send(data);
-    } else {
-        console.warn("provider is not set");
-        this.queued.push(data);
-    }
-};
-
-ProviderManager.prototype.set = function(provider) {
-    if(this.provider !== undefined && this.provider.unload !== undefined) {
-        this.provider.unload();
-    }
-
-    this.provider = provider;
-    this.ready = true;
-};
-
-ProviderManager.prototype.sendQueued = function() {
-    for(var i = 0; this.queued.length; i++) {
-        // Resend
-        this.send(this.queued[i]);
-    }
-};
-
-ProviderManager.prototype.installed = function() {
-    return this.provider !== undefined;
-};
-
-ProviderManager.prototype.startPolling = function (data, pollId) {
-    if (!this.provider || !this.provider.poll) {
-        return;
-    }
-    this.polls.push({data: data, id: pollId});
-};
-
-ProviderManager.prototype.stopPolling = function (pollId) {
-    for (var i = this.polls.length; i--;) {
-        var poll = this.polls[i];
-        if (poll.id === pollId) {
-            this.polls.splice(i, 1);
-        }
-    }
-};
-
-web3.provider = new ProviderManager();
-
-web3.setProvider = function(provider) {
-    provider.onmessage = messageHandler;
-    web3.provider.set(provider);
-    web3.provider.sendQueued();
-};
-
-web3.haveProvider = function() {
-    return !!web3.provider.provider;
-};
-
-var Filter = function(options, impl) {
-    this.impl = impl;
-    this.callbacks = [];
-
-    var self = this;
-    this.promise = impl.newFilter(options);
-    this.promise.then(function (id) {
-        self.id = id;
-        web3.on(impl.changed, id, self.trigger.bind(self));
-        web3.provider.startPolling({call: impl.changed, args: [id]}, id);
-    });
-};
-
-Filter.prototype.arrived = function(callback) {
-    this.changed(callback);
-};
-
-Filter.prototype.changed = function(callback) {
-    var self = this;
-    this.promise.then(function(id) {
-        self.callbacks.push(callback);
-    });
-};
-
-Filter.prototype.trigger = function(messages) {
-    for(var i = 0; i < this.callbacks.length; i++) {
-        this.callbacks[i].call(this, messages);
-    }
-};
-
-Filter.prototype.uninstall = function() {
-    var self = this;
-    this.promise.then(function (id) {
-        self.impl.uninstallFilter(id);
-        web3.provider.stopPolling(id);
-        web3.off(impl.changed, id);
-    });
-};
-
-Filter.prototype.messages = function() {
-    var self = this;
-    return this.promise.then(function (id) {
-        return self.impl.getMessages(id);
-    });
-};
-
-Filter.prototype.logs = function () {
-    return this.messages();
-};
-
-function messageHandler(data) {
-    if(data._event !== undefined) {
-        web3.trigger(data._event, data._id, data.data);
-        return;
-    }
-
-    if(data._id) {
-        var cb = web3._callbacks[data._id];
-        if (cb) {
-            cb.call(this, data.error, data.data);
-            delete web3._callbacks[data._id];
-        }
-    }
-}
-
-module.exports = web3;
diff --git a/cmd/ethtest/lib/qt.js b/cmd/ethtest/lib/qt.js
deleted file mode 100644
index f022395476e4fbc7d84e367eac35934915e07f49..0000000000000000000000000000000000000000
--- a/cmd/ethtest/lib/qt.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-    This file is part of ethereum.js.
-
-    ethereum.js is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    ethereum.js is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public License
-    along with ethereum.js.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file qt.js
- * @authors:
- *   Jeffrey Wilcke <jeff@ethdev.com>
- *   Marek Kotewicz <marek@ethdev.com>
- * @date 2014
- */
-
-var QtProvider = function() {
-    this.handlers = [];
-
-    var self = this;
-    navigator.qt.onmessage = function (message) {
-        self.handlers.forEach(function (handler) {
-            handler.call(self, JSON.parse(message.data));
-        });
-    };
-};
-
-QtProvider.prototype.send = function(payload) {
-    navigator.qt.postMessage(JSON.stringify(payload));
-};
-
-Object.defineProperty(QtProvider.prototype, "onmessage", {
-    set: function(handler) {
-        this.handlers.push(handler);
-    }
-});
-
-module.exports = QtProvider;
diff --git a/cmd/ethtest/lib/websocket.js b/cmd/ethtest/lib/websocket.js
deleted file mode 100644
index 24a0725313fb4811e4ebcb00938bcc6025aabf33..0000000000000000000000000000000000000000
--- a/cmd/ethtest/lib/websocket.js
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
-    This file is part of ethereum.js.
-
-    ethereum.js is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    ethereum.js is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public License
-    along with ethereum.js.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file websocket.js
- * @authors:
- *   Jeffrey Wilcke <jeff@ethdev.com>
- *   Marek Kotewicz <marek@ethdev.com>
- *   Marian Oancea <marian@ethdev.com>
- * @date 2014
- */
-
-// TODO: work out which of the following two lines it is supposed to be...
-//if (process.env.NODE_ENV !== 'build') {
-if ("build" !== "build") {/*
-    var WebSocket = require('ws'); // jshint ignore:line
-*/}
-
-var WebSocketProvider = function(host) {
-    // onmessage handlers
-    this.handlers = [];
-    // queue will be filled with messages if send is invoked before the ws is ready
-    this.queued = [];
-    this.ready = false;
-
-    this.ws = new WebSocket(host);
-
-    var self = this;
-    this.ws.onmessage = function(event) {
-        for(var i = 0; i < self.handlers.length; i++) {
-            self.handlers[i].call(self, JSON.parse(event.data), event);
-        }
-    };
-
-    this.ws.onopen = function() {
-        self.ready = true;
-
-        for(var i = 0; i < self.queued.length; i++) {
-            // Resend
-            self.send(self.queued[i]);
-        }
-    };
-};
-
-WebSocketProvider.prototype.send = function(payload) {
-    if(this.ready) {
-        var data = JSON.stringify(payload);
-
-        this.ws.send(data);
-    } else {
-        this.queued.push(payload);
-    }
-};
-
-WebSocketProvider.prototype.onMessage = function(handler) {
-    this.handlers.push(handler);
-};
-
-WebSocketProvider.prototype.unload = function() {
-    this.ws.close();
-};
-Object.defineProperty(WebSocketProvider.prototype, "onmessage", {
-    set: function(provider) { this.onMessage(provider); }
-});
-
-module.exports = WebSocketProvider;
diff --git a/cmd/ethtest/package.json b/cmd/ethtest/package.json
deleted file mode 100644
index 24141ea2e40d5a9c24a4810cae4ea32e59fa53bb..0000000000000000000000000000000000000000
--- a/cmd/ethtest/package.json
+++ /dev/null
@@ -1,67 +0,0 @@
-{
-  "name": "ethereum.js",
-  "namespace": "ethereum",
-  "version": "0.0.5",
-  "description": "Ethereum Compatible JavaScript API",
-  "main": "./index.js",
-  "directories": {
-    "lib": "./lib"
-  },
-  "dependencies": {
-    "es6-promise": "*",
-    "ws": "*",
-    "xmlhttprequest": "*"
-  },
-  "devDependencies": {
-    "bower": ">=1.3.0",
-    "browserify": ">=6.0",
-    "del": ">=0.1.1",
-    "envify": "^3.0.0",
-    "exorcist": "^0.1.6",
-    "gulp": ">=3.4.0",
-    "gulp-jshint": ">=1.5.0",
-    "gulp-rename": ">=1.2.0",
-    "gulp-uglify": ">=1.0.0",
-    "jshint": ">=2.5.0",
-    "uglifyify": "^2.6.0",
-    "unreachable-branch-transform": "^0.1.0",
-    "vinyl-source-stream": "^1.0.0"
-  },
-  "scripts": {
-    "build": "gulp",
-    "watch": "gulp watch",
-    "lint": "gulp lint"
-  },
-  "repository": {
-    "type": "git",
-    "url": "https://github.com/ethereum/ethereum.js.git"
-  },
-  "homepage": "https://github.com/ethereum/ethereum.js",
-  "bugs": {
-    "url": "https://github.com/ethereum/ethereum.js/issues"
-  },
-  "keywords": [
-    "ethereum",
-    "javascript",
-    "API"
-  ],
-  "author": "ethdev.com",
-  "authors": [
-    {
-      "name": "Jeffery Wilcke",
-      "email": "jeff@ethdev.com",
-      "url": "https://github.com/obscuren"
-    },
-    {
-      "name": "Marek Kotewicz",
-      "email": "marek@ethdev.com",
-      "url": "https://github.com/debris"
-    },
-    {
-      "name": "Marian Oancea",
-      "email": "marian@ethdev.com",
-      "url": "https://github.com/cubedro"
-    }
-  ],
-  "license": "LGPL-3.0"
-}
diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml
index 06a7bc2a8ed9b8385a730e8682681a174aa824d4..5df4c8aad2debb00f840fbb9f0902adb6cff6673 100644
--- a/cmd/mist/assets/qml/main.qml
+++ b/cmd/mist/assets/qml/main.qml
@@ -866,12 +866,14 @@ ApplicationWindow {
 			     model: ListModel { id: pastPeers }
 
 			     Component.onCompleted: {
+				     /*
 				     var ips = eth.pastPeers()
 				     for(var i = 0; i < ips.length; i++) {
 					     pastPeers.append({text: ips.get(i)})
 				     }
 
 				     pastPeers.insert(0, {text: "poc-7.ethdev.com:30303"})
+				     */
 			     }
 		     }
 
diff --git a/cmd/mist/assets/qml/views/wallet.qml b/cmd/mist/assets/qml/views/wallet.qml
index 9727ef35c82280d150842821b4d9021083b34ccf..b81273a1731fdde7c543a7fa6ed40e300bb173b8 100644
--- a/cmd/mist/assets/qml/views/wallet.qml
+++ b/cmd/mist/assets/qml/views/wallet.qml
@@ -20,7 +20,7 @@ Rectangle {
 	}
 
 	function setBalance() {
-		balance.text = "<b>Balance</b>: " + eth.numberToHuman(eth.balanceAt(eth.key().address))
+		//balance.text = "<b>Balance</b>: " + eth.numberToHuman(eth.balanceAt(eth.key().address))
 		if(menuItem)
 			menuItem.secondaryTitle = eth.numberToHuman(eth.balanceAt(eth.key().address))
 	}
diff --git a/cmd/mist/bindings.go b/cmd/mist/bindings.go
index 6d2342c876f20828a844416f983224c616fb8443..66d8d14916eaeb8a960da57d9b9b4f47aa2ddc9d 100644
--- a/cmd/mist/bindings.go
+++ b/cmd/mist/bindings.go
@@ -72,7 +72,7 @@ func (gui *Gui) GetCustomIdentifier() string {
 // functions that allow Gui to implement interface guilogger.LogSystem
 func (gui *Gui) SetLogLevel(level logger.LogLevel) {
 	gui.logLevel = level
-	gui.stdLog.SetLogLevel(level)
+	gui.eth.Logger().SetLogLevel(level)
 	gui.config.Save("loglevel", level)
 }
 
diff --git a/cmd/mist/debugger.go b/cmd/mist/debugger.go
index 0e97a6652c5ed6b100b2352f4ad93bd8ac2aa618..618e31f4ed7cc6ae5c71bcd44db1200d56f6649e 100644
--- a/cmd/mist/debugger.go
+++ b/cmd/mist/debugger.go
@@ -151,7 +151,7 @@ func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, data
 
 	block := self.lib.eth.ChainManager().CurrentBlock()
 
-	env := utils.NewEnv(statedb, block, account.Address(), value)
+	env := utils.NewEnv(self.lib.eth.ChainManager(), statedb, block, account.Address(), value)
 
 	self.Logf("callsize %d", len(script))
 	go func() {
diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go
index 98ca70b162b3324c9a48e0595f09f0b930c38937..8e533d9772109a42997ad834be1810da8c85e8c4 100644
--- a/cmd/mist/gui.go
+++ b/cmd/mist/gui.go
@@ -72,8 +72,7 @@ type Gui struct {
 
 	plugins map[string]plugin
 
-	miner  *miner.Miner
-	stdLog logger.LogSystem
+	miner *miner.Miner
 }
 
 // Create GUI, but doesn't start it
@@ -113,7 +112,7 @@ func (gui *Gui) Start(assetPath string) {
 	// Expose the eth library and the ui library to QML
 	context.SetVar("gui", gui)
 	context.SetVar("eth", gui.uiLib)
-	context.SetVar("shh", gui.whisper)
+	//context.SetVar("shh", gui.whisper)
 
 	// Load the main QML interface
 	data, _ := ethutil.Config.Db.Get([]byte("KeyRing"))
diff --git a/cmd/mist/main.go b/cmd/mist/main.go
index 6f578ff48f8b7027210146f32bc7ab1db6d95902..ce5e8449a0e960d796d8db6b411f7243315c6c1b 100644
--- a/cmd/mist/main.go
+++ b/cmd/mist/main.go
@@ -26,15 +26,17 @@ import (
 	"github.com/ethereum/go-ethereum/cmd/utils"
 	"github.com/ethereum/go-ethereum/eth"
 	"github.com/ethereum/go-ethereum/logger"
+	"github.com/ethereum/go-ethereum/p2p"
 	"gopkg.in/qml.v1"
 )
 
 const (
 	ClientIdentifier = "Mist"
-	Version          = "0.7.11"
+	Version          = "0.8.0"
 )
 
 var ethereum *eth.Ethereum
+var mainlogger = logger.NewLogger("MAIN")
 
 func run() error {
 	// precedence: code-internal flag default < config file < environment variables < command line
@@ -43,27 +45,24 @@ func run() error {
 	tstart := time.Now()
 	config := utils.InitConfig(VmType, ConfigFile, Datadir, "ETH")
 
-	utils.InitDataDir(Datadir)
-
-	stdLog := utils.InitLogging(Datadir, LogFile, LogLevel, DebugFile)
-
-	db := utils.NewDatabase()
-	err := utils.DBSanityCheck(db)
+	ethereum, err := eth.New(&eth.Config{
+		Name:       ClientIdentifier,
+		Version:    Version,
+		KeyStore:   KeyStore,
+		DataDir:    Datadir,
+		LogFile:    LogFile,
+		LogLevel:   LogLevel,
+		Identifier: Identifier,
+		MaxPeers:   MaxPeer,
+		Port:       OutboundPort,
+		NATType:    PMPGateway,
+		PMPGateway: PMPGateway,
+		KeyRing:    KeyRing,
+	})
 	if err != nil {
-		ErrorWindow(err)
-
-		os.Exit(1)
-	}
-	keyManager := utils.NewKeyManager(KeyStore, Datadir, db)
-
-	// create, import, export keys
-	utils.KeyTasks(keyManager, KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive)
-	clientIdentity := utils.NewClientIdentity(ClientIdentifier, Version, Identifier, string(keyManager.PublicKey()))
-	ethereum := utils.NewEthereum(db, clientIdentity, keyManager, utils.NatType(NatType, PMPGateway), OutboundPort, MaxPeer)
-
-	if ShowGenesis {
-		utils.ShowGenesis(ethereum)
+		mainlogger.Fatalln(err)
 	}
+	utils.KeyTasks(ethereum.KeyManager(), KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive)
 
 	if StartRpc {
 		utils.StartRpc(ethereum, RpcPort)
@@ -73,8 +72,7 @@ func run() error {
 		utils.StartWebSockets(ethereum)
 	}
 
-	gui := NewWindow(ethereum, config, clientIdentity, KeyRing, LogLevel)
-	gui.stdLog = stdLog
+	gui := NewWindow(ethereum, config, ethereum.ClientIdentity().(*p2p.SimpleClientIdentity), KeyRing, LogLevel)
 
 	utils.RegisterInterrupt(func(os.Signal) {
 		gui.Stop()
diff --git a/cmd/peerserver/main.go b/cmd/peerserver/main.go
index 0fa7a9b440cd4ac434be337f1c25006d9bf5c0d8..18d183f0bd38037b944a78a2da00ed570c8f1eac 100644
--- a/cmd/peerserver/main.go
+++ b/cmd/peerserver/main.go
@@ -18,7 +18,7 @@ func main() {
 	marshaled := elliptic.Marshal(crypto.S256(), key.PublicKey.X, key.PublicKey.Y)
 
 	srv := p2p.Server{
-		MaxPeers:   10,
+		MaxPeers:   100,
 		Identity:   p2p.NewSimpleClientIdentity("Ethereum(G)", "0.1", "Peer Server Two", string(marshaled)),
 		ListenAddr: ":30301",
 		NAT:        p2p.UPNP(),
@@ -29,12 +29,12 @@ func main() {
 	}
 
 	// add seed peers
-	seed, err := net.ResolveTCPAddr("tcp", "poc-7.ethdev.com:30300")
+	seed, err := net.ResolveTCPAddr("tcp", "poc-8.ethdev.com:30303")
 	if err != nil {
 		fmt.Println("couldn't resolve:", err)
-		os.Exit(1)
+	} else {
+		srv.SuggestPeer(seed.IP, seed.Port, nil)
 	}
-	srv.SuggestPeer(seed.IP, seed.Port, nil)
 
 	select {}
 }
diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go
index 466c5138358a286d08dd5acbe2b01db0f41e8f74..6b1cf3726564a8dbe8dd955739cc854c89cfc2dd 100644
--- a/cmd/utils/cmd.go
+++ b/cmd/utils/cmd.go
@@ -2,9 +2,6 @@ package utils
 
 import (
 	"fmt"
-	"io"
-	"log"
-	"net"
 	"os"
 	"os/signal"
 	"path"
@@ -16,11 +13,9 @@ import (
 	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/eth"
-	"github.com/ethereum/go-ethereum/ethdb"
 	"github.com/ethereum/go-ethereum/ethutil"
 	"github.com/ethereum/go-ethereum/logger"
 	"github.com/ethereum/go-ethereum/miner"
-	"github.com/ethereum/go-ethereum/p2p"
 	"github.com/ethereum/go-ethereum/rlp"
 	"github.com/ethereum/go-ethereum/rpc"
 	"github.com/ethereum/go-ethereum/xeth"
@@ -52,15 +47,8 @@ func RunInterruptCallbacks(sig os.Signal) {
 	}
 }
 
-func AbsolutePath(Datadir string, filename string) string {
-	if path.IsAbs(filename) {
-		return filename
-	}
-	return path.Join(Datadir, filename)
-}
-
 func openLogFile(Datadir string, filename string) *os.File {
-	path := AbsolutePath(Datadir, filename)
+	path := ethutil.AbsolutePath(Datadir, filename)
 	file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
 	if err != nil {
 		panic(fmt.Sprintf("error opening log file '%s': %v", filename, err))
@@ -76,23 +64,13 @@ func confirm(message string) bool {
 		if r == "n" || r == "y" {
 			break
 		} else {
-			fmt.Printf("Yes or no?", r)
+			fmt.Printf("Yes or no? (%s)", r)
 		}
 	}
 	return r == "y"
 }
 
-func DBSanityCheck(db ethutil.Database) error {
-	d, _ := db.Get([]byte("ProtocolVersion"))
-	protov := ethutil.NewValue(d).Uint()
-	if protov != eth.ProtocolVersion && protov != 0 {
-		return fmt.Errorf("Database version mismatch. Protocol(%d / %d). `rm -rf %s`", protov, eth.ProtocolVersion, ethutil.Config.ExecPath+"/database")
-	}
-
-	return nil
-}
-
-func InitDataDir(Datadir string) {
+func initDataDir(Datadir string) {
 	_, err := os.Stat(Datadir)
 	if err != nil {
 		if os.IsNotExist(err) {
@@ -102,26 +80,8 @@ func InitDataDir(Datadir string) {
 	}
 }
 
-func InitLogging(Datadir string, LogFile string, LogLevel int, DebugFile string) logger.LogSystem {
-	var writer io.Writer
-	if LogFile == "" {
-		writer = os.Stdout
-	} else {
-		writer = openLogFile(Datadir, LogFile)
-	}
-
-	sys := logger.NewStdLogSystem(writer, log.LstdFlags, logger.LogLevel(LogLevel))
-	logger.AddLogSystem(sys)
-	if DebugFile != "" {
-		writer = openLogFile(Datadir, DebugFile)
-		logger.AddLogSystem(logger.NewStdLogSystem(writer, log.LstdFlags, logger.DebugLevel))
-	}
-
-	return sys
-}
-
 func InitConfig(vmType int, ConfigFile string, Datadir string, EnvPrefix string) *ethutil.ConfigManager {
-	InitDataDir(Datadir)
+	initDataDir(Datadir)
 	cfg := ethutil.ReadConfig(ConfigFile, Datadir, EnvPrefix)
 	cfg.VmType = vmType
 
@@ -138,43 +98,6 @@ func exit(err error) {
 	os.Exit(status)
 }
 
-func NewDatabase() ethutil.Database {
-	db, err := ethdb.NewLDBDatabase("database")
-	if err != nil {
-		exit(err)
-	}
-	return db
-}
-
-func NewClientIdentity(clientIdentifier, version, customIdentifier string, pubkey string) *p2p.SimpleClientIdentity {
-	return p2p.NewSimpleClientIdentity(clientIdentifier, version, customIdentifier, pubkey)
-}
-
-func NatType(natType string, gateway string) (nat p2p.NAT) {
-	switch natType {
-	case "UPNP":
-		nat = p2p.UPNP()
-	case "PMP":
-		ip := net.ParseIP(gateway)
-		if ip == nil {
-			clilogger.Fatalf("cannot resolve PMP gateway IP %s", gateway)
-		}
-		nat = p2p.PMP(ip)
-	case "":
-	default:
-		clilogger.Fatalf("unrecognised NAT type '%s'", natType)
-	}
-	return
-}
-
-func NewEthereum(db ethutil.Database, clientIdentity p2p.ClientIdentity, keyManager *crypto.KeyManager, nat p2p.NAT, OutboundPort string, MaxPeer int) *eth.Ethereum {
-	ethereum, err := eth.New(db, clientIdentity, keyManager, nat, OutboundPort, MaxPeer)
-	if err != nil {
-		clilogger.Fatalln("eth start err:", err)
-	}
-	return ethereum
-}
-
 func StartEthereum(ethereum *eth.Ethereum, UseSeed bool) {
 	clilogger.Infof("Starting %s", ethereum.ClientIdentity())
 	ethereum.Start(UseSeed)
@@ -184,24 +107,6 @@ func StartEthereum(ethereum *eth.Ethereum, UseSeed bool) {
 	})
 }
 
-func ShowGenesis(ethereum *eth.Ethereum) {
-	clilogger.Infoln(ethereum.ChainManager().Genesis())
-	exit(nil)
-}
-
-func NewKeyManager(KeyStore string, Datadir string, db ethutil.Database) *crypto.KeyManager {
-	var keyManager *crypto.KeyManager
-	switch {
-	case KeyStore == "db":
-		keyManager = crypto.NewDBKeyManager(db)
-	case KeyStore == "file":
-		keyManager = crypto.NewFileKeyManager(Datadir)
-	default:
-		exit(fmt.Errorf("unknown keystore type: %s", KeyStore))
-	}
-	return keyManager
-}
-
 func DefaultAssetPath() string {
 	var assetPath string
 	// If the current working directory is the go-ethereum dir
diff --git a/cmd/utils/vm_env.go b/cmd/utils/vm_env.go
index 19091bdc5dd731bbcede7dc23b2556497427a9ca..acc2ffad95107b3c80f806f663bac5c3b7f6cd94 100644
--- a/cmd/utils/vm_env.go
+++ b/cmd/utils/vm_env.go
@@ -10,6 +10,7 @@ import (
 )
 
 type VMEnv struct {
+	chain *core.ChainManager
 	state *state.StateDB
 	block *types.Block
 
@@ -20,8 +21,9 @@ type VMEnv struct {
 	Gas   *big.Int
 }
 
-func NewEnv(state *state.StateDB, block *types.Block, transactor []byte, value *big.Int) *VMEnv {
+func NewEnv(chain *core.ChainManager, state *state.StateDB, block *types.Block, transactor []byte, value *big.Int) *VMEnv {
 	return &VMEnv{
+		chain:      chain,
 		state:      state,
 		block:      block,
 		transactor: transactor,
@@ -35,12 +37,18 @@ func (self *VMEnv) PrevHash() []byte      { return self.block.ParentHash() }
 func (self *VMEnv) Coinbase() []byte      { return self.block.Coinbase() }
 func (self *VMEnv) Time() int64           { return self.block.Time() }
 func (self *VMEnv) Difficulty() *big.Int  { return self.block.Difficulty() }
-func (self *VMEnv) BlockHash() []byte     { return self.block.Hash() }
 func (self *VMEnv) GasLimit() *big.Int    { return self.block.GasLimit() }
 func (self *VMEnv) Value() *big.Int       { return self.value }
 func (self *VMEnv) State() *state.StateDB { return self.state }
 func (self *VMEnv) Depth() int            { return self.depth }
 func (self *VMEnv) SetDepth(i int)        { self.depth = i }
+func (self *VMEnv) GetHash(n uint64) []byte {
+	if block := self.chain.GetBlockByNumber(n); block != nil {
+		return block.Hash()
+	}
+
+	return nil
+}
 func (self *VMEnv) AddLog(log state.Log) {
 	self.state.AddLog(log)
 }
diff --git a/core/block_manager.go b/core/block_manager.go
index 8a5455306c942f66b4196f10bbbea0dca9a0587d..76385ea1fdb3ae0bb10d26b34d7afed22962f311 100644
--- a/core/block_manager.go
+++ b/core/block_manager.go
@@ -6,7 +6,6 @@ import (
 	"fmt"
 	"math/big"
 	"sync"
-	"time"
 
 	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/crypto"
@@ -22,18 +21,6 @@ import (
 
 var statelogger = logger.NewLogger("BLOCK")
 
-type Peer interface {
-	Inbound() bool
-	LastSend() time.Time
-	LastPong() int64
-	Host() []byte
-	Port() uint16
-	Version() string
-	PingTime() string
-	Connected() *int32
-	Caps() *ethutil.Value
-}
-
 type EthManager interface {
 	BlockManager() *BlockManager
 	ChainManager() *ChainManager
@@ -113,7 +100,7 @@ done:
 		txGas := new(big.Int).Set(tx.Gas())
 
 		cb := state.GetStateObject(coinbase.Address())
-		st := NewStateTransition(cb, tx, state, block)
+		st := NewStateTransition(NewEnv(state, self.bc, tx, block), tx, cb)
 		_, err = st.TransitionState()
 		if err != nil {
 			switch {
@@ -232,6 +219,8 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
 		// Sync the current block's state to the database and cancelling out the deferred Undo
 		state.Sync()
 
+		state.Manifest().SetHash(block.Hash())
+
 		messages := state.Manifest().Messages
 		state.Manifest().Reset()
 
@@ -339,10 +328,10 @@ func (sm *BlockManager) AccumelateRewards(statedb *state.StateDB, block, parent
 	account.AddAmount(reward)
 
 	statedb.Manifest().AddMessage(&state.Message{
-		To:     block.Header().Coinbase,
-		Input:  nil,
-		Origin: nil,
-		Block:  block.Hash(), Timestamp: int64(block.Header().Time), Coinbase: block.Header().Coinbase, Number: block.Header().Number,
+		To:        block.Header().Coinbase,
+		Input:     nil,
+		Origin:    nil,
+		Timestamp: int64(block.Header().Time), Coinbase: block.Header().Coinbase, Number: block.Header().Number,
 		Value: new(big.Int).Add(reward, block.Reward),
 	})
 
diff --git a/core/chain_manager.go b/core/chain_manager.go
index ece98d78308c0e16bca84cb65472fd8dc43491ae..82b17cd931cb2f1315e57a676f697d875a1f9796 100644
--- a/core/chain_manager.go
+++ b/core/chain_manager.go
@@ -271,15 +271,15 @@ func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block {
 	self.mu.RLock()
 	defer self.mu.RUnlock()
 
-	block := self.currentBlock
-	for ; block != nil; block = self.GetBlock(block.Header().ParentHash) {
-		if block.Header().Number.Uint64() == num {
-			break
-		}
-	}
+	var block *types.Block
 
-	if block != nil && block.Header().Number.Uint64() == 0 && num != 0 {
-		return nil
+	if num <= self.currentBlock.Number().Uint64() {
+		block = self.currentBlock
+		for ; block != nil; block = self.GetBlock(block.Header().ParentHash) {
+			if block.Header().Number.Uint64() == num {
+				break
+			}
+		}
 	}
 
 	return block
diff --git a/core/state_transition.go b/core/state_transition.go
index 91cfd5fe3bb0280f99f537f42737a9c0f89c4c69..b22c5bf21787393249f90e233b72f7d4d38a4466 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -4,7 +4,6 @@ import (
 	"fmt"
 	"math/big"
 
-	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/ethutil"
 	"github.com/ethereum/go-ethereum/state"
@@ -28,18 +27,17 @@ import (
  * 6) Derive new state root
  */
 type StateTransition struct {
-	coinbase, receiver []byte
-	msg                Message
-	gas, gasPrice      *big.Int
-	initialGas         *big.Int
-	value              *big.Int
-	data               []byte
-	state              *state.StateDB
-	block              *types.Block
+	coinbase      []byte
+	msg           Message
+	gas, gasPrice *big.Int
+	initialGas    *big.Int
+	value         *big.Int
+	data          []byte
+	state         *state.StateDB
 
 	cb, rec, sen *state.StateObject
 
-	Env vm.Environment
+	env vm.Environment
 }
 
 type Message interface {
@@ -69,16 +67,19 @@ func MessageGasValue(msg Message) *big.Int {
 	return new(big.Int).Mul(msg.Gas(), msg.GasPrice())
 }
 
-func NewStateTransition(coinbase *state.StateObject, msg Message, state *state.StateDB, block *types.Block) *StateTransition {
-	return &StateTransition{coinbase.Address(), msg.To(), msg, new(big.Int), new(big.Int).Set(msg.GasPrice()), new(big.Int), msg.Value(), msg.Data(), state, block, coinbase, nil, nil, nil}
-}
-
-func (self *StateTransition) VmEnv() vm.Environment {
-	if self.Env == nil {
-		self.Env = NewEnv(self.state, self.msg, self.block)
+func NewStateTransition(env vm.Environment, msg Message, coinbase *state.StateObject) *StateTransition {
+	return &StateTransition{
+		coinbase:   coinbase.Address(),
+		env:        env,
+		msg:        msg,
+		gas:        new(big.Int),
+		gasPrice:   new(big.Int).Set(msg.GasPrice()),
+		initialGas: new(big.Int),
+		value:      msg.Value(),
+		data:       msg.Data(),
+		state:      env.State(),
+		cb:         coinbase,
 	}
-
-	return self.Env
 }
 
 func (self *StateTransition) Coinbase() *state.StateObject {
@@ -183,7 +184,7 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) {
 		return
 	}
 
-	vmenv := self.VmEnv()
+	vmenv := self.env
 	var ref vm.ContextRef
 	if MessageCreatesContract(msg) {
 		contract := MakeContract(msg, self.state)
diff --git a/core/vm_env.go b/core/vm_env.go
index 4e0315ff3b2105a4915d2c58f41150bfe81d934a..624a633334262a8b6ba5670c45c3c1b29aca0ce8 100644
--- a/core/vm_env.go
+++ b/core/vm_env.go
@@ -13,10 +13,12 @@ type VMEnv struct {
 	block *types.Block
 	msg   Message
 	depth int
+	chain *ChainManager
 }
 
-func NewEnv(state *state.StateDB, msg Message, block *types.Block) *VMEnv {
+func NewEnv(state *state.StateDB, chain *ChainManager, msg Message, block *types.Block) *VMEnv {
 	return &VMEnv{
+		chain: chain,
 		state: state,
 		block: block,
 		msg:   msg,
@@ -25,16 +27,21 @@ func NewEnv(state *state.StateDB, msg Message, block *types.Block) *VMEnv {
 
 func (self *VMEnv) Origin() []byte        { return self.msg.From() }
 func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number() }
-func (self *VMEnv) PrevHash() []byte      { return self.block.ParentHash() }
 func (self *VMEnv) Coinbase() []byte      { return self.block.Coinbase() }
 func (self *VMEnv) Time() int64           { return self.block.Time() }
 func (self *VMEnv) Difficulty() *big.Int  { return self.block.Difficulty() }
-func (self *VMEnv) BlockHash() []byte     { return self.block.Hash() }
 func (self *VMEnv) GasLimit() *big.Int    { return self.block.GasLimit() }
 func (self *VMEnv) Value() *big.Int       { return self.msg.Value() }
 func (self *VMEnv) State() *state.StateDB { return self.state }
 func (self *VMEnv) Depth() int            { return self.depth }
 func (self *VMEnv) SetDepth(i int)        { self.depth = i }
+func (self *VMEnv) GetHash(n uint64) []byte {
+	if block := self.chain.GetBlockByNumber(n); block != nil {
+		return block.Hash()
+	}
+
+	return nil
+}
 func (self *VMEnv) AddLog(log state.Log) {
 	self.state.AddLog(log)
 }
diff --git a/eth/backend.go b/eth/backend.go
index 36c1ac30f3792256da575b893d3ff11aa3d141e2..bf6c9128266fd6b7d279ae62463f82d9b3c98723 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -1,11 +1,13 @@
 package eth
 
 import (
+	"fmt"
 	"net"
 	"sync"
 
 	"github.com/ethereum/go-ethereum/core"
 	"github.com/ethereum/go-ethereum/crypto"
+	"github.com/ethereum/go-ethereum/ethdb"
 	"github.com/ethereum/go-ethereum/ethutil"
 	"github.com/ethereum/go-ethereum/event"
 	ethlogger "github.com/ethereum/go-ethereum/logger"
@@ -19,6 +21,24 @@ const (
 	seedNodeAddress = "poc-7.ethdev.com:30300"
 )
 
+type Config struct {
+	Name       string
+	Version    string
+	Identifier string
+	KeyStore   string
+	DataDir    string
+	LogFile    string
+	LogLevel   int
+	KeyRing    string
+
+	MaxPeers   int
+	Port       string
+	NATType    string
+	PMPGateway string
+
+	KeyManager *crypto.KeyManager
+}
+
 var logger = ethlogger.NewLogger("SERV")
 
 type Ethereum struct {
@@ -38,7 +58,7 @@ type Ethereum struct {
 	blockPool    *BlockPool
 	whisper      *whisper.Whisper
 
-	server   *p2p.Server
+	net      *p2p.Server
 	eventMux *event.TypeMux
 	txSub    event.Subscription
 	blockSub event.Subscription
@@ -47,6 +67,7 @@ type Ethereum struct {
 	keyManager *crypto.KeyManager
 
 	clientIdentity p2p.ClientIdentity
+	logger         ethlogger.LogSystem
 
 	synclock  sync.Mutex
 	syncGroup sync.WaitGroup
@@ -54,7 +75,36 @@ type Ethereum struct {
 	Mining bool
 }
 
-func New(db ethutil.Database, identity p2p.ClientIdentity, keyManager *crypto.KeyManager, nat p2p.NAT, port string, maxPeers int) (*Ethereum, error) {
+func New(config *Config) (*Ethereum, error) {
+	// Boostrap database
+	logger := ethlogger.New(config.DataDir, config.LogFile, config.LogLevel)
+	db, err := ethdb.NewLDBDatabase("database")
+	if err != nil {
+		return nil, err
+	}
+
+	// Perform database sanity checks
+	d, _ := db.Get([]byte("ProtocolVersion"))
+	protov := ethutil.NewValue(d).Uint()
+	if protov != ProtocolVersion && protov != 0 {
+		return nil, fmt.Errorf("Database version mismatch. Protocol(%d / %d). `rm -rf %s`", protov, ProtocolVersion, ethutil.Config.ExecPath+"/database")
+	}
+
+	// Create new keymanager
+	var keyManager *crypto.KeyManager
+	switch config.KeyStore {
+	case "db":
+		keyManager = crypto.NewDBKeyManager(db)
+	case "file":
+		keyManager = crypto.NewFileKeyManager(config.DataDir)
+	default:
+		return nil, fmt.Errorf("unknown keystore type: %s", config.KeyStore)
+	}
+	// Initialise the keyring
+	keyManager.Init(config.KeyRing, 0, false)
+
+	// Create a new client id for this instance. This will help identifying the node on the network
+	clientId := p2p.NewSimpleClientIdentity(config.Name, config.Version, config.Identifier, keyManager.PublicKey())
 
 	saveProtocolVersion(db)
 	ethutil.Config.Db = db
@@ -64,9 +114,10 @@ func New(db ethutil.Database, identity p2p.ClientIdentity, keyManager *crypto.Ke
 		quit:           make(chan bool),
 		db:             db,
 		keyManager:     keyManager,
-		clientIdentity: identity,
+		clientIdentity: clientId,
 		blacklist:      p2p.NewBlacklist(),
 		eventMux:       &event.TypeMux{},
+		logger:         logger,
 	}
 
 	eth.chainManager = core.NewChainManager(eth.EventMux())
@@ -85,17 +136,20 @@ func New(db ethutil.Database, identity p2p.ClientIdentity, keyManager *crypto.Ke
 	ethProto := EthProtocol(eth.txPool, eth.chainManager, eth.blockPool)
 	protocols := []p2p.Protocol{ethProto, eth.whisper.Protocol()}
 
-	server := &p2p.Server{
-		Identity:   identity,
-		MaxPeers:   maxPeers,
+	nat, err := p2p.ParseNAT(config.NATType, config.PMPGateway)
+	if err != nil {
+		return nil, err
+	}
+
+	eth.net = &p2p.Server{
+		Identity:   clientId,
+		MaxPeers:   config.MaxPeers,
 		Protocols:  protocols,
-		ListenAddr: ":" + port,
+		ListenAddr: ":" + config.Port,
 		Blacklist:  eth.blacklist,
 		NAT:        nat,
 	}
 
-	eth.server = server
-
 	return eth, nil
 }
 
@@ -103,6 +157,10 @@ func (s *Ethereum) KeyManager() *crypto.KeyManager {
 	return s.keyManager
 }
 
+func (s *Ethereum) Logger() ethlogger.LogSystem {
+	return s.logger
+}
+
 func (s *Ethereum) ClientIdentity() p2p.ClientIdentity {
 	return s.clientIdentity
 }
@@ -144,20 +202,20 @@ func (s *Ethereum) IsListening() bool {
 }
 
 func (s *Ethereum) PeerCount() int {
-	return s.server.PeerCount()
+	return s.net.PeerCount()
 }
 
 func (s *Ethereum) Peers() []*p2p.Peer {
-	return s.server.Peers()
+	return s.net.Peers()
 }
 
 func (s *Ethereum) MaxPeers() int {
-	return s.server.MaxPeers
+	return s.net.MaxPeers
 }
 
 // Start the ethereum
 func (s *Ethereum) Start(seed bool) error {
-	err := s.server.Start()
+	err := s.net.Start()
 	if err != nil {
 		return err
 	}
@@ -191,7 +249,7 @@ func (self *Ethereum) SuggestPeer(addr string) error {
 		return err
 	}
 
-	self.server.SuggestPeer(netaddr.IP, netaddr.Port, nil)
+	self.net.SuggestPeer(netaddr.IP, netaddr.Port, nil)
 	return nil
 }
 
@@ -227,7 +285,7 @@ func (self *Ethereum) txBroadcastLoop() {
 	// automatically stops if unsubscribe
 	for obj := range self.txSub.Chan() {
 		event := obj.(core.TxPreEvent)
-		self.server.Broadcast("eth", TxMsg, []interface{}{event.Tx.RlpData()})
+		self.net.Broadcast("eth", TxMsg, []interface{}{event.Tx.RlpData()})
 	}
 }
 
@@ -236,7 +294,7 @@ func (self *Ethereum) blockBroadcastLoop() {
 	for obj := range self.txSub.Chan() {
 		switch ev := obj.(type) {
 		case core.NewMinedBlockEvent:
-			self.server.Broadcast("eth", NewBlockMsg, ev.Block.RlpData())
+			self.net.Broadcast("eth", NewBlockMsg, ev.Block.RlpData())
 		}
 	}
 }
diff --git a/ethutil/path.go b/ethutil/path.go
index cfbc389508cc1517da208e0844db064fcc51206a..f64e3849e0fc1e0a78d64d11db390c8fd2d0e5ea 100644
--- a/ethutil/path.go
+++ b/ethutil/path.go
@@ -4,6 +4,7 @@ import (
 	"io/ioutil"
 	"os"
 	"os/user"
+	"path"
 	"strings"
 )
 
@@ -58,3 +59,10 @@ func WriteFile(filePath string, content []byte) error {
 
 	return nil
 }
+
+func AbsolutePath(Datadir string, filename string) string {
+	if path.IsAbs(filename) {
+		return filename
+	}
+	return path.Join(Datadir, filename)
+}
diff --git a/logger/log.go b/logger/log.go
new file mode 100644
index 0000000000000000000000000000000000000000..53065f870bf1d7531ec920743bef3318c75e1cc9
--- /dev/null
+++ b/logger/log.go
@@ -0,0 +1,33 @@
+package logger
+
+import (
+	"fmt"
+	"io"
+	"log"
+	"os"
+
+	"github.com/ethereum/go-ethereum/ethutil"
+)
+
+func openLogFile(datadir string, filename string) *os.File {
+	path := ethutil.AbsolutePath(datadir, filename)
+	file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
+	if err != nil {
+		panic(fmt.Sprintf("error opening log file '%s': %v", filename, err))
+	}
+	return file
+}
+
+func New(datadir string, logFile string, logLevel int) LogSystem {
+	var writer io.Writer
+	if logFile == "" {
+		writer = os.Stdout
+	} else {
+		writer = openLogFile(datadir, logFile)
+	}
+
+	sys := NewStdLogSystem(writer, log.LstdFlags, LogLevel(logLevel))
+	AddLogSystem(sys)
+
+	return sys
+}
diff --git a/p2p/client_identity.go b/p2p/client_identity.go
index bc865b63b04f54a89013cdca1e5462d553d095d6..f15fd01bfc6ddc3487e333f77cb906d722b58188 100644
--- a/p2p/client_identity.go
+++ b/p2p/client_identity.go
@@ -17,10 +17,10 @@ type SimpleClientIdentity struct {
 	customIdentifier string
 	os               string
 	implementation   string
-	pubkey           string
+	pubkey           []byte
 }
 
-func NewSimpleClientIdentity(clientIdentifier string, version string, customIdentifier string, pubkey string) *SimpleClientIdentity {
+func NewSimpleClientIdentity(clientIdentifier string, version string, customIdentifier string, pubkey []byte) *SimpleClientIdentity {
 	clientIdentity := &SimpleClientIdentity{
 		clientIdentifier: clientIdentifier,
 		version:          version,
diff --git a/p2p/nat.go b/p2p/nat.go
new file mode 100644
index 0000000000000000000000000000000000000000..9b771c3e8c12cb8fbfd1c3f4113efb755a13bed7
--- /dev/null
+++ b/p2p/nat.go
@@ -0,0 +1,23 @@
+package p2p
+
+import (
+	"fmt"
+	"net"
+)
+
+func ParseNAT(natType string, gateway string) (nat NAT, err error) {
+	switch natType {
+	case "UPNP":
+		nat = UPNP()
+	case "PMP":
+		ip := net.ParseIP(gateway)
+		if ip == nil {
+			return nil, fmt.Errorf("cannot resolve PMP gateway IP %s", gateway)
+		}
+		nat = PMP(ip)
+	case "":
+	default:
+		return nil, fmt.Errorf("unrecognised NAT type '%s'", natType)
+	}
+	return
+}
diff --git a/core/dagger.go b/pow/dagger/dagger.go
similarity index 99%
rename from core/dagger.go
rename to pow/dagger/dagger.go
index 3039d89959998b521d1d747764d0c451df8684c2..9ac00044335d7f167088324ee2a051063f282ddb 100644
--- a/core/dagger.go
+++ b/pow/dagger/dagger.go
@@ -1,4 +1,4 @@
-package core
+package dagger
 
 import (
 	"hash"
diff --git a/core/dagger_test.go b/pow/dagger/dagger_test.go
similarity index 96%
rename from core/dagger_test.go
rename to pow/dagger/dagger_test.go
index e80064e6bf4cd809f401756a65caade10820dba7..f3a71d1eb4cd738b250f60bf8d65f5ff9cadafd1 100644
--- a/core/dagger_test.go
+++ b/pow/dagger/dagger_test.go
@@ -1,4 +1,4 @@
-package core
+package dagger
 
 import (
 	"math/big"
diff --git a/state/manifest.go b/state/manifest.go
index 21cd04a1a9d8f05f528ac4690519f652423f2e55..994019a086f21d1c452bcd43ddfd38ab6554c57f 100644
--- a/state/manifest.go
+++ b/state/manifest.go
@@ -30,6 +30,12 @@ func (self *Manifest) AddMessage(msg *Message) *Message {
 	return msg
 }
 
+func (self *Manifest) SetHash(hash []byte) {
+	for _, message := range self.Messages {
+		message.Block = hash
+	}
+}
+
 type Messages []*Message
 type Message struct {
 	To, From  []byte
diff --git a/tests/helper/vm.go b/tests/helper/vm.go
index aa17313b77e1b5398f9c281da0d3c752b1a97d99..123003faa3eeeaef4dd287d19432efd96cf7732a 100644
--- a/tests/helper/vm.go
+++ b/tests/helper/vm.go
@@ -55,9 +55,11 @@ func (self *Env) PrevHash() []byte      { return self.parent }
 func (self *Env) Coinbase() []byte      { return self.coinbase }
 func (self *Env) Time() int64           { return self.time }
 func (self *Env) Difficulty() *big.Int  { return self.difficulty }
-func (self *Env) BlockHash() []byte     { return nil }
 func (self *Env) State() *state.StateDB { return self.state }
 func (self *Env) GasLimit() *big.Int    { return self.gasLimit }
+func (self *Env) GetHash(n uint64) []byte {
+	return nil
+}
 func (self *Env) AddLog(log state.Log) {
 	self.logs = append(self.logs, log)
 }
@@ -126,10 +128,9 @@ func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.
 
 	message := NewMessage(keyPair.Address(), to, data, value, gas, price)
 	Log.DebugDetailf("message{ to: %x, from %x, value: %v, gas: %v, price: %v }\n", message.to[:4], message.from[:4], message.value, message.gas, message.price)
-	st := core.NewStateTransition(coinbase, message, statedb, nil)
 	vmenv := NewEnvFromMap(statedb, env, tx)
+	st := core.NewStateTransition(vmenv, message, coinbase)
 	vmenv.origin = keyPair.Address()
-	st.Env = vmenv
 	ret, err := st.TransitionState()
 	statedb.Update(vmenv.Gas)
 
diff --git a/vm/context.go b/vm/context.go
index ccbadabdaa2ab2d5fb424875172ca7b87a0ceda8..d14df1aa777a878d2e08bada36abebe45adea4e5 100644
--- a/vm/context.go
+++ b/vm/context.go
@@ -5,7 +5,6 @@ import (
 	"math/big"
 
 	"github.com/ethereum/go-ethereum/ethutil"
-	"github.com/ethereum/go-ethereum/state"
 )
 
 type ContextRef interface {
@@ -15,10 +14,9 @@ type ContextRef interface {
 }
 
 type Context struct {
-	caller  ContextRef
-	object  ContextRef
-	Code    []byte
-	message *state.Message
+	caller ContextRef
+	object ContextRef
+	Code   []byte
 
 	Gas, UsedGas, Price *big.Int
 
@@ -26,8 +24,8 @@ type Context struct {
 }
 
 // Create a new context for the given data items
-func NewContext(msg *state.Message, caller ContextRef, object ContextRef, code []byte, gas, price *big.Int) *Context {
-	c := &Context{message: msg, caller: caller, object: object, Code: code, Args: nil}
+func NewContext(caller ContextRef, object ContextRef, code []byte, gas, price *big.Int) *Context {
+	c := &Context{caller: caller, object: object, Code: code, Args: nil}
 
 	// Gas should be a pointer so it can safely be reduced through the run
 	// This pointer will be off the state transition
@@ -40,13 +38,13 @@ func NewContext(msg *state.Message, caller ContextRef, object ContextRef, code [
 	return c
 }
 
-func (c *Context) GetOp(x uint64) OpCode {
-	return OpCode(c.GetByte(x))
+func (c *Context) GetOp(n uint64) OpCode {
+	return OpCode(c.GetByte(n))
 }
 
-func (c *Context) GetByte(x uint64) byte {
-	if x < uint64(len(c.Code)) {
-		return c.Code[x]
+func (c *Context) GetByte(n uint64) byte {
+	if n < uint64(len(c.Code)) {
+		return c.Code[n]
 	}
 
 	return 0
diff --git a/vm/environment.go b/vm/environment.go
index 01bbd56ceac9336e9939a39759dbd3835ea6ca5d..8ec13ee412fcfe63a186d3befb7259c842682ea4 100644
--- a/vm/environment.go
+++ b/vm/environment.go
@@ -14,11 +14,10 @@ type Environment interface {
 
 	Origin() []byte
 	BlockNumber() *big.Int
-	PrevHash() []byte
+	GetHash(n uint64) []byte
 	Coinbase() []byte
 	Time() int64
 	Difficulty() *big.Int
-	BlockHash() []byte
 	GasLimit() *big.Int
 	Transfer(from, to Account, amount *big.Int) error
 	AddLog(state.Log)
@@ -31,11 +30,6 @@ type Environment interface {
 	Create(me ContextRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error, ContextRef)
 }
 
-type Object interface {
-	GetStorage(key *big.Int) *ethutil.Value
-	SetStorage(key *big.Int, value *ethutil.Value)
-}
-
 type Account interface {
 	SubBalance(amount *big.Int)
 	AddBalance(amount *big.Int)
diff --git a/vm/types.go b/vm/types.go
index ec9c7e74e6c3161f6df00c493d72481863d1f2dd..1ea80a212d600cb2b0cdc6390c6911b9b6c1bcd3 100644
--- a/vm/types.go
+++ b/vm/types.go
@@ -59,7 +59,7 @@ const (
 const (
 
 	// 0x40 range - block operations
-	PREVHASH OpCode = 0x40 + iota
+	BLOCKHASH OpCode = 0x40 + iota
 	COINBASE
 	TIMESTAMP
 	NUMBER
@@ -216,7 +216,7 @@ var opCodeToString = map[OpCode]string{
 	GASPRICE:     "TXGASPRICE",
 
 	// 0x40 range - block operations
-	PREVHASH:    "PREVHASH",
+	BLOCKHASH:   "BLOCKHASH",
 	COINBASE:    "COINBASE",
 	TIMESTAMP:   "TIMESTAMP",
 	NUMBER:      "NUMBER",
diff --git a/vm/vm_debug.go b/vm/vm_debug.go
index 6ad385fd0c9db5ac3058a63f0280993bcfbd07cb..92e4154e4f7e60b7851ebc7a7ef8d216f74dcfd9 100644
--- a/vm/vm_debug.go
+++ b/vm/vm_debug.go
@@ -42,12 +42,12 @@ func (self *DebugVm) Run(me, caller ContextRef, code []byte, value, gas, price *
 
 	msg := self.env.State().Manifest().AddMessage(&state.Message{
 		To: me.Address(), From: caller.Address(),
-		Input:  callData,
-		Origin: self.env.Origin(),
-		Block:  self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
+		Input:     callData,
+		Origin:    self.env.Origin(),
+		Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
 		Value: value,
 	})
-	context := NewContext(msg, caller, me, code, gas, price)
+	context := NewContext(caller, me, code, gas, price)
 
 	if self.Recoverable {
 		// Recover from any require exception
@@ -83,7 +83,7 @@ func (self *DebugVm) Run(me, caller ContextRef, code []byte, value, gas, price *
 		jump = func(from uint64, to *big.Int) {
 			p := to.Uint64()
 
-			nop := OpCode(context.GetOp(p))
+			nop := context.GetOp(p)
 			if !destinations.Has(p) {
 				panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p))
 			}
@@ -516,12 +516,15 @@ func (self *DebugVm) Run(me, caller ContextRef, code []byte, value, gas, price *
 			self.Printf(" => %v", context.Price)
 
 			// 0x40 range
-		case PREVHASH:
-			prevHash := self.env.PrevHash()
-
-			stack.Push(ethutil.BigD(prevHash))
+		case BLOCKHASH:
+			num := stack.Pop()
+			if num.Cmp(new(big.Int).Sub(self.env.BlockNumber(), ethutil.Big256)) < 0 {
+				stack.Push(ethutil.Big0)
+			} else {
+				stack.Push(ethutil.BigD(self.env.GetHash(num.Uint64())))
+			}
 
-			self.Printf(" => 0x%x", prevHash)
+			self.Printf(" => 0x%x", stack.Peek().Bytes())
 		case COINBASE:
 			coinbase := self.env.Coinbase()
 
@@ -614,7 +617,7 @@ func (self *DebugVm) Run(me, caller ContextRef, code []byte, value, gas, price *
 			val, loc := stack.Popn()
 			statedb.SetState(context.Address(), loc.Bytes(), val)
 
-			context.message.AddStorageChange(loc.Bytes())
+			msg.AddStorageChange(loc.Bytes())
 
 			self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
 		case JUMP:
diff --git a/xeth/pipe.go b/xeth/pipe.go
index cae6ee1decb34479451d4ed814b89dcf4845ee51..05cefd8ad288263d6a99eb609ea74ada5975f957 100644
--- a/xeth/pipe.go
+++ b/xeth/pipe.go
@@ -87,7 +87,7 @@ func (self *XEth) ExecuteObject(object *Object, data []byte, value, gas, price *
 
 	self.Vm.State = self.World().State().Copy()
 
-	vmenv := NewEnv(self.Vm.State, block, value.BigInt(), initiator.Address())
+	vmenv := NewEnv(self.chainManager, self.Vm.State, block, value.BigInt(), initiator.Address())
 	return vmenv.Call(initiator, object.Address(), data, gas.BigInt(), price.BigInt(), value.BigInt())
 }
 
diff --git a/xeth/vm_env.go b/xeth/vm_env.go
index d2a21afd5dbd307b33a94687ec1606bf7c176c17..1470b9eaa56393692c08b78cf42ca4828135b335 100644
--- a/xeth/vm_env.go
+++ b/xeth/vm_env.go
@@ -10,6 +10,7 @@ import (
 )
 
 type VMEnv struct {
+	chain  *core.ChainManager
 	state  *state.StateDB
 	block  *types.Block
 	value  *big.Int
@@ -18,7 +19,7 @@ type VMEnv struct {
 	depth int
 }
 
-func NewEnv(state *state.StateDB, block *types.Block, value *big.Int, sender []byte) *VMEnv {
+func NewEnv(chain *core.ChainManager, state *state.StateDB, block *types.Block, value *big.Int, sender []byte) *VMEnv {
 	return &VMEnv{
 		state:  state,
 		block:  block,
@@ -33,12 +34,18 @@ func (self *VMEnv) PrevHash() []byte      { return self.block.ParentHash() }
 func (self *VMEnv) Coinbase() []byte      { return self.block.Coinbase() }
 func (self *VMEnv) Time() int64           { return self.block.Time() }
 func (self *VMEnv) Difficulty() *big.Int  { return self.block.Difficulty() }
-func (self *VMEnv) BlockHash() []byte     { return self.block.Hash() }
 func (self *VMEnv) GasLimit() *big.Int    { return self.block.GasLimit() }
 func (self *VMEnv) Value() *big.Int       { return self.value }
 func (self *VMEnv) State() *state.StateDB { return self.state }
 func (self *VMEnv) Depth() int            { return self.depth }
 func (self *VMEnv) SetDepth(i int)        { self.depth = i }
+func (self *VMEnv) GetHash(n uint64) []byte {
+	if block := self.chain.GetBlockByNumber(n); block != nil {
+		return block.Hash()
+	}
+
+	return nil
+}
 func (self *VMEnv) AddLog(log state.Log) {
 	self.state.AddLog(log)
 }