diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go
index 6d4bfe1cb7be349bcf8e0e0e7cc26374a7c844dc..6a98edec109c9cea8539e6f58ce91fa4f5e5a0b8 100644
--- a/accounts/abi/bind/backends/simulated.go
+++ b/accounts/abi/bind/backends/simulated.go
@@ -133,11 +133,11 @@ func (b *SimulatedBackend) stateByBlockNumber(ctx context.Context, blockNumber *
 	if blockNumber == nil || blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) == 0 {
 		return b.blockchain.State()
 	}
-	block, err := b.BlockByNumber(ctx, blockNumber)
+	block, err := b.blockByNumberNoLock(ctx, blockNumber)
 	if err != nil {
 		return nil, err
 	}
-	return b.blockchain.StateAt(block.Hash())
+	return b.blockchain.StateAt(block.Root())
 }
 
 // CodeAt returns the code associated with a certain account in the blockchain.
@@ -244,6 +244,12 @@ func (b *SimulatedBackend) BlockByNumber(ctx context.Context, number *big.Int) (
 	b.mu.Lock()
 	defer b.mu.Unlock()
 
+	return b.blockByNumberNoLock(ctx, number)
+}
+
+// blockByNumberNoLock retrieves a block from the database by number, caching it
+// (associated with its hash) if found without Lock.
+func (b *SimulatedBackend) blockByNumberNoLock(ctx context.Context, number *big.Int) (*types.Block, error) {
 	if number == nil || number.Cmp(b.pendingBlock.Number()) == 0 {
 		return b.blockchain.CurrentBlock(), nil
 	}
diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go
index a55b4460aa8ad1138f8ba84dc377f748945817ef..25b36d497d6b3aabf9b4669248a1c7e84bc55b13 100644
--- a/accounts/abi/bind/backends/simulated_test.go
+++ b/accounts/abi/bind/backends/simulated_test.go
@@ -268,6 +268,16 @@ func TestSimulatedBackend_NonceAt(t *testing.T) {
 	if newNonce != nonce+uint64(1) {
 		t.Errorf("received incorrect nonce. expected 1, got %v", nonce)
 	}
+	// create some more blocks
+	sim.Commit()
+	// Check that we can get data for an older block/state
+	newNonce, err = sim.NonceAt(bgCtx, testAddr, big.NewInt(1))
+	if err != nil {
+		t.Fatalf("could not get nonce for test addr: %v", err)
+	}
+	if newNonce != nonce+uint64(1) {
+		t.Fatalf("received incorrect nonce. expected 1, got %v", nonce)
+	}
 }
 
 func TestSimulatedBackend_SendTransaction(t *testing.T) {