A lightweight virtual filesystem that uses the internet as block storage.
bitchain is a Rust CLI for managing content-addressed binary chains.
It breaks files into immutable SHA-256 blocks, distributes them across HTTP, HTTPS, S3, or local storage, and reconstructs them on demand.
Perfect for versioning large files, distributing datasets, or building decentralized storage systems.
- Ingest a single file or directory into a JSON-based bitchain manifest
- Support local file URIs, HTTP(S) URIs, and S3 block URIs
- Upload blocks to S3 when
--uri-baseusess3:// - Dry-run ingesting without writing data
- Rebuild files from a bitchain manifest
- Validate bitchain JSON structure
- Backwards-compatible old-style bitchain format support
graph LR
A["📁 Input File(s)"] -->|Ingest| B["🔗 Split into Blocks"]
B -->|SHA-256 Hash| C["🔐 Content-Addressed Blocks"]
C -->|Upload| D["☁️ Block Storage"]
D -->|S3, HTTP, File| E["📝 Bitchain Manifest"]
E -->|Rebuild| F["📁 Reconstruct Files"]
style A fill:#e1f5ff
style B fill:#fff9c4
style C fill:#f3e5f5
style D fill:#c8e6c9
style E fill:#ffe0b2
style F fill:#e1f5ff
Each file is split into fixed-size blocks (default 1MB), hashed with SHA-256, and stored at URIs. The bitchain manifest records file paths and block URIs, enabling lossless reconstruction from any available block source.
Build from source:
cargo build --releaseRun from the workspace:
cargo run -- <command>Use the included Makefile for common tasks:
make build # Compile the project
make test # Run tests
make lint # Format and lint
make fmt # Format code
make check # Run cargo check
make all # build + lint + test
make run # Run with argumentsCreate or update the config file with:
cargo run -- --setup-configThis writes JSON to ~/.bitchain/config.
If you choose AWS credentials, the CLI will prompt for:
- AWS Access Key ID
- AWS Secret Access Key
- AWS Region
- optional AWS Session Token
Ingest a file or directory and create a bitchain manifest.
cargo run -- ingest --input path/to/file.iso --uri-base s3://bucket/prefix --output file.bitchain.jsonFor directory ingestion:
cargo run -- ingest --input ./data --uri-base s3://bucket/prefix --output data.bitchain.jsonIf --uri-base is not provided, ingest writes blocks locally and uses file:// URIs.
Optional flags:
--output-dir <dir>: local directory for block files when--uri-baseis not set--block-size <bytes>: bytes per block (default1048576)--dry-run: simulate ingest without writing files or uploading
Rebuild files from an existing bitchain JSON manifest.
cargo run -- rebuild --bitchain file.bitchain.json --output-dir restoredThis reconstructs each files[].path entry under the output directory.
It tries each block URI in order and uses the first successful download.
Print a bitchain manifest to stdout.
cargo run -- show file.bitchain.jsonValidate the manifest structure.
cargo run -- validate file.bitchain.jsonPrint CLI help:
cargo run -- helpBitchain manifests use the following JSON schema:
{
"version": "1.0",
"files": [
{
"path": "relative/path/to/file.txt",
"blocks": [
{
"hash": "<sha256-hash-of-block>",
"uris": [
"s3://bucket/prefix/relative/path/to/file.txt/<hash>",
"https://example.com/blocks/<hash>.bin"
]
}
]
}
]
}version: manifest version stringfiles: array of file entriesfiles[].path: original file path preserved from ingestfiles[].blocks: ordered block list for the fileblocks[].hash: SHA-256 hash of block bytesblocks[].uris: candidate URIs for the block
For formal validation, see bitchain-schema.json. The schema uses JSON Schema draft-07 and validates both the modern multi-file format and legacy single-file format.
Run a dry-run of a directory ingest:
cargo run -- ingest --input ./docs --uri-base s3://alpha.softsurve.com --dry-runIngest a file locally and produce a manifest:
cargo run -- ingest --input ./image.iso --output-dir ./blocks --output image.bitchain.jsonRebuild from a manifest:
cargo run -- rebuild --bitchain image.bitchain.json --output-dir ./restoredValidate a manifest:
cargo run -- validate image.bitchain.json