diff --git a/rollup/missing_header_fields/export-headers-toolkit/.gitignore b/rollup/missing_header_fields/export-headers-toolkit/.gitignore
new file mode 100644
index 000000000000..adbb97d2d313
--- /dev/null
+++ b/rollup/missing_header_fields/export-headers-toolkit/.gitignore
@@ -0,0 +1 @@
+data/
\ No newline at end of file
diff --git a/rollup/missing_header_fields/export-headers-toolkit/Dockerfile b/rollup/missing_header_fields/export-headers-toolkit/Dockerfile
new file mode 100644
index 000000000000..04f729a05ef7
--- /dev/null
+++ b/rollup/missing_header_fields/export-headers-toolkit/Dockerfile
@@ -0,0 +1,13 @@
+FROM golang:1.22
+
+WORKDIR /app
+
+COPY go.mod go.sum ./
+
+RUN go mod download
+
+COPY . .
+
+RUN go build -o main .
+
+ENTRYPOINT ["./main"]
\ No newline at end of file
diff --git a/rollup/missing_header_fields/export-headers-toolkit/README.md b/rollup/missing_header_fields/export-headers-toolkit/README.md
new file mode 100644
index 000000000000..339bcada3d59
--- /dev/null
+++ b/rollup/missing_header_fields/export-headers-toolkit/README.md
@@ -0,0 +1,63 @@
+# Export missing block header fields toolkit
+
+A toolkit for exporting and transforming missing block header fields of Scroll before {{upgrade_name}} TODO: replace when upgrade is clear.
+
+## Context
+We are using the [Clique consensus](https://eips.ethereum.org/EIPS/eip-225) in Scroll L2. Amongst others, it requires the following header fields:
+- `extraData`
+- `difficulty`
+
+However, before {{upgrade_name}}, these fields were not stored on L1/DA.
+In order for nodes to be able to reconstruct the correct block hashes when only reading data from L1, 
+we need to provide the historical values of these fields to these nodes through a separate file.
+
+This toolkit provides commands to export the missing fields, deduplicate the data and create a file 
+with the missing fields that can be used to reconstruct the correct block hashes when only reading data from L1.
+
+The toolkit provides the following commands:
+- `fetch` - Fetch missing block header fields from a running Scroll L2 node and store in a file
+- `dedup` - Deduplicate the headers file, print unique values and create a new file with the deduplicated headers 
+
+## Binary layout deduplicated missing header fields file
+The deduplicated header file binary layout is as follows:
+
+```plaintext
+<unique_vanity_count:uint8><unique_vanity_1:[32]byte>...<unique_vanity_n:[32]byte><header_1:header>...<header_n:header>
+
+Where:
+- unique_vanity_count: number of unique vanities n
+- unique_vanity_i: unique vanity i
+- header_i: block header i
+- header: 
+    <flags:uint8><seal:[65|85]byte>
+    - flags: bitmask, lsb first
+	    - bit 0-5: index of the vanity in the sorted vanities list
+	    - bit 6: 0 if difficulty is 2, 1 if difficulty is 1
+	    - bit 7: 0 if seal length is 65, 1 if seal length is 85
+```
+
+## How to run
+Each of the commands has its own set of flags and options. To display the help message run with `--help` flag.
+
+1. Fetch the missing block header fields from a running Scroll L2 node via RPC and store in a file (approx 40min for 5.5M blocks).
+2. Deduplicate the headers file, print unique values and create a new file with the deduplicated headers
+
+```bash
+go run main.go fetch --rpc=http://localhost:8545 --start=0 --end=100 --batch=10 --parallelism=10 --output=headers.bin --humanOutput=true
+go run main.go dedup --input=headers.bin --output=headers-dedup.bin
+```
+
+
+### With Docker
+To run the toolkit with Docker, build the Docker image and run the commands inside the container.
+
+```bash  
+docker build -t export-headers-toolkit .
+
+# depending on the Docker config maybe finding the RPC container's IP with docker inspect is necessary. Potentially host IP works: http://172.17.0.1:8545
+docker run --rm -v "$(pwd)":/app/result export-headers-toolkit fetch --rpc=<address> --start=0 --end=5422047 --batch=10000 --parallelism=10 --output=/app/result/headers.bin --humanOutput=/app/result/headers.csv
+docker run --rm -v "$(pwd)":/app/result export-headers-toolkit dedup --input=/app/result/headers.bin --output=/app/result/headers-dedup.bin 
+```
+
+
+
diff --git a/rollup/missing_header_fields/export-headers-toolkit/cmd/dedup.go b/rollup/missing_header_fields/export-headers-toolkit/cmd/dedup.go
new file mode 100644
index 000000000000..e2bbd7ee4ddd
--- /dev/null
+++ b/rollup/missing_header_fields/export-headers-toolkit/cmd/dedup.go
@@ -0,0 +1,296 @@
+package cmd
+
+import (
+	"bufio"
+	"bytes"
+	"crypto/sha256"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"log"
+	"os"
+	"strconv"
+	"strings"
+
+	"github.com/spf13/cobra"
+
+	"github.com/scroll-tech/go-ethereum/common"
+
+	"github.com/scroll-tech/go-ethereum/export-headers-toolkit/types"
+)
+
+// dedupCmd represents the dedup command
+var dedupCmd = &cobra.Command{
+	Use:   "dedup",
+	Short: "Deduplicate the headers file, print unique values and create a new file with the deduplicated headers",
+	Long: `Deduplicate the headers file, print unique values and create a new file with the deduplicated headers.
+
+The binary layout of the deduplicated file is as follows:
+- 1 byte for the count of unique vanity
+- 32 bytes for each unique vanity
+- for each header:
+  - 1 byte (bitmask, lsb first): 
+	- bit 0-5: index of the vanity in the sorted vanities list
+	- bit 6: 0 if difficulty is 2, 1 if difficulty is 1
+	- bit 7: 0 if seal length is 65, 1 if seal length is 85
+  - 65 or 85 bytes for the seal`,
+	Run: func(cmd *cobra.Command, args []string) {
+		inputFile, err := cmd.Flags().GetString("input")
+		if err != nil {
+			log.Fatalf("Error reading output flag: %v", err)
+		}
+		outputFile, err := cmd.Flags().GetString("output")
+		if err != nil {
+			log.Fatalf("Error reading output flag: %v", err)
+		}
+		verifyFile, err := cmd.Flags().GetString("verify")
+		if err != nil {
+			log.Fatalf("Error reading verify flag: %v", err)
+		}
+
+		if verifyFile != "" {
+			verifyInputFile(verifyFile, inputFile)
+		}
+
+		_, seenVanity, _ := runAnalysis(inputFile)
+		runDedup(inputFile, outputFile, seenVanity)
+
+		if verifyFile != "" {
+			verifyOutputFile(verifyFile, outputFile)
+		}
+
+		runSHA256(outputFile)
+	},
+}
+
+func init() {
+	rootCmd.AddCommand(dedupCmd)
+
+	dedupCmd.Flags().String("input", "headers.bin", "headers file")
+	dedupCmd.Flags().String("output", "headers-dedup.bin", "deduplicated, binary formatted file")
+	dedupCmd.Flags().String("verify", "", "verify the input and output files with the given .csv file")
+}
+
+func runAnalysis(inputFile string) (seenDifficulty map[uint64]int, seenVanity map[[32]byte]bool, seenSealLen map[int]int) {
+	reader := newHeaderReader(inputFile)
+	defer reader.close()
+
+	// track header fields we've seen
+	seenDifficulty = make(map[uint64]int)
+	seenVanity = make(map[[32]byte]bool)
+	seenSealLen = make(map[int]int)
+
+	reader.read(func(header *types.Header) {
+		seenDifficulty[header.Difficulty]++
+		seenVanity[header.Vanity()] = true
+		seenSealLen[header.SealLen()]++
+	})
+
+	// Print distinct values and report
+	fmt.Println("--------------------------------------------------")
+	for diff, count := range seenDifficulty {
+		fmt.Printf("Difficulty %d: %d\n", diff, count)
+	}
+
+	for vanity := range seenVanity {
+		fmt.Printf("Vanity: %x\n", vanity)
+	}
+
+	for sealLen, count := range seenSealLen {
+		fmt.Printf("SealLen %d bytes: %d\n", sealLen, count)
+	}
+
+	fmt.Println("--------------------------------------------------")
+	fmt.Printf("Unique values seen in the headers file (last seen block: %d):\n", reader.lastHeader.Number)
+	fmt.Printf("Distinct count: Difficulty:%d, Vanity:%d, SealLen:%d\n", len(seenDifficulty), len(seenVanity), len(seenSealLen))
+	fmt.Printf("--------------------------------------------------\n\n")
+
+	return seenDifficulty, seenVanity, seenSealLen
+}
+
+func runDedup(inputFile, outputFile string, seenVanity map[[32]byte]bool) {
+	reader := newHeaderReader(inputFile)
+	defer reader.close()
+
+	writer := newMissingHeaderFileWriter(outputFile, seenVanity)
+	defer writer.close()
+
+	writer.missingHeaderWriter.writeVanities()
+
+	reader.read(func(header *types.Header) {
+		writer.missingHeaderWriter.write(header)
+	})
+}
+
+func runSHA256(outputFile string) {
+	f, err := os.Open(outputFile)
+	defer f.Close()
+	if err != nil {
+		log.Fatalf("Error opening file: %v", err)
+	}
+
+	h := sha256.New()
+	if _, err = io.Copy(h, f); err != nil {
+		log.Fatalf("Error hashing file: %v", err)
+	}
+
+	fmt.Printf("Deduplicated headers written to %s with sha256 checksum: %x\n", outputFile, h.Sum(nil))
+}
+
+type headerReader struct {
+	file       *os.File
+	reader     *bufio.Reader
+	lastHeader *types.Header
+}
+
+func newHeaderReader(inputFile string) *headerReader {
+	f, err := os.Open(inputFile)
+	if err != nil {
+		log.Fatalf("Error opening input file: %v", err)
+	}
+
+	h := &headerReader{
+		file:   f,
+		reader: bufio.NewReader(f),
+	}
+
+	return h
+}
+
+func (h *headerReader) read(callback func(header *types.Header)) {
+	headerSizeBytes := make([]byte, types.HeaderSizeSerialized)
+
+	for {
+		_, err := io.ReadFull(h.reader, headerSizeBytes)
+		if err != nil {
+			if err == io.EOF {
+				break
+			}
+			log.Fatalf("Error reading headerSizeBytes: %v", err)
+		}
+		headerSize := binary.BigEndian.Uint16(headerSizeBytes)
+
+		headerBytes := make([]byte, headerSize)
+		_, err = io.ReadFull(h.reader, headerBytes)
+		if err != nil {
+			if err == io.EOF {
+				break
+			}
+			log.Fatalf("Error reading headerBytes: %v", err)
+		}
+		header := new(types.Header).FromBytes(headerBytes)
+
+		// sanity check: make sure headers are in order
+		if h.lastHeader != nil && header.Number != h.lastHeader.Number+1 {
+			fmt.Println("lastHeader:", h.lastHeader.String())
+			log.Fatalf("Missing block: %d, got %d instead", h.lastHeader.Number+1, header.Number)
+		}
+		h.lastHeader = header
+
+		callback(header)
+	}
+}
+
+func (h *headerReader) close() {
+	h.file.Close()
+}
+
+type csvHeaderReader struct {
+	file   *os.File
+	reader *bufio.Reader
+}
+
+func newCSVHeaderReader(verifyFile string) *csvHeaderReader {
+	f, err := os.Open(verifyFile)
+	if err != nil {
+		log.Fatalf("Error opening verify file: %v", err)
+	}
+
+	h := &csvHeaderReader{
+		file:   f,
+		reader: bufio.NewReader(f),
+	}
+
+	return h
+}
+
+func (h *csvHeaderReader) readNext() *types.Header {
+	line, err := h.reader.ReadString('\n')
+	if err != nil {
+		if err == io.EOF {
+			return nil
+		}
+		log.Fatalf("Error reading line: %v", err)
+	}
+
+	s := strings.Split(line, ",")
+	extraString := strings.Split(s[2], "\n")
+
+	num, err := strconv.ParseUint(s[0], 10, 64)
+	if err != nil {
+		log.Fatalf("Error parsing block number: %v", err)
+	}
+	difficulty, err := strconv.ParseUint(s[1], 10, 64)
+	if err != nil {
+		log.Fatalf("Error parsing difficulty: %v", err)
+	}
+	extra := common.FromHex(extraString[0])
+
+	header := types.NewHeader(num, difficulty, extra)
+	return header
+}
+
+func (h *csvHeaderReader) close() {
+	h.file.Close()
+}
+
+func verifyInputFile(verifyFile, inputFile string) {
+	csvReader := newCSVHeaderReader(verifyFile)
+	defer csvReader.close()
+
+	binaryReader := newHeaderReader(inputFile)
+	defer binaryReader.close()
+
+	binaryReader.read(func(header *types.Header) {
+		csvHeader := csvReader.readNext()
+
+		if !csvHeader.Equal(header) {
+			log.Fatalf("Header mismatch: %v != %v", csvHeader, header)
+		}
+	})
+
+	log.Printf("All headers match in %s and %s\n", verifyFile, inputFile)
+}
+
+func verifyOutputFile(verifyFile, outputFile string) {
+	csvReader := newCSVHeaderReader(verifyFile)
+	defer csvReader.close()
+
+	dedupReader, err := NewReader(outputFile)
+	if err != nil {
+		log.Fatalf("Error opening dedup file: %v", err)
+	}
+	defer dedupReader.Close()
+
+	for {
+		header := csvReader.readNext()
+		if header == nil {
+			if _, _, err = dedupReader.ReadNext(); err == nil {
+				log.Fatalf("Expected EOF, got more headers")
+			}
+			break
+		}
+
+		difficulty, extraData, err := dedupReader.Read(header.Number)
+		if err != nil {
+			log.Fatalf("Error reading header: %v", err)
+		}
+
+		if header.Difficulty != difficulty {
+			log.Fatalf("Difficulty mismatch: headerNum %d: %d != %d", header.Number, header.Difficulty, difficulty)
+		}
+		if !bytes.Equal(header.ExtraData, extraData) {
+			log.Fatalf("ExtraData mismatch: headerNum %d: %x != %x", header.Number, header.ExtraData, extraData)
+		}
+	}
+}
diff --git a/rollup/missing_header_fields/export-headers-toolkit/cmd/fetch.go b/rollup/missing_header_fields/export-headers-toolkit/cmd/fetch.go
new file mode 100644
index 000000000000..b9799d12ba29
--- /dev/null
+++ b/rollup/missing_header_fields/export-headers-toolkit/cmd/fetch.go
@@ -0,0 +1,247 @@
+package cmd
+
+import (
+	"bufio"
+	"container/heap"
+	"context"
+	"fmt"
+	"log"
+	"math/big"
+	"os"
+	"sync"
+	"time"
+
+	"github.com/spf13/cobra"
+
+	"github.com/scroll-tech/go-ethereum/ethclient"
+
+	"github.com/scroll-tech/go-ethereum/export-headers-toolkit/types"
+)
+
+var fetchCmd = &cobra.Command{
+	Use:   "fetch",
+	Short: "Fetch missing block header fields from a running Scroll L2 node via RPC and store in a file",
+	Long: `Fetch allows to retrieve the missing block header fields from a running Scroll L2 node via RPC.
+It produces a binary file and optionally a human readable csv file with the missing fields.`,
+	Run: func(cmd *cobra.Command, args []string) {
+		rpc, err := cmd.Flags().GetString("rpc")
+		if err != nil {
+			log.Fatalf("Error reading rpc flag: %v", err)
+		}
+		client, err := ethclient.Dial(rpc)
+		if err != nil {
+			log.Fatalf("Error connecting to RPC: %v", err)
+		}
+		startBlockNum, err := cmd.Flags().GetUint64("start")
+		if err != nil {
+			log.Fatalf("Error reading start flag: %v", err)
+		}
+		endBlockNum, err := cmd.Flags().GetUint64("end")
+		if err != nil {
+			log.Fatalf("Error reading end flag: %v", err)
+		}
+		batchSize, err := cmd.Flags().GetUint64("batch")
+		if err != nil {
+			log.Fatalf("Error reading batch flag: %v", err)
+		}
+		maxParallelGoroutines, err := cmd.Flags().GetInt("parallelism")
+		if err != nil {
+			log.Fatalf("Error reading parallelism flag: %v", err)
+		}
+		outputFile, err := cmd.Flags().GetString("output")
+		if err != nil {
+			log.Fatalf("Error reading output flag: %v", err)
+		}
+		humanReadableOutputFile, err := cmd.Flags().GetString("humanOutput")
+		if err != nil {
+			log.Fatalf("Error reading humanReadable flag: %v", err)
+		}
+
+		runFetch(client, startBlockNum, endBlockNum, batchSize, maxParallelGoroutines, outputFile, humanReadableOutputFile)
+	},
+}
+
+func init() {
+	rootCmd.AddCommand(fetchCmd)
+
+	fetchCmd.Flags().String("rpc", "http://localhost:8545", "RPC URL")
+	fetchCmd.Flags().Uint64("start", 0, "start block number")
+	fetchCmd.Flags().Uint64("end", 1000, "end block number")
+	fetchCmd.Flags().Uint64("batch", 100, "batch size")
+	fetchCmd.Flags().Int("parallelism", 10, "max parallel goroutines each working on batch size blocks")
+	fetchCmd.Flags().String("output", "headers.bin", "output file")
+	fetchCmd.Flags().String("humanOutput", "", "additionally produce human readable csv file")
+}
+
+func headerByNumberWithRetry(client *ethclient.Client, blockNum uint64, maxRetries int) (*types.Header, error) {
+	var innerErr error
+	for i := 0; i < maxRetries; i++ {
+		header, err := client.HeaderByNumber(context.Background(), big.NewInt(int64(blockNum)))
+		if err == nil {
+			return &types.Header{
+				Number:     header.Number.Uint64(),
+				Difficulty: header.Difficulty.Uint64(),
+				ExtraData:  header.Extra,
+			}, nil
+		}
+
+		innerErr = err // save the last error to return it if all retries fail
+
+		// Wait before retrying
+		time.Sleep(time.Duration(i*200) * time.Millisecond)
+		log.Printf("Retrying header fetch for block %d, retry %d, error %v", blockNum, i+1, err)
+	}
+
+	return nil, fmt.Errorf("error fetching header for block %d: %v", blockNum, innerErr)
+}
+
+func fetchHeaders(client *ethclient.Client, start, end uint64, headersChan chan<- *types.Header) {
+	for i := start; i <= end; i++ {
+		header, err := headerByNumberWithRetry(client, i, 15)
+		if err != nil {
+			log.Fatalf("Error fetching header %d: %v", i, err)
+		}
+
+		headersChan <- header
+	}
+}
+
+func writeHeadersToFile(outputFile string, humanReadableOutputFile string, startBlockNum uint64, headersChan <-chan *types.Header) {
+	writer := newFilesWriter(outputFile, humanReadableOutputFile)
+	defer writer.close()
+
+	headerHeap := &types.HeaderHeap{}
+	heap.Init(headerHeap)
+
+	nextHeaderNum := startBlockNum
+
+	// receive all headers and write them in order by using a sorted heap
+	for header := range headersChan {
+		heap.Push(headerHeap, header)
+
+		// write all headers that are in order
+		for headerHeap.Len() > 0 && (*headerHeap)[0].Number == nextHeaderNum {
+			nextHeaderNum++
+			sortedHeader := heap.Pop(headerHeap).(*types.Header)
+			writer.write(sortedHeader)
+		}
+	}
+
+	fmt.Println("Finished writing headers to file, last block number:", nextHeaderNum-1)
+}
+
+func runFetch(client *ethclient.Client, startBlockNum uint64, endBlockNum uint64, batchSize uint64, maxGoroutines int, outputFile string, humanReadableOutputFile string) {
+	headersChan := make(chan *types.Header, maxGoroutines*int(batchSize))
+	tasks := make(chan task, maxGoroutines)
+
+	var wgConsumer sync.WaitGroup
+	// start consumer goroutine to sort and write headers to file
+	go func() {
+		wgConsumer.Add(1)
+		writeHeadersToFile(outputFile, humanReadableOutputFile, startBlockNum, headersChan)
+		wgConsumer.Done()
+	}()
+
+	var wgProducers sync.WaitGroup
+	// start producer goroutines to fetch headers
+	for i := 0; i < maxGoroutines; i++ {
+		wgProducers.Add(1)
+		go func() {
+			for {
+				t, ok := <-tasks
+				if !ok {
+					break
+				}
+				fetchHeaders(client, t.start, t.end, headersChan)
+			}
+			wgProducers.Done()
+		}()
+	}
+
+	// create tasks/work packages for producer goroutines
+	for start := startBlockNum; start <= endBlockNum; start += batchSize {
+		end := start + batchSize - 1
+		if end > endBlockNum {
+			end = endBlockNum
+		}
+		fmt.Println("Fetching headers for blocks", start, "to", end)
+
+		tasks <- task{start, end}
+	}
+
+	close(tasks)
+	wgProducers.Wait()
+	close(headersChan)
+	wgConsumer.Wait()
+}
+
+type task struct {
+	start uint64
+	end   uint64
+}
+
+// filesWriter is a helper struct to write headers to binary and human-readable csv files at the same time.
+type filesWriter struct {
+	binaryFile   *os.File
+	binaryWriter *bufio.Writer
+
+	humanReadable bool
+	csvFile       *os.File
+	csvWriter     *bufio.Writer
+}
+
+func newFilesWriter(outputFile string, humanReadableOutputFile string) *filesWriter {
+	binaryFile, err := os.Create(outputFile)
+	if err != nil {
+		log.Fatalf("Error creating binary file: %v", err)
+	}
+
+	f := &filesWriter{
+		binaryFile:    binaryFile,
+		binaryWriter:  bufio.NewWriter(binaryFile),
+		humanReadable: humanReadableOutputFile != "",
+	}
+
+	if humanReadableOutputFile != "" {
+		csvFile, err := os.Create(humanReadableOutputFile)
+		if err != nil {
+			log.Fatalf("Error creating human readable file: %v", err)
+		}
+		f.csvFile = csvFile
+		f.csvWriter = bufio.NewWriter(csvFile)
+	}
+
+	return f
+}
+
+func (f *filesWriter) close() {
+	if err := f.binaryWriter.Flush(); err != nil {
+		log.Fatalf("Error flushing binary buffer: %v", err)
+	}
+	if f.humanReadable {
+		if err := f.csvWriter.Flush(); err != nil {
+			log.Fatalf("Error flushing csv buffer: %v", err)
+		}
+	}
+
+	f.binaryFile.Close()
+	if f.humanReadable {
+		f.csvFile.Close()
+	}
+}
+func (f *filesWriter) write(header *types.Header) {
+	bytes, err := header.Bytes()
+	if err != nil {
+		log.Fatalf("Error converting header to bytes: %v", err)
+	}
+
+	if _, err = f.binaryWriter.Write(bytes); err != nil {
+		log.Fatalf("Error writing to binary file: %v", err)
+	}
+
+	if f.humanReadable {
+		if _, err = f.csvWriter.WriteString(header.String()); err != nil {
+			log.Fatalf("Error writing to human readable file: %v", err)
+		}
+	}
+}
diff --git a/rollup/missing_header_fields/export-headers-toolkit/cmd/missing_header_reader.go b/rollup/missing_header_fields/export-headers-toolkit/cmd/missing_header_reader.go
new file mode 100644
index 000000000000..773b4e06451c
--- /dev/null
+++ b/rollup/missing_header_fields/export-headers-toolkit/cmd/missing_header_reader.go
@@ -0,0 +1,120 @@
+package cmd
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"os"
+)
+
+// TODO: instead of duplicating this file, missing_header_fields.Reader should be used in toolkit
+
+type missingHeader struct {
+	headerNum  uint64
+	difficulty uint64
+	extraData  []byte
+}
+
+type Reader struct {
+	file           *os.File
+	reader         *bufio.Reader
+	sortedVanities map[int][32]byte
+	lastReadHeader *missingHeader
+}
+
+func NewReader(filePath string) (*Reader, error) {
+	f, err := os.Open(filePath)
+	if err != nil {
+		return nil, fmt.Errorf("failed to open file: %v", err)
+	}
+
+	r := &Reader{
+		file:   f,
+		reader: bufio.NewReader(f),
+	}
+
+	// read the count of unique vanities
+	vanityCount, err := r.reader.ReadByte()
+	if err != nil {
+		return nil, err
+	}
+
+	// read the unique vanities
+	r.sortedVanities = make(map[int][32]byte)
+	for i := uint8(0); i < vanityCount; i++ {
+		var vanity [32]byte
+		if _, err = r.reader.Read(vanity[:]); err != nil {
+			return nil, err
+		}
+		r.sortedVanities[int(i)] = vanity
+	}
+
+	return r, nil
+}
+
+func (r *Reader) Read(headerNum uint64) (difficulty uint64, extraData []byte, err error) {
+	if r.lastReadHeader == nil {
+		if _, _, err = r.ReadNext(); err != nil {
+			return 0, nil, err
+		}
+	}
+
+	if headerNum > r.lastReadHeader.headerNum {
+		// skip the headers until the requested header number
+		for i := r.lastReadHeader.headerNum; i < headerNum; i++ {
+			if _, _, err = r.ReadNext(); err != nil {
+				return 0, nil, err
+			}
+		}
+	}
+
+	if headerNum == r.lastReadHeader.headerNum {
+		return r.lastReadHeader.difficulty, r.lastReadHeader.extraData, nil
+	}
+
+	// headerNum < r.lastReadHeader.headerNum is not supported
+	return 0, nil, fmt.Errorf("requested header %d below last read header number %d", headerNum, r.lastReadHeader.headerNum)
+}
+
+func (r *Reader) ReadNext() (difficulty uint64, extraData []byte, err error) {
+	// read the bitmask
+	bitmaskByte, err := r.reader.ReadByte()
+	if err != nil {
+		return 0, nil, fmt.Errorf("failed to read bitmask: %v", err)
+	}
+
+	bits := newBitMaskFromByte(bitmaskByte)
+
+	seal := make([]byte, bits.sealLen())
+
+	if _, err = io.ReadFull(r.reader, seal); err != nil {
+		return 0, nil, fmt.Errorf("failed to read seal: %v", err)
+	}
+
+	// construct the extraData field
+	vanity := r.sortedVanities[bits.vanityIndex()]
+	var b bytes.Buffer
+	b.Write(vanity[:])
+	b.Write(seal)
+
+	// we don't have the header number, so we'll just increment the last read header number
+	// we assume that the headers are written in order, starting from 0
+	if r.lastReadHeader == nil {
+		r.lastReadHeader = &missingHeader{
+			headerNum:  0,
+			difficulty: uint64(bits.difficulty()),
+			extraData:  b.Bytes(),
+		}
+	} else {
+		r.lastReadHeader.headerNum++
+		r.lastReadHeader.difficulty = uint64(bits.difficulty())
+		r.lastReadHeader.extraData = b.Bytes()
+	}
+
+	return difficulty, b.Bytes(), nil
+}
+
+func (r *Reader) Close() error {
+	return r.file.Close()
+}
diff --git a/rollup/missing_header_fields/export-headers-toolkit/cmd/missing_header_writer.go b/rollup/missing_header_fields/export-headers-toolkit/cmd/missing_header_writer.go
new file mode 100644
index 000000000000..5b3eed1c2cbd
--- /dev/null
+++ b/rollup/missing_header_fields/export-headers-toolkit/cmd/missing_header_writer.go
@@ -0,0 +1,169 @@
+package cmd
+
+import (
+	"bufio"
+	"bytes"
+	"io"
+	"log"
+	"os"
+	"sort"
+
+	"github.com/scroll-tech/go-ethereum/export-headers-toolkit/types"
+)
+
+// maxVanityCount is the maximum number of unique vanities that can be represented with 6 bits in the bitmask
+const maxVanityCount = 1 << 6
+
+type missingHeaderFileWriter struct {
+	file   *os.File
+	writer *bufio.Writer
+
+	missingHeaderWriter *missingHeaderWriter
+}
+
+func newMissingHeaderFileWriter(filename string, seenVanity map[[32]byte]bool) *missingHeaderFileWriter {
+	if len(seenVanity) > maxVanityCount {
+		log.Fatalf("Number of unique vanities exceeds maximum: %d > %d", len(seenVanity), maxVanityCount)
+	}
+
+	file, err := os.Create(filename)
+	if err != nil {
+		log.Fatalf("Error creating file: %v", err)
+	}
+
+	writer := bufio.NewWriter(file)
+	return &missingHeaderFileWriter{
+		file:                file,
+		writer:              writer,
+		missingHeaderWriter: newMissingHeaderWriter(writer, seenVanity),
+	}
+}
+
+func (m *missingHeaderFileWriter) close() {
+	if err := m.writer.Flush(); err != nil {
+		log.Fatalf("Error flushing writer: %v", err)
+	}
+	if err := m.file.Close(); err != nil {
+		log.Fatalf("Error closing file: %v", err)
+	}
+}
+
+type missingHeaderWriter struct {
+	writer io.Writer
+
+	sortedVanities    [][32]byte
+	sortedVanitiesMap map[[32]byte]int
+	seenDifficulty    map[uint64]int
+	seenSealLen       map[int]int
+}
+
+func newMissingHeaderWriter(writer io.Writer, seenVanity map[[32]byte]bool) *missingHeaderWriter {
+	// sort the vanities and assign an index to each so that we can write the index of the vanity in the header
+	sortedVanities := make([][32]byte, 0, len(seenVanity))
+	for vanity := range seenVanity {
+		sortedVanities = append(sortedVanities, vanity)
+	}
+	sort.Slice(sortedVanities, func(i, j int) bool {
+		return bytes.Compare(sortedVanities[i][:], sortedVanities[j][:]) < 0
+	})
+	sortedVanitiesMap := make(map[[32]byte]int)
+	for i, vanity := range sortedVanities {
+		sortedVanitiesMap[vanity] = i
+	}
+
+	return &missingHeaderWriter{
+		writer:            writer,
+		sortedVanities:    sortedVanities,
+		sortedVanitiesMap: sortedVanitiesMap,
+	}
+}
+
+func (m *missingHeaderWriter) writeVanities() {
+	// write the count of unique vanities
+	if _, err := m.writer.Write([]byte{uint8(len(m.sortedVanitiesMap))}); err != nil {
+		log.Fatalf("Error writing unique vanity count: %v", err)
+	}
+
+	// write the unique vanities
+	for _, vanity := range m.sortedVanities {
+		if _, err := m.writer.Write(vanity[:]); err != nil {
+			log.Fatalf("Error writing vanity: %v", err)
+		}
+	}
+}
+
+func (m *missingHeaderWriter) write(header *types.Header) {
+	// 1. prepare the bitmask
+	bits := newBitMask(m.sortedVanitiesMap[header.Vanity()], int(header.Difficulty), header.SealLen())
+
+	// 2. write the header: bitmask and seal
+	if _, err := m.writer.Write(bits.Bytes()); err != nil {
+		log.Fatalf("Error writing bitmask: %v", err)
+	}
+
+	if _, err := m.writer.Write(header.Seal()); err != nil {
+		log.Fatalf("Error writing seal: %v", err)
+	}
+}
+
+// bitMask is a bitmask that encodes the following information:
+//
+//	bit 0-5: index of the vanity in the sorted vanities list
+//	bit 6: 0 if difficulty is 2, 1 if difficulty is 1
+//	bit 7: 0 if seal length is 65, 1 if seal length is 85
+type bitMask struct {
+	b uint8
+}
+
+func newBitMaskFromByte(b uint8) bitMask {
+	return bitMask{b}
+}
+
+func newBitMask(vanityIndex int, difficulty int, sealLen int) bitMask {
+	b := uint8(0)
+
+	if vanityIndex >= maxVanityCount {
+		log.Fatalf("Vanity index exceeds maximum: %d >= %d", vanityIndex, maxVanityCount)
+	}
+	b |= uint8(vanityIndex) & 0b00111111
+
+	if difficulty == 1 {
+		b |= 1 << 6
+	} else if difficulty != 2 {
+		log.Fatalf("Invalid difficulty: %d", difficulty)
+	}
+
+	if sealLen == 85 {
+		b |= 1 << 7
+	} else if sealLen != 65 {
+		log.Fatalf("Invalid seal length: %d", sealLen)
+	}
+
+	return bitMask{b}
+}
+
+func (b bitMask) vanityIndex() int {
+	return int(b.b & 0b00111111)
+}
+
+func (b bitMask) difficulty() int {
+	val := (b.b >> 6) & 0x01
+	if val == 0 {
+		return 2
+	} else {
+		return 1
+	}
+}
+
+func (b bitMask) sealLen() int {
+	val := (b.b >> 7) & 0x01
+	if val == 0 {
+		return 65
+	} else {
+		return 85
+	}
+}
+
+func (b bitMask) Bytes() []byte {
+	return []byte{b.b}
+}
diff --git a/rollup/missing_header_fields/export-headers-toolkit/cmd/missing_header_writer_test.go b/rollup/missing_header_fields/export-headers-toolkit/cmd/missing_header_writer_test.go
new file mode 100644
index 000000000000..25c5d039dd93
--- /dev/null
+++ b/rollup/missing_header_fields/export-headers-toolkit/cmd/missing_header_writer_test.go
@@ -0,0 +1,101 @@
+package cmd
+
+import (
+	"bytes"
+	"crypto/rand"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+
+	"github.com/scroll-tech/go-ethereum/export-headers-toolkit/types"
+)
+
+func TestMissingHeaderWriter(t *testing.T) {
+	vanity1 := [32]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}
+	vanity2 := [32]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}
+	vanity8 := [32]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08}
+
+	var expectedBytes []byte
+	expectedBytes = append(expectedBytes, 0x03)
+	expectedBytes = append(expectedBytes, vanity1[:]...)
+	expectedBytes = append(expectedBytes, vanity2[:]...)
+	expectedBytes = append(expectedBytes, vanity8[:]...)
+
+	seenVanity := map[[32]byte]bool{
+		vanity8: true,
+		vanity1: true,
+		vanity2: true,
+	}
+	var buf []byte
+	bytesBuffer := bytes.NewBuffer(buf)
+	mhw := newMissingHeaderWriter(bytesBuffer, seenVanity)
+
+	mhw.writeVanities()
+	assert.Equal(t, expectedBytes, bytesBuffer.Bytes())
+
+	// Header0
+	{
+		seal := randomSeal(65)
+		header := types.NewHeader(0, 2, append(vanity1[:], seal...))
+		mhw.write(header)
+
+		// bit 0-5:0x0 index0, bit 6=0: difficulty 2, bit 7=0: seal length 65
+		expectedBytes = append(expectedBytes, 0b00000000)
+		expectedBytes = append(expectedBytes, seal...)
+		assert.Equal(t, expectedBytes, bytesBuffer.Bytes())
+	}
+
+	// Header1
+	{
+		seal := randomSeal(65)
+		header := types.NewHeader(1, 1, append(vanity2[:], seal...))
+		mhw.write(header)
+
+		// bit 0-5:0x1 index1, bit 6=1: difficulty 1, bit 7=0: seal length 65
+		expectedBytes = append(expectedBytes, 0b01000001)
+		expectedBytes = append(expectedBytes, seal...)
+		assert.Equal(t, expectedBytes, bytesBuffer.Bytes())
+	}
+
+	// Header2
+	{
+		seal := randomSeal(85)
+		header := types.NewHeader(2, 2, append(vanity2[:], seal...))
+		mhw.write(header)
+
+		// bit 0-5:0x1 index1, bit 6=0: difficulty 2, bit 7=1: seal length 85
+		expectedBytes = append(expectedBytes, 0b10000001)
+		expectedBytes = append(expectedBytes, seal...)
+		assert.Equal(t, expectedBytes, bytesBuffer.Bytes())
+	}
+
+	// Header3
+	{
+		seal := randomSeal(85)
+		header := types.NewHeader(3, 1, append(vanity8[:], seal...))
+		mhw.write(header)
+
+		// bit 0-5:0x2 index2, bit 6=1: difficulty 1, bit 7=1: seal length 85
+		expectedBytes = append(expectedBytes, 0b11000010)
+		expectedBytes = append(expectedBytes, seal...)
+		assert.Equal(t, expectedBytes, bytesBuffer.Bytes())
+	}
+
+	// Header4
+	{
+		seal := randomSeal(65)
+		header := types.NewHeader(4, 2, append(vanity1[:], seal...))
+		mhw.write(header)
+
+		// bit 0-5:0x0 index0, bit 6=0: difficulty 2, bit 7=0: seal length 65
+		expectedBytes = append(expectedBytes, 0b00000000)
+		expectedBytes = append(expectedBytes, seal...)
+		assert.Equal(t, expectedBytes, bytesBuffer.Bytes())
+	}
+}
+
+func randomSeal(length int) []byte {
+	buf := make([]byte, length)
+	_, _ = rand.Read(buf)
+	return buf
+}
diff --git a/rollup/missing_header_fields/export-headers-toolkit/cmd/root.go b/rollup/missing_header_fields/export-headers-toolkit/cmd/root.go
new file mode 100644
index 000000000000..9b485e96dd62
--- /dev/null
+++ b/rollup/missing_header_fields/export-headers-toolkit/cmd/root.go
@@ -0,0 +1,32 @@
+package cmd
+
+import (
+	"os"
+
+	"github.com/spf13/cobra"
+)
+
+// rootCmd represents the base command when called without any subcommands
+var rootCmd = &cobra.Command{
+	Use:   "export-headers-toolkit",
+	Short: "A toolkit for exporting and transforming missing block header fields of Scroll",
+	Long: `A toolkit for exporting and transforming missing block header fields of Scroll.
+
+The fields difficulty and extraData are missing from header data stored on L1 before {{upgrade_name}}. 
+This toolkit provides commands to export the missing fields, deduplicate the data and create a 
+file with the missing fields that can be used to reconstruct the correct block hashes when only reading 
+data from L1.`,
+}
+
+// Execute adds all child commands to the root command and sets flags appropriately.
+// This is called by main.main(). It only needs to happen once to the rootCmd.
+func Execute() {
+	err := rootCmd.Execute()
+	if err != nil {
+		os.Exit(1)
+	}
+}
+
+func init() {
+	rootCmd.CompletionOptions.DisableDefaultCmd = true
+}
diff --git a/rollup/missing_header_fields/export-headers-toolkit/go.mod b/rollup/missing_header_fields/export-headers-toolkit/go.mod
new file mode 100644
index 000000000000..97806cc8252f
--- /dev/null
+++ b/rollup/missing_header_fields/export-headers-toolkit/go.mod
@@ -0,0 +1,71 @@
+module github.com/scroll-tech/go-ethereum/export-headers-toolkit
+
+go 1.22
+
+require (
+	github.com/scroll-tech/go-ethereum v1.10.14-0.20240624092647-7da0bd5480e9
+	github.com/spf13/cobra v1.8.1
+	github.com/stretchr/testify v1.9.0
+)
+
+require (
+	github.com/VictoriaMetrics/fastcache v1.12.1 // indirect
+	github.com/bits-and-blooms/bitset v1.13.0 // indirect
+	github.com/btcsuite/btcd v0.20.1-beta // indirect
+	github.com/cespare/xxhash/v2 v2.2.0 // indirect
+	github.com/consensys/bavard v0.1.13 // indirect
+	github.com/consensys/gnark-crypto v0.12.1 // indirect
+	github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea // indirect
+	github.com/edsrzf/mmap-go v1.0.0 // indirect
+	github.com/ethereum/c-kzg-4844/bindings/go v0.0.0-20230126171313-363c7d7593b4 // indirect
+	github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
+	github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect
+	github.com/go-ole/go-ole v1.3.0 // indirect
+	github.com/go-stack/stack v1.8.1 // indirect
+	github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
+	github.com/google/uuid v1.1.5 // indirect
+	github.com/gorilla/websocket v1.4.2 // indirect
+	github.com/hashicorp/go-bexpr v0.1.10 // indirect
+	github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
+	github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
+	github.com/holiman/uint256 v1.3.0 // indirect
+	github.com/huin/goupnp v1.0.2 // indirect
+	github.com/iden3/go-iden3-crypto v0.0.16 // indirect
+	github.com/inconshreveable/mousetrap v1.1.0 // indirect
+	github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 // indirect
+	github.com/mattn/go-colorable v0.1.8 // indirect
+	github.com/mattn/go-isatty v0.0.12 // indirect
+	github.com/mattn/go-runewidth v0.0.15 // indirect
+	github.com/mitchellh/mapstructure v1.4.1 // indirect
+	github.com/mitchellh/pointerstructure v1.2.0 // indirect
+	github.com/mmcloughlin/addchain v0.4.0 // indirect
+	github.com/olekukonko/tablewriter v0.0.5 // indirect
+	github.com/pkg/errors v0.9.1 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	github.com/prometheus/tsdb v0.7.1 // indirect
+	github.com/rivo/uniseg v0.4.4 // indirect
+	github.com/rjeczalik/notify v0.9.1 // indirect
+	github.com/rs/cors v1.7.0 // indirect
+	github.com/scroll-tech/da-codec v0.0.0-20240605080813-32bfc9fccde7 // indirect
+	github.com/scroll-tech/zktrie v0.8.4 // indirect
+	github.com/shirou/gopsutil v3.21.11+incompatible // indirect
+	github.com/spf13/pflag v1.0.5 // indirect
+	github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 // indirect
+	github.com/supranational/blst v0.3.12 // indirect
+	github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
+	github.com/tklauser/go-sysconf v0.3.14 // indirect
+	github.com/tklauser/numcpus v0.8.0 // indirect
+	github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef // indirect
+	github.com/yusufpapurcu/wmi v1.2.4 // indirect
+	golang.org/x/crypto v0.25.0 // indirect
+	golang.org/x/sync v0.7.0 // indirect
+	golang.org/x/sys v0.22.0 // indirect
+	golang.org/x/text v0.16.0 // indirect
+	golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
+	gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
+	gopkg.in/urfave/cli.v1 v1.20.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
+	rsc.io/tmplfunc v0.0.3 // indirect
+)
diff --git a/rollup/missing_header_fields/export-headers-toolkit/go.sum b/rollup/missing_header_fields/export-headers-toolkit/go.sum
new file mode 100644
index 000000000000..c0fc07b58407
--- /dev/null
+++ b/rollup/missing_header_fields/export-headers-toolkit/go.sum
@@ -0,0 +1,262 @@
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
+github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40=
+github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o=
+github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
+github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE=
+github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
+github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
+github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
+github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
+github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
+github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
+github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
+github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
+github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
+github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
+github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
+github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
+github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ=
+github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI=
+github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M=
+github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY=
+github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI=
+github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc=
+github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea h1:j4317fAZh7X6GqbFowYdYdI0L9bwxL07jyPZIdepyZ0=
+github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
+github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
+github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
+github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
+github.com/ethereum/c-kzg-4844/bindings/go v0.0.0-20230126171313-363c7d7593b4 h1:B2mpK+MNqgPqk2/KNi1LbqwtZDy5F7iy0mynQiBr8VA=
+github.com/ethereum/c-kzg-4844/bindings/go v0.0.0-20230126171313-363c7d7593b4/go.mod h1:y4GA2JbAUama1S4QwYjC2hefgGLU8Ul0GMtL/ADMF1c=
+github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c=
+github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
+github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
+github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
+github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
+github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-logfmt/logfmt v0.3.0 h1:8HUsc87TaSWLKwrnumgC8/YconD2fJQsRJAsWaPg2ic=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
+github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
+github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
+github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk=
+github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
+github.com/google/uuid v1.1.5 h1:kxhtnfFVi+rYdOALN0B3k9UT86zVJKfBimRaciULW4I=
+github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
+github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE=
+github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0=
+github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs=
+github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
+github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao=
+github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA=
+github.com/holiman/uint256 v1.3.0 h1:4wdcm/tnd0xXdu7iS3ruNvxkWwrb4aeBQv19ayYn8F4=
+github.com/holiman/uint256 v1.3.0/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/huin/goupnp v1.0.2 h1:RfGLP+h3mvisuWEyybxNq5Eft3NWhHLPeUN72kpKZoI=
+github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM=
+github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
+github.com/iden3/go-iden3-crypto v0.0.16 h1:zN867xiz6HgErXVIV/6WyteGcOukE9gybYTorBMEdsk=
+github.com/iden3/go-iden3-crypto v0.0.16/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E=
+github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 h1:6OvNmYgJyexcZ3pYbTI9jWx5tHo1Dee/tWbLMfPe2TA=
+github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
+github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
+github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
+github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
+github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
+github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
+github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
+github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
+github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
+github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A=
+github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4=
+github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY=
+github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU=
+github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU=
+github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
+github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
+github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
+github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
+github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
+github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
+github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
+github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
+github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA=
+github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
+github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
+github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE=
+github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
+github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
+github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
+github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
+github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/scroll-tech/da-codec v0.0.0-20240605080813-32bfc9fccde7 h1:CDrPMqifvAVyYqu0x1J5qickVV0b51tApPnOwDYLESI=
+github.com/scroll-tech/da-codec v0.0.0-20240605080813-32bfc9fccde7/go.mod h1:1wWYii0OPwd5kw+xrz0PFgS420xNadrNF1x/ELJT+TM=
+github.com/scroll-tech/go-ethereum v1.10.14-0.20240624092647-7da0bd5480e9 h1:Jq4TTYcHVAIVPUHNYbOzNxEsWf+9Q3b30YQaMyl0TDI=
+github.com/scroll-tech/go-ethereum v1.10.14-0.20240624092647-7da0bd5480e9/go.mod h1:byf/mZ8jLYUCnUePTicjJWn+RvKdxDn7buS6glTnMwQ=
+github.com/scroll-tech/zktrie v0.8.4 h1:UagmnZ4Z3ITCk+aUq9NQZJNAwnWl4gSxsLb2Nl7IgRE=
+github.com/scroll-tech/zktrie v0.8.4/go.mod h1:XvNo7vAk8yxNyTjBDj5WIiFzYW4bx/gJ78+NK6Zn6Uk=
+github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
+github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
+github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
+github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 h1:Gb2Tyox57NRNuZ2d3rmvB3pcmbu7O1RS3m8WRx7ilrg=
+github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/supranational/blst v0.3.12 h1:Vfas2U2CFHhniv2QkUm2OVa1+pGTdqtpqm9NnhUUbZ8=
+github.com/supranational/blst v0.3.12/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
+github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
+github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
+github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU=
+github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY=
+github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY=
+github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE=
+github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZW24CsNJDfeh9Ex6Pm0Rcpc7qrgKBiL44vF4=
+github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
+github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
+github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
+golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
+golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
+golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
+golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
+golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
+golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
+golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
+golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
+gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0=
+gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU=
+rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA=
diff --git a/rollup/missing_header_fields/export-headers-toolkit/main.go b/rollup/missing_header_fields/export-headers-toolkit/main.go
new file mode 100644
index 000000000000..1d8e22abe8cb
--- /dev/null
+++ b/rollup/missing_header_fields/export-headers-toolkit/main.go
@@ -0,0 +1,9 @@
+package main
+
+import (
+	"github.com/scroll-tech/go-ethereum/export-headers-toolkit/cmd"
+)
+
+func main() {
+	cmd.Execute()
+}
diff --git a/rollup/missing_header_fields/export-headers-toolkit/types/header.go b/rollup/missing_header_fields/export-headers-toolkit/types/header.go
new file mode 100644
index 000000000000..ffd76c8a8bb5
--- /dev/null
+++ b/rollup/missing_header_fields/export-headers-toolkit/types/header.go
@@ -0,0 +1,94 @@
+package types
+
+import (
+	"encoding/binary"
+	"fmt"
+
+	"github.com/scroll-tech/go-ethereum/common"
+)
+
+const HeaderSizeSerialized = 2
+const VanitySize = 32
+
+type Header struct {
+	Number     uint64
+	Difficulty uint64
+	ExtraData  []byte
+}
+
+func NewHeader(number, difficulty uint64, extraData []byte) *Header {
+	return &Header{
+		Number:     number,
+		Difficulty: difficulty,
+		ExtraData:  extraData,
+	}
+}
+
+func (h *Header) String() string {
+	return fmt.Sprintf("%d,%d,%s\n", h.Number, h.Difficulty, common.Bytes2Hex(h.ExtraData))
+}
+
+func (h *Header) Equal(other *Header) bool {
+	if h.Number != other.Number {
+		return false
+	}
+	if h.Difficulty != other.Difficulty {
+		return false
+	}
+	if len(h.ExtraData) != len(other.ExtraData) {
+		return false
+	}
+	for i, b := range h.ExtraData {
+		if b != other.ExtraData[i] {
+			return false
+		}
+	}
+	return true
+}
+
+// Bytes returns the byte representation of the header including the initial 2 bytes for the size.
+func (h *Header) Bytes() ([]byte, error) {
+	size := 8 + 8 + len(h.ExtraData)
+
+	buf := make([]byte, HeaderSizeSerialized+size)
+	binary.BigEndian.PutUint16(buf[:2], uint16(size))
+	binary.BigEndian.PutUint64(buf[2:10], h.Number)
+	binary.BigEndian.PutUint64(buf[10:18], h.Difficulty)
+	copy(buf[18:], h.ExtraData)
+	return buf, nil
+}
+
+func (h *Header) Vanity() [VanitySize]byte {
+	return [VanitySize]byte(h.ExtraData[:VanitySize])
+}
+
+func (h *Header) Seal() []byte {
+	return h.ExtraData[VanitySize:]
+}
+
+func (h *Header) SealLen() int {
+	return len(h.Seal())
+}
+
+// FromBytes reads the header from the byte representation excluding the initial 2 bytes for the size.
+func (h *Header) FromBytes(buf []byte) *Header {
+	h.Number = binary.BigEndian.Uint64(buf[:8])
+	h.Difficulty = binary.BigEndian.Uint64(buf[8:16])
+	h.ExtraData = buf[16:]
+
+	return h
+}
+
+type HeaderHeap []*Header
+
+func (h HeaderHeap) Len() int            { return len(h) }
+func (h HeaderHeap) Less(i, j int) bool  { return h[i].Number < h[j].Number }
+func (h HeaderHeap) Swap(i, j int)       { h[i], h[j] = h[j], h[i] }
+func (h *HeaderHeap) Push(x interface{}) { *h = append(*h, x.(*Header)) }
+func (h *HeaderHeap) Pop() interface{} {
+	old := *h
+	n := len(old)
+	item := old[n-1]
+	*h = old[0 : n-1]
+	return item
+}