ZooBC wiki
Data and storage

Files on the chain (DFS)

ZooBC has two ways to keep a file. A DFS file is for small content: the file travels inside its own transaction, and the chain records it as a dataset row of its owner. Larger files go to the decentralised storage pool, cut into pieces that never touch the chain. This article covers DFS files.

The record and the content

A DFS file of an owner at a path is the dataset row (owner, owner, "dfs:" + path): the setter and the recipient are both the owner, and the property is dfs: followed by the path. The row's value is the hex form of a metadata record:

  • the SHA3-256 hash of the content, and its size;
  • the permissions (0644);
  • two timestamps;
  • the number of chunks and the hash of each chunk.

The content itself travels inside the transaction body. A body can be at most 65,536 bytes, so a DFS file holds up to about 64 KiB. The nodes keep the bytes in a local chunk table beside the chain; they are not part of the consensus state. The row on the chain holds the hashes, so anyone can check the content against it.

Paths

A path starts with / and is at most 1,024 bytes long. It may not contain //, .., a NUL byte, a carriage return or a line feed. A trailing / is dropped, so /a/b/ and /a/b name the same file. Only the DFS transactions may write rows under dfs: or dfs:dir:; a SetupAccountDataset with either prefix is refused.

Create, update, delete

TransactionTypeWhat it does
DFSCreateFile8creates the file at a path, with its content
DFSUpdateFile264replaces the content at the same path
DFSDeleteFile520removes the file

A create over an existing file, and an update or a delete of a missing file, are paid no-ops: the fee is charged and nothing changes. An app should therefore read the path's row before it chooses between create and update.

Rent and refunds

A DFS row is a dataset object like any other. It has its own deposit address (ZBS_…) that anyone can fund, and it pays dataset rent every period on its bytes, the property plus the hex value: at the starting price, 0.05 ZBC per MiB per period on mainnet. The rent is taken from the deposit and then from the owner, and credited to the longevity pool. If neither can pay, the row is deactivated, as for any dataset.

Deleting a DFS file gives each payer, the owner included, its own unused part of the deposit back. The money is consumed first in, first out: the oldest payment is used up before the next one is touched, so the most recent payers get back the most.

DFS file or stored file?

DFS fileStored file
Sizeup to about 64 KiBup to 100,000 pieces of 1 MiB
Contentinside the transactionpieces on five holder nodes, never on the chain
On the chainone row under dfs:the manifest: root, sizes and piece ids
Changesupdate and delete at the same pathnew content has a new root, so it is a new file
Rent goes tothe longevity poolthe storage pool
Access controlnone: the content is in a public transactiona private flag with an allow list

Neither way relies on the ZooBC Foundation's machines or on the uploader's computer.

Two ways to keep a file: a DFS file inside its transaction, or a stored file cut into pieces held by five nodes.
Two ways to keep a file: a DFS file inside its transaction, or a stored file cut into pieces held by five nodes.

See also