A storage provider is a service that stores files for a fee.
You can download
storage-daemon-cli for Linux/Windows/MacOS binaries from TON Auto Builds.
Compile from sources
You can compile
storage-damon-cli from sources using this instruction.
It consists of a smart contract that accepts storage requests and manages payment from clients, and an application that uploads and serves the files to clients. Here's how it works:
- The owner of the provider launches the
storage-daemon, deploys the main smart contract, and sets up the parameters. The contract's address is shared with potential clients.
- Using the
storage-daemon, the client creates a Bag from their files and sends a special internal message to the provider's smart contract.
- The provider's smart contract creates a storage contract to handle this specific Bag.
- The provider, upon finding the request in the blockchain, downloads the Bag and activates the storage contract.
- The client can then transfer payment for storage to the storage contract. To receive the payment, the provider regularly presents the contract with proof that they are still storing the Bag.
- If the funds on the storage contract run out, the contract is considered inactive and the provider is no longer required to store the Bag. The client can either refill the contract or retrieve their files.
The client can also retrieve their files at any time by providing proof of ownership to the storage contract. The contract will then release the files to the client and deactivate itself.
Using a Provider by Clients
In order to use a storage provider, you need to know the address of its smart contract. The client can obtain the provider's parameters with the following command in
The provider's parameters:
- Whether new storage contracts are accepted.
- Minimum and maximum Bag size (in bytes).
- Rate - the cost of storage. Specified in nanoTON per megabyte per day.
- Max span - how often the provider should provide proofs of Bag storage.
A request to store
You need to create a Bag and generate a message with the following command:
new-contract-message <BagID> <file> --query-id 0 --provider <address>
Executing this command may take some time for large Bags. The message body will be saved to
<file> (not the entire internal message). Query id can be any number from 0 to
2^64-1. The message contains the provider's parameters (rate and max span). These parameters will be printed out after executing the command, so they should be double checked before sending. If the provider's owner changes the parameters, the message will be rejected, so the conditions of the new storage contract will be exactly what the client expects.
The client must then send the message with this body to the provider's address. In case of an error the message will come back to the sender (bounce). Otherwise, a new storage contract will be created and the client will receive a message from it with
op=0xbf7bd0c1 and the same query id.
At this point the contract is not yet active. Once the provider downloads the Bag, it will activate the storage contract and the client will receive a message with
op=0xd4caedcd (also from the storage contract).
The storage contract has a "client balance" - these are the funds that the client transferred to the contract and which have not yet been paid to the provider. Funds are gradually debited from this balance (at a rate equal to the rate per megabyte per day). The initial balance is what the client transferred with the request to create the storage contract. The client can then top up the balance by making simple transfers to the storage contract (this can be done from any address). The remaining client balance is returned by the
get_storage_contract_data get method as the second value (
The contract may be closed for the following cases:
In case of the storage contract being closed, the client receives a message with the remaining balance and
- Immediately after creation, before activation, if the provider refuses to accept the contract (the provider's limit is exceeded or other errors).
- The client balance reaches 0.
- The provider can voluntarily close the contract.
- The client can voluntarily close the contract by sending a message with
op=0x79f937eafrom its own address and any query id.
Running and Configuring a Provider
The Storage Provider is part of the
storage-daemon, and is managed by the
storage-daemon needs to be started with the
Create a main smart contract
You can do this from
You will be asked to send a non-bounceable message with 1 TON to the specified address in order to initialize the provider. You can check that the contract has been created using the
By default, the contract is set to not accept new storage contracts. Before activating it, you need to configure the provider. The provider's settings consist of a configuration (stored in
storage-daemon) and contract parameters (stored in the blockchain).
max contracts- maximum number of storage contracts that can exist at the same time.
max total size- maximum total size of Bags in storage contracts. You can view the configuration values using
get-provider-info, and change them with:
set-provider-config --max-contracts 100 --max-total-size 100000000000
accept- whether to accept new storage contracts.
max file size,
min file size- size limits for one Bag.
rate- storage cost (specified in nanoTONs per megabyte per day).
max span- how often the provider will have to submit storage proofs.
You can view the parameters using
get-provider-info, and change them with:
set-provider-params --accept 1 --rate 1000000000 --max-span 86400 --min-file-size 1024 --max-file-size 1000000000
It is worth paying attention
Note: in the
set-provider-params command, you can specify only some of the parameters. The others will be taken from the current parameters. Since the data in the blockchain is not updated instantly, several consecutive
set-provider-params commands can lead to unexpected results.
It is recommended to initially put more than 1 TON on the provider's balance, so that there are enough funds to cover the commissions for working with storage contracts. However, do not send too many TONs with the first non-bounceable message.
After setting the
accept parameter to
1, the smart contract will start accepting requests from clients and creating storage contracts, while the storage daemon will automatically process them: downloading and distributing Bags, generating storage proofs.
Further Work With the Provider
List of existing storage contracts
get-provider-info --contracts --balances
Each storage contract has a
Contract$ balance listed; the difference between them can be withdrawn to the main provider contract with the command
withdraw-all will withdraw funds from all contracts that have at least
1 TON available.
Any storage contract can be closed with the command
close-contract <address>. This will also transfer the funds to the main contract. The same will happen automatically when the client's balance runs out. The Bag files will be deleted in this case (unless there are other contracts using the same Bag).
You can transfer funds from the main smart contract to any address (the amount is specified in nanoTON):
send-coins <address> <amount>
send-coins <address> <amount> --message "Some message"
All Bags stored by the provider are available with the command
list, and can be used as usual. To prevent disrupting the provider's operations, do not delete them or use this storage daemon to work with any other Bags.