Open-source project
ethstorage/es-node avatar
ethstorage/es-node

es-node is the Go implementation of an EthStorage storage provider

Golang implementation of the EthStorage node.

812 stars106 forksGoNOASSERTION

At a glance

What is it?
EthStorage is a modular, decentralized storage Layer 2 offering programmable key-value storage built on data availability, and es-node is its node implementation in Go. The repository covers the storage provider role, builds with CGO and the rapidsnark assembly tag, ships a Docker image exposing three ports, and is licensed under the Business Source License rather than a standard open source licence.
Who is it for?
es-node fits a team that wants to participate in the EthStorage network as a storage provider, or a team that wants to read a working implementation of a data availability backed key-value layer, since the Go code covers the prover, the networking and the storage side in one tree. It is not the right starting point for an application developer, because the README points those readers at the documentation and the network rather than at a client library.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A storage Layer 2, and one node in it

es-node is the Golang implementation of the EthStorage node, and the README is short because the project itself is a thin slice of a larger system.

EthStorage is described as a modular and decentralized storage Layer 2 that offers programmable key-value storage powered by Data Availability. The stated purpose is to enable long-term data availability solutions for rollups and to open possibilities for fully on-chain applications such as games, social networks and AI.

The key-value framing is the important part of that description, because it is what separates this from a blob store. The data availability layer underneath provides the durable, verifiable storage, and the layer two on top exposes it as a key-value interface that contracts can read and write, which is what makes the on-chain application story possible.

The documentation lives in two places. Detailed specifications and testing tutorials are in the docs/ directory of this repository, and the wider project documentation is at docs.ethstorage.io, with the project website at ethstorage.io.

This repository is the node, and the node has more than one role: it stores data, it participates in the network, and it proves things about what it stores. The dependency list shows the shape of that, with go-ethereum and the optimism packages for the chain side, libp2p for peer to peer networking, the KZG libraries for the data availability commitment scheme, and rapidsnark for the proving side.

The role the README points you at: storage provider

The Getting Started section is short and it names a specific job.

If you are interested in earning rewards by storing data, the README says to consider running es-node in the EthStorage network as a storage provider. For prerequisites and detailed instructions, it points at the Storage Providers' guide in the EthStorage documentation rather than duplicating them here.

That division is worth noting, because it tells you what this repository is and is not. The repository is the implementation, and the operational guide lives with the network documentation, which is where the chain to join, the keys to configure and the reward rules would be described.

The node therefore has a job that is partly technical and partly economic. It holds data on behalf of the network, it is expected to be online, and it earns a share of the rewards for doing so. Running one well is an operational commitment, not a one-off install, and the existence of a separate guide for it says as much.

For support and news, the README points at a Discord server for technical questions and at the project's X account for news about EthStorage.

The dependency list describes the cryptography

The go.mod file is unusually informative for a node implementation, because the libraries tell you what the node actually does.

The module path is github.com/ethstorage/go-ethstorage, it requires Go 1.24.0 with a toolchain line pinning go1.24.9. On the chain side there is go-ethereum at 1.16.5, the optimism packages, a consensus client library, and a hardened derivation library. The KZG side comes from the crate-crypto go-kzg-4844 package, protolambda's go-kzg, gnark-crypto and the iden3 cryptography packages.

Proving is where rapidsnark appears, both in the iden3 rapidsnark witness and types packages, which pairs with the Makefile's rapidsnark_asm build tag.

For storage and networking there is the billy library from ethstorage itself, which is the file storage abstraction the node uses, ipfs go-datastore, libp2p with its pubsub implementation, snappy for compression, a memory mapped file helper, mmap-go, and a fallocate helper, go-fallocate, which is how a node reserves disk space ahead of writing rather than discovering it is out of room later.

The interface layer is cobra for the command line and urfave/cli, with gorilla/mux for the HTTP routes, hashicorp's LRU for caching, and status-im's keycard-go, which suggests support for hardware key storage for the node's identity or keys. The test dependency is stretchr/testify.

Two things stand out for an operator. CGO is required, so the build needs a C toolchain, and the node is built against a specific chain client, which is a compatibility surface to keep in mind when the chain upgrades.

Building es-node needs CGO and copies a proving payload

The Makefile shows the build shape, and the first target is the interesting one because it does more than compile.

bash
env GO111MODULE=on CGO_ENABLED=1 GOOS=$(TARGETOS) GOARCH=$(TARGETARCH) go build -v $(LDFLAGS) -o build/bin/es-node -tags rapidsnark_asm ./cmd/es-node/

Three things are fixed there. CGO_ENABLED=1, so the node links against C libraries, the rapidsnark_asm tag selects the assembly implementation of the prover, and the output goes to build/bin/es-node.

The es-node target then assembles the payload around that binary.

bash
es-node: build
	cp -r ethstorage/prover/snark_lib build/bin
	mkdir -p build/bin/snark_lib/zkey
	mkdir -p build/bin/snarkbuild

The proving library is copied out of the source tree into the build directory, along with the zkey directory and the snarkbuild directory. That means the binary is not self-contained: a node that only has es-node on its PATH is missing the pieces it needs to prove.

The linker flags stamp the binary with the commit, the commit date, a version meta value and the build time, which is the usual practice for a daemon that operators will need to identify later.

Testing and linting are the two other targets. The test target runs the whole tree with go test -v ./..., and the lint target runs golangci-lint with a set of extra linters enabled, including goimports, sqlclosecheck, bodyclose, asciicheck, misspell and errorlint, with errors.As and errors.Is excluded from the errorlint check.

The container image and the three ports it opens

The Dockerfile is a two stage build that ends in a surprisingly busy runtime image.

The builder stage is a stock Go 1.24 image, the source is copied in, and the build runs through make, which is the Makefile described above. The runtime stage is alpine:latest, and it copies the build directory across, so the snark_lib payload travels with the binary.

The runtime then installs a set of packages with apk.

bash
RUN apk add --no-cache bash curl libstdc++ gcompat libgomp nodejs npm
RUN npm install -g snarkjs

Two of those deserve a note. The gcompat package provides a glibc compatibility layer, which is what lets a CGO binary built against glibc run on Alpine, and libgomp is the OpenMP runtime that the proving code links against.

The Node.js and npm install followed by a global snarkjs is the most surprising line, since the rest of the project is Go. It is there to supply the JavaScript tooling that the proving workflow uses, and it is a reminder that the prover's toolchain is not purely a Go toolchain.

The image exposes three ports.

bash
EXPOSE 9545 9222 30305/udp

The metrics and debug port 9222 is the usual Go debugging port, 9545 is the node's own service port, and 30305 over UDP is the libp2p port, which is the peer-to-peer traffic that the network runs on.

A matrix of shell scripts, one per network and mode

The top level of the repository is a long list of shell scripts, and reading their names tells you how the project expects a node to be operated.

There is an init.sh family, with init-l2.sh, init-mainnet.sh and init-rpc.sh variants, and a run family with run.sh, run-l2.sh, run-mainnet.sh, and a parallel set of run-rpc.sh, run-l2-rpc.sh and run-mainnet-rpc.sh. There is a sync family with sync.sh, sync-l2.sh and sync-mainnet.sh, and a small set of -it- scripts, run-it.sh, run-l2-it.sh and run-it-rpc.sh, which are the integration test variants.

The naming shows two axes. The first is which network you are on, mainnet or the layer two test network, and the second is whether the node runs with an RPC endpoint or without one, since a node that serves requests and a node that only participates in storage and proving are different things.

The integration_tests/ directory in the tree is the counterpart to those scripts, so the same matrix appears in code and in shell.

The Dockerfile copies the scripts into the image and makes them executable, which confirms that the shell entry points are the supported way to start the node rather than something left over from development. The cmd/ directory holds the Go command itself, and the ethstorage/ directory holds the implementation, with a Dockerfile, a .dockerignore and a golangci.yml alongside them.

The licence is a business source licence, not a standard one

The README states that the repository is licensed under BSL, with a link to the LICENSE file, and GitHub's own classification of the repository licence is recorded as a custom one that it cannot categorise. Those two statements together are the accurate description: this is not MIT, not Apache and not GPL.

A business source licence is a source-available arrangement rather than an open source one. The code is published in a form that lets you run it, and the usual mechanism is that it converts to an open source licence after a period, or converts to a commercial licence if the vendor chooses. The specific terms, including the change date and what happens if the project is discontinued, are in the LICENSE file and are the only authoritative statement.

The practical advice is to read that file before you deploy, especially if you intend to modify the node, distribute it, or run it as part of a service for someone else. The rule of thumb is that the licence terms, not the presence of a public repository, decide what you can do, and a self-hoster who is only running the node for themselves is in a very different position from a vendor who wants to ship it.

The release history gives a sense of the project's pace: v0.2.10 on 2026-04-16, v0.2.9 on 2026-03-09 and v0.2.8 on 2025-11-20, with the last push to the repository on 2026-10-21, so the tree is moving ahead of the published binaries.

Editorial conclusion

es-node fits a team that wants to participate in the EthStorage network as a storage provider, or a team that wants to read a working implementation of a data availability backed key-value layer, since the Go code covers the prover, the networking and the storage side in one tree. It is not the right starting point for an application developer, because the README points those readers at the documentation and the network rather than at a client library. Before you deploy it, read the BSL licence, because the repository is not under a standard open source licence, and note that the last tagged release is v0.2.10 from 2026-04-16 while the last push was on 2026-10-21, so the tree moves ahead of the published binaries.

Frequently asked questions

What is es-node and what does EthStorage do?

es-node is the Golang implementation of the EthStorage node. EthStorage is described as a modular and decentralized storage Layer 2 offering programmable key-value storage powered by Data Availability, intended for long-term data availability for rollups and for fully on-chain applications such as games, social networks and AI.

How do I build es-node from source?

Run make, which invokes a go build with CGO_ENABLED=1, the rapidsnark_asm build tag and the output going to build/bin/es-node. The es-node target also copies the snark_lib proving library into the build directory and creates the zkey and snarkbuild directories, and the build stamps the commit and build time into the binary.

What ports does the es-node Docker image expose?

Three: 9545 for the node service, 9222 for the Go debugging and metrics port, and 30305 over UDP for the libp2p peer to peer traffic. The runtime image is Alpine with bash, curl, libstdc++, gcompat, libgomp, nodejs and npm, and snarkjs installed globally.

What licence is the es-node repository under?

The README states the repository is licensed under BSL and links the LICENSE file, and GitHub records the licence as a custom one it cannot categorise, so it is a business source licence rather than a standard open source licence. The terms in the LICENSE file decide what you may do with it.

Which network does es-node connect to?

Both, through separate entry points. The repository has init.sh, run.sh and sync.sh scripts alongside l2 and mainnet variants and matching rpc variants, and the README sends operators to the Storage Providers' guide in the EthStorage documentation for the prerequisites and detailed instructions.

Official sources

  1. ethstorage/es-node on GitHub
  2. Issues
  3. README
  4. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ethstorage-es-node.svg)](https://hysenlabs.com/projects/ethstorage-es-node)

Was this useful?