Create a Table for Immutable Files on IPFS

Create a Table for Immutable Files on IPFS

Create relations between IPFS-based content and mutable metadata with Tableland + Filebase.

Filebase is an S3-compatible object storage platform that allows you to store data in a secure, redundant, and performant manner across multiple decentralized storage networks. In practice, they provide an S3-compatible API layer on top of decentralized storage networks such as IPFS, Sia/Skynet, Storj. They also offer a super intuitive web console for storing and managing your data.

Filebase can be used to store data in “buckets” (think folders) with associated metadata. They are containers for data objects. You can upload files to IPFS by creating a new bucket on Filebase’s IPFS storage network. Like any content-addressable data on IPFS, objects stored on via Filebase on the IPFS network have an associated IPFS CID which is unique to each file, but isn’t easily identifiable like typical file IDs or storage paths. To solve this, you can create a table on Tableland that tracks your objects and their associated file name, type, and IPFS CID so you can query it whenever you need to quickly reference an object.


  • Download and install the Tableland CLI tool: npm i -g @tableland/cli
  • Sign up for a Filebase account, and grab your Access and Secret Keys. Learn how to view your access keys here.
  • Have a Filebase bucket created on the IPFS network. For instructions on how to create a bucket on the IPFS network, see here.

Tracking Assets

We’ll start by creating a new table called AssetTracker, that we’ll use to track our Filebase assets. The table definition is given below. You can use the tableland CLI tool to create the table. See our Command Line docs for details on getting started with the CLI tool.

Using vanilla SQL, the CREATE statement would look like the following:

CREATE TABLE AssetTracker (
	id INT,
	name TEXT,
	type TEXT,
	cid TEXT,
	provider TEXT,
	url TEXT,

And when using the CLI tableland create command, it would translate to the following where you simply pass the table schema and optional prefix AssetTracker:

export TBL_PRIVATE_KEY=privatekeystringasdf1234

tableland create "id INT, name TEXT, type TEXT, cid TEXT, provider TEXT, url TEXT, PRIMARY KEY (id)" "AssetTracker"

This will create a table (say with the name AssetTracker_5_77) on the Tableland network. You’ll need to reference your own table’s name later to update and query the table. It should look something like the following as a response to create:

  "tableId": "77",
  "prefix": "AssetTracker",
  "chainId": 5,
  "txnHash": "0x1bfd6ce07e6b63a699458cdaba09e6f6649134e3db7a8743ff1863a4c6e23ea9",
  "blockNumber": 7164108,
  "name": "AssetTracker_5_77"

If you have your own API keys for Alchemy, Infura, and/or Etherscan, you can avoid any rate limiting warning message. See tableland create --help for details.

Then, insert some data to query using the write CLI command, which does take the following vanilla SQL statement (and replace AssetTracker_5_77 with your own):

INSERT INTO AssetTracker_5_77  VALUES (

Namely, use write in the following capacity:

tableland write "INSERT INTO AssetTracker_5_77  VALUES (

Replace AssetTracker_5_77 with the value you received in the previous create step. The following table has some additional objects you might want to include.

To query the database, use the following statement via the CLI’s read command:

SELECT * FROM AssetTracker_5_77;

To properly demonstrate, this would resemble the following (where the table’s name should be the one you’ve created in the steps above):

tableland read "SELECT * FROM AssetTracker_5_77;"

This example queries all entries in the table. You can modify this to reflect your desired query for a single object or a certain criteria of objects.

For more information on Filebase, check out their documentation here.