diff --git a/core/rawdb/eradb/eradb.go b/core/rawdb/eradb/eradb.go
new file mode 100644
index 0000000000..b9d2bb7dff
--- /dev/null
+++ b/core/rawdb/eradb/eradb.go
@@ -0,0 +1,131 @@
+// Copyright 2025 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package eradb
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "path"
+ "sync"
+
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/internal/era"
+ "github.com/ethereum/go-ethereum/log"
+)
+
+type EraDatabase struct {
+ datadir string
+ table map[uint64]*era.Era
+ mu sync.RWMutex
+}
+
+// New creates a new EraDatabase instance.
+func New(datadir string) (*EraDatabase, error) {
+ // Ensure the datadir is not a symbolic link if it exists.
+ if info, err := os.Lstat(datadir); !os.IsNotExist(err) {
+ if info == nil {
+ log.Warn("Could not Lstat the database", "path", datadir)
+ return nil, errors.New("lstat failed")
+ }
+ if info.Mode()&os.ModeSymlink != 0 {
+ log.Warn("Symbolic link erastore is not supported", "path", datadir)
+ return nil, errors.New("symbolic link datadir is not supported")
+ }
+ }
+ if err := os.MkdirAll(datadir, 0755); err != nil {
+ return nil, err
+ }
+ log.Info("Opened erastore", "datadir", datadir)
+ return &EraDatabase{datadir: datadir, table: make(map[uint64]*era.Era)}, nil
+}
+
+// scan returns a list of all era1 files in the datadir.
+func (db *EraDatabase) scan() ([]string, error) {
+ entries, err := os.ReadDir(db.datadir)
+ if err != nil {
+ return nil, err
+ }
+ var files []string
+ for _, entry := range entries {
+ if entry.IsDir() || entry.Type()&os.ModeSymlink != 0 {
+ continue
+ }
+ // Skip files that are not era1 files.
+ if path.Ext(entry.Name()) != ".era1" {
+ continue
+ }
+ files = append(files, entry.Name())
+ }
+ return files, nil
+}
+
+func (db *EraDatabase) openEra(name string) (*era.Era, error) {
+ e, err := era.Open(name)
+ if err != nil {
+ return nil, err
+ }
+ // Assign an epoch to the table.
+ if e.Count() != uint64(era.MaxEra1Size) {
+ return nil, fmt.Errorf("pre-merge era1 files must be full. Want: %d, have: %d", era.MaxEra1Size, e.Count())
+ }
+ if e.Start()%uint64(era.MaxEra1Size) != 0 {
+ return nil, fmt.Errorf("pre-merge era1 file has invalid boundary. %d %% %d != 0", e.Start(), era.MaxEra1Size)
+ }
+ epoch := e.Start() / uint64(era.MaxEra1Size)
+ db.mu.Lock()
+ db.table[epoch] = e
+ db.mu.Unlock()
+ return e, nil
+}
+
+func (db *EraDatabase) Close() {
+ db.mu.Lock()
+ defer db.mu.Unlock()
+ for _, e := range db.table {
+ if err := e.Close(); err != nil {
+ log.Warn("Failed to close era", "error", err)
+ }
+ }
+ db.table = nil
+}
+
+func (db *EraDatabase) GetBlockByNumber(number uint64) (*types.Block, error) {
+ files, err := db.scan()
+ if err != nil {
+ return nil, err
+ }
+ for _, file := range files {
+ _, err := db.openEra(path.Join(db.datadir, file))
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ // Lookup the table by epoch.
+ epoch := number / uint64(era.MaxEra1Size)
+ db.mu.RLock()
+ defer db.mu.RUnlock()
+ if e, ok := db.table[epoch]; ok {
+ block, err := e.GetBlockByNumber(number)
+ if err == nil {
+ return block, nil
+ }
+ }
+
+ return nil, errors.New("block not found")
+}
diff --git a/core/rawdb/eradb/eradb_test.go b/core/rawdb/eradb/eradb_test.go
new file mode 100644
index 0000000000..452103d1b3
--- /dev/null
+++ b/core/rawdb/eradb/eradb_test.go
@@ -0,0 +1,39 @@
+// Copyright 2025 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package eradb
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestEraDatabase_Scan(t *testing.T) {
+ // Create the database
+ db, err := New("testdata")
+ require.NoError(t, err)
+
+ // Scan for era files
+ files, err := db.scan()
+ require.NoError(t, err)
+
+ t.Log(files)
+ block, err := db.GetBlockByNumber(15000)
+ require.NoError(t, err)
+ defer db.Close()
+ require.Equal(t, uint64(15000), block.NumberU64())
+}
diff --git a/core/rawdb/eradb/testdata/sepolia-00000-643a00f7.era1 b/core/rawdb/eradb/testdata/sepolia-00000-643a00f7.era1
new file mode 100644
index 0000000000..a601a40c23
Binary files /dev/null and b/core/rawdb/eradb/testdata/sepolia-00000-643a00f7.era1 differ
diff --git a/core/rawdb/eradb/testdata/sepolia-00001-f3ea493e.era1 b/core/rawdb/eradb/testdata/sepolia-00001-f3ea493e.era1
new file mode 100644
index 0000000000..426de38810
Binary files /dev/null and b/core/rawdb/eradb/testdata/sepolia-00001-f3ea493e.era1 differ
diff --git a/core/rawdb/eradb/testdata/sepolia-00002-dcb01f4d.era1 b/core/rawdb/eradb/testdata/sepolia-00002-dcb01f4d.era1
new file mode 100644
index 0000000000..34f7bd4424
Binary files /dev/null and b/core/rawdb/eradb/testdata/sepolia-00002-dcb01f4d.era1 differ
diff --git a/core/rawdb/eradb/testdata/sepolia-00003-18b32584.era1 b/core/rawdb/eradb/testdata/sepolia-00003-18b32584.era1
new file mode 100644
index 0000000000..2a3b1a5354
Binary files /dev/null and b/core/rawdb/eradb/testdata/sepolia-00003-18b32584.era1 differ
diff --git a/core/rawdb/eradb/testdata/sepolia-00004-e93b3f11.era1 b/core/rawdb/eradb/testdata/sepolia-00004-e93b3f11.era1
new file mode 100644
index 0000000000..0b6ccc2ef4
Binary files /dev/null and b/core/rawdb/eradb/testdata/sepolia-00004-e93b3f11.era1 differ