Blockchain File Storage Made Simple

How to use a Multi-Version database to store files immutably.

Database Guru
3 min readDec 8, 2020

--

Have you ever considered storing sensitive files on the blockchain? There are many benefits over traditional storage:

  • Data is stored immutably and is indelible.
  • Files are encrypted end-to-end.
  • Files are digitally signed by the user.

From a security standpoint, these features help mitigate risk associated with data breaches. Adversaries can’t leak documents that aren’t their own and existing documents can’t be altered, edited, or deleted.

At blockpoint Systems we strive to bring the most security to our users. Using the bSQL language you can easily store immutable files in our Multi-Version Database.

A Small Demonstration

In this article I will show you how to easily set up file storage in bSQL using a basic example.

Let’s define the basic workflow of our example application.

  • A user logs in.
  • The user stores a file with a description in the database.
  • The user will later read the file and its corresponding description.

Setting Up the Database

I’ll be using a local version of MDB. You can demo the system here or inquire about a developer’s instance using this link. Every MDB comes with a fully integrated blockchain file store!

Building the Containers

In order to store a description and its corresponding file, we must create a new blockchain to link our descriptions to our files. The blockchain descriptions will have the following columns:

  • id is a primary key that is incremented after each insertion.
  • file_id references the corresponding file stored in the file store.
  • file_name is the name of the file being stored.
  • description is a packed string that describes the file.

Seems simple enough. Guess what, the code is simple too!

CREATE BLOCKCHAIN main.descriptions HISTORICAL PLUS (
id UINT64 AUTO INCREMENT
PRIMARY
,
file_id UINT64
FOREIGN KEY
[main.sysfiles, id],
file_name STRING PACKED,
description STRING PACKED
);

bSQL’s file store is managed internally using various system blockchains. This simplifies implementation by abstracting away various storage protocols. Additionally, we can define relationships within our database between files and records. For example, the file_id column in the descriptions blockchain references the system blockchain sysfiles. This enforces that files can’t exist in descriptions without the corresponding file being stored in the system.

Inserting Files

MDB uses a login’s encryption key to encrypt files when they are streamed into the database. Encryption keys are managed by the internal bSQL key store. All stored keys are encrypted by their corresponding logins master key, making them undecipherable without the key, eliminating the potential for leaked keys. When logged in, the user can only decrypt files associated with keys that he has access to. If neccesary, logins can share keys and files with other logins.

We insert a file into the database using the STORE FILE keyword.

STORE FILE “my_first_file” 
PATH = “users/me/my_file.pdf”
ENCRYPT = TRUE;

The corresponding output is:

ID: 0

Now we can use the outputted file_id to store our file description. This constitutes inserting the description into the descriptions blockchain.

INSERT main.descriptions (file_id, file_name, description) 
VALUES (
0,
"my_first_file",
“This file is used as an example to illustrate bSQL file storage”
);

Reading Files

In order to read a file, it must be exported from the database. We stored additional metadata in descriptions, such as the file name, to help write our EXPORT FILE command.

EXPORT FILE “my_first_file” 
DIRECTORY = “users/me/”
WITH NAME
“my_first_exported_file.pdf”;
  • As noted previously, only the user who encrypted the file can decrypt it using the EXPORT FILE command.

The file is decrypted and exported to the file path “users/me/my_first_exported_file.pdf”. To access the description associated with the file, we can read from the descriptions blockchain.

SELECT file_id, descrpition 
FROM main.descriptions
WHERE descriptions.name = “my_first_file”;

Conclusion

We tried to make file integration as easy and secure as possible. If you have any questions or suggestions please leave them in the comments below. Follow this page for more information on blockpoint and the bSQL language. Cheers!

--

--