Skip to main content

Storage costs

In Massa, each network node maintains a full copy of the ledger. To prevent the requirement of massive storage capacities, a ledger-size limit of 10TB has been set. This limit is essential to encourage widespread adoption and enable users to run nodes from their homes. To ensure compliance with this limit, a mechanism has been established that correlates storage space with locked coins.

For every byte of storage space claimed, whether it's for storing address and balance information, keys in the datastore, bytecode, or other data elements, users are required to lock a corresponding amount of coins. These locked coins act as a commitment and are released when the allocated storage space is released.

To determine the amount of coins needed to lock for each byte of storage, the value of 0.0001 Massa coin (MAS) has been chosen. This value ensures that if all of the total initial coin supply (1,000,000,000 MAS) is locked for storage only, the 10TB limit is reached and no account can push this limit further because there are no more coins available.

The initial ledger entry for address and balance incurs a cost of 0.001 MAS.

Datastore entries also occupy space:

  • a base size of 4 bytes that represents the average storage used for storing an empty key-value entry
  • the length of the key
  • the length of the value

To calculate the storage cost for a specific address in the ledger, the formula includes the address size, balance constant, bytecode length, and the sum of constants for each datastore key and its corresponding value size.

The overall formula is:

CostMAS=0.001+0.0001BytecodeSize+0.0001i(4+DataStoreKeySizei+DatastoreValueSizei)Cost_{MAS} = 0.001 + 0.0001 * BytecodeSize + 0.0001 * \sum_i (4 + DataStoreKeySize_i + DatastoreValueSize_i)

It's important to note that the storage costs are always paid by the address that initiates the Application Binary Interface (ABI) call. For example, if the ABI functions setBytecode or setBycodeOf are used, the associated storage costs will be charged to the address making the call.

Examples

Transferring coins to a non-existing account

When creating a new account in Massa, a minimum of 0.001 MAS needs to be sent alongside the operation that creates the new account (e.g., a transfer). This cost covers the creation of the address and its associated balance.

You create a new account using the Massa Client massa-client, you can generate a secret key (wallet_generate_secret_key)) and verify its address using the wallet_info function. However, that operation is done fully offline and the new account does not appear in the blockchain just yet.

Now imagine a sender account wants to send 10 MAS to your new account using a Transaction operation transferring 10 MAS to your newly generated address. Since the newly created account is not in the state just yet, 0.001 coins from the transferred amount are reserved for writing the account address and balance, and your newly created account's balance becomes 9.999. Note that if the transferred amount is lower than 0.001 MAS, the new destination account can not be written and the operation payload run fails.

In any subsequent transfers towards your now-written account, no coins will be reserved for storage and you will receive the full transferred amount.

Datastore handling in a smart contract

Suppose you want to store your username "kevin" under the key "username" in the datastore of an existing account, both in utf-8 bytes. The value is 5 bytes long and the key is 8 bytes long and we assume that that entry did not exist before in the datastore of the account. In that case, you need to send an operation that creates this new entry in your datastore using a Smart Contract. Storing the entry locks 0.0001 * (4 + 8 + 5) = 0,0017 MAS coins.

Now suppose that you change that existing entry to a new nickname "kev". The new value is shorter: freeing 2 bytes causes 0.0001 * 2 = 0.0002 coins to be refunded.

Now let's change the nickname again from "kev" to "ned". This does not change the datastore size and does not change the coin balance.

Now, let's change the nickname again from "ned" to "pierre". This uses 3 extra byte and therefore locks 0.0001 * 3 = 0.0003 MAS coins.

In case you then delete the "nickname" datastore entry (with the "pierre" value), 0.0001 * (4 + 8 + 6) = 0.0018 coins are refunded.

info

In the case of a refund for storage costs, the address that receives the refund is the one that initiates the ABI call (setBytecode or setBycodeOf for example), which may differ from the address that initially paid for the storage.

If you are a Smart Contract developer and want your users to cover the storage costs for your contract, you can utilize the coins passed via the "coins" parameter of the "CallSC" operation. Additionally, you can save their addresses in your datastore to facilitate future refunds.