HomeGuidesAPI ReferenceChangelog
GuidesAPI ReferenceCommunityDiscordBlogFAQBug BountyAnnouncementsChange Log
Guides

Virtual Machine Storage

Introduction

As a Virtual Machine running on the TRON protocol, the TVM requires the ability to interact with data on the blockchain. Consequently, it must be able to help smart contracts access blockchain data.

There are two methods in which smart contracts access the blockchain:

  1. Blockchain Data (i.e. Account Data, Voting Data, Token Issuance, etc.)
  2. Smart Contract Data: Storage

Accessing Data on the Chain

During TVM running, often there are inquiries into the chain data, such as account data, and token issuance data. During TRON's development, in order to prevent regular inquiries into the chain on the hard drive, every smart contract initiation will create a related blockchain data cache. For every smart contract, the same key can only be used two times to access LevelDB, once for first time reading and again for new data (including deleting key).

Storage

Storage is for preserving smart contract status. Every contract uses its own Storage in Solidity. In Solidity, the primary commands for accessing Storage data are SLOAD and STORE.

The data in Storage is multiple Key-Value pairs, including storage-key and storage-value, and the Key-Value pair is a word (32 bytes in solidity).

In Solidity, different data types have corresponding rules for determining their structure, as referred to in this document. Solidity determines the logical structure of Storage Key. For different contracts, the same storage-key may appear, so the storage cannot be directly stored in the existing database (LevelDB) in its logical structure. In order to be more effectively combined with the chain, the physical storage on the chain must be designed accordingly.

Since access to storage in a smart contract is often just a part of the storage-key, it is better to load storage by on-demand access, rather than load all the storage into memory each time. Thus, the storage-key in each contract needs to be globally unique to be able to store it in the same database.

The logical structure of the storage-key determines the subsequent 16 bytes to ensure the uniqueness of the storage-key in the same contract. So you can use the hash of the contract address and the last 16 bytes of the storage-key to form a globally unique key. The composition logic is as follows:

input: 32-byte address hash, 32-byte storage-key
output: [Initial 16-bytes of address hash : End 16-bytes of storage-key]

example1
input:
address base58: TGtZHTi4FZHjoNzcLcD36BnAX6FMSpLaKq
address hex   : 414BE7BB5E1D250BEAF39ADB69F73527071E303375
address hash  : a59e620dbf248894f097d9a6e5bcb6a2e72ab51b3d0ec19219c45be0dfc0b47d
storage-key   : bbbbbb5be78dbadf6c4e817c6d170bbb47e9916f8f6cc4607c5f3819ce98497b
output:
Final key : a59e620dbf248894f097d9a6e5bcb6a247e9916f8f6cc4607c5f3819ce98497b

example2
input:
address base58: TGtZHTi4FZHjoNzcLcD36BnAX6FMSpLaKq
address hex   : 414BE7BB5E1D250BEAF39ADB69F73527071E303375
address hash  : a59e620dbf248894f097d9a6e5bcb6a2e72ab51b3d0ec19219c45be0dfc0b47d
storage-key   : 0000000000000000000000000000000000000000000000000000000000000001
output:
Final key : a59e620dbf248894f097d9a6e5bcb6a200000000000000000000000000000001