BAMFS
Use BAMFS

IPFS

Every BAMFS root has a canonical IPFS CIDv1, derived identically on-chain and off.

Every BAMFS file and directory has a canonical IPFS CIDv1, computable both on-chain (IpfsCidResolver) and off-chain (@bamfs/sdk). The two agree byte-for-byte.

This is not a mirror. Nothing is copied anywhere — it is the address the same content would have on IPFS, which is what lets an independent pin land on an address the chain already knows.

The profile

ParameterValue
CID versionv1
Multihashsha2-256
File codecraw for single-block, dag-pb for multi-block
Directory codecdag-pb
Chunk size262,144 bytes (256 KiB)
DAG shapeBalanced, raw leaves
Max links per node174
Entry orderingLexicographic by name
Base encodingbase32, lowercase, unpadded

These are the IPFS defaults for ipfs add --cid-version=1 --raw-leaves, so the CID matches what a stock IPFS client produces.

A file that fits in one 256 KiB block is CIDv1(raw, sha256(bytes)). Larger files fold into a balanced DAG: 256 KiB raw leaves, wrapped in groups of ≤174 links, recursing to a single root.

There is no protocol-level size cap on the resolver. What bounds it is the eth_call gas budget of the node serving the read — a provider setting, not a chain one, so the ceiling moves with your endpoint. See Deployments.

Compression is invisible to it

An IPFS CID is computed over a file's logical bytes. The same content stored compressed and uncompressed yields the same IPFS CID, even though its BAMFS CIDs differ — a BAMFS CID commits to the stored bytes.

The asymmetry runs opposite to intuition:

CodecOn-chain resolverOff-chain SDK
noneyesyes
fastlzyesyes
gzip, brotliCompressionNotSupportedyes

The resolver can inflate exactly the codecs with a Solidity decompressor registered. FastLZ has one. gzip would need DEFLATE with Huffman decoding in Solidity — possible, large, gas-expensive, and not planned.

So a gzip root does have an ordinary IPFS CID; the chain just cannot derive it for you. The SDK, CLI, and web app all do it off-chain. The limit is on-chain decompression, not the protocol and not IPFS.

Addressing the compressed bytes instead would sidestep this, and is deliberately not done: gateways serve the bytes a CID addresses, so a visitor would get a .gz file instead of the page.

Pinning

Nothing pins your content automatically. BAMFS runs no pinner. Content resolves from contract storage whether or not it is on IPFS, so pinning is a speed optimisation and never a durability requirement.

The CLI pins and then verifies the result:

bamfs pin --project-id <id> --provider local
bamfs pin --project-id <id> --provider pinata --api-key <JWT>
bamfs pin --project-id <id> --provider web3storage --api-key <key>

It reads the tree from chain, pins it, and checks the provider's reported root against the CID BAMFS computed.

By hand, over the same files:

ipfs add -r --cid-version=1 ./your-project

That reproduces the profile exactly — --cid-version=1 is what implies raw leaves. Verified against a live project: the importer and the on-chain resolver return the same CID.

Once pinned, set the project's bamfs.gateway so the gateway tries your pin before rebuilding from chain.

Checking

bamfs verify <cid>              # on-chain and local, compared
bamfs verify <cid> --local      # off-chain only, works for gzip roots

On this page