Skip to content

corehannah/blackbase

Repository files navigation

BlackBase

BlackBase is a privacy-first document collaboration dApp built on Zama FHEVM. It keeps document bodies encrypted off-chain, stores only ciphertext on-chain, and uses Fully Homomorphic Encryption to protect the access key while still enabling shared editing and permissioned access.

Overview

BlackBase lets a user generate a random EVM address as a secret key, encrypt that key with Zama FHE, and store the encrypted key plus an empty document body on-chain. Authorized users can later decrypt the key locally and use it to encrypt or decrypt the document body. The chain never sees the plaintext key or body.

What Problems It Solves

  • On-chain documents are public by default. BlackBase provides a privacy-preserving workflow where only ciphertext is stored.
  • Key sharing is hard in decentralized apps. BlackBase enables access control that does not reveal the key on-chain.
  • Collaboration usually requires a centralized backend. This app stores the encrypted body on-chain while keeping decryption local.
  • Traditional encryption flows leak metadata or require a trusted key server. Here, the key is protected by FHE and shared by permissions.

Core Advantages

  • End-to-end privacy for document bodies using client-side AES-GCM encryption.
  • FHE-protected access key stored on-chain; the key is never revealed on-chain in plaintext.
  • On-chain access control with explicit grants to collaborators.
  • Works with standard wallets and Sepolia without a custom backend.
  • Clear separation of read (viem) and write (ethers) responsibilities in the frontend.

How It Works (Step by Step)

  1. Create a document

    • The client generates a random EVM address A locally (used as the document key).
    • A is encrypted using Zama FHE into an encrypted eaddress handle.
    • The contract stores: document name, encrypted key, empty body, owner, and timestamp.
  2. Open and decrypt

    • An authorized user fetches the encrypted key and encrypted body from the contract.
    • The user requests a Zama FHE user decrypt flow to decrypt the encrypted key locally.
    • The decrypted key A never leaves the client.
  3. Edit and update

    • The document body is encrypted locally using AES-GCM derived from the key A.
    • The encrypted body is sent on-chain via updateDocument.
  4. Share access

    • The owner grants access to another address.
    • The contract adds permission and allows that address to decrypt the encrypted key via FHE.

Architecture Summary

On-chain:

  • EncryptedDocuments contract stores metadata and ciphertext.
  • Access control is enforced on-chain.
  • Zama FHE allows encrypted key sharing without exposing the plaintext key.

Off-chain:

  • The client encrypts/decrypts the document body locally.
  • Zama FHE user decrypt is handled in the browser.
  • No centralized server or storage is required.

Smart Contract (EncryptedDocuments)

Contract location: contracts/EncryptedDocuments.sol

Document fields stored on-chain:

  • name: string (public)
  • encryptedBody: string (ciphertext payload)
  • encryptedKey: eaddress (FHE encrypted key)
  • owner: address
  • updatedAt: uint256 (timestamp)
  • exists: bool

Main functions:

  • createDocument(name, encryptedKey, inputProof) -> docId
  • updateDocument(docId, encryptedBody)
  • grantAccess(docId, grantee)
  • getDocumentInfo(docId) -> (name, owner, updatedAt)
  • getDocumentCiphertext(docId, viewer) -> (encryptedBody, encryptedKey)
  • hasAccess(docId, viewer) -> bool
  • getDocumentsByOwner(owner) -> uint256[]

Events:

  • DocumentCreated(docId, owner, name)
  • DocumentUpdated(docId, editor)
  • AccessGranted(docId, owner, grantee)

Access model:

  • Owner is recorded at creation.
  • Only authorized addresses can update a document.
  • Owner grants access for decryption and editing.

Frontend

Location: src/

Key behaviors:

  • Writes use ethers (signer, transactions).
  • Reads use viem (public client).
  • Document body encryption uses AES-GCM in the browser.
  • Zama FHE SDK handles encrypted key creation and decryption.
  • Network configuration is Sepolia-only.

Important frontend configs:

  • src/src/config/contracts.ts holds CONTRACT_ADDRESS and CONTRACT_ABI.
  • src/src/config/wagmi.ts holds the WalletConnect projectId.

Cryptography Details

Encrypted key:

  • The key is an EVM address A generated locally.
  • It is encrypted using Zama FHE as an eaddress handle.
  • FHE permissions allow authorized users to decrypt the key.

Encrypted body:

  • The body is encrypted in the browser using AES-GCM.
  • The key is derived from A by SHA-256 and used as an AES key.
  • The payload is stored as "ivHex:cipherHex".

Tech Stack

  • Solidity 0.8.27
  • Hardhat + hardhat-deploy
  • Zama FHEVM Solidity + JS SDK
  • React + Vite + TypeScript
  • wagmi + RainbowKit
  • viem (reads) + ethers v6 (writes)

Project Structure

contracts/                 Smart contracts
deploy/                    Deployment scripts
tasks/                     Hardhat tasks
test/                      Contract tests
docs/                      Zama references
src/                       Frontend (React + Vite)

Setup

Prerequisites:

  • Node.js 20+
  • npm
  • A Sepolia wallet + test ETH
  • Infura API key
  • WalletConnect project ID
  1. Install root dependencies
npm install
  1. Configure environment for Hardhat

Create a .env file in the repo root:

INFURA_API_KEY=YOUR_INFURA_KEY
PRIVATE_KEY=YOUR_PRIVATE_KEY
ETHERSCAN_API_KEY=OPTIONAL

Notes:

  • Use PRIVATE_KEY only (no mnemonic).
  • PRIVATE_KEY can include or omit the 0x prefix.
  1. Compile and test
npm run compile
npm run test
  1. Deploy locally (Hardhat) if needed
npx hardhat deploy
  1. Deploy to Sepolia
npx hardhat deploy --network sepolia
  1. Sync contract address and ABI to the frontend
  • Copy the deployed address into src/src/config/contracts.ts as CONTRACT_ADDRESS.
  • Copy the ABI array from deployments/sepolia/EncryptedDocuments.json into CONTRACT_ABI.
  1. Configure WalletConnect
  • Edit src/src/config/wagmi.ts and set projectId.
  1. Install and run the frontend
cd src
npm install
npm run dev

Usage Guide

Create a document:

  • Connect a wallet.
  • Enter a name and click Create Document.
  • Save the generated key and document id.

Open and edit a document:

  • Enter the document id.
  • Decrypt the key (requires access).
  • Decrypt the body, edit, and save.

Share access:

  • Enter the document id and recipient address.
  • Grant access so the recipient can decrypt and edit.

Hardhat Tasks (Optional CLI Helpers)

Examples:

npx hardhat task:doc-address
npx hardhat task:doc-create --name "Research Draft"
npx hardhat task:doc-info --docid 1
npx hardhat task:doc-decrypt-key --docid 1
npx hardhat task:doc-grant --docid 1 --grantee 0xYourAddress
npx hardhat task:doc-update --docid 1 --body "ciphertext"

Testing Notes

  • The FHEVM test suite runs against the mocked FHEVM in Hardhat.
  • Sepolia tests are not supported by the FHEVM mock.

Security and Privacy Notes

  • Document names, owners, and timestamps are public on-chain.
  • Document bodies are encrypted off-chain; only ciphertext is stored on-chain.
  • The encryption key is never stored in plaintext and is protected by FHE.
  • Access control is enforced on-chain; unauthorized writes revert.
  • Losing the decrypted key A means you cannot decrypt existing ciphertext.

Future Roadmap

  • Document version history and diff view.
  • Stronger metadata privacy (name encryption).
  • Multi-recipient key sharing with revocation policies.
  • Large content support via encrypted off-chain storage and on-chain hash pointers.
  • Activity feed and audit logs for team workflows.
  • Mobile-friendly signer flow and batch updates.

License

BSD-3-Clause-Clear. See LICENSE.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors