diff --git a/build/test-global-coverage.sh b/build/test-global-coverage.sh
index 417c829f4..5bb233a31 100755
--- a/build/test-global-coverage.sh
+++ b/build/test-global-coverage.sh
@@ -16,7 +16,7 @@ for pkg in $(go list ./...); do
     # drop the namespace prefix.
     dir=${pkg##github.com/ethereum/go-ethereum/}
     
-    if [[ $dir != "tests/vm" ]]; then
+    if [[ $dir != "tests" ]]; then
         go test -covermode=count -coverprofile=$dir/profile.tmp $pkg
     fi
     if [[ -f $dir/profile.tmp ]]; then
diff --git a/cmd/ethtest/main.go b/cmd/ethtest/main.go
index c2c94d6c4..278d2133f 100644
--- a/cmd/ethtest/main.go
+++ b/cmd/ethtest/main.go
@@ -17,217 +17,201 @@
 /**
  * @authors:
  * 	Jeffrey Wilcke <i@jev.io>
+ * 	Taylor Gerring <taylor.gerring@gmail.com>
  */
 
 package main
 
 import (
-	"bytes"
-	"encoding/json"
+	"fmt"
 	"io"
 	"io/ioutil"
-	"log"
-	"math/big"
 	"os"
-	"strconv"
+	"path/filepath"
 	"strings"
 
-	"github.com/ethereum/go-ethereum/common"
-	"github.com/ethereum/go-ethereum/core/state"
-	"github.com/ethereum/go-ethereum/core/types"
-	"github.com/ethereum/go-ethereum/core/vm"
-	"github.com/ethereum/go-ethereum/ethdb"
-	"github.com/ethereum/go-ethereum/logger"
+	"github.com/codegangsta/cli"
 	"github.com/ethereum/go-ethereum/logger/glog"
-	"github.com/ethereum/go-ethereum/tests/helper"
+	"github.com/ethereum/go-ethereum/tests"
 )
 
-type Log struct {
-	AddressF string   `json:"address"`
-	DataF    string   `json:"data"`
-	TopicsF  []string `json:"topics"`
-	BloomF   string   `json:"bloom"`
-}
+var (
+	continueOnError = false
+	testExtension   = ".json"
+	defaultTest     = "all"
+	defaultDir      = "."
+	allTests        = []string{"BlockTests", "StateTests", "TransactionTests", "VMTests"}
+	skipTests       = []string{}
 
-func (self Log) Address() []byte      { return common.Hex2Bytes(self.AddressF) }
-func (self Log) Data() []byte         { return common.Hex2Bytes(self.DataF) }
-func (self Log) RlpData() interface{} { return nil }
-func (self Log) Topics() [][]byte {
-	t := make([][]byte, len(self.TopicsF))
-	for i, topic := range self.TopicsF {
-		t[i] = common.Hex2Bytes(topic)
+	TestFlag = cli.StringFlag{
+		Name:  "test",
+		Usage: "Test type (string): VMTests, TransactionTests, StateTests, BlockTests",
+		Value: defaultTest,
 	}
-	return t
-}
-
-type Account struct {
-	Balance string
-	Code    string
-	Nonce   string
-	Storage map[string]string
-}
-
-func StateObjectFromAccount(db common.Database, addr string, account Account) *state.StateObject {
-	obj := state.NewStateObject(common.HexToAddress(addr), db)
-	obj.SetBalance(common.Big(account.Balance))
-
-	if common.IsHex(account.Code) {
-		account.Code = account.Code[2:]
+	FileFlag = cli.StringFlag{
+		Name:   "file",
+		Usage:  "Test file or directory. Directories are searched for .json files 1 level deep",
+		Value:  defaultDir,
+		EnvVar: "ETHEREUM_TEST_PATH",
 	}
-	obj.SetCode(common.Hex2Bytes(account.Code))
-	obj.SetNonce(common.Big(account.Nonce).Uint64())
+	ContinueOnErrorFlag = cli.BoolFlag{
+		Name:  "continue",
+		Usage: "Continue running tests on error (true) or [default] exit immediately (false)",
+	}
+	ReadStdInFlag = cli.BoolFlag{
+		Name:  "stdin",
+		Usage: "Accept input from stdin instead of reading from file",
+	}
+	SkipTestsFlag = cli.StringFlag{
+		Name:  "skip",
+		Usage: "Tests names to skip",
+	}
+)
 
-	return obj
-}
+func runTestWithReader(test string, r io.Reader) error {
+	glog.Infoln("runTest", test)
+	var err error
+	switch strings.ToLower(test) {
+	case "bk", "block", "blocktest", "blockchaintest", "blocktests", "blockchaintests":
+		err = tests.RunBlockTestWithReader(r, skipTests)
+	case "st", "state", "statetest", "statetests":
+		err = tests.RunStateTestWithReader(r, skipTests)
+	case "tx", "transactiontest", "transactiontests":
+		err = tests.RunTransactionTestsWithReader(r, skipTests)
+	case "vm", "vmtest", "vmtests":
+		err = tests.RunVmTestWithReader(r, skipTests)
+	default:
+		err = fmt.Errorf("Invalid test type specified: %v", test)
+	}
 
-type VmTest struct {
-	Callcreates   interface{}
-	Env           Env
-	Exec          map[string]string
-	Transaction   map[string]string
-	Logs          []Log
-	Gas           string
-	Out           string
-	Post          map[string]Account
-	Pre           map[string]Account
-	PostStateRoot string
-}
-
-type Env struct {
-	CurrentCoinbase   string
-	CurrentDifficulty string
-	CurrentGasLimit   string
-	CurrentNumber     string
-	CurrentTimestamp  interface{}
-	PreviousHash      string
-}
-
-func RunVmTest(r io.Reader) (failed int) {
-	tests := make(map[string]VmTest)
-
-	data, _ := ioutil.ReadAll(r)
-	err := json.Unmarshal(data, &tests)
 	if err != nil {
-		log.Fatalln(err)
+		return err
 	}
 
-	vm.Debug = true
-	glog.SetV(4)
-	glog.SetToStderr(true)
-	for name, test := range tests {
-		db, _ := ethdb.NewMemDatabase()
-		statedb := state.New(common.Hash{}, db)
-		for addr, account := range test.Pre {
-			obj := StateObjectFromAccount(db, addr, account)
-			statedb.SetStateObject(obj)
-		}
+	return nil
+}
+
+func getFiles(path string) ([]string, error) {
+	glog.Infoln("getFiles", path)
+	var files []string
+	f, err := os.Open(path)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+
+	fi, err := f.Stat()
+	if err != nil {
+		return nil, err
+	}
+
+	switch mode := fi.Mode(); {
+	case mode.IsDir():
+		fi, _ := ioutil.ReadDir(path)
+		files = make([]string, len(fi))
+		for i, v := range fi {
+			// only go 1 depth and leave directory entires blank
+			if !v.IsDir() && v.Name()[len(v.Name())-len(testExtension):len(v.Name())] == testExtension {
+				files[i] = filepath.Join(path, v.Name())
+				glog.Infoln("Found file", files[i])
+			}
+		}
+	case mode.IsRegular():
+		files = make([]string, 1)
+		files[0] = path
+	}
+
+	return files, nil
+}
+
+func runSuite(test, file string) {
+	var tests []string
+
+	if test == defaultTest {
+		tests = allTests
+	} else {
+		tests = []string{test}
+	}
+
+	for _, curTest := range tests {
+		glog.Infoln("runSuite", curTest, file)
+		var err error
+		var files []string
+		if test == defaultTest {
+			files, err = getFiles(filepath.Join(file, curTest))
 
-		env := make(map[string]string)
-		env["currentCoinbase"] = test.Env.CurrentCoinbase
-		env["currentDifficulty"] = test.Env.CurrentDifficulty
-		env["currentGasLimit"] = test.Env.CurrentGasLimit
-		env["currentNumber"] = test.Env.CurrentNumber
-		env["previousHash"] = test.Env.PreviousHash
-		if n, ok := test.Env.CurrentTimestamp.(float64); ok {
-			env["currentTimestamp"] = strconv.Itoa(int(n))
 		} else {
-			env["currentTimestamp"] = test.Env.CurrentTimestamp.(string)
+			files, err = getFiles(file)
+		}
+		if err != nil {
+			glog.Fatalln(err)
 		}
 
-		ret, logs, _, _ := helper.RunState(statedb, env, test.Transaction)
-		statedb.Sync()
-
-		rexp := helper.FromHex(test.Out)
-		if bytes.Compare(rexp, ret) != 0 {
-			glog.V(logger.Info).Infof("%s's return failed. Expected %x, got %x\n", name, rexp, ret)
-			failed = 1
+		if len(files) == 0 {
+			glog.Warningln("No files matched path")
 		}
-
-		for addr, account := range test.Post {
-			obj := statedb.GetStateObject(common.HexToAddress(addr))
-			if obj == nil {
+		for _, curFile := range files {
+			// Skip blank entries
+			if len(curFile) == 0 {
 				continue
 			}
 
-			if len(test.Exec) == 0 {
-				if obj.Balance().Cmp(common.Big(account.Balance)) != 0 {
-					glog.V(logger.Info).Infof("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance()))
-					failed = 1
+			r, err := os.Open(curFile)
+			if err != nil {
+				glog.Fatalln(err)
+			}
+			defer r.Close()
+
+			err = runTestWithReader(curTest, r)
+			if err != nil {
+				if continueOnError {
+					glog.Errorln(err)
+				} else {
+					glog.Fatalln(err)
 				}
 			}
 
-			for addr, value := range account.Storage {
-				v := obj.GetState(common.HexToHash(addr)).Bytes()
-				vexp := helper.FromHex(value)
-
-				if bytes.Compare(v, vexp) != 0 {
-					glog.V(logger.Info).Infof("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address().Bytes()[0:4], addr, vexp, v, common.BigD(vexp), common.BigD(v))
-					failed = 1
-				}
-			}
 		}
-
-		statedb.Sync()
-		//if !bytes.Equal(common.Hex2Bytes(test.PostStateRoot), statedb.Root()) {
-		if common.HexToHash(test.PostStateRoot) != statedb.Root() {
-			glog.V(logger.Info).Infof("%s's : Post state root failed. Expected %s, got %x", name, test.PostStateRoot, statedb.Root())
-			failed = 1
-		}
-
-		if len(test.Logs) > 0 {
-			if len(test.Logs) != len(logs) {
-				glog.V(logger.Info).Infof("log length failed. Expected %d, got %d", len(test.Logs), len(logs))
-				failed = 1
-			} else {
-				for i, log := range test.Logs {
-					if common.HexToAddress(log.AddressF) != logs[i].Address {
-						glog.V(logger.Info).Infof("'%s' log address failed. Expected %v got %x", name, log.AddressF, logs[i].Address)
-						failed = 1
-					}
-
-					if !bytes.Equal(logs[i].Data, helper.FromHex(log.DataF)) {
-						glog.V(logger.Info).Infof("'%s' log data failed. Expected %v got %x", name, log.DataF, logs[i].Data)
-						failed = 1
-					}
-
-					if len(log.TopicsF) != len(logs[i].Topics) {
-						glog.V(logger.Info).Infof("'%s' log topics length failed. Expected %d got %d", name, len(log.TopicsF), logs[i].Topics)
-						failed = 1
-					} else {
-						for j, topic := range log.TopicsF {
-							if common.HexToHash(topic) != logs[i].Topics[j] {
-								glog.V(logger.Info).Infof("'%s' log topic[%d] failed. Expected %v got %x", name, j, topic, logs[i].Topics[j])
-								failed = 1
-							}
-						}
-					}
-					genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256)
-
-					if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) {
-						glog.V(logger.Info).Infof("'%s' bloom failed.", name)
-						failed = 1
-					}
-				}
-			}
-		}
-
-		if failed == 1 {
-			glog.V(logger.Info).Infoln(string(statedb.Dump()))
-		}
-
-		logger.Flush()
 	}
+}
 
-	return
+func setupApp(c *cli.Context) {
+	flagTest := c.GlobalString(TestFlag.Name)
+	flagFile := c.GlobalString(FileFlag.Name)
+	continueOnError = c.GlobalBool(ContinueOnErrorFlag.Name)
+	useStdIn := c.GlobalBool(ReadStdInFlag.Name)
+	skipTests = strings.Split(c.GlobalString(SkipTestsFlag.Name), " ")
+
+	if !useStdIn {
+		runSuite(flagTest, flagFile)
+	} else {
+		if err := runTestWithReader(flagTest, os.Stdin); err != nil {
+			glog.Fatalln(err)
+		}
+
+	}
 }
 
 func main() {
-	helper.Logger.SetLogLevel(5)
-	vm.Debug = true
+	glog.SetToStderr(true)
 
-	if len(os.Args) > 1 {
-		os.Exit(RunVmTest(strings.NewReader(os.Args[1])))
-	} else {
-		os.Exit(RunVmTest(os.Stdin))
+	app := cli.NewApp()
+	app.Name = "ethtest"
+	app.Usage = "go-ethereum test interface"
+	app.Action = setupApp
+	app.Version = "0.2.0"
+	app.Author = "go-ethereum team"
+
+	app.Flags = []cli.Flag{
+		TestFlag,
+		FileFlag,
+		ContinueOnErrorFlag,
+		ReadStdInFlag,
+		SkipTestsFlag,
 	}
+
+	if err := app.Run(os.Args); err != nil {
+		glog.Fatalln(err)
+	}
+
 }
diff --git a/cmd/geth/blocktestcmd.go b/cmd/geth/blocktestcmd.go
index ffea4400e..116eec2b3 100644
--- a/cmd/geth/blocktestcmd.go
+++ b/cmd/geth/blocktestcmd.go
@@ -86,6 +86,7 @@ func runBlockTest(ctx *cli.Context) {
 }
 
 func runOneBlockTest(ctx *cli.Context, test *tests.BlockTest) (*eth.Ethereum, error) {
+	// TODO remove in favor of logic contained in tests package
 	cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx)
 	cfg.NewDB = func(path string) (common.Database, error) { return ethdb.NewMemDatabase() }
 	cfg.MaxPeers = 0 // disable network
diff --git a/tests/block_test.go b/tests/block_test.go
index d5136efce..bdf983786 100644
--- a/tests/block_test.go
+++ b/tests/block_test.go
@@ -3,112 +3,71 @@ package tests
 import (
 	"path/filepath"
 	"testing"
-
-	"github.com/ethereum/go-ethereum/accounts"
-	"github.com/ethereum/go-ethereum/common"
-	"github.com/ethereum/go-ethereum/crypto"
-	"github.com/ethereum/go-ethereum/eth"
-	"github.com/ethereum/go-ethereum/ethdb"
 )
 
-// TODO: refactor test setup & execution to better align with vm and tx tests
 func TestBcValidBlockTests(t *testing.T) {
-	// SimpleTx3 genesis block does not validate against calculated state root
-	// as of 2015-06-09. unskip once working /Gustav
-	runBlockTestsInFile("files/BlockTests/bcValidBlockTest.json", []string{"SimpleTx3"}, t)
+	err := RunBlockTest(filepath.Join(blockTestDir, "bcValidBlockTest.json"), BlockSkipTests)
+	if err != nil {
+		t.Fatal(err)
+	}
 }
 
 func TestBcUncleTests(t *testing.T) {
-	runBlockTestsInFile("files/BlockTests/bcUncleTest.json", []string{}, t)
-	runBlockTestsInFile("files/BlockTests/bcBruncleTest.json", []string{}, t)
+	err := RunBlockTest(filepath.Join(blockTestDir, "bcUncleTest.json"), BlockSkipTests)
+	if err != nil {
+		t.Fatal(err)
+	}
+	err = RunBlockTest(filepath.Join(blockTestDir, "bcBruncleTest.json"), BlockSkipTests)
+	if err != nil {
+		t.Fatal(err)
+	}
 }
 
 func TestBcUncleHeaderValidityTests(t *testing.T) {
-	runBlockTestsInFile("files/BlockTests/bcUncleHeaderValiditiy.json", []string{}, t)
+	err := RunBlockTest(filepath.Join(blockTestDir, "bcUncleHeaderValiditiy.json"), BlockSkipTests)
+	if err != nil {
+		t.Fatal(err)
+	}
 }
 
 func TestBcInvalidHeaderTests(t *testing.T) {
-	runBlockTestsInFile("files/BlockTests/bcInvalidHeaderTest.json", []string{}, t)
+	err := RunBlockTest(filepath.Join(blockTestDir, "bcInvalidHeaderTest.json"), BlockSkipTests)
+	if err != nil {
+		t.Fatal(err)
+	}
 }
 
 func TestBcInvalidRLPTests(t *testing.T) {
-	runBlockTestsInFile("files/BlockTests/bcInvalidRLPTest.json", []string{}, t)
+	err := RunBlockTest(filepath.Join(blockTestDir, "bcInvalidRLPTest.json"), BlockSkipTests)
+	if err != nil {
+		t.Fatal(err)
+	}
 }
 
 func TestBcRPCAPITests(t *testing.T) {
-	runBlockTestsInFile("files/BlockTests/bcRPC_API_Test.json", []string{}, t)
+	err := RunBlockTest(filepath.Join(blockTestDir, "bcRPC_API_Test.json"), BlockSkipTests)
+	if err != nil {
+		t.Fatal(err)
+	}
 }
 
 func TestBcForkBlockTests(t *testing.T) {
-	runBlockTestsInFile("files/BlockTests/bcForkBlockTest.json", []string{}, t)
+	err := RunBlockTest(filepath.Join(blockTestDir, "bcForkBlockTest.json"), BlockSkipTests)
+	if err != nil {
+		t.Fatal(err)
+	}
 }
 
 func TestBcTotalDifficulty(t *testing.T) {
-	runBlockTestsInFile("files/BlockTests/bcTotalDifficultyTest.json", []string{}, t)
+	err := RunBlockTest(filepath.Join(blockTestDir, "bcTotalDifficultyTest.json"), BlockSkipTests)
+	if err != nil {
+		t.Fatal(err)
+	}
 }
 
 func TestBcWallet(t *testing.T) {
-	runBlockTestsInFile("files/BlockTests/bcWalletTest.json", []string{}, t)
-}
-
-func runBlockTestsInFile(filepath string, snafus []string, t *testing.T) {
-	bt, err := LoadBlockTests(filepath)
+	err := RunBlockTest(filepath.Join(blockTestDir, "bcWalletTest.json"), BlockSkipTests)
 	if err != nil {
 		t.Fatal(err)
 	}
-
-	notWorking := make(map[string]bool, 100)
-	for _, name := range snafus {
-		notWorking[name] = true
-	}
-
-	for name, test := range bt {
-		if !notWorking[name] {
-			runBlockTest(name, test, t)
-		}
-	}
-}
-
-func runBlockTest(name string, test *BlockTest, t *testing.T) {
-	cfg := testEthConfig()
-	ethereum, err := eth.New(cfg)
-	if err != nil {
-		t.Fatalf("%v", err)
-	}
-
-	err = ethereum.Start()
-	if err != nil {
-		t.Fatalf("%v", err)
-	}
-
-	// import the genesis block
-	ethereum.ResetWithGenesisBlock(test.Genesis)
-
-	// import pre accounts
-	statedb, err := test.InsertPreState(ethereum)
-	if err != nil {
-		t.Fatalf("InsertPreState: %v", err)
-	}
-
-	err = test.TryBlocksInsert(ethereum.ChainManager())
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if err = test.ValidatePostState(statedb); err != nil {
-		t.Fatal("post state validation failed: %v", err)
-	}
-	t.Log("Test passed: ", name)
-}
-
-func testEthConfig() *eth.Config {
-	ks := crypto.NewKeyStorePassphrase(filepath.Join(common.DefaultDataDir(), "keystore"))
-
-	return &eth.Config{
-		DataDir:        common.DefaultDataDir(),
-		Verbosity:      5,
-		Etherbase:      "primary",
-		AccountManager: accounts.NewManager(ks),
-		NewDB:          func(path string) (common.Database, error) { return ethdb.NewMemDatabase() },
-	}
 }
diff --git a/tests/block_test_util.go b/tests/block_test_util.go
index 200fcbd59..5fdc6402e 100644
--- a/tests/block_test_util.go
+++ b/tests/block_test_util.go
@@ -3,21 +3,24 @@ package tests
 import (
 	"bytes"
 	"encoding/hex"
-	"encoding/json"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"math/big"
+	"path/filepath"
 	"runtime"
 	"strconv"
 	"strings"
 	"time"
 
+	"github.com/ethereum/go-ethereum/accounts"
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/core"
 	"github.com/ethereum/go-ethereum/core/state"
 	"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/logger/glog"
 	"github.com/ethereum/go-ethereum/rlp"
 )
 
@@ -83,20 +86,104 @@ type btTransaction struct {
 	Value    string
 }
 
-// LoadBlockTests loads a block test JSON file.
-func LoadBlockTests(file string) (map[string]*BlockTest, error) {
-	bt := make(map[string]*btJSON)
-	if err := LoadJSON(file, &bt); err != nil {
-		return nil, err
+func RunBlockTestWithReader(r io.Reader, skipTests []string) error {
+	btjs := make(map[string]*btJSON)
+	if err := readJson(r, &btjs); err != nil {
+		return err
 	}
-	out := make(map[string]*BlockTest)
-	for name, in := range bt {
-		var err error
-		if out[name], err = convertTest(in); err != nil {
-			return out, fmt.Errorf("bad test %q: %v", name, err)
+
+	bt, err := convertBlockTests(btjs)
+	if err != nil {
+		return err
+	}
+
+	if err := runBlockTests(bt, skipTests); err != nil {
+		return err
+	}
+	return nil
+}
+
+func RunBlockTest(file string, skipTests []string) error {
+	btjs := make(map[string]*btJSON)
+	if err := readJsonFile(file, &btjs); err != nil {
+		return err
+	}
+
+	bt, err := convertBlockTests(btjs)
+	if err != nil {
+		return err
+	}
+	if err := runBlockTests(bt, skipTests); err != nil {
+		return err
+	}
+	return nil
+}
+
+func runBlockTests(bt map[string]*BlockTest, skipTests []string) error {
+	skipTest := make(map[string]bool, len(skipTests))
+	for _, name := range skipTests {
+		skipTest[name] = true
+	}
+
+	for name, test := range bt {
+		// if the test should be skipped, return
+		if skipTest[name] {
+			glog.Infoln("Skipping block test", name)
+			return nil
 		}
+
+		// test the block
+		if err := runBlockTest(test); err != nil {
+			return err
+		}
+		glog.Infoln("Block test passed: ", name)
+
+	}
+	return nil
+
+}
+func runBlockTest(test *BlockTest) error {
+	cfg := test.makeEthConfig()
+	ethereum, err := eth.New(cfg)
+	if err != nil {
+		return err
+	}
+
+	err = ethereum.Start()
+	if err != nil {
+		return err
+	}
+
+	// import the genesis block
+	ethereum.ResetWithGenesisBlock(test.Genesis)
+
+	// import pre accounts
+	statedb, err := test.InsertPreState(ethereum)
+	if err != nil {
+		return fmt.Errorf("InsertPreState: %v", err)
+	}
+
+	err = test.TryBlocksInsert(ethereum.ChainManager())
+	if err != nil {
+		return err
+	}
+
+	if err = test.ValidatePostState(statedb); err != nil {
+		return fmt.Errorf("post state validation failed: %v", err)
+	}
+	return nil
+}
+
+func (test *BlockTest) makeEthConfig() *eth.Config {
+	ks := crypto.NewKeyStorePassphrase(filepath.Join(common.DefaultDataDir(), "keystore"))
+
+	return &eth.Config{
+		DataDir:        common.DefaultDataDir(),
+		Verbosity:      5,
+		Etherbase:      "primary",
+		AccountManager: accounts.NewManager(ks),
+		NewDB:          func(path string) (common.Database, error) { return ethdb.NewMemDatabase() },
 	}
-	return out, nil
 }
 
 // InsertPreState populates the given database with the genesis
@@ -173,7 +260,7 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
 		if b.BlockHeader == nil {
 			return fmt.Errorf("Block insertion should have failed")
 		}
-		err = validateBlockHeader(b.BlockHeader, cb.Header())
+		err = t.validateBlockHeader(b.BlockHeader, cb.Header())
 		if err != nil {
 			return fmt.Errorf("Block header validation failed: ", err)
 		}
@@ -181,7 +268,7 @@ func (t *BlockTest) TryBlocksInsert(chainManager *core.ChainManager) error {
 	return nil
 }
 
-func validateBlockHeader(h *btHeader, h2 *types.Header) error {
+func (s *BlockTest) validateBlockHeader(h *btHeader, h2 *types.Header) error {
 	expectedBloom := mustConvertBytes(h.Bloom)
 	if !bytes.Equal(expectedBloom, h2.Bloom.Bytes()) {
 		return fmt.Errorf("Bloom: expected: %v, decoded: %v", expectedBloom, h2.Bloom.Bytes())
@@ -284,7 +371,18 @@ func (t *BlockTest) ValidatePostState(statedb *state.StateDB) error {
 	return nil
 }
 
-func convertTest(in *btJSON) (out *BlockTest, err error) {
+func convertBlockTests(in map[string]*btJSON) (map[string]*BlockTest, error) {
+	out := make(map[string]*BlockTest)
+	for name, test := range in {
+		var err error
+		if out[name], err = convertBlockTest(test); err != nil {
+			return out, fmt.Errorf("bad test %q: %v", name, err)
+		}
+	}
+	return out, nil
+}
+
+func convertBlockTest(in *btJSON) (out *BlockTest, err error) {
 	// the conversion handles errors by catching panics.
 	// you might consider this ugly, but the alternative (passing errors)
 	// would be much harder to read.
@@ -392,34 +490,13 @@ func mustConvertUint(in string, base int) uint64 {
 	return out
 }
 
-// LoadJSON reads the given file and unmarshals its content.
-func LoadJSON(file string, val interface{}) error {
-	content, err := ioutil.ReadFile(file)
-	if err != nil {
-		return err
+func LoadBlockTests(file string) (map[string]*BlockTest, error) {
+	btjs := make(map[string]*btJSON)
+	if err := readJsonFile(file, &btjs); err != nil {
+		return nil, err
 	}
-	if err := json.Unmarshal(content, val); err != nil {
-		if syntaxerr, ok := err.(*json.SyntaxError); ok {
-			line := findLine(content, syntaxerr.Offset)
-			return fmt.Errorf("JSON syntax error at %v:%v: %v", file, line, err)
-		}
-		return fmt.Errorf("JSON unmarshal error in %v: %v", file, err)
-	}
-	return nil
-}
 
-// findLine returns the line number for the given offset into data.
-func findLine(data []byte, offset int64) (line int) {
-	line = 1
-	for i, r := range string(data) {
-		if int64(i) >= offset {
-			return
-		}
-		if r == '\n' {
-			line++
-		}
-	}
-	return
+	return convertBlockTests(btjs)
 }
 
 // Nothing to see here, please move along...
diff --git a/tests/helper/common.go b/tests/helper/common.go
deleted file mode 100644
index 21ea2261f..000000000
--- a/tests/helper/common.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package helper
-
-import "github.com/ethereum/go-ethereum/common"
-
-func FromHex(h string) []byte {
-	if common.IsHex(h) {
-		h = h[2:]
-	}
-
-	return common.Hex2Bytes(h)
-}
diff --git a/tests/helper/init.go b/tests/helper/init.go
deleted file mode 100644
index 73d563e02..000000000
--- a/tests/helper/init.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package helper
-
-import (
-	"log"
-	"os"
-
-	logpkg "github.com/ethereum/go-ethereum/logger"
-)
-
-var Logger *logpkg.StdLogSystem
-var Log = logpkg.NewLogger("TEST")
-
-func init() {
-	Logger = logpkg.NewStdLogSystem(os.Stdout, log.LstdFlags, logpkg.InfoLevel)
-	logpkg.AddLogSystem(Logger)
-}
diff --git a/tests/helper/readers.go b/tests/helper/readers.go
deleted file mode 100644
index 03313aeda..000000000
--- a/tests/helper/readers.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package helper
-
-import (
-	"encoding/json"
-	"io"
-	"io/ioutil"
-	"net/http"
-	"os"
-	"testing"
-)
-
-func readJSON(t *testing.T, reader io.Reader, value interface{}) {
-	data, err := ioutil.ReadAll(reader)
-	err = json.Unmarshal(data, &value)
-	if err != nil {
-		t.Error(err)
-	}
-}
-
-func CreateHttpTests(t *testing.T, uri string, value interface{}) {
-	resp, err := http.Get(uri)
-	if err != nil {
-		t.Error(err)
-
-		return
-	}
-	defer resp.Body.Close()
-
-	readJSON(t, resp.Body, value)
-}
-
-func CreateFileTests(t *testing.T, fn string, value interface{}) {
-	file, err := os.Open(fn)
-	if err != nil {
-		t.Error(err)
-
-		return
-	}
-	defer file.Close()
-
-	readJSON(t, file, value)
-}
diff --git a/tests/helper/trie.go b/tests/helper/trie.go
deleted file mode 100644
index 9e666d333..000000000
--- a/tests/helper/trie.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package helper
-
-import "github.com/ethereum/go-ethereum/trie"
-
-type MemDatabase struct {
-	db map[string][]byte
-}
-
-func NewMemDatabase() (*MemDatabase, error) {
-	db := &MemDatabase{db: make(map[string][]byte)}
-	return db, nil
-}
-func (db *MemDatabase) Put(key []byte, value []byte) {
-	db.db[string(key)] = value
-}
-func (db *MemDatabase) Get(key []byte) ([]byte, error) {
-	return db.db[string(key)], nil
-}
-func (db *MemDatabase) Delete(key []byte) error {
-	delete(db.db, string(key))
-	return nil
-}
-func (db *MemDatabase) Print()              {}
-func (db *MemDatabase) Close()              {}
-func (db *MemDatabase) LastKnownTD() []byte { return nil }
-
-func NewTrie() *trie.Trie {
-	db, _ := NewMemDatabase()
-
-	return trie.New(nil, db)
-}
diff --git a/tests/init.go b/tests/init.go
new file mode 100644
index 000000000..9fe98a0d1
--- /dev/null
+++ b/tests/init.go
@@ -0,0 +1,82 @@
+package tests
+
+import (
+	"encoding/json"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"os"
+	"path/filepath"
+)
+
+var (
+	baseDir            = filepath.Join(".", "files")
+	blockTestDir       = filepath.Join(baseDir, "BlockTests")
+	stateTestDir       = filepath.Join(baseDir, "StateTests")
+	transactionTestDir = filepath.Join(baseDir, "TransactionTests")
+	vmTestDir          = filepath.Join(baseDir, "VMTests")
+
+	BlockSkipTests = []string{"SimpleTx3"}
+	TransSkipTests = []string{"TransactionWithHihghNonce256"}
+	StateSkipTests = []string{"mload32bitBound_return", "mload32bitBound_return2"}
+	VmSkipTests    = []string{}
+)
+
+func readJson(reader io.Reader, value interface{}) error {
+	data, err := ioutil.ReadAll(reader)
+	if err != nil {
+		return fmt.Errorf("Error reading JSON file", err.Error())
+	}
+
+	if err = json.Unmarshal(data, &value); err != nil {
+		if syntaxerr, ok := err.(*json.SyntaxError); ok {
+			line := findLine(data, syntaxerr.Offset)
+			return fmt.Errorf("JSON syntax error at line %v: %v", line, err)
+		}
+		return fmt.Errorf("JSON unmarshal error: %v", err)
+	}
+	return nil
+}
+
+func readJsonHttp(uri string, value interface{}) error {
+	resp, err := http.Get(uri)
+	if err != nil {
+		return err
+	}
+	defer resp.Body.Close()
+
+	err = readJson(resp.Body, value)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func readJsonFile(fn string, value interface{}) error {
+	file, err := os.Open(fn)
+	if err != nil {
+		return err
+	}
+	defer file.Close()
+
+	err = readJson(file, value)
+	if err != nil {
+		return fmt.Errorf("%s in file %s", err.Error(), fn)
+	}
+	return nil
+}
+
+// findLine returns the line number for the given offset into data.
+func findLine(data []byte, offset int64) (line int) {
+	line = 1
+	for i, r := range string(data) {
+		if int64(i) >= offset {
+			return
+		}
+		if r == '\n' {
+			line++
+		}
+	}
+	return
+}
diff --git a/tests/state_test.go b/tests/state_test.go
new file mode 100644
index 000000000..e58f588f4
--- /dev/null
+++ b/tests/state_test.go
@@ -0,0 +1,134 @@
+package tests
+
+import (
+	"os"
+	"path/filepath"
+	"testing"
+)
+
+func TestStateSystemOperations(t *testing.T) {
+	fn := filepath.Join(stateTestDir, "stSystemOperationsTest.json")
+	if err := RunStateTest(fn, StateSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestStateExample(t *testing.T) {
+	fn := filepath.Join(stateTestDir, "stExample.json")
+	if err := RunStateTest(fn, StateSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestStatePreCompiledContracts(t *testing.T) {
+	fn := filepath.Join(stateTestDir, "stPreCompiledContracts.json")
+	if err := RunStateTest(fn, StateSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestStateRecursiveCreate(t *testing.T) {
+	fn := filepath.Join(stateTestDir, "stRecursiveCreate.json")
+	if err := RunStateTest(fn, StateSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestStateSpecial(t *testing.T) {
+	fn := filepath.Join(stateTestDir, "stSpecialTest.json")
+	if err := RunStateTest(fn, StateSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestStateRefund(t *testing.T) {
+	fn := filepath.Join(stateTestDir, "stRefundTest.json")
+	if err := RunStateTest(fn, StateSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestStateBlockHash(t *testing.T) {
+	fn := filepath.Join(stateTestDir, "stBlockHashTest.json")
+	if err := RunStateTest(fn, StateSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestStateInitCode(t *testing.T) {
+	fn := filepath.Join(stateTestDir, "stInitCodeTest.json")
+	if err := RunStateTest(fn, StateSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestStateLog(t *testing.T) {
+	fn := filepath.Join(stateTestDir, "stLogTests.json")
+	if err := RunStateTest(fn, StateSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestStateTransaction(t *testing.T) {
+	fn := filepath.Join(stateTestDir, "stTransactionTest.json")
+	if err := RunStateTest(fn, StateSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestCallCreateCallCode(t *testing.T) {
+	fn := filepath.Join(stateTestDir, "stCallCreateCallCodeTest.json")
+	if err := RunStateTest(fn, StateSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestMemory(t *testing.T) {
+	fn := filepath.Join(stateTestDir, "stMemoryTest.json")
+	if err := RunStateTest(fn, StateSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestMemoryStress(t *testing.T) {
+	if os.Getenv("TEST_VM_COMPLEX") == "" {
+		t.Skip()
+	}
+	fn := filepath.Join(stateTestDir, "stMemoryStressTest.json")
+	if err := RunStateTest(fn, StateSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestQuadraticComplexity(t *testing.T) {
+	if os.Getenv("TEST_VM_COMPLEX") == "" {
+		t.Skip()
+	}
+	fn := filepath.Join(stateTestDir, "stQuadraticComplexityTest.json")
+	if err := RunStateTest(fn, StateSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestSolidity(t *testing.T) {
+	fn := filepath.Join(stateTestDir, "stSolidityTest.json")
+	if err := RunStateTest(fn, StateSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestWallet(t *testing.T) {
+	fn := filepath.Join(stateTestDir, "stWalletTest.json")
+	if err := RunStateTest(fn, StateSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestStateTestsRandom(t *testing.T) {
+	fns, _ := filepath.Glob("./files/StateTests/RandomTests/*")
+	for _, fn := range fns {
+		if err := RunStateTest(fn, StateSkipTests); err != nil {
+			t.Error(err)
+		}
+	}
+}
diff --git a/tests/state_test_util.go b/tests/state_test_util.go
new file mode 100644
index 000000000..e9abad788
--- /dev/null
+++ b/tests/state_test_util.go
@@ -0,0 +1,181 @@
+package tests
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"math/big"
+	"strconv"
+
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/core"
+	"github.com/ethereum/go-ethereum/core/state"
+	"github.com/ethereum/go-ethereum/core/vm"
+	"github.com/ethereum/go-ethereum/crypto"
+	"github.com/ethereum/go-ethereum/ethdb"
+	"github.com/ethereum/go-ethereum/logger/glog"
+)
+
+func RunStateTestWithReader(r io.Reader, skipTests []string) error {
+	tests := make(map[string]VmTest)
+	if err := readJson(r, &tests); err != nil {
+		return err
+	}
+
+	if err := runStateTests(tests, skipTests); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func RunStateTest(p string, skipTests []string) error {
+	tests := make(map[string]VmTest)
+	if err := readJsonFile(p, &tests); err != nil {
+		return err
+	}
+
+	if err := runStateTests(tests, skipTests); err != nil {
+		return err
+	}
+
+	return nil
+
+}
+
+func runStateTests(tests map[string]VmTest, skipTests []string) error {
+	skipTest := make(map[string]bool, len(skipTests))
+	for _, name := range skipTests {
+		skipTest[name] = true
+	}
+
+	for name, test := range tests {
+		if skipTest[name] {
+			glog.Infoln("Skipping state test", name)
+			return nil
+		}
+
+		if err := runStateTest(test); err != nil {
+			return fmt.Errorf("%s: %s\n", name, err.Error())
+		}
+
+		glog.Infoln("State test passed: ", name)
+		//fmt.Println(string(statedb.Dump()))
+	}
+	return nil
+
+}
+
+func runStateTest(test VmTest) error {
+	db, _ := ethdb.NewMemDatabase()
+	statedb := state.New(common.Hash{}, db)
+	for addr, account := range test.Pre {
+		obj := StateObjectFromAccount(db, addr, account)
+		statedb.SetStateObject(obj)
+		for a, v := range account.Storage {
+			obj.SetState(common.HexToHash(a), common.HexToHash(v))
+		}
+	}
+
+	// XXX Yeah, yeah...
+	env := make(map[string]string)
+	env["currentCoinbase"] = test.Env.CurrentCoinbase
+	env["currentDifficulty"] = test.Env.CurrentDifficulty
+	env["currentGasLimit"] = test.Env.CurrentGasLimit
+	env["currentNumber"] = test.Env.CurrentNumber
+	env["previousHash"] = test.Env.PreviousHash
+	if n, ok := test.Env.CurrentTimestamp.(float64); ok {
+		env["currentTimestamp"] = strconv.Itoa(int(n))
+	} else {
+		env["currentTimestamp"] = test.Env.CurrentTimestamp.(string)
+	}
+
+	var (
+		ret []byte
+		// gas  *big.Int
+		// err  error
+		logs state.Logs
+	)
+
+	ret, logs, _, _ = RunState(statedb, env, test.Transaction)
+
+	// // Compare expected  and actual return
+	rexp := common.FromHex(test.Out)
+	if bytes.Compare(rexp, ret) != 0 {
+		return fmt.Errorf("return failed. Expected %x, got %x\n", rexp, ret)
+	}
+
+	// check post state
+	for addr, account := range test.Post {
+		obj := statedb.GetStateObject(common.HexToAddress(addr))
+		if obj == nil {
+			continue
+		}
+
+		if obj.Balance().Cmp(common.Big(account.Balance)) != 0 {
+			return fmt.Errorf("(%x) balance failed. Expected %v, got %v => %v\n", obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance()))
+		}
+
+		if obj.Nonce() != common.String2Big(account.Nonce).Uint64() {
+			return fmt.Errorf("(%x) nonce failed. Expected %v, got %v\n", obj.Address().Bytes()[:4], account.Nonce, obj.Nonce())
+		}
+
+		for addr, value := range account.Storage {
+			v := obj.GetState(common.HexToHash(addr))
+			vexp := common.HexToHash(value)
+
+			if v != vexp {
+				return fmt.Errorf("(%x: %s) storage failed. Expected %x, got %x (%v %v)\n", obj.Address().Bytes()[0:4], addr, vexp, v, vexp.Big(), v.Big())
+			}
+		}
+	}
+
+	statedb.Sync()
+	if common.HexToHash(test.PostStateRoot) != statedb.Root() {
+		return fmt.Errorf("Post state root error. Expected %s, got %x", test.PostStateRoot, statedb.Root())
+	}
+
+	// check logs
+	if len(test.Logs) > 0 {
+		if err := checkLogs(test.Logs, logs); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.Logs, *big.Int, error) {
+	var (
+		keyPair, _ = crypto.NewKeyPairFromSec([]byte(common.Hex2Bytes(tx["secretKey"])))
+		data       = common.FromHex(tx["data"])
+		gas        = common.Big(tx["gasLimit"])
+		price      = common.Big(tx["gasPrice"])
+		value      = common.Big(tx["value"])
+		nonce      = common.Big(tx["nonce"]).Uint64()
+		caddr      = common.HexToAddress(env["currentCoinbase"])
+	)
+
+	var to *common.Address
+	if len(tx["to"]) > 2 {
+		t := common.HexToAddress(tx["to"])
+		to = &t
+	}
+	// Set pre compiled contracts
+	vm.Precompiled = vm.PrecompiledContracts()
+
+	snapshot := statedb.Copy()
+	coinbase := statedb.GetOrNewStateObject(caddr)
+	coinbase.SetGasPool(common.Big(env["currentGasLimit"]))
+
+	message := NewMessage(common.BytesToAddress(keyPair.Address()), to, data, value, gas, price, nonce)
+	vmenv := NewEnvFromMap(statedb, env, tx)
+	vmenv.origin = common.BytesToAddress(keyPair.Address())
+	ret, _, err := core.ApplyMessage(vmenv, message, coinbase)
+	if core.IsNonceErr(err) || core.IsInvalidTxErr(err) || state.IsGasLimitErr(err) {
+		statedb.Set(snapshot)
+	}
+	statedb.Update()
+
+	return ret, vmenv.state.Logs(), vmenv.Gas, err
+}
diff --git a/tests/transaction_test.go b/tests/transaction_test.go
index 7ae1c8788..70aa65cdd 100644
--- a/tests/transaction_test.go
+++ b/tests/transaction_test.go
@@ -1,44 +1,26 @@
 package tests
 
 import (
+	"path/filepath"
 	"testing"
 )
 
 func TestTransactions(t *testing.T) {
-	notWorking := make(map[string]bool, 100)
-
-	// TODO: all these tests should work! remove them from the array when they work
-	snafus := []string{
-		"TransactionWithHihghNonce256", // fails due to testing upper bound of 256 bit nonce
-	}
-
-	for _, name := range snafus {
-		notWorking[name] = true
-	}
-
-	var err error
-	err = RunTransactionTests("./files/TransactionTests/ttTransactionTest.json",
-		notWorking)
+	err := RunTransactionTests(filepath.Join(transactionTestDir, "ttTransactionTest.json"), TransSkipTests)
 	if err != nil {
 		t.Fatal(err)
 	}
 }
 
 func TestWrongRLPTransactions(t *testing.T) {
-	notWorking := make(map[string]bool, 100)
-	var err error
-	err = RunTransactionTests("./files/TransactionTests/ttWrongRLPTransaction.json",
-		notWorking)
+	err := RunTransactionTests(filepath.Join(transactionTestDir, "ttWrongRLPTransaction.json"), TransSkipTests)
 	if err != nil {
 		t.Fatal(err)
 	}
 }
 
 func Test10MBtx(t *testing.T) {
-	notWorking := make(map[string]bool, 100)
-	var err error
-	err = RunTransactionTests("./files/TransactionTests/tt10mbDataField.json",
-		notWorking)
+	err := RunTransactionTests(filepath.Join(transactionTestDir, "tt10mbDataField.json"), TransSkipTests)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go
index 82038c3e8..45caf26fd 100644
--- a/tests/transaction_test_util.go
+++ b/tests/transaction_test_util.go
@@ -4,10 +4,12 @@ import (
 	"bytes"
 	"errors"
 	"fmt"
+	"io"
 	"runtime"
 
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/core/types"
+	"github.com/ethereum/go-ethereum/logger/glog"
 	"github.com/ethereum/go-ethereum/rlp"
 )
 
@@ -30,25 +32,69 @@ type TransactionTest struct {
 	Transaction TtTransaction
 }
 
-func RunTransactionTests(file string, notWorking map[string]bool) error {
+func RunTransactionTestsWithReader(r io.Reader, skipTests []string) error {
+	skipTest := make(map[string]bool, len(skipTests))
+	for _, name := range skipTests {
+		skipTest[name] = true
+	}
+
 	bt := make(map[string]TransactionTest)
-	if err := LoadJSON(file, &bt); err != nil {
+	if err := readJson(r, &bt); err != nil {
 		return err
 	}
-	for name, in := range bt {
-		var err error
-		// TODO: remove this, we currently ignore some tests which are broken
-		if !notWorking[name] {
-			if err = runTest(in); err != nil {
-				return fmt.Errorf("bad test %s: %v", name, err)
-			}
-			fmt.Println("Test passed:", name)
+
+	for name, test := range bt {
+		// if the test should be skipped, return
+		if skipTest[name] {
+			glog.Infoln("Skipping transaction test", name)
+			return nil
 		}
+		// test the block
+		if err := runTransactionTest(test); err != nil {
+			return err
+		}
+		glog.Infoln("Transaction test passed: ", name)
+
 	}
 	return nil
 }
 
-func runTest(txTest TransactionTest) (err error) {
+func RunTransactionTests(file string, skipTests []string) error {
+	tests := make(map[string]TransactionTest)
+	if err := readJsonFile(file, &tests); err != nil {
+		return err
+	}
+
+	if err := runTransactionTests(tests, skipTests); err != nil {
+		return err
+	}
+	return nil
+}
+
+func runTransactionTests(tests map[string]TransactionTest, skipTests []string) error {
+	skipTest := make(map[string]bool, len(skipTests))
+	for _, name := range skipTests {
+		skipTest[name] = true
+	}
+
+	for name, test := range tests {
+		// if the test should be skipped, return
+		if skipTest[name] {
+			glog.Infoln("Skipping transaction test", name)
+			return nil
+		}
+
+		// test the block
+		if err := runTransactionTest(test); err != nil {
+			return err
+		}
+		glog.Infoln("Transaction test passed: ", name)
+
+	}
+	return nil
+}
+
+func runTransactionTest(txTest TransactionTest) (err error) {
 	tx := new(types.Transaction)
 	err = rlp.DecodeBytes(mustConvertBytes(txTest.Rlp), tx)
 
diff --git a/tests/helper/vm.go b/tests/util.go
similarity index 64%
rename from tests/helper/vm.go
rename to tests/util.go
index e29a2d8ee..67650c188 100644
--- a/tests/helper/vm.go
+++ b/tests/util.go
@@ -1,16 +1,113 @@
-package helper
+package tests
 
 import (
+	"bytes"
 	"errors"
+	"fmt"
 	"math/big"
 
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/core"
 	"github.com/ethereum/go-ethereum/core/state"
+	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/core/vm"
 	"github.com/ethereum/go-ethereum/crypto"
 )
 
+func checkLogs(tlog []Log, logs state.Logs) error {
+
+	if len(tlog) != len(logs) {
+		return fmt.Errorf("log length mismatch. Expected %d, got %d", len(tlog), len(logs))
+	} else {
+		for i, log := range tlog {
+			if common.HexToAddress(log.AddressF) != logs[i].Address {
+				return fmt.Errorf("log address expected %v got %x", log.AddressF, logs[i].Address)
+			}
+
+			if !bytes.Equal(logs[i].Data, common.FromHex(log.DataF)) {
+				return fmt.Errorf("log data expected %v got %x", log.DataF, logs[i].Data)
+			}
+
+			if len(log.TopicsF) != len(logs[i].Topics) {
+				return fmt.Errorf("log topics length expected %d got %d", len(log.TopicsF), logs[i].Topics)
+			} else {
+				for j, topic := range log.TopicsF {
+					if common.HexToHash(topic) != logs[i].Topics[j] {
+						return fmt.Errorf("log topic[%d] expected %v got %x", j, topic, logs[i].Topics[j])
+					}
+				}
+			}
+			genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256)
+
+			if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) {
+				return fmt.Errorf("bloom mismatch")
+			}
+		}
+	}
+	return nil
+}
+
+type Account struct {
+	Balance string
+	Code    string
+	Nonce   string
+	Storage map[string]string
+}
+
+type Log struct {
+	AddressF string   `json:"address"`
+	DataF    string   `json:"data"`
+	TopicsF  []string `json:"topics"`
+	BloomF   string   `json:"bloom"`
+}
+
+func (self Log) Address() []byte      { return common.Hex2Bytes(self.AddressF) }
+func (self Log) Data() []byte         { return common.Hex2Bytes(self.DataF) }
+func (self Log) RlpData() interface{} { return nil }
+func (self Log) Topics() [][]byte {
+	t := make([][]byte, len(self.TopicsF))
+	for i, topic := range self.TopicsF {
+		t[i] = common.Hex2Bytes(topic)
+	}
+	return t
+}
+
+func StateObjectFromAccount(db common.Database, addr string, account Account) *state.StateObject {
+	obj := state.NewStateObject(common.HexToAddress(addr), db)
+	obj.SetBalance(common.Big(account.Balance))
+
+	if common.IsHex(account.Code) {
+		account.Code = account.Code[2:]
+	}
+	obj.SetCode(common.Hex2Bytes(account.Code))
+	obj.SetNonce(common.Big(account.Nonce).Uint64())
+
+	return obj
+}
+
+type VmEnv struct {
+	CurrentCoinbase   string
+	CurrentDifficulty string
+	CurrentGasLimit   string
+	CurrentNumber     string
+	CurrentTimestamp  interface{}
+	PreviousHash      string
+}
+
+type VmTest struct {
+	Callcreates interface{}
+	//Env         map[string]string
+	Env           VmEnv
+	Exec          map[string]string
+	Transaction   map[string]string
+	Logs          []Log
+	Gas           string
+	Out           string
+	Post          map[string]Account
+	Pre           map[string]Account
+	PostStateRoot string
+}
+
 type Env struct {
 	depth        int
 	state        *state.StateDB
@@ -27,8 +124,9 @@ type Env struct {
 	difficulty *big.Int
 	gasLimit   *big.Int
 
+	logs []vm.StructLog
+
 	vmTest bool
-	logs   []vm.StructLog
 }
 
 func NewEnv(state *state.StateDB) *Env {
@@ -140,64 +238,6 @@ func (self *Env) Create(caller vm.ContextRef, data []byte, gas, price, value *bi
 	}
 }
 
-func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Logs, *big.Int, error) {
-	var (
-		to    = common.HexToAddress(exec["address"])
-		from  = common.HexToAddress(exec["caller"])
-		data  = FromHex(exec["data"])
-		gas   = common.Big(exec["gas"])
-		price = common.Big(exec["gasPrice"])
-		value = common.Big(exec["value"])
-	)
-	// Reset the pre-compiled contracts for VM tests.
-	vm.Precompiled = make(map[string]*vm.PrecompiledAccount)
-
-	caller := state.GetOrNewStateObject(from)
-
-	vmenv := NewEnvFromMap(state, env, exec)
-	vmenv.vmTest = true
-	vmenv.skipTransfer = true
-	vmenv.initial = true
-	ret, err := vmenv.Call(caller, to, data, gas, price, value)
-
-	return ret, vmenv.state.Logs(), vmenv.Gas, err
-}
-
-func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.Logs, *big.Int, error) {
-	var (
-		keyPair, _ = crypto.NewKeyPairFromSec([]byte(common.Hex2Bytes(tx["secretKey"])))
-		data       = FromHex(tx["data"])
-		gas        = common.Big(tx["gasLimit"])
-		price      = common.Big(tx["gasPrice"])
-		value      = common.Big(tx["value"])
-		nonce      = common.Big(tx["nonce"]).Uint64()
-		caddr      = common.HexToAddress(env["currentCoinbase"])
-	)
-
-	var to *common.Address
-	if len(tx["to"]) > 2 {
-		t := common.HexToAddress(tx["to"])
-		to = &t
-	}
-	// Set pre compiled contracts
-	vm.Precompiled = vm.PrecompiledContracts()
-
-	snapshot := statedb.Copy()
-	coinbase := statedb.GetOrNewStateObject(caddr)
-	coinbase.SetGasPool(common.Big(env["currentGasLimit"]))
-
-	message := NewMessage(common.BytesToAddress(keyPair.Address()), to, data, value, gas, price, nonce)
-	vmenv := NewEnvFromMap(statedb, env, tx)
-	vmenv.origin = common.BytesToAddress(keyPair.Address())
-	ret, _, err := core.ApplyMessage(vmenv, message, coinbase)
-	if core.IsNonceErr(err) || core.IsInvalidTxErr(err) || state.IsGasLimitErr(err) {
-		statedb.Set(snapshot)
-	}
-	statedb.Update()
-
-	return ret, vmenv.state.Logs(), vmenv.Gas, err
-}
-
 type Message struct {
 	from              common.Address
 	to                *common.Address
diff --git a/tests/vm/.ethtest b/tests/vm/.ethtest
deleted file mode 100644
index e69de29bb..000000000
diff --git a/tests/vm/gh_test.go b/tests/vm/gh_test.go
deleted file mode 100644
index be9e89d9c..000000000
--- a/tests/vm/gh_test.go
+++ /dev/null
@@ -1,388 +0,0 @@
-package vm
-
-import (
-	"bytes"
-	"math/big"
-	"os"
-	"path/filepath"
-	"strconv"
-	"testing"
-
-	"github.com/ethereum/go-ethereum/common"
-	"github.com/ethereum/go-ethereum/core/state"
-	"github.com/ethereum/go-ethereum/core/types"
-	"github.com/ethereum/go-ethereum/ethdb"
-	"github.com/ethereum/go-ethereum/logger"
-	"github.com/ethereum/go-ethereum/tests/helper"
-)
-
-type Account struct {
-	Balance string
-	Code    string
-	Nonce   string
-	Storage map[string]string
-}
-
-type Log struct {
-	AddressF string   `json:"address"`
-	DataF    string   `json:"data"`
-	TopicsF  []string `json:"topics"`
-	BloomF   string   `json:"bloom"`
-}
-
-func (self Log) Address() []byte      { return common.Hex2Bytes(self.AddressF) }
-func (self Log) Data() []byte         { return common.Hex2Bytes(self.DataF) }
-func (self Log) RlpData() interface{} { return nil }
-func (self Log) Topics() [][]byte {
-	t := make([][]byte, len(self.TopicsF))
-	for i, topic := range self.TopicsF {
-		t[i] = common.Hex2Bytes(topic)
-	}
-	return t
-}
-
-func StateObjectFromAccount(db common.Database, addr string, account Account) *state.StateObject {
-	obj := state.NewStateObject(common.HexToAddress(addr), db)
-	obj.SetBalance(common.Big(account.Balance))
-
-	if common.IsHex(account.Code) {
-		account.Code = account.Code[2:]
-	}
-	obj.SetCode(common.Hex2Bytes(account.Code))
-	obj.SetNonce(common.Big(account.Nonce).Uint64())
-
-	return obj
-}
-
-type Env struct {
-	CurrentCoinbase   string
-	CurrentDifficulty string
-	CurrentGasLimit   string
-	CurrentNumber     string
-	CurrentTimestamp  interface{}
-	PreviousHash      string
-}
-
-type VmTest struct {
-	Callcreates interface{}
-	//Env         map[string]string
-	Env           Env
-	Exec          map[string]string
-	Transaction   map[string]string
-	Logs          []Log
-	Gas           string
-	Out           string
-	Post          map[string]Account
-	Pre           map[string]Account
-	PostStateRoot string
-}
-
-func RunVmTest(p string, t *testing.T) {
-
-	tests := make(map[string]VmTest)
-	helper.CreateFileTests(t, p, &tests)
-
-	for name, test := range tests {
-		/*
-			vm.Debug = true
-			glog.SetV(4)
-			glog.SetToStderr(true)
-			if name != "Call50000_sha256" {
-				continue
-			}
-		*/
-		db, _ := ethdb.NewMemDatabase()
-		statedb := state.New(common.Hash{}, db)
-		for addr, account := range test.Pre {
-			obj := StateObjectFromAccount(db, addr, account)
-			statedb.SetStateObject(obj)
-			for a, v := range account.Storage {
-				obj.SetState(common.HexToHash(a), common.HexToHash(v))
-			}
-		}
-
-		// XXX Yeah, yeah...
-		env := make(map[string]string)
-		env["currentCoinbase"] = test.Env.CurrentCoinbase
-		env["currentDifficulty"] = test.Env.CurrentDifficulty
-		env["currentGasLimit"] = test.Env.CurrentGasLimit
-		env["currentNumber"] = test.Env.CurrentNumber
-		env["previousHash"] = test.Env.PreviousHash
-		if n, ok := test.Env.CurrentTimestamp.(float64); ok {
-			env["currentTimestamp"] = strconv.Itoa(int(n))
-		} else {
-			env["currentTimestamp"] = test.Env.CurrentTimestamp.(string)
-		}
-
-		var (
-			ret  []byte
-			gas  *big.Int
-			err  error
-			logs state.Logs
-		)
-
-		isVmTest := len(test.Exec) > 0
-		if isVmTest {
-			ret, logs, gas, err = helper.RunVm(statedb, env, test.Exec)
-		} else {
-			ret, logs, gas, err = helper.RunState(statedb, env, test.Transaction)
-		}
-
-		switch name {
-		// the memory required for these tests (4294967297 bytes) would take too much time.
-		// on 19 May 2015 decided to skip these tests their output.
-		case "mload32bitBound_return", "mload32bitBound_return2":
-		default:
-			rexp := helper.FromHex(test.Out)
-			if bytes.Compare(rexp, ret) != 0 {
-				t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret)
-			}
-		}
-
-		if isVmTest {
-			if len(test.Gas) == 0 && err == nil {
-				t.Errorf("%s's gas unspecified, indicating an error. VM returned (incorrectly) successfull", name)
-			} else {
-				gexp := common.Big(test.Gas)
-				if gexp.Cmp(gas) != 0 {
-					t.Errorf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas)
-				}
-			}
-		}
-
-		for addr, account := range test.Post {
-			obj := statedb.GetStateObject(common.HexToAddress(addr))
-			if obj == nil {
-				continue
-			}
-
-			if len(test.Exec) == 0 {
-				if obj.Balance().Cmp(common.Big(account.Balance)) != 0 {
-					t.Errorf("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance()))
-				}
-
-				if obj.Nonce() != common.String2Big(account.Nonce).Uint64() {
-					t.Errorf("%s's : (%x) nonce failed. Expected %v, got %v\n", name, obj.Address().Bytes()[:4], account.Nonce, obj.Nonce())
-				}
-
-			}
-
-			for addr, value := range account.Storage {
-				v := obj.GetState(common.HexToHash(addr))
-				vexp := common.HexToHash(value)
-
-				if v != vexp {
-					t.Errorf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address().Bytes()[0:4], addr, vexp, v, vexp.Big(), v.Big())
-				}
-			}
-		}
-
-		if !isVmTest {
-			statedb.Sync()
-			//if !bytes.Equal(common.Hex2Bytes(test.PostStateRoot), statedb.Root()) {
-			if common.HexToHash(test.PostStateRoot) != statedb.Root() {
-				t.Errorf("%s's : Post state root error. Expected %s, got %x", name, test.PostStateRoot, statedb.Root())
-			}
-		}
-
-		if len(test.Logs) > 0 {
-			if len(test.Logs) != len(logs) {
-				t.Errorf("log length mismatch. Expected %d, got %d", len(test.Logs), len(logs))
-			} else {
-				for i, log := range test.Logs {
-					if common.HexToAddress(log.AddressF) != logs[i].Address {
-						t.Errorf("'%s' log address expected %v got %x", name, log.AddressF, logs[i].Address)
-					}
-
-					if !bytes.Equal(logs[i].Data, helper.FromHex(log.DataF)) {
-						t.Errorf("'%s' log data expected %v got %x", name, log.DataF, logs[i].Data)
-					}
-
-					if len(log.TopicsF) != len(logs[i].Topics) {
-						t.Errorf("'%s' log topics length expected %d got %d", name, len(log.TopicsF), logs[i].Topics)
-					} else {
-						for j, topic := range log.TopicsF {
-							if common.HexToHash(topic) != logs[i].Topics[j] {
-								t.Errorf("'%s' log topic[%d] expected %v got %x", name, j, topic, logs[i].Topics[j])
-							}
-						}
-					}
-					genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256)
-
-					if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) {
-						t.Errorf("'%s' bloom mismatch", name)
-					}
-				}
-			}
-		}
-		//fmt.Println(string(statedb.Dump()))
-	}
-	logger.Flush()
-}
-
-// I've created a new function for each tests so it's easier to identify where the problem lies if any of them fail.
-func TestVMArithmetic(t *testing.T) {
-	const fn = "../files/VMTests/vmArithmeticTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestBitwiseLogicOperation(t *testing.T) {
-	const fn = "../files/VMTests/vmBitwiseLogicOperationTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestBlockInfo(t *testing.T) {
-	const fn = "../files/VMTests/vmBlockInfoTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestEnvironmentalInfo(t *testing.T) {
-	const fn = "../files/VMTests/vmEnvironmentalInfoTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestFlowOperation(t *testing.T) {
-	const fn = "../files/VMTests/vmIOandFlowOperationsTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestLogTest(t *testing.T) {
-	const fn = "../files/VMTests/vmLogTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestPerformance(t *testing.T) {
-	const fn = "../files/VMTests/vmPerformanceTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestPushDupSwap(t *testing.T) {
-	const fn = "../files/VMTests/vmPushDupSwapTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestVMSha3(t *testing.T) {
-	const fn = "../files/VMTests/vmSha3Test.json"
-	RunVmTest(fn, t)
-}
-
-func TestVm(t *testing.T) {
-	const fn = "../files/VMTests/vmtests.json"
-	RunVmTest(fn, t)
-}
-
-func TestVmLog(t *testing.T) {
-	const fn = "../files/VMTests/vmLogTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestInputLimits(t *testing.T) {
-	const fn = "../files/VMTests/vmInputLimits.json"
-	RunVmTest(fn, t)
-}
-
-func TestInputLimitsLight(t *testing.T) {
-	const fn = "../files/VMTests/vmInputLimitsLight.json"
-	RunVmTest(fn, t)
-}
-
-func TestStateSystemOperations(t *testing.T) {
-	const fn = "../files/StateTests/stSystemOperationsTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestStateExample(t *testing.T) {
-	const fn = "../files/StateTests/stExample.json"
-	RunVmTest(fn, t)
-}
-
-func TestStatePreCompiledContracts(t *testing.T) {
-	const fn = "../files/StateTests/stPreCompiledContracts.json"
-	RunVmTest(fn, t)
-}
-
-func TestStateRecursiveCreate(t *testing.T) {
-	const fn = "../files/StateTests/stRecursiveCreate.json"
-	RunVmTest(fn, t)
-}
-
-func TestStateSpecial(t *testing.T) {
-	const fn = "../files/StateTests/stSpecialTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestStateRefund(t *testing.T) {
-	const fn = "../files/StateTests/stRefundTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestStateBlockHash(t *testing.T) {
-	const fn = "../files/StateTests/stBlockHashTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestStateInitCode(t *testing.T) {
-	const fn = "../files/StateTests/stInitCodeTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestStateLog(t *testing.T) {
-	const fn = "../files/StateTests/stLogTests.json"
-	RunVmTest(fn, t)
-}
-
-func TestStateTransaction(t *testing.T) {
-	const fn = "../files/StateTests/stTransactionTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestCallCreateCallCode(t *testing.T) {
-	const fn = "../files/StateTests/stCallCreateCallCodeTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestMemory(t *testing.T) {
-	const fn = "../files/StateTests/stMemoryTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestMemoryStress(t *testing.T) {
-	if os.Getenv("TEST_VM_COMPLEX") == "" {
-		t.Skip()
-	}
-	const fn = "../files/StateTests/stMemoryStressTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestQuadraticComplexity(t *testing.T) {
-	if os.Getenv("TEST_VM_COMPLEX") == "" {
-		t.Skip()
-	}
-	const fn = "../files/StateTests/stQuadraticComplexityTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestSolidity(t *testing.T) {
-	const fn = "../files/StateTests/stSolidityTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestWallet(t *testing.T) {
-	const fn = "../files/StateTests/stWalletTest.json"
-	RunVmTest(fn, t)
-}
-
-func TestStateTestsRandom(t *testing.T) {
-	fns, _ := filepath.Glob("../files/StateTests/RandomTests/*")
-	for _, fn := range fns {
-		RunVmTest(fn, t)
-	}
-}
-
-func TestVMRandom(t *testing.T) {
-	t.Skip() // fucked as of 2015-06-09. unskip once unfucked /Gustav
-	fns, _ := filepath.Glob("../files/VMTests/RandomTests/*")
-	for _, fn := range fns {
-		RunVmTest(fn, t)
-	}
-}
diff --git a/tests/vm/nowarn.go b/tests/vm/nowarn.go
deleted file mode 100644
index 2a45a6cc6..000000000
--- a/tests/vm/nowarn.go
+++ /dev/null
@@ -1,3 +0,0 @@
-// This silences the warning given by 'go install ./...'.
-
-package vm
diff --git a/tests/vm_test.go b/tests/vm_test.go
new file mode 100644
index 000000000..4e417da5a
--- /dev/null
+++ b/tests/vm_test.go
@@ -0,0 +1,107 @@
+package tests
+
+import (
+	"path/filepath"
+	"testing"
+)
+
+// I've created a new function for each tests so it's easier to identify where the problem lies if any of them fail.
+func TestVMArithmetic(t *testing.T) {
+	fn := filepath.Join(vmTestDir, "vmArithmeticTest.json")
+	if err := RunVmTest(fn, VmSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestBitwiseLogicOperation(t *testing.T) {
+	fn := filepath.Join(vmTestDir, "vmBitwiseLogicOperationTest.json")
+	if err := RunVmTest(fn, VmSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestBlockInfo(t *testing.T) {
+	fn := filepath.Join(vmTestDir, "vmBlockInfoTest.json")
+	if err := RunVmTest(fn, VmSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestEnvironmentalInfo(t *testing.T) {
+	fn := filepath.Join(vmTestDir, "vmEnvironmentalInfoTest.json")
+	if err := RunVmTest(fn, VmSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestFlowOperation(t *testing.T) {
+	fn := filepath.Join(vmTestDir, "vmIOandFlowOperationsTest.json")
+	if err := RunVmTest(fn, VmSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestLogTest(t *testing.T) {
+	fn := filepath.Join(vmTestDir, "vmLogTest.json")
+	if err := RunVmTest(fn, VmSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestPerformance(t *testing.T) {
+	fn := filepath.Join(vmTestDir, "vmPerformanceTest.json")
+	if err := RunVmTest(fn, VmSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestPushDupSwap(t *testing.T) {
+	fn := filepath.Join(vmTestDir, "vmPushDupSwapTest.json")
+	if err := RunVmTest(fn, VmSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestVMSha3(t *testing.T) {
+	fn := filepath.Join(vmTestDir, "vmSha3Test.json")
+	if err := RunVmTest(fn, VmSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestVm(t *testing.T) {
+	fn := filepath.Join(vmTestDir, "vmtests.json")
+	if err := RunVmTest(fn, VmSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestVmLog(t *testing.T) {
+	fn := filepath.Join(vmTestDir, "vmLogTest.json")
+	if err := RunVmTest(fn, VmSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestInputLimits(t *testing.T) {
+	fn := filepath.Join(vmTestDir, "vmInputLimits.json")
+	if err := RunVmTest(fn, VmSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestInputLimitsLight(t *testing.T) {
+	fn := filepath.Join(vmTestDir, "vmInputLimitsLight.json")
+	if err := RunVmTest(fn, VmSkipTests); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestVMRandom(t *testing.T) {
+	fns, _ := filepath.Glob(filepath.Join(baseDir, "RandomTests", "*"))
+	for _, fn := range fns {
+		if err := RunVmTest(fn, VmSkipTests); err != nil {
+			t.Error(err)
+		}
+	}
+}
diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go
new file mode 100644
index 000000000..286991764
--- /dev/null
+++ b/tests/vm_test_util.go
@@ -0,0 +1,170 @@
+package tests
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"math/big"
+	"strconv"
+
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/core/state"
+	"github.com/ethereum/go-ethereum/core/vm"
+	"github.com/ethereum/go-ethereum/ethdb"
+	"github.com/ethereum/go-ethereum/logger/glog"
+)
+
+func RunVmTestWithReader(r io.Reader, skipTests []string) error {
+	tests := make(map[string]VmTest)
+	err := readJson(r, &tests)
+	if err != nil {
+		return err
+	}
+
+	if err != nil {
+		return err
+	}
+
+	if err := runVmTests(tests, skipTests); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func RunVmTest(p string, skipTests []string) error {
+
+	tests := make(map[string]VmTest)
+	err := readJsonFile(p, &tests)
+	if err != nil {
+		return err
+	}
+
+	if err := runVmTests(tests, skipTests); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func runVmTests(tests map[string]VmTest, skipTests []string) error {
+	skipTest := make(map[string]bool, len(skipTests))
+	for _, name := range skipTests {
+		skipTest[name] = true
+	}
+
+	for name, test := range tests {
+		if skipTest[name] {
+			glog.Infoln("Skipping VM test", name)
+			return nil
+		}
+
+		if err := runVmTest(test); err != nil {
+			return fmt.Errorf("%s %s", name, err.Error())
+		}
+
+		glog.Infoln("VM test passed: ", name)
+		//fmt.Println(string(statedb.Dump()))
+	}
+	return nil
+}
+
+func runVmTest(test VmTest) error {
+	db, _ := ethdb.NewMemDatabase()
+	statedb := state.New(common.Hash{}, db)
+	for addr, account := range test.Pre {
+		obj := StateObjectFromAccount(db, addr, account)
+		statedb.SetStateObject(obj)
+		for a, v := range account.Storage {
+			obj.SetState(common.HexToHash(a), common.HexToHash(v))
+		}
+	}
+
+	// XXX Yeah, yeah...
+	env := make(map[string]string)
+	env["currentCoinbase"] = test.Env.CurrentCoinbase
+	env["currentDifficulty"] = test.Env.CurrentDifficulty
+	env["currentGasLimit"] = test.Env.CurrentGasLimit
+	env["currentNumber"] = test.Env.CurrentNumber
+	env["previousHash"] = test.Env.PreviousHash
+	if n, ok := test.Env.CurrentTimestamp.(float64); ok {
+		env["currentTimestamp"] = strconv.Itoa(int(n))
+	} else {
+		env["currentTimestamp"] = test.Env.CurrentTimestamp.(string)
+	}
+
+	var (
+		ret  []byte
+		gas  *big.Int
+		err  error
+		logs state.Logs
+	)
+
+	ret, logs, gas, err = RunVm(statedb, env, test.Exec)
+
+	// Compare expected and actual return
+	rexp := common.FromHex(test.Out)
+	if bytes.Compare(rexp, ret) != 0 {
+		return fmt.Errorf("return failed. Expected %x, got %x\n", rexp, ret)
+	}
+
+	// Check gas usage
+	if len(test.Gas) == 0 && err == nil {
+		return fmt.Errorf("gas unspecified, indicating an error. VM returned (incorrectly) successfull")
+	} else {
+		gexp := common.Big(test.Gas)
+		if gexp.Cmp(gas) != 0 {
+			return fmt.Errorf("gas failed. Expected %v, got %v\n", gexp, gas)
+		}
+	}
+
+	// check post state
+	for addr, account := range test.Post {
+		obj := statedb.GetStateObject(common.HexToAddress(addr))
+		if obj == nil {
+			continue
+		}
+
+		for addr, value := range account.Storage {
+			v := obj.GetState(common.HexToHash(addr))
+			vexp := common.HexToHash(value)
+
+			if v != vexp {
+				return fmt.Errorf("(%x: %s) storage failed. Expected %x, got %x (%v %v)\n", obj.Address().Bytes()[0:4], addr, vexp, v, vexp.Big(), v.Big())
+			}
+		}
+	}
+
+	// check logs
+	if len(test.Logs) > 0 {
+		lerr := checkLogs(test.Logs, logs)
+		if lerr != nil {
+			return lerr
+		}
+	}
+
+	return nil
+}
+
+func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Logs, *big.Int, error) {
+	var (
+		to    = common.HexToAddress(exec["address"])
+		from  = common.HexToAddress(exec["caller"])
+		data  = common.FromHex(exec["data"])
+		gas   = common.Big(exec["gas"])
+		price = common.Big(exec["gasPrice"])
+		value = common.Big(exec["value"])
+	)
+	// Reset the pre-compiled contracts for VM tests.
+	vm.Precompiled = make(map[string]*vm.PrecompiledAccount)
+
+	caller := state.GetOrNewStateObject(from)
+
+	vmenv := NewEnvFromMap(state, env, exec)
+	vmenv.vmTest = true
+	vmenv.skipTransfer = true
+	vmenv.initial = true
+	ret, err := vmenv.Call(caller, to, data, gas, price, value)
+
+	return ret, vmenv.state.Logs(), vmenv.Gas, err
+}