BVM
  • About bvm
    • Development infrastructure for Bitcoin
    • Follow our progress
  • getting started
    • Build a Bitcoin L2 with BVM Studio
    • Level up with Bitcoin dapps
    • Deploy your own Bitcoin dapp
  • L1 Scaling solutions
    • What are Bitcoin Shards? [WIP]
    • Compute sharding [WIP]
    • Data sharding [WIP]
    • Case studies [WIP]
      • SHARD_BVM
        • Bitcoin Virtual Machine #0
      • SHARD_DA [WIP]
      • SHARD_AI [WIP]
  • L2 Scaling solutions
    • What are Bitcoin rollups?
    • Optimistic rollups
    • ZK rollups
  • l3 scaling solutions
    • What are Bitcoin appchains?
    • Rollups from appchains to L2s
  • Bitcoin decentralized bridges
    • Bitcoin <> BVM bridge
    • Bitcoin <> Ethereum bridge [WIP]
    • Bitcoin <> Solana bridge [WIP]
  • bvm studio
    • Overview
    • Build a Bitcoin L2
    • Monitor a Bitcoin L2
    • Scale a Bitcoin L2
    • Building blocks
  • bitcoin heartbeats
    • Overview
    • Chain heartbeats
      • Key metrics
      • Bitcoin's 5 levels of scalability
    • Wallet heartbeats [WIP]
    • Dapp heartbeats [WIP]
  • bitcoin api
    • RaaS API
    • Chain API [WIP]
  • bitcoin dapps
    • Overview
    • EVM code tutorials
      • Build a Bitcoin Name System
      • Build an Ordinals alternative
      • BFS: Build an IPFS alternative
      • Decentralized AI
      • Auction
      • Decentralized Discord
      • Fully onchain Tic-Tac-Toe
      • BRC-721: NFTs
      • Operate your project using a DAO
      • Raise funds through a Crowdsale
      • Issue your own governance token
    • SVM code tutorials [WIP]
Powered by GitBook
On this page
  • Write the BFS smart contract
  • Clone the smart contract examples
  • Compile the contracts
  • Deploy the contracts
  • Interact with the contracts
  1. bitcoin dapps
  2. EVM code tutorials

BFS: Build an IPFS alternative

Let's build the Bitcoin File System (BFS), a decentralized, open, and permissionless file storage on Bitcoin.

  • write a file to Bitcoin

  • read a file from Bitcoin

  • support large files

Write the BFS smart contract

It turns out that writing the Bitcoin File System smart contract is very simple. Here is a basic contract to provide decentralized file storage on Bitcoin Virtual Machine.

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

import "@openzeppelin/contracts/utils/Counters.sol";

error FileExists();

contract BFS {
        using Counters for Counters.Counter;
        Counters.Counter private idCounter;
        mapping(address => mapping(string => mapping(uint256 => bytes))) public dataStorage;
        mapping(address => mapping(string => uint256)) public chunks; // max chunk index
        mapping(address => mapping(string => uint256)) public bfsId;

        constructor () {
                idCounter.increment(); // start from 1
        }

        function store(string memory filename, uint256 chunkIndex, bytes memory _data) external {
                if (dataStorage[msg.sender][filename][chunkIndex].length > 0) {
                        revert FileExists();
                }
                dataStorage[msg.sender][filename][chunkIndex] = _data;
                if (chunks[msg.sender][filename] < chunkIndex) {
                        chunks[msg.sender][filename] = chunkIndex;
                }
                bfsId[msg.sender][filename] = idCounter.current();
                idCounter.increment();
        }

        function load(address addr, string memory filename, uint256 chunkIndex) public view returns (bytes memory, int256) {
                uint256 temp = chunkIndex + 1;
                int256 nextChunk = (temp > chunks[addr][filename]) ? -1 : int256(temp);
                return (dataStorage[addr][filename][chunkIndex], nextChunk);
        }

        function count(address addr, string memory filename) public view returns (uint256) {
                return chunks[addr][filename];
        }

        function getId(address addr, string memory filename) public view returns (uint256) {
                return bfsId[addr][filename];
        }
}

The store() function saves a chunk of a file. The load() function returns the data of a specific chunk. And the getId() function returns the ID of the file.

You can save a large file onto Bitcoin by splitting it into smaller chunks, committing them to Bitcoin, and retrieving & merging them back as needed.

BFS files are immutable.

Clone the smart contract examples

We've prepared a few different examples for you to get started. The BNS example is located at smart-contract-examples/contracts/BNS.sol.

git clone https://github.com/trustlesscomputer/smart-contract-examples.git

Compile the contracts

To compile your contracts, use the built-in hardhat compile task.

cd smart-contract-examples
npm install
npx hardhat compile

Deploy the contracts

Review config file hardhat.config.ts. The network configs should look like this.

  networks: {
    mynw: {
      url: "http://localhost:10002",
      accounts: {
        mnemonic: "<your mnemonic with funds>"
      },
      timeout: 100_000,
    },
    blockscoutVerify: {
      blockscoutURL: "http://localhost:4000", // your explorer URL
      ...
    }
  }

Run the deploy scripts using hardhat-deploy.

npx hardhat deploy --tags BFS

Make sure the accounts in hardhat.config.ts have some $BVM.

Interact with the contracts

Once the contracts are deployed, you can interact with them. We've prepared a few hardhat tasks to make it easy for you to interact with the contracts.

# store data
echo "this is some text" > data.txt
npx hardhat write-storage --filename ./data.txt
npx hardhat read-storage --filename ./data.txt # read data, print it as readable text
PreviousBuild an Ordinals alternativeNextDecentralized AI

Last updated 11 months ago