Getting Started with FastFS: Decentralized File Storage on NEAR Protocol

2 min read

FastFS by Fast NEAR is a decentralized file storage system built on the NEAR blockchain, designed to provide a standardized protocol for uploading and serving files. By leveraging NEAR’s transaction capabilities, FastFS ensures that files are stored on-chain and accessible via predictable URLs, facilitating seamless integration with decentralized applications (dApps).


🔗 URL Structure

Each file uploaded to FastFS is accessible through a URL formatted as:

https://{predecessor_id}.fastfs.io/{receiver_id}/{relative_path}
  • predecessor_id: The account initiating the upload.

  • receiver_id: The contract account handling the file storage.

  • relative_path: The file’s designated path within the storage system.

Example:
Uploading an image via a transaction from mob.near to fastfs.near with the relative path fastnear.png results in the URL:

https://mob.near.fastfs.io/fastfs.near/fastnear.png

🧾 Upload Process

1. Prepare File Data
Construct a data structure containing the file’s relative path and content:

const fastfsData = {
simple: {
relativePath: "path/to/your/file.png",
content: {
mimeType: "image/png",
content: new Uint8Array(fileBuffer) // File content as byte array
}
}
};

2. Serialize Data
Use Borsh serialization to encode the data:

import { serialize as borshSerialize } from "borsh";

const serializedData = borshSerialize(FastfsSchema.FastfsData, fastfsData);
const base64Data = near.utils.bytesToBase64(serializedData);

3. Submit Transaction
Send a NEAR transaction with the following parameters:

  • Method Name: __fastdata_fastfs

  • Arguments: base64Data

  • Receiver: fastfs.near

await near.functionCall({
contractId: "fastfs.near",
methodName: "__fastdata_fastfs",
args: base64Data,
gas: "300000000000000", // 300 TGas
attachedDeposit: "0"
});

✅ Validation Rules

FastFS enforces specific validation criteria to maintain data integrity:

  • Relative Path: Must not exceed 1,024 characters.

  • MIME Type: Required and cannot be empty.

  • Content: Optional; if omitted, the file is considered deleted.

impl SimpleFastfs {
pub fn is_valid(&self) -> bool {
if self.relative_path.len() > MAX_RELATIVE_PATH_LENGTH {
return false;
}
if let Some(content) = &self.content {
if content.mime_type.is_empty() {
return false;
}
}
true
}
}

🗃️ Storage and Indexing

FastFS utilizes an indexer to process transactions and store metadata in ScyllaDB, including:

  • Transaction details: Receipt ID, block height, timestamp.

  • Account information: Predecessor ID, receiver ID, signer ID.

  • File data: Relative path, MIME type, content bytes.

  • Indexing metadata: Shard ID, receipt index, action index.


🔧 Developer Tools

FastFS provides several repositories to facilitate integration:G2

  • FastFS Server: Handles file serving and routing.

  • FastData Indexer: Processes and indexes transactions.

  • Drag & Drop Interface: User-friendly frontend for file uploads.

These tools enable developers to seamlessly incorporate decentralized file storage into their applications.


For more detailed information, refer to the FastFS Upload Format Documentation.

Updated: June 2, 2025

Leave a Comment


To leave a comment you should to:


Scroll to Top