Overview of the Decentralized File Storage System

The decentralized file storage system consists of the following key components:

  1. File Upload: Users can upload files, which will be hashed and stored on the blockchain.
  2. File Retrieval: Users can retrieve files by providing their corresponding hashes.
  3. Access Control: Only the file uploader can access the file's details.

Smart Contract Structure

The smart contract will include functions for uploading and retrieving file hashes. Below is a simplified structure of the contract:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract DecentralizedFileStorage {
    struct File {
        string fileHash;
        address uploader;
        uint256 timestamp;
    }

    mapping(string => File) private files;

    event FileUploaded(string indexed fileHash, address indexed uploader, uint256 timestamp);

    function uploadFile(string memory _fileHash) public {
        require(bytes(_fileHash).length > 0, "File hash cannot be empty");
        require(files[_fileHash].uploader == address(0), "File already exists");

        files[_fileHash] = File(_fileHash, msg.sender, block.timestamp);
        emit FileUploaded(_fileHash, msg.sender, block.timestamp);
    }

    function getFile(string memory _fileHash) public view returns (string memory, address, uint256) {
        require(files[_fileHash].uploader != address(0), "File does not exist");
        
        File memory file = files[_fileHash];
        return (file.fileHash, file.uploader, file.timestamp);
    }
}

Explanation of the Code

  • Struct Definition: The File struct holds the file's hash, the address of the uploader, and the timestamp of when it was uploaded.
  • Mapping: A mapping from the file hash to the File struct allows us to store and retrieve file details efficiently.
  • Events: The FileUploaded event is emitted whenever a file is uploaded, enabling front-end applications to listen for uploads.
  • Functions:
  • uploadFile: This function allows users to upload a file by providing its hash. It checks that the hash is not empty and that it does not already exist.
  • getFile: This function retrieves the details of a file based on its hash. It ensures that the file exists before returning its details.

Development Best Practices

  1. Input Validation: Always validate inputs to prevent unexpected behavior and ensure data integrity.
  2. Event Emission: Emit events for significant actions, such as file uploads, to enable efficient tracking and logging on the front end.
  3. Access Control: Implement access control mechanisms to restrict sensitive operations to authorized users.

Testing the Smart Contract

To test the smart contract, you can use Remix IDE or deploy it on a local Ethereum test network. Here’s a simple test scenario using JavaScript with the Truffle framework:

const DecentralizedFileStorage = artifacts.require("DecentralizedFileStorage");

contract("DecentralizedFileStorage", accounts => {
    let instance;

    before(async () => {
        instance = await DecentralizedFileStorage.deployed();
    });

    it("should upload a file", async () => {
        const fileHash = "QmT78zSuBMuW8y8gQvE2Fz1W9bR4rQ8wZ1F3g6S6p8u8Z8";
        await instance.uploadFile(fileHash, { from: accounts[0] });

        const file = await instance.getFile(fileHash);
        assert.equal(file[0], fileHash, "File hash does not match");
        assert.equal(file[1], accounts[0], "Uploader address does not match");
    });

    it("should not allow duplicate uploads", async () => {
        const fileHash = "QmT78zSuBMuW8y8gQvE2Fz1W9bR4rQ8wZ1F3g6S6p8u8Z8";
        try {
            await instance.uploadFile(fileHash, { from: accounts[1] });
            assert.fail("Expected error not received");
        } catch (error) {
            assert(error.message.includes("File already exists"), "Error message does not match");
        }
    });
});

Summary of Key Features

FeatureDescription
File UploadUsers can upload files by providing their hashes.
File RetrievalUsers can retrieve file details using the hash.
Event LoggingEvents are emitted for uploads, enhancing transparency.
Input ValidationEnsures data integrity and prevents duplicate uploads.

Conclusion

In this tutorial, we have built a basic decentralized file storage system using Solidity. This system allows users to upload and retrieve files securely while ensuring that the integrity of the data is maintained on the blockchain. By following best practices in smart contract development, you can create robust and secure decentralized applications.

Learn more with useful resources: