solana-program-dumper
Dump a deployed Solana program's executable (.so) and every account it owns, in one command.
Useful when reverse engineering a program you don't have the source for: you get the ELF to disassemble, plus the on-chain state laid out on disk with the account sizes in the filenames, which is usually where you start guessing at the account layouts.
$ soldump --program Config1111111111111111111111111111111111111 --url devnet
Wrote executable to soldump/program.so (157184 bytes)
Found 303 program accounts
Wrote 303 accounts to soldump/<data_len>_<address>.bin
Requirements
The Solana CLI must be installed and on your
PATH. soldump shells out to solana program dump to fetch the executable, so without it
you'll get:
error: could not dump program executable: the `solana` CLI is required but was not found on your PATH.
Install it with:
$ sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)"
Everything else (fetching the program's accounts) goes over plain JSON-RPC and needs no extra tools.
Install
$ cargo install solana-program-dumper
The installed binary is named soldump.
Usage
soldump [OPTIONS] --program <PROGRAM> --url <URL>
Which, using the attached moniker form and the default output directory, is just:
$ soldump -p <PROGRAM> -ud
| Flag | Description |
|---|---|
-p, --program <ADDRESS> |
Program address (base58). |
-u, --url <URL> |
RPC endpoint, or a moniker: mainnet-beta/m, devnet/d, testnet/t, localhost/l. Attached form works too, as in -ud/-um. |
-d, --dir <DIR> |
Output directory, created if missing. Defaults to ./soldump. |
-s, --skip-size <N> |
Skip accounts whose data length is exactly N. Repeatable. |
-o, --only-size <N> |
Fetch only accounts whose data length is exactly N. |
-c, --commitment <LEVEL> |
processed, confirmed (default), or finalized. |
-t, --timeout <SECONDS> |
RPC timeout for the account dump. Default 30. |
Existing files in the output directory are overwritten. Note that files from a previous run are
not removed, so pointing two different programs at one directory leaves you with both programs'
accounts mixed together — use a fresh --dir per program.
Output layout
soldump/
├── program.so # the ELF, ready for a disassembler
├── 0_2JadyCW3....bin # one file per owned account:
├── 643_5h2MQ7h....bin # <data_len>_<address>.bin
└── 1001_HxLLJz....bin
Names lead with the data length so the directory sorts by account layout — with an unknown program, accounts of the same size are almost always the same type, so this is the fastest way to see how many distinct account kinds exist.
Filtering
--only-size is pushed to the RPC node as a getProgramAccounts dataSize filter, so the
matching accounts are the only ones that cross the wire. Reach for it first on large programs.
--skip-size is applied locally, after fetching, because getProgramAccounts filters are
inclusive — there is no "everything except this size" filter. It's for trimming noise (empty
accounts, one dominant account type) out of the output directory.
# Only the 165-byte accounts, filtered server-side
$ soldump -p <PROGRAM> -u m --only-size 165
# Everything except empty accounts
$ soldump -p <PROGRAM> -u m --skip-size 0
getProgramAccounts on public endpoints
Most public RPC endpoints — including api.mainnet-beta.solana.com — rate-limit or outright
refuse getProgramAccounts for programs with many accounts. If the account dump fails while the
.so succeeds, that's usually why. Use --only-size to narrow the query, or point --url at a
dedicated RPC provider.
A large program's state can also simply take longer than the 30-second default to come back, which
surfaces as error sending request. Raise it with --timeout 120. This applies to the account
dump only — the executable is fetched by the solana CLI, which uses its own timeout.
The two halves run independently: if the executable can't be dumped (closed program, RPC
hiccup), the account dump is still attempted, and vice versa. soldump exits non-zero if either
half failed.
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.