diff --git a/cmd/evm/main.go b/cmd/evm/main.go
index 8af0cebbb5263eade26e55f1b4cd7f1a8755a988..0693d7cd3252c6d6031a8710582129643a1cf979 100644
--- a/cmd/evm/main.go
+++ b/cmd/evm/main.go
@@ -29,7 +29,6 @@ import (
 	"github.com/ethereum/go-ethereum/core/state"
 	"github.com/ethereum/go-ethereum/core/vm"
 	"github.com/ethereum/go-ethereum/core/vm/runtime"
-	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/ethdb"
 	"github.com/ethereum/go-ethereum/logger/glog"
 	"gopkg.in/urfave/cli.v1"
@@ -115,9 +114,13 @@ func run(ctx *cli.Context) error {
 	glog.SetToStderr(true)
 	glog.SetV(ctx.GlobalInt(VerbosityFlag.Name))
 
-	db, _ := ethdb.NewMemDatabase()
-	statedb, _ := state.New(common.Hash{}, db)
-	sender := statedb.CreateAccount(common.StringToAddress("sender"))
+	var (
+		db, _      = ethdb.NewMemDatabase()
+		statedb, _ = state.New(common.Hash{}, db)
+		address    = common.StringToAddress("sender")
+		sender     = vm.AccountRef(address)
+	)
+	statedb.CreateAccount(common.StringToAddress("sender"))
 
 	logger := vm.NewStructLogger(nil)
 
@@ -166,10 +169,11 @@ func run(ctx *cli.Context) error {
 			},
 		})
 	} else {
-		receiver := statedb.CreateAccount(common.StringToAddress("receiver"))
-		receiver.SetCode(crypto.Keccak256Hash(code), code)
+		receiverAddress := common.StringToAddress("receiver")
+		statedb.CreateAccount(receiverAddress)
+		statedb.SetCode(receiverAddress, code)
 
-		ret, err = runtime.Call(receiver.Address(), common.Hex2Bytes(ctx.GlobalString(InputFlag.Name)), &runtime.Config{
+		ret, err = runtime.Call(receiverAddress, common.Hex2Bytes(ctx.GlobalString(InputFlag.Name)), &runtime.Config{
 			Origin:   sender.Address(),
 			State:    statedb,
 			GasLimit: common.Big(ctx.GlobalString(GasFlag.Name)).Uint64(),
diff --git a/core/blockchain.go b/core/blockchain.go
index cc0ddf1ed80865b849b9ba916a686802f3cbabdb..b57eb48e3af5e29c645bba0f2546801e071693d8 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -214,7 +214,6 @@ func (self *BlockChain) loadLastState() error {
 		return err
 	}
 	self.stateCache = statedb
-	self.stateCache.GetAccount(common.Address{})
 
 	// Issue a status log for the user
 	headerTd := self.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64())
diff --git a/core/dao.go b/core/dao.go
index a7f544c3d92acbe081b90527121fb87659fae4ef..7e376e68aac7c7a80294d0557b92d2e355e6d9fd 100644
--- a/core/dao.go
+++ b/core/dao.go
@@ -62,13 +62,13 @@ func ValidateDAOHeaderExtraData(config *params.ChainConfig, header *types.Header
 // contract.
 func ApplyDAOHardFork(statedb *state.StateDB) {
 	// Retrieve the contract to refund balances into
-	refund := statedb.GetOrNewStateObject(params.DAORefundContract)
+	if !statedb.Exist(params.DAORefundContract) {
+		statedb.CreateAccount(params.DAORefundContract)
+	}
 
 	// Move every DAO account and extra-balance account funds into the refund contract
 	for _, addr := range params.DAODrainList {
-		if account := statedb.GetStateObject(addr); account != nil {
-			refund.AddBalance(account.Balance())
-			account.SetBalance(new(big.Int))
-		}
+		statedb.AddBalance(params.DAORefundContract, statedb.GetBalance(addr))
+		statedb.SetBalance(addr, new(big.Int))
 	}
 }
diff --git a/core/state/journal.go b/core/state/journal.go
index 68d07fa03cda0a48b067889d92d2d9535a4ad852..5cd41477d921e6966b72b91b65d8b9169f7023ab 100644
--- a/core/state/journal.go
+++ b/core/state/journal.go
@@ -34,7 +34,7 @@ type (
 		account *common.Address
 	}
 	resetObjectChange struct {
-		prev *StateObject
+		prev *stateObject
 	}
 	suicideChange struct {
 		account     *common.Address
@@ -86,7 +86,7 @@ func (ch resetObjectChange) undo(s *StateDB) {
 }
 
 func (ch suicideChange) undo(s *StateDB) {
-	obj := s.GetStateObject(*ch.account)
+	obj := s.getStateObject(*ch.account)
 	if obj != nil {
 		obj.suicided = ch.prev
 		obj.setBalance(ch.prevbalance)
@@ -103,19 +103,19 @@ func (ch touchChange) undo(s *StateDB) {
 }
 
 func (ch balanceChange) undo(s *StateDB) {
-	s.GetStateObject(*ch.account).setBalance(ch.prev)
+	s.getStateObject(*ch.account).setBalance(ch.prev)
 }
 
 func (ch nonceChange) undo(s *StateDB) {
-	s.GetStateObject(*ch.account).setNonce(ch.prev)
+	s.getStateObject(*ch.account).setNonce(ch.prev)
 }
 
 func (ch codeChange) undo(s *StateDB) {
-	s.GetStateObject(*ch.account).setCode(common.BytesToHash(ch.prevhash), ch.prevcode)
+	s.getStateObject(*ch.account).setCode(common.BytesToHash(ch.prevhash), ch.prevcode)
 }
 
 func (ch storageChange) undo(s *StateDB) {
-	s.GetStateObject(*ch.account).setState(ch.key, ch.prevalue)
+	s.getStateObject(*ch.account).setState(ch.key, ch.prevalue)
 }
 
 func (ch refundChange) undo(s *StateDB) {
diff --git a/core/state/managed_state.go b/core/state/managed_state.go
index 0d8f9dd28457823f78f62a1a0f169bb985fb0250..1390ef4a00af4ccc155b05dc0753fb854e80d0b5 100644
--- a/core/state/managed_state.go
+++ b/core/state/managed_state.go
@@ -23,7 +23,7 @@ import (
 )
 
 type account struct {
-	stateObject *StateObject
+	stateObject *stateObject
 	nstart      uint64
 	nonces      []bool
 }
@@ -128,7 +128,7 @@ func (ms *ManagedState) getAccount(addr common.Address) *account {
 	} else {
 		// Always make sure the state account nonce isn't actually higher
 		// than the tracked one.
-		so := ms.StateDB.GetStateObject(addr)
+		so := ms.StateDB.getStateObject(addr)
 		if so != nil && uint64(len(account.nonces))+account.nstart < so.Nonce() {
 			ms.accounts[addr] = newAccount(so)
 		}
@@ -138,6 +138,6 @@ func (ms *ManagedState) getAccount(addr common.Address) *account {
 	return ms.accounts[addr]
 }
 
-func newAccount(so *StateObject) *account {
+func newAccount(so *stateObject) *account {
 	return &account{so, so.Nonce(), nil}
 }
diff --git a/core/state/managed_state_test.go b/core/state/managed_state_test.go
index 0a3be9f5a93d7ca65ad3411ae2dec36e5d02f29d..ea5737a0892eb10ef9a337af4d1d0f2fc6746233 100644
--- a/core/state/managed_state_test.go
+++ b/core/state/managed_state_test.go
@@ -30,7 +30,7 @@ func create() (*ManagedState, *account) {
 	statedb, _ := New(common.Hash{}, db)
 	ms := ManageState(statedb)
 	ms.StateDB.SetNonce(addr, 100)
-	ms.accounts[addr] = newAccount(ms.StateDB.GetStateObject(addr))
+	ms.accounts[addr] = newAccount(ms.StateDB.getStateObject(addr))
 	return ms, ms.accounts[addr]
 }
 
diff --git a/core/state/state_object.go b/core/state/state_object.go
index da1914c9bc031fc54cdc96a274c89d401f90710a..4fb69b6462c1d70a1105c9de261546d0fd45be2a 100644
--- a/core/state/state_object.go
+++ b/core/state/state_object.go
@@ -57,13 +57,13 @@ func (self Storage) Copy() Storage {
 	return cpy
 }
 
-// StateObject represents an Ethereum account which is being modified.
+// stateObject represents an Ethereum account which is being modified.
 //
 // The usage pattern is as follows:
 // First you need to obtain a state object.
 // Account values can be accessed and modified through the object.
 // Finally, call CommitTrie to write the modified storage trie into a database.
-type StateObject struct {
+type stateObject struct {
 	address common.Address // Ethereum address of this account
 	data    Account
 	db      *StateDB
@@ -93,7 +93,7 @@ type StateObject struct {
 }
 
 // empty returns whether the account is considered empty.
-func (s *StateObject) empty() bool {
+func (s *stateObject) empty() bool {
 	return s.data.Nonce == 0 && s.data.Balance.BitLen() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash)
 }
 
@@ -107,29 +107,29 @@ type Account struct {
 }
 
 // newObject creates a state object.
-func newObject(db *StateDB, address common.Address, data Account, onDirty func(addr common.Address)) *StateObject {
+func newObject(db *StateDB, address common.Address, data Account, onDirty func(addr common.Address)) *stateObject {
 	if data.Balance == nil {
 		data.Balance = new(big.Int)
 	}
 	if data.CodeHash == nil {
 		data.CodeHash = emptyCodeHash
 	}
-	return &StateObject{db: db, address: address, data: data, cachedStorage: make(Storage), dirtyStorage: make(Storage), onDirty: onDirty}
+	return &stateObject{db: db, address: address, data: data, cachedStorage: make(Storage), dirtyStorage: make(Storage), onDirty: onDirty}
 }
 
 // EncodeRLP implements rlp.Encoder.
-func (c *StateObject) EncodeRLP(w io.Writer) error {
+func (c *stateObject) EncodeRLP(w io.Writer) error {
 	return rlp.Encode(w, c.data)
 }
 
 // setError remembers the first non-nil error it is called with.
-func (self *StateObject) setError(err error) {
+func (self *stateObject) setError(err error) {
 	if self.dbErr == nil {
 		self.dbErr = err
 	}
 }
 
-func (self *StateObject) markSuicided() {
+func (self *stateObject) markSuicided() {
 	self.suicided = true
 	if self.onDirty != nil {
 		self.onDirty(self.Address())
@@ -140,7 +140,7 @@ func (self *StateObject) markSuicided() {
 	}
 }
 
-func (c *StateObject) touch() {
+func (c *stateObject) touch() {
 	c.db.journal = append(c.db.journal, touchChange{
 		account: &c.address,
 		prev:    c.touched,
@@ -152,7 +152,7 @@ func (c *StateObject) touch() {
 	c.touched = true
 }
 
-func (c *StateObject) getTrie(db trie.Database) *trie.SecureTrie {
+func (c *stateObject) getTrie(db trie.Database) *trie.SecureTrie {
 	if c.trie == nil {
 		var err error
 		c.trie, err = trie.NewSecure(c.data.Root, db, 0)
@@ -165,7 +165,7 @@ func (c *StateObject) getTrie(db trie.Database) *trie.SecureTrie {
 }
 
 // GetState returns a value in account storage.
-func (self *StateObject) GetState(db trie.Database, key common.Hash) common.Hash {
+func (self *stateObject) GetState(db trie.Database, key common.Hash) common.Hash {
 	value, exists := self.cachedStorage[key]
 	if exists {
 		return value
@@ -185,7 +185,7 @@ func (self *StateObject) GetState(db trie.Database, key common.Hash) common.Hash
 }
 
 // SetState updates a value in account storage.
-func (self *StateObject) SetState(db trie.Database, key, value common.Hash) {
+func (self *stateObject) SetState(db trie.Database, key, value common.Hash) {
 	self.db.journal = append(self.db.journal, storageChange{
 		account:  &self.address,
 		key:      key,
@@ -194,7 +194,7 @@ func (self *StateObject) SetState(db trie.Database, key, value common.Hash) {
 	self.setState(key, value)
 }
 
-func (self *StateObject) setState(key, value common.Hash) {
+func (self *stateObject) setState(key, value common.Hash) {
 	self.cachedStorage[key] = value
 	self.dirtyStorage[key] = value
 
@@ -205,7 +205,7 @@ func (self *StateObject) setState(key, value common.Hash) {
 }
 
 // updateTrie writes cached storage modifications into the object's storage trie.
-func (self *StateObject) updateTrie(db trie.Database) {
+func (self *stateObject) updateTrie(db trie.Database) {
 	tr := self.getTrie(db)
 	for key, value := range self.dirtyStorage {
 		delete(self.dirtyStorage, key)
@@ -220,14 +220,14 @@ func (self *StateObject) updateTrie(db trie.Database) {
 }
 
 // UpdateRoot sets the trie root to the current root hash of
-func (self *StateObject) updateRoot(db trie.Database) {
+func (self *stateObject) updateRoot(db trie.Database) {
 	self.updateTrie(db)
 	self.data.Root = self.trie.Hash()
 }
 
 // CommitTrie the storage trie of the object to dwb.
 // This updates the trie root.
-func (self *StateObject) CommitTrie(db trie.Database, dbw trie.DatabaseWriter) error {
+func (self *stateObject) CommitTrie(db trie.Database, dbw trie.DatabaseWriter) error {
 	self.updateTrie(db)
 	if self.dbErr != nil {
 		return self.dbErr
@@ -241,7 +241,7 @@ func (self *StateObject) CommitTrie(db trie.Database, dbw trie.DatabaseWriter) e
 
 // AddBalance removes amount from c's balance.
 // It is used to add funds to the destination account of a transfer.
-func (c *StateObject) AddBalance(amount *big.Int) {
+func (c *stateObject) AddBalance(amount *big.Int) {
 	// EIP158: We must check emptiness for the objects such that the account
 	// clearing (0,0,0 objects) can take effect.
 	if amount.Cmp(common.Big0) == 0 {
@@ -260,7 +260,7 @@ func (c *StateObject) AddBalance(amount *big.Int) {
 
 // SubBalance removes amount from c's balance.
 // It is used to remove funds from the origin account of a transfer.
-func (c *StateObject) SubBalance(amount *big.Int) {
+func (c *stateObject) SubBalance(amount *big.Int) {
 	if amount.Cmp(common.Big0) == 0 {
 		return
 	}
@@ -271,7 +271,7 @@ func (c *StateObject) SubBalance(amount *big.Int) {
 	}
 }
 
-func (self *StateObject) SetBalance(amount *big.Int) {
+func (self *stateObject) SetBalance(amount *big.Int) {
 	self.db.journal = append(self.db.journal, balanceChange{
 		account: &self.address,
 		prev:    new(big.Int).Set(self.data.Balance),
@@ -279,7 +279,7 @@ func (self *StateObject) SetBalance(amount *big.Int) {
 	self.setBalance(amount)
 }
 
-func (self *StateObject) setBalance(amount *big.Int) {
+func (self *stateObject) setBalance(amount *big.Int) {
 	self.data.Balance = amount
 	if self.onDirty != nil {
 		self.onDirty(self.Address())
@@ -288,9 +288,9 @@ func (self *StateObject) setBalance(amount *big.Int) {
 }
 
 // Return the gas back to the origin. Used by the Virtual machine or Closures
-func (c *StateObject) ReturnGas(gas *big.Int) {}
+func (c *stateObject) ReturnGas(gas *big.Int) {}
 
-func (self *StateObject) deepCopy(db *StateDB, onDirty func(addr common.Address)) *StateObject {
+func (self *stateObject) deepCopy(db *StateDB, onDirty func(addr common.Address)) *stateObject {
 	stateObject := newObject(db, self.address, self.data, onDirty)
 	stateObject.trie = self.trie
 	stateObject.code = self.code
@@ -307,12 +307,12 @@ func (self *StateObject) deepCopy(db *StateDB, onDirty func(addr common.Address)
 //
 
 // Returns the address of the contract/account
-func (c *StateObject) Address() common.Address {
+func (c *stateObject) Address() common.Address {
 	return c.address
 }
 
 // Code returns the contract code associated with this object, if any.
-func (self *StateObject) Code(db trie.Database) []byte {
+func (self *stateObject) Code(db trie.Database) []byte {
 	if self.code != nil {
 		return self.code
 	}
@@ -327,7 +327,7 @@ func (self *StateObject) Code(db trie.Database) []byte {
 	return code
 }
 
-func (self *StateObject) SetCode(codeHash common.Hash, code []byte) {
+func (self *stateObject) SetCode(codeHash common.Hash, code []byte) {
 	prevcode := self.Code(self.db.db)
 	self.db.journal = append(self.db.journal, codeChange{
 		account:  &self.address,
@@ -337,7 +337,7 @@ func (self *StateObject) SetCode(codeHash common.Hash, code []byte) {
 	self.setCode(codeHash, code)
 }
 
-func (self *StateObject) setCode(codeHash common.Hash, code []byte) {
+func (self *stateObject) setCode(codeHash common.Hash, code []byte) {
 	self.code = code
 	self.data.CodeHash = codeHash[:]
 	self.dirtyCode = true
@@ -347,7 +347,7 @@ func (self *StateObject) setCode(codeHash common.Hash, code []byte) {
 	}
 }
 
-func (self *StateObject) SetNonce(nonce uint64) {
+func (self *stateObject) SetNonce(nonce uint64) {
 	self.db.journal = append(self.db.journal, nonceChange{
 		account: &self.address,
 		prev:    self.data.Nonce,
@@ -355,7 +355,7 @@ func (self *StateObject) SetNonce(nonce uint64) {
 	self.setNonce(nonce)
 }
 
-func (self *StateObject) setNonce(nonce uint64) {
+func (self *stateObject) setNonce(nonce uint64) {
 	self.data.Nonce = nonce
 	if self.onDirty != nil {
 		self.onDirty(self.Address())
@@ -363,37 +363,21 @@ func (self *StateObject) setNonce(nonce uint64) {
 	}
 }
 
-func (self *StateObject) CodeHash() []byte {
+func (self *stateObject) CodeHash() []byte {
 	return self.data.CodeHash
 }
 
-func (self *StateObject) Balance() *big.Int {
+func (self *stateObject) Balance() *big.Int {
 	return self.data.Balance
 }
 
-func (self *StateObject) Nonce() uint64 {
+func (self *stateObject) Nonce() uint64 {
 	return self.data.Nonce
 }
 
-// Never called, but must be present to allow StateObject to be used
+// Never called, but must be present to allow stateObject to be used
 // as a vm.Account interface that also satisfies the vm.ContractRef
 // interface. Interfaces are awesome.
-func (self *StateObject) Value() *big.Int {
-	panic("Value on StateObject should never be called")
-}
-
-func (self *StateObject) ForEachStorage(cb func(key, value common.Hash) bool) {
-	// When iterating over the storage check the cache first
-	for h, value := range self.cachedStorage {
-		cb(h, value)
-	}
-
-	it := self.getTrie(self.db.db).Iterator()
-	for it.Next() {
-		// ignore cached values
-		key := common.BytesToHash(self.trie.GetKey(it.Key))
-		if _, ok := self.cachedStorage[key]; !ok {
-			cb(key, common.BytesToHash(it.Value))
-		}
-	}
+func (self *stateObject) Value() *big.Int {
+	panic("Value on stateObject should never be called")
 }
diff --git a/core/state/state_test.go b/core/state/state_test.go
index 435d1d8293d5409d743ce590280681298e1c2ec2..3bc63c1486cfd10d8d7c0612dd75617e3175cf9c 100644
--- a/core/state/state_test.go
+++ b/core/state/state_test.go
@@ -152,7 +152,7 @@ func TestSnapshot2(t *testing.T) {
 	state.SetState(stateobjaddr1, storageaddr, data1)
 
 	// db, trie are already non-empty values
-	so0 := state.GetStateObject(stateobjaddr0)
+	so0 := state.getStateObject(stateobjaddr0)
 	so0.SetBalance(big.NewInt(42))
 	so0.SetNonce(43)
 	so0.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e'}), []byte{'c', 'a', 'f', 'e'})
@@ -164,7 +164,7 @@ func TestSnapshot2(t *testing.T) {
 	state.Reset(root)
 
 	// and one with deleted == true
-	so1 := state.GetStateObject(stateobjaddr1)
+	so1 := state.getStateObject(stateobjaddr1)
 	so1.SetBalance(big.NewInt(52))
 	so1.SetNonce(53)
 	so1.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e', '2'}), []byte{'c', 'a', 'f', 'e', '2'})
@@ -172,7 +172,7 @@ func TestSnapshot2(t *testing.T) {
 	so1.deleted = true
 	state.setStateObject(so1)
 
-	so1 = state.GetStateObject(stateobjaddr1)
+	so1 = state.getStateObject(stateobjaddr1)
 	if so1 != nil {
 		t.Fatalf("deleted object not nil when getting")
 	}
@@ -180,7 +180,7 @@ func TestSnapshot2(t *testing.T) {
 	snapshot := state.Snapshot()
 	state.RevertToSnapshot(snapshot)
 
-	so0Restored := state.GetStateObject(stateobjaddr0)
+	so0Restored := state.getStateObject(stateobjaddr0)
 	// Update lazily-loaded values before comparing.
 	so0Restored.GetState(db, storageaddr)
 	so0Restored.Code(db)
@@ -188,13 +188,13 @@ func TestSnapshot2(t *testing.T) {
 	compareStateObjects(so0Restored, so0, t)
 
 	// deleted should be nil, both before and after restore of state copy
-	so1Restored := state.GetStateObject(stateobjaddr1)
+	so1Restored := state.getStateObject(stateobjaddr1)
 	if so1Restored != nil {
 		t.Fatalf("deleted object not nil after restoring snapshot: %+v", so1Restored)
 	}
 }
 
-func compareStateObjects(so0, so1 *StateObject, t *testing.T) {
+func compareStateObjects(so0, so1 *stateObject, t *testing.T) {
 	if so0.Address() != so1.Address() {
 		t.Fatalf("Address mismatch: have %v, want %v", so0.address, so1.address)
 	}
diff --git a/core/state/statedb.go b/core/state/statedb.go
index 68009deec33b3b23d8aaedc3ac9ac25483ba3e31..cae2dc4b2b170b27afc14f36dbd3b918c3b46093 100644
--- a/core/state/statedb.go
+++ b/core/state/statedb.go
@@ -25,7 +25,6 @@ import (
 
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/core/types"
-	"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"
@@ -64,7 +63,7 @@ type StateDB struct {
 	codeSizeCache *lru.Cache
 
 	// This map holds 'live' objects, which will get modified while processing a state transition.
-	stateObjects      map[common.Address]*StateObject
+	stateObjects      map[common.Address]*stateObject
 	stateObjectsDirty map[common.Address]struct{}
 
 	// The refund counter, also used by state transitioning.
@@ -97,7 +96,7 @@ func New(root common.Hash, db ethdb.Database) (*StateDB, error) {
 		db:                db,
 		trie:              tr,
 		codeSizeCache:     csc,
-		stateObjects:      make(map[common.Address]*StateObject),
+		stateObjects:      make(map[common.Address]*stateObject),
 		stateObjectsDirty: make(map[common.Address]struct{}),
 		refund:            new(big.Int),
 		logs:              make(map[common.Hash][]*types.Log),
@@ -119,7 +118,7 @@ func (self *StateDB) New(root common.Hash) (*StateDB, error) {
 		db:                self.db,
 		trie:              tr,
 		codeSizeCache:     self.codeSizeCache,
-		stateObjects:      make(map[common.Address]*StateObject),
+		stateObjects:      make(map[common.Address]*stateObject),
 		stateObjectsDirty: make(map[common.Address]struct{}),
 		refund:            new(big.Int),
 		logs:              make(map[common.Hash][]*types.Log),
@@ -138,7 +137,7 @@ func (self *StateDB) Reset(root common.Hash) error {
 		return err
 	}
 	self.trie = tr
-	self.stateObjects = make(map[common.Address]*StateObject)
+	self.stateObjects = make(map[common.Address]*stateObject)
 	self.stateObjectsDirty = make(map[common.Address]struct{})
 	self.thash = common.Hash{}
 	self.bhash = common.Hash{}
@@ -227,23 +226,19 @@ func (self *StateDB) AddRefund(gas *big.Int) {
 // Exist reports whether the given account address exists in the state.
 // Notably this also returns true for suicided accounts.
 func (self *StateDB) Exist(addr common.Address) bool {
-	return self.GetStateObject(addr) != nil
+	return self.getStateObject(addr) != nil
 }
 
 // Empty returns whether the state object is either non-existent
 // or empty according to the EIP161 specification (balance = nonce = code = 0)
 func (self *StateDB) Empty(addr common.Address) bool {
-	so := self.GetStateObject(addr)
+	so := self.getStateObject(addr)
 	return so == nil || so.empty()
 }
 
-func (self *StateDB) GetAccount(addr common.Address) vm.Account {
-	return self.GetStateObject(addr)
-}
-
 // Retrieve the balance from the given address or 0 if object not found
 func (self *StateDB) GetBalance(addr common.Address) *big.Int {
-	stateObject := self.GetStateObject(addr)
+	stateObject := self.getStateObject(addr)
 	if stateObject != nil {
 		return stateObject.Balance()
 	}
@@ -251,7 +246,7 @@ func (self *StateDB) GetBalance(addr common.Address) *big.Int {
 }
 
 func (self *StateDB) GetNonce(addr common.Address) uint64 {
-	stateObject := self.GetStateObject(addr)
+	stateObject := self.getStateObject(addr)
 	if stateObject != nil {
 		return stateObject.Nonce()
 	}
@@ -260,7 +255,7 @@ func (self *StateDB) GetNonce(addr common.Address) uint64 {
 }
 
 func (self *StateDB) GetCode(addr common.Address) []byte {
-	stateObject := self.GetStateObject(addr)
+	stateObject := self.getStateObject(addr)
 	if stateObject != nil {
 		code := stateObject.Code(self.db)
 		key := common.BytesToHash(stateObject.CodeHash())
@@ -271,7 +266,7 @@ func (self *StateDB) GetCode(addr common.Address) []byte {
 }
 
 func (self *StateDB) GetCodeSize(addr common.Address) int {
-	stateObject := self.GetStateObject(addr)
+	stateObject := self.getStateObject(addr)
 	if stateObject == nil {
 		return 0
 	}
@@ -287,7 +282,7 @@ func (self *StateDB) GetCodeSize(addr common.Address) int {
 }
 
 func (self *StateDB) GetCodeHash(addr common.Address) common.Hash {
-	stateObject := self.GetStateObject(addr)
+	stateObject := self.getStateObject(addr)
 	if stateObject == nil {
 		return common.Hash{}
 	}
@@ -295,7 +290,7 @@ func (self *StateDB) GetCodeHash(addr common.Address) common.Hash {
 }
 
 func (self *StateDB) GetState(a common.Address, b common.Hash) common.Hash {
-	stateObject := self.GetStateObject(a)
+	stateObject := self.getStateObject(a)
 	if stateObject != nil {
 		return stateObject.GetState(self.db, b)
 	}
@@ -303,7 +298,7 @@ func (self *StateDB) GetState(a common.Address, b common.Hash) common.Hash {
 }
 
 func (self *StateDB) HasSuicided(addr common.Address) bool {
-	stateObject := self.GetStateObject(addr)
+	stateObject := self.getStateObject(addr)
 	if stateObject != nil {
 		return stateObject.suicided
 	}
@@ -362,9 +357,9 @@ func (self *StateDB) SetState(addr common.Address, key common.Hash, value common
 // This clears the account balance.
 //
 // The account's state object is still available until the state is committed,
-// GetStateObject will return a non-nil account after Suicide.
+// getStateObject will return a non-nil account after Suicide.
 func (self *StateDB) Suicide(addr common.Address) bool {
-	stateObject := self.GetStateObject(addr)
+	stateObject := self.getStateObject(addr)
 	if stateObject == nil {
 		return false
 	}
@@ -383,7 +378,7 @@ func (self *StateDB) Suicide(addr common.Address) bool {
 //
 
 // updateStateObject writes the given object to the trie.
-func (self *StateDB) updateStateObject(stateObject *StateObject) {
+func (self *StateDB) updateStateObject(stateObject *stateObject) {
 	addr := stateObject.Address()
 	data, err := rlp.EncodeToBytes(stateObject)
 	if err != nil {
@@ -393,14 +388,14 @@ func (self *StateDB) updateStateObject(stateObject *StateObject) {
 }
 
 // deleteStateObject removes the given object from the state trie.
-func (self *StateDB) deleteStateObject(stateObject *StateObject) {
+func (self *StateDB) deleteStateObject(stateObject *stateObject) {
 	stateObject.deleted = true
 	addr := stateObject.Address()
 	self.trie.Delete(addr[:])
 }
 
 // Retrieve a state object given my the address. Returns nil if not found.
-func (self *StateDB) GetStateObject(addr common.Address) (stateObject *StateObject) {
+func (self *StateDB) getStateObject(addr common.Address) (stateObject *stateObject) {
 	// Prefer 'live' objects.
 	if obj := self.stateObjects[addr]; obj != nil {
 		if obj.deleted {
@@ -425,13 +420,13 @@ func (self *StateDB) GetStateObject(addr common.Address) (stateObject *StateObje
 	return obj
 }
 
-func (self *StateDB) setStateObject(object *StateObject) {
+func (self *StateDB) setStateObject(object *stateObject) {
 	self.stateObjects[object.Address()] = object
 }
 
 // Retrieve a state object or create a new state object if nil
-func (self *StateDB) GetOrNewStateObject(addr common.Address) *StateObject {
-	stateObject := self.GetStateObject(addr)
+func (self *StateDB) GetOrNewStateObject(addr common.Address) *stateObject {
+	stateObject := self.getStateObject(addr)
 	if stateObject == nil || stateObject.deleted {
 		stateObject, _ = self.createObject(addr)
 	}
@@ -446,8 +441,8 @@ func (self *StateDB) MarkStateObjectDirty(addr common.Address) {
 
 // createObject creates a new state object. If there is an existing account with
 // the given address, it is overwritten and returned as the second return value.
-func (self *StateDB) createObject(addr common.Address) (newobj, prev *StateObject) {
-	prev = self.GetStateObject(addr)
+func (self *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) {
+	prev = self.getStateObject(addr)
 	newobj = newObject(self, addr, Account{}, self.MarkStateObjectDirty)
 	newobj.setNonce(0) // sets the object to dirty
 	if prev == nil {
@@ -472,12 +467,32 @@ func (self *StateDB) createObject(addr common.Address) (newobj, prev *StateObjec
 //   2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1)
 //
 // Carrying over the balance ensures that Ether doesn't disappear.
-func (self *StateDB) CreateAccount(addr common.Address) vm.Account {
+func (self *StateDB) CreateAccount(addr common.Address) {
 	new, prev := self.createObject(addr)
 	if prev != nil {
 		new.setBalance(prev.data.Balance)
 	}
-	return new
+}
+
+func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) {
+	so := db.getStateObject(addr)
+	if so == nil {
+		return
+	}
+
+	// When iterating over the storage check the cache first
+	for h, value := range so.cachedStorage {
+		cb(h, value)
+	}
+
+	it := so.getTrie(db.db).Iterator()
+	for it.Next() {
+		// ignore cached values
+		key := common.BytesToHash(db.trie.GetKey(it.Key))
+		if _, ok := so.cachedStorage[key]; !ok {
+			cb(key, common.BytesToHash(it.Value))
+		}
+	}
 }
 
 // Copy creates a deep, independent copy of the state.
@@ -492,7 +507,7 @@ func (self *StateDB) Copy() *StateDB {
 		trie:              self.trie,
 		pastTries:         self.pastTries,
 		codeSizeCache:     self.codeSizeCache,
-		stateObjects:      make(map[common.Address]*StateObject, len(self.stateObjectsDirty)),
+		stateObjects:      make(map[common.Address]*stateObject, len(self.stateObjectsDirty)),
 		stateObjectsDirty: make(map[common.Address]struct{}, len(self.stateObjectsDirty)),
 		refund:            new(big.Int).Set(self.refund),
 		logs:              make(map[common.Hash][]*types.Log, len(self.logs)),
diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go
index 8743173009ab90dce372618141bc68f3c0ae3dfe..597de3be537ac3fb64d5d7e8cc52096f7c4fd8fe 100644
--- a/core/state/statedb_test.go
+++ b/core/state/statedb_test.go
@@ -331,12 +331,11 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error {
 		checkeq("GetCodeHash", state.GetCodeHash(addr), checkstate.GetCodeHash(addr))
 		checkeq("GetCodeSize", state.GetCodeSize(addr), checkstate.GetCodeSize(addr))
 		// Check storage.
-		if obj := state.GetStateObject(addr); obj != nil {
-			obj.ForEachStorage(func(key, val common.Hash) bool {
+		if obj := state.getStateObject(addr); obj != nil {
+			state.ForEachStorage(addr, func(key, val common.Hash) bool {
 				return checkeq("GetState("+key.Hex()+")", val, checkstate.GetState(addr, key))
 			})
-			checkobj := checkstate.GetStateObject(addr)
-			checkobj.ForEachStorage(func(key, checkval common.Hash) bool {
+			checkstate.ForEachStorage(addr, func(key, checkval common.Hash) bool {
 				return checkeq("GetState("+key.Hex()+")", state.GetState(addr, key), checkval)
 			})
 		}
diff --git a/core/state_transition.go b/core/state_transition.go
index 09c6c8bf34e6e8662cb1ca7c905b13f68f598c20..6acc78479393126f17d5ae825c87fa2b4501e08a 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -17,7 +17,7 @@
 package core
 
 import (
-	"fmt"
+	"errors"
 	"math/big"
 
 	"github.com/ethereum/go-ethereum/common"
@@ -28,7 +28,8 @@ import (
 )
 
 var (
-	Big0 = big.NewInt(0)
+	Big0                         = big.NewInt(0)
+	errInsufficientBalanceForGas = errors.New("insufficient balance to pay for gas")
 )
 
 /*
@@ -136,27 +137,28 @@ func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) ([]byte, *big.Int, erro
 	return ret, gasUsed, err
 }
 
-func (self *StateTransition) from() vm.Account {
+func (self *StateTransition) from() vm.AccountRef {
 	f := self.msg.From()
 	if !self.state.Exist(f) {
-		return self.state.CreateAccount(f)
+		self.state.CreateAccount(f)
 	}
-	return self.state.GetAccount(f)
+	return vm.AccountRef(f)
 }
 
-func (self *StateTransition) to() vm.Account {
+func (self *StateTransition) to() vm.AccountRef {
 	if self.msg == nil {
-		return nil
+		return vm.AccountRef{}
 	}
 	to := self.msg.To()
 	if to == nil {
-		return nil // contract creation
+		return vm.AccountRef{} // contract creation
 	}
 
+	reference := vm.AccountRef(*to)
 	if !self.state.Exist(*to) {
-		return self.state.CreateAccount(*to)
+		self.state.CreateAccount(*to)
 	}
-	return self.state.GetAccount(*to)
+	return reference
 }
 
 func (self *StateTransition) useGas(amount uint64) error {
@@ -176,9 +178,12 @@ func (self *StateTransition) buyGas() error {
 
 	mgval := new(big.Int).Mul(mgas, self.gasPrice)
 
-	sender := self.from()
-	if sender.Balance().Cmp(mgval) < 0 {
-		return fmt.Errorf("insufficient ETH for gas (%x). Req %v, has %v", sender.Address().Bytes()[:4], mgval, sender.Balance())
+	var (
+		state  = self.state
+		sender = self.from()
+	)
+	if state.GetBalance(sender.Address()).Cmp(mgval) < 0 {
+		return errInsufficientBalanceForGas
 	}
 	if err := self.gp.SubGas(mgas); err != nil {
 		return err
@@ -186,7 +191,7 @@ func (self *StateTransition) buyGas() error {
 	self.gas += mgas.Uint64()
 
 	self.initialGas.Set(mgas)
-	sender.SubBalance(mgval)
+	state.SubBalance(sender.Address(), mgval)
 	return nil
 }
 
@@ -272,7 +277,7 @@ func (self *StateTransition) refundGas() {
 	// exchanged at the original rate.
 	sender := self.from() // err already checked
 	remaining := new(big.Int).Mul(new(big.Int).SetUint64(self.gas), self.gasPrice)
-	sender.AddBalance(remaining)
+	self.state.AddBalance(sender.Address(), remaining)
 
 	// Apply refund counter, capped to half of the used gas.
 	uhalf := remaining.Div(self.gasUsed(), common.Big2)
diff --git a/core/vm/contract.go b/core/vm/contract.go
index 091106d84d77054007bd418126be139420fab3b2..66748e82158993b1a911b4f47e28f1c511162de1 100644
--- a/core/vm/contract.go
+++ b/core/vm/contract.go
@@ -25,11 +25,20 @@ import (
 // ContractRef is a reference to the contract's backing object
 type ContractRef interface {
 	Address() common.Address
-	Value() *big.Int
-	SetCode(common.Hash, []byte)
-	ForEachStorage(callback func(key, value common.Hash) bool)
 }
 
+// AccountRef implements ContractRef.
+//
+// Account references are used during EVM initialisation and
+// it's primary use is to fetch addresses. Removing this object
+// proves difficult because of the cached jump destinations which
+// are fetched from the parent contract (i.e. the caller), which
+// is a ContractRef.
+type AccountRef common.Address
+
+// Address casts AccountRef to a Address
+func (ar AccountRef) Address() common.Address { return (common.Address)(ar) }
+
 // Contract represents an ethereum contract in the state database. It contains
 // the the contract code, calling arguments. Contract implements ContractRef
 type Contract struct {
@@ -69,7 +78,8 @@ func NewContract(caller ContractRef, object ContractRef, value *big.Int, gas uin
 	// Gas should be a pointer so it can safely be reduced through the run
 	// This pointer will be off the state transition
 	c.Gas = gas
-	c.value = new(big.Int).Set(value)
+	// ensures a value is set
+	c.value = value
 
 	return c
 }
@@ -80,7 +90,10 @@ func (c *Contract) AsDelegate() *Contract {
 	c.DelegateCall = true
 	// NOTE: caller must, at all times be a contract. It should never happen
 	// that caller is something other than a Contract.
-	c.CallerAddress = c.caller.(*Contract).CallerAddress
+	parent := c.caller.(*Contract)
+	c.CallerAddress = parent.CallerAddress
+	c.value = parent.value
+
 	return c
 }
 
@@ -138,9 +151,3 @@ func (self *Contract) SetCallCode(addr *common.Address, hash common.Hash, code [
 	self.CodeHash = hash
 	self.CodeAddr = addr
 }
-
-// EachStorage iterates the contract's storage and calls a method for every key
-// value pair.
-func (self *Contract) ForEachStorage(cb func(key, value common.Hash) bool) {
-	self.caller.ForEachStorage(cb)
-}
diff --git a/core/vm/evm.go b/core/vm/evm.go
index 0c5d998c2944dee449f917b9593bf9346e9e4961..d1fac6c1031c0ec38c33d74bb5f1250aa9f24b7d 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -116,7 +116,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
 	}
 
 	var (
-		to       Account
+		to       = AccountRef(addr)
 		snapshot = evm.StateDB.Snapshot()
 	)
 	if !evm.StateDB.Exist(addr) {
@@ -124,9 +124,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
 			return nil, gas, nil
 		}
 
-		to = evm.StateDB.CreateAccount(addr)
-	} else {
-		to = evm.StateDB.GetAccount(addr)
+		evm.StateDB.CreateAccount(addr)
 	}
 	evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value)
 
@@ -169,7 +167,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
 
 	var (
 		snapshot = evm.StateDB.Snapshot()
-		to       = evm.StateDB.GetAccount(caller.Address())
+		to       = AccountRef(caller.Address())
 	)
 	// initialise a new contract and set the code that is to be used by the
 	// E The contract is a scoped evmironment for this execution context
@@ -205,11 +203,11 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
 
 	var (
 		snapshot = evm.StateDB.Snapshot()
-		to       = evm.StateDB.GetAccount(caller.Address())
+		to       = AccountRef(caller.Address())
 	)
 
 	// Iinitialise a new contract and make initialise the delegate values
-	contract := NewContract(caller, to, caller.Value(), gas).AsDelegate()
+	contract := NewContract(caller, to, nil, gas).AsDelegate()
 	contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
 
 	ret, err = evm.interpreter.Run(contract, input)
@@ -243,16 +241,16 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I
 
 	snapshot := evm.StateDB.Snapshot()
 	contractAddr = crypto.CreateAddress(caller.Address(), nonce)
-	to := evm.StateDB.CreateAccount(contractAddr)
+	evm.StateDB.CreateAccount(contractAddr)
 	if evm.ChainConfig().IsEIP158(evm.BlockNumber) {
 		evm.StateDB.SetNonce(contractAddr, 1)
 	}
-	evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value)
+	evm.Transfer(evm.StateDB, caller.Address(), contractAddr, value)
 
 	// initialise a new contract and set the code that is to be used by the
 	// E The contract is a scoped evmironment for this execution context
 	// only.
-	contract := NewContract(caller, to, value, gas)
+	contract := NewContract(caller, AccountRef(contractAddr), value, gas)
 	contract.SetCallCode(&contractAddr, crypto.Keccak256Hash(code), code)
 
 	ret, err = evm.interpreter.Run(contract, nil)
diff --git a/core/vm/interface.go b/core/vm/interface.go
index 6f15112eea0f200dcaf2d0a6fd239f5015a2abf9..4d8ece41ca8510fe75cef89a7e0583fb73df993a 100644
--- a/core/vm/interface.go
+++ b/core/vm/interface.go
@@ -25,8 +25,7 @@ import (
 
 // StateDB is an EVM database for full state querying.
 type StateDB interface {
-	GetAccount(common.Address) Account
-	CreateAccount(common.Address) Account
+	CreateAccount(common.Address)
 
 	SubBalance(common.Address, *big.Int)
 	AddBalance(common.Address, *big.Int)
@@ -61,20 +60,8 @@ type StateDB interface {
 
 	AddLog(*types.Log)
 	AddPreimage(common.Hash, []byte)
-}
 
-// Account represents a contract or basic ethereum account.
-type Account interface {
-	SubBalance(amount *big.Int)
-	AddBalance(amount *big.Int)
-	SetBalance(*big.Int)
-	SetNonce(uint64)
-	Balance() *big.Int
-	Address() common.Address
-	ReturnGas(*big.Int)
-	SetCode(common.Hash, []byte)
-	ForEachStorage(cb func(key, value common.Hash) bool)
-	Value() *big.Int
+	ForEachStorage(common.Address, func(common.Hash, common.Hash) bool)
 }
 
 // CallContext provides a basic interface for the EVM calling conventions. The EVM EVM
diff --git a/core/vm/logger.go b/core/vm/logger.go
index db8c20e07f9a30b6c88bf96809231e86b6c1251d..3845b1073dba44b0c3a6e5d00f6e58457d8386bc 100644
--- a/core/vm/logger.go
+++ b/core/vm/logger.go
@@ -144,7 +144,8 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost *b
 			storage = make(Storage)
 			// Get the contract account and loop over each storage entry. This may involve looping over
 			// the trie and is a very expensive process.
-			env.StateDB.GetAccount(contract.Address()).ForEachStorage(func(key, value common.Hash) bool {
+
+			env.StateDB.ForEachStorage(contract.Address(), func(key, value common.Hash) bool {
 				storage[key] = value
 				// Return true, indicating we'd like to continue.
 				return true
diff --git a/core/vm/logger_test.go b/core/vm/logger_test.go
index ca60cba43e8fa763fc6eafd8ad6d39d974354c25..e755a18e2a24afae0fede7fdc96328b17d14f73e 100644
--- a/core/vm/logger_test.go
+++ b/core/vm/logger_test.go
@@ -46,10 +46,6 @@ type dummyStateDB struct {
 	ref *dummyContractRef
 }
 
-func (d dummyStateDB) GetAccount(common.Address) Account {
-	return d.ref
-}
-
 func TestStoreCapture(t *testing.T) {
 	var (
 		env      = NewEVM(Context{}, nil, params.TestChainConfig, Config{EnableJit: false, ForceJit: false})
diff --git a/core/vm/noop.go b/core/vm/noop.go
index 7835eeaf35c76c793b8ee90e503e698688080bbe..2a04a95654ecc7c731de49432f4d110ebd449d0d 100644
--- a/core/vm/noop.go
+++ b/core/vm/noop.go
@@ -45,26 +45,26 @@ func (NoopEVMCallContext) DelegateCall(me ContractRef, addr common.Address, data
 
 type NoopStateDB struct{}
 
-func (NoopStateDB) GetAccount(common.Address) Account                 { return nil }
-func (NoopStateDB) CreateAccount(common.Address) Account              { return nil }
-func (NoopStateDB) SubBalance(common.Address, *big.Int)               {}
-func (NoopStateDB) AddBalance(common.Address, *big.Int)               {}
-func (NoopStateDB) GetBalance(common.Address) *big.Int                { return nil }
-func (NoopStateDB) GetNonce(common.Address) uint64                    { return 0 }
-func (NoopStateDB) SetNonce(common.Address, uint64)                   {}
-func (NoopStateDB) GetCodeHash(common.Address) common.Hash            { return common.Hash{} }
-func (NoopStateDB) GetCode(common.Address) []byte                     { return nil }
-func (NoopStateDB) SetCode(common.Address, []byte)                    {}
-func (NoopStateDB) GetCodeSize(common.Address) int                    { return 0 }
-func (NoopStateDB) AddRefund(*big.Int)                                {}
-func (NoopStateDB) GetRefund() *big.Int                               { return nil }
-func (NoopStateDB) GetState(common.Address, common.Hash) common.Hash  { return common.Hash{} }
-func (NoopStateDB) SetState(common.Address, common.Hash, common.Hash) {}
-func (NoopStateDB) Suicide(common.Address) bool                       { return false }
-func (NoopStateDB) HasSuicided(common.Address) bool                   { return false }
-func (NoopStateDB) Exist(common.Address) bool                         { return false }
-func (NoopStateDB) Empty(common.Address) bool                         { return false }
-func (NoopStateDB) RevertToSnapshot(int)                              {}
-func (NoopStateDB) Snapshot() int                                     { return 0 }
-func (NoopStateDB) AddLog(*types.Log)                                 {}
-func (NoopStateDB) AddPreimage(common.Hash, []byte)                   {}
+func (NoopStateDB) CreateAccount(common.Address)                                       {}
+func (NoopStateDB) SubBalance(common.Address, *big.Int)                                {}
+func (NoopStateDB) AddBalance(common.Address, *big.Int)                                {}
+func (NoopStateDB) GetBalance(common.Address) *big.Int                                 { return nil }
+func (NoopStateDB) GetNonce(common.Address) uint64                                     { return 0 }
+func (NoopStateDB) SetNonce(common.Address, uint64)                                    {}
+func (NoopStateDB) GetCodeHash(common.Address) common.Hash                             { return common.Hash{} }
+func (NoopStateDB) GetCode(common.Address) []byte                                      { return nil }
+func (NoopStateDB) SetCode(common.Address, []byte)                                     {}
+func (NoopStateDB) GetCodeSize(common.Address) int                                     { return 0 }
+func (NoopStateDB) AddRefund(*big.Int)                                                 {}
+func (NoopStateDB) GetRefund() *big.Int                                                { return nil }
+func (NoopStateDB) GetState(common.Address, common.Hash) common.Hash                   { return common.Hash{} }
+func (NoopStateDB) SetState(common.Address, common.Hash, common.Hash)                  {}
+func (NoopStateDB) Suicide(common.Address) bool                                        { return false }
+func (NoopStateDB) HasSuicided(common.Address) bool                                    { return false }
+func (NoopStateDB) Exist(common.Address) bool                                          { return false }
+func (NoopStateDB) Empty(common.Address) bool                                          { return false }
+func (NoopStateDB) RevertToSnapshot(int)                                               {}
+func (NoopStateDB) Snapshot() int                                                      { return 0 }
+func (NoopStateDB) AddLog(*types.Log)                                                  {}
+func (NoopStateDB) AddPreimage(common.Hash, []byte)                                    {}
+func (NoopStateDB) ForEachStorage(common.Address, func(common.Hash, common.Hash) bool) {}
diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go
index cf46603dbd895c6dd0f02b5dc6fc3b51a1b57aa2..94265626f20065eba7fa6f822fdd7fe3ab0b2566 100644
--- a/core/vm/runtime/runtime.go
+++ b/core/vm/runtime/runtime.go
@@ -105,17 +105,17 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
 		cfg.State, _ = state.New(common.Hash{}, db)
 	}
 	var (
-		vmenv    = NewEnv(cfg, cfg.State)
-		sender   = cfg.State.CreateAccount(cfg.Origin)
-		receiver = cfg.State.CreateAccount(common.StringToAddress("contract"))
+		address = common.StringToAddress("contract")
+		vmenv   = NewEnv(cfg, cfg.State)
+		sender  = vm.AccountRef(cfg.Origin)
 	)
+	cfg.State.CreateAccount(address)
 	// set the receiver's (the executing contract) code for execution.
-	receiver.SetCode(crypto.Keccak256Hash(code), code)
-
+	cfg.State.SetCode(address, code)
 	// Call the code with the given configuration.
 	ret, _, err := vmenv.Call(
 		sender,
-		receiver.Address(),
+		common.StringToAddress("contract"),
 		input,
 		cfg.GasLimit,
 		cfg.Value,
@@ -137,7 +137,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, error) {
 	}
 	var (
 		vmenv  = NewEnv(cfg, cfg.State)
-		sender = cfg.State.CreateAccount(cfg.Origin)
+		sender = vm.AccountRef(cfg.Origin)
 	)
 
 	// Call the code with the given configuration.
diff --git a/light/state.go b/light/state.go
index b6cefc9b90ff3e2d20dd47754cb04ad8db9b9372..f19748e8958adccb2d11af5fb1a04622964bcbfd 100644
--- a/light/state.go
+++ b/light/state.go
@@ -268,6 +268,26 @@ func (self *LightState) CreateStateObject(ctx context.Context, addr common.Addre
 	return newSo, nil
 }
 
+// ForEachStorage calls a callback function for every key/value pair found
+// in the local storage cache. Note that unlike core/state.StateObject,
+// light.StateObject only returns cached values and doesn't download the
+// entire storage tree.
+func (self *LightState) ForEachStorage(ctx context.Context, addr common.Address, cb func(key, value common.Hash) bool) error {
+	so, err := self.GetStateObject(ctx, addr)
+	if err != nil {
+		return err
+	}
+
+	if so == nil {
+		return nil
+	}
+
+	for h, v := range so.storage {
+		cb(h, v)
+	}
+	return nil
+}
+
 //
 // Setting, copying of the state methods
 //
diff --git a/light/vm_env.go b/light/vm_env.go
index d2cc7e96085377af916ad921319839a0856d378d..ebd229de8663b168e46342fccfae01fc8fa5351b 100644
--- a/light/vm_env.go
+++ b/light/vm_env.go
@@ -21,7 +21,6 @@ import (
 
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/core/types"
-	"github.com/ethereum/go-ethereum/core/vm"
 	"github.com/ethereum/go-ethereum/crypto"
 	"golang.org/x/net/context"
 )
@@ -64,27 +63,10 @@ func (self *VMState) RevertToSnapshot(idx int) {
 	self.snapshots = self.snapshots[:idx]
 }
 
-// GetAccount returns the account object of the given account or nil if the
-// account does not exist
-func (s *VMState) GetAccount(addr common.Address) vm.Account {
-	so, err := s.state.GetStateObject(s.ctx, addr)
-	s.errHandler(err)
-	if err != nil {
-		// return a dummy state object to avoid panics
-		so = s.state.newStateObject(addr)
-	}
-	return so
-}
-
 // CreateAccount creates creates a new account object and takes ownership.
-func (s *VMState) CreateAccount(addr common.Address) vm.Account {
-	so, err := s.state.CreateStateObject(s.ctx, addr)
+func (s *VMState) CreateAccount(addr common.Address) {
+	_, err := s.state.CreateStateObject(s.ctx, addr)
 	s.errHandler(err)
-	if err != nil {
-		// return a dummy state object to avoid panics
-		so = s.state.newStateObject(addr)
-	}
-	return so
 }
 
 // AddBalance adds the given amount to the balance of the specified account
@@ -99,6 +81,15 @@ func (s *VMState) SubBalance(addr common.Address, amount *big.Int) {
 	s.errHandler(err)
 }
 
+// ForEachStorage calls a callback function for every key/value pair found
+// in the local storage cache. Note that unlike core/state.StateObject,
+// light.StateObject only returns cached values and doesn't download the
+// entire storage tree.
+func (s *VMState) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) {
+	err := s.state.ForEachStorage(s.ctx, addr, cb)
+	s.errHandler(err)
+}
+
 // GetBalance retrieves the balance from the given address or 0 if the account does
 // not exist
 func (s *VMState) GetBalance(addr common.Address) *big.Int {
diff --git a/tests/block_test_util.go b/tests/block_test_util.go
index 695b47e0b4c159d1c58a8f2f1778dd1c3bb71f95..9199be774e4be373cbe8e43452d224292130653a 100644
--- a/tests/block_test_util.go
+++ b/tests/block_test_util.go
@@ -32,7 +32,6 @@ import (
 	"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"
 	"github.com/ethereum/go-ethereum/ethdb"
 	"github.com/ethereum/go-ethereum/event"
 	"github.com/ethereum/go-ethereum/logger/glog"
@@ -222,10 +221,12 @@ func (t *BlockTest) InsertPreState(db ethdb.Database) (*state.StateDB, error) {
 		if err != nil {
 			return nil, err
 		}
-		obj := statedb.CreateAccount(common.HexToAddress(addrString))
-		obj.SetCode(crypto.Keccak256Hash(code), code)
-		obj.SetBalance(balance)
-		obj.SetNonce(nonce)
+
+		addr := common.HexToAddress(addrString)
+		statedb.CreateAccount(addr)
+		statedb.SetCode(addr, code)
+		statedb.SetBalance(addr, balance)
+		statedb.SetNonce(addr, nonce)
 		for k, v := range acct.Storage {
 			statedb.SetState(common.HexToAddress(addrString), common.HexToHash(k), common.HexToHash(v))
 		}
diff --git a/tests/state_test_util.go b/tests/state_test_util.go
index e8ab29d1433087dc4be1a605b1df7be8ea09450c..a2a0482057e266d4c59384a318893fa9e54415e4 100644
--- a/tests/state_test_util.go
+++ b/tests/state_test_util.go
@@ -165,25 +165,25 @@ func runStateTest(chainConfig *params.ChainConfig, test VmTest) error {
 
 	// check post state
 	for addr, account := range test.Post {
-		obj := statedb.GetStateObject(common.HexToAddress(addr))
-		if obj == nil {
+		address := common.HexToAddress(addr)
+		if !statedb.Exist(address) {
 			return fmt.Errorf("did not find expected post-state account: %s", addr)
 		}
 
-		if obj.Balance().Cmp(common.Big(account.Balance)) != 0 {
-			return fmt.Errorf("(%x) balance failed. Expected: %v have: %v\n", obj.Address().Bytes()[:4], common.String2Big(account.Balance), obj.Balance())
+		if balance := statedb.GetBalance(address); balance.Cmp(common.Big(account.Balance)) != 0 {
+			return fmt.Errorf("(%x) balance failed. Expected: %v have: %v\n", address[:4], common.String2Big(account.Balance), balance)
 		}
 
-		if obj.Nonce() != common.String2Big(account.Nonce).Uint64() {
-			return fmt.Errorf("(%x) nonce failed. Expected: %v have: %v\n", obj.Address().Bytes()[:4], account.Nonce, obj.Nonce())
+		if nonce := statedb.GetNonce(address); nonce != common.String2Big(account.Nonce).Uint64() {
+			return fmt.Errorf("(%x) nonce failed. Expected: %v have: %v\n", address[:4], account.Nonce, nonce)
 		}
 
 		for addr, value := range account.Storage {
-			v := statedb.GetState(obj.Address(), common.HexToHash(addr))
+			v := statedb.GetState(address, common.HexToHash(addr))
 			vexp := common.HexToHash(value)
 
 			if v != vexp {
-				return fmt.Errorf("storage failed:\n%x: %s:\nexpected: %x\nhave:     %x\n(%v %v)\n", obj.Address().Bytes(), addr, vexp, v, vexp.Big(), v.Big())
+				return fmt.Errorf("storage failed:\n%x: %s:\nexpected: %x\nhave:     %x\n(%v %v)\n", address[:4], addr, vexp, v, vexp.Big(), v.Big())
 			}
 		}
 	}
diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go
index 1edf0e425aacc7bee4e69d0771cd66f022a2e9b6..3b7ba9b31ab04e70e6aae1b86babf6e419f1cde7 100644
--- a/tests/vm_test_util.go
+++ b/tests/vm_test_util.go
@@ -187,16 +187,16 @@ func runVmTest(test VmTest) error {
 	}
 
 	// check post state
-	for addr, account := range test.Post {
-		obj := statedb.GetStateObject(common.HexToAddress(addr))
-		if obj == nil {
+	for address, account := range test.Post {
+		accountAddr := common.HexToAddress(address)
+		if !statedb.Exist(accountAddr) {
 			continue
 		}
 		for addr, value := range account.Storage {
-			v := statedb.GetState(obj.Address(), common.HexToHash(addr))
+			v := statedb.GetState(accountAddr, 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())
+				return fmt.Errorf("(%x: %s) storage failed. Expected %x, got %x (%v %v)\n", addr[:4], addr, vexp, v, vexp.Big(), v.Big())
 			}
 		}
 	}