Filestorage - smart contract, that controls decentralized file storage on SKALE chains.
Filestorage is a cost-effective storage layer within Ethereum capable of handling files up to 100MB. Filestorage uses UNIX-based filesystem of SKALE chains. Filestorage smart contract is a set of functions to interact with files on EVM. This contract may be predeployed on SKALE chains. It contains functions to work with Filestorage precompiled smart contracts.
Smart contract language - Solidity 0.8.9
To start using Filestorage (upload/delete files and create/remove directories) the space should be allocated for specific account, it could be done from account that is given ALLOCATOR_ROLE. Rules of occupying space in Filestorage:
- For directory 4096 bytes is taken
- File could be uploaded up to 100 MB (104857600 bytes)
- Occupying space for file is rounded up to the nearest multiple of 4096 bytes
- Empty file takes 4096 bytes of free space
After deleting file/directory's amount of space is freed according to the rules above
function reserveSpace(address userAddress, uint reservedSpace)
Reserves the Filestorage space for specific address. Could be called only with ALLOCATOR_ROLE
Parameters:
Parameter | Description |
---|---|
address userAddress |
Address to allocate space for |
uint reservedSpace |
Amount of space to reserve in bytes |
function setVersion(string newVersion)
Set the Filestorage version. Could be called only with DEFAULT_ADMIN_ROLE
Parameters:
Parameter | Description |
---|---|
string newVersion |
New version of the Filestorage |
function version()
Get the Filestorage version.
Parameters:
Parameter | Description |
---|---|
string |
Version of the Filestorage |
function getTotalStorageSpace()
Gets total space in Filestorage in bytes.
Returns:
Parameter | Description |
---|---|
uint |
Space in bytes |
function getTotalStorageSpace()
Gets total reserved space in Filestorage in bytes.
Returns:
Parameter | Description |
---|---|
uint |
Space in bytes |
function getReservedSpace(address owner)
Gets reserved space for account.
Parameters:
Parameter | Description |
---|---|
address owner |
Account address |
Returns:
Parameter | Description |
---|---|
uint |
Size of reserved space for account |
function getOccupiedSpace(address owner)
Gets occupied space for account.
Parameters:
Parameter | Description |
---|---|
address owner |
Account address |
Returns:
Parameter | Description |
---|---|
uint |
Size of occupied space for account in bytes |
To begin the uploading process, the file should be broken into chunks of 1MB (< 1MB for the last chunk) which are uploaded as separate transactions to FileStorage.sol. The pipeline of the uploading file is:
- creating empty file of fixed size on EVM by calling
startUpload
, - uploading data chunk by chunk with
uploadChunk
, - checking the file validity and finishing process with
finishUpload
.
function startUpload(string memory filePath, uint256 fileSize)
Creates empty file on EVM with specific name and size. Owner of the file - message sender.
- Function is called by file owner
- Maximum amount of directories and files in one directory is 8196
- Maximum filesize is 100,000,000 bytes
- Owner should have enough free space
Parameters:
Parameter | Description |
---|---|
string filePath |
Path to the file in account directory |
uint256 fileSize |
Uploaded file size in bytes |
function uploadChunk(string memory filePath, uint position, bytes memory data)
Uploads 1MB chunk of data from specific position in specific file by file owner.
- Function is called by file owner.
Parameters:
Parameter | Description |
---|---|
string filePath |
Path to the file in account directory |
uint position |
Uploaded chunk position |
bytes data |
Uploaded chunk data |
function finishUpload(string memory filePath)
Finishes uploading of the file. Checks whether all chunks are uploaded correctly.
- Function is called by file owner.
Parameters:
Parameter | Description |
---|---|
string filePath |
Path to the file in account directory |
function deleteFile(string memory filePath)
Deletes file from Filestorage.
- Function is called by file owner.
Parameters:
Parameter | Description |
---|---|
string filePath |
Path to the file in account directory |
function readChunk(string memory storagePath, uint position, uint length)
public
view
returns (bytes32[MAX_BLOCK_COUNT] memory out)
Reads chunk from file from specific position with specific length. Returns bytes32
array of fixed size with requested data.
- Maximum length of the chunk to read is 1Mb
Parameters:
Parameter | Description |
---|---|
string storagePath |
Full path of the file in Filestorage |
uint position |
First byte to read from |
uint length |
Uploaded chunk length |
Returns:
Parameter | Description |
---|---|
bytes32[] out |
Requested chunk data split across bytes32 array |
function getFileSize(string memory storagePath)
public
view
returns (uint fileSize)
Gets size of the requested file in bytes.
Parameters:
Parameter | Description |
---|---|
string storagePath |
Full path of the file in Filestorage |
Returns:
Parameter | Description |
---|---|
uint fileSize |
Size of requested file |
function getFileStatus(string memory storagePath)
public
view
returns (int)
Returns status of the requested file:
- 0 - file does not exist
- 1 - file is created but has not finished uploading
- 2 - file is fully uploaded
Parameters:
Parameter | Description |
---|---|
string storagePath |
Full path of the file in Filestorage |
Returns:
Parameter | Description |
---|---|
uint fileStatus |
Status of requested file |
Filestorage is represented with UNIX-based filesystem that consisted of files and directories. Directories are stored in Directory
structure that contains information about its content in ContentInfo
structure. Maximum amount of content in separate directory is 8196.
function createDirectory(string memory directoryPath)
Creates directory in Filestorage. Owner of the directory - message sender.
- Function is called by directory owner
- Maximum amount of directories and files in one directory is 8196
Parameters:
Parameter | Description |
---|---|
string directoryPath |
Path to the directory in account root directory |
function deleteDirectory(string memory directoryPath)
Deletes directory from Filestorage.
- Function is called by directory owner
Parameters:
Parameter | Description |
---|---|
string directoryPath |
Path to the directory in account root directory |
function listDirectory(string memory storagePath)
public
view
returns (ContentInfo[])
List information about content of the specific directory.
Parameters:
Parameter | Description |
---|---|
string storagePath |
Full path of the directory in Filestorage |
Returns:
Parameter | Description |
---|---|
ContentInfo[] |
Array of content stored in directory |
Object ContentInfo
can be file or directory and contains:
Field | Description |
---|---|
string name |
Content name |
bool isFile |
Whether content is file |
uint size |
File size, in bytes |
int status |
File uploading status |
bool[] isChunkUploaded |
Array with statuses of each chunk (true - chunk uploaded, false - otherwise) |
Create an .env file with following data:
ENTRYPOINT='SKALE endpoint'
PRIVATEKEY='Private key for test account'
Compile FileStorage.sol
:
truffle compile
Tests run only on SKALE chains. Create an .env file with following data:
ENTRYPOINT='SKALE endpoint'
SCHAIN_OWNER_PK='Private key of SKALE endpoint owner (or account with money)'
PRIVATEKEY='Private key for test account'
Run tests:
truffle test --network skaled