Smart Contract Storage
What is a smart contract storage?
Each smart contract deployed on the Neo blockchain owns a private storage where only the contract itself can read, write, modify, and delete data. Data in the storage is stored in the form of key-value pairs, where Key can be a string or a byte array (ByteArray) and Value can be any type. For more information refer to Storage Class .
In Neo, most storage operations are performed through StorageMap , which appends a prefix to the Storage Key. Different prefixes are equivalent to different database tables. Using StorageMap to operate the storage is more safely.
Smart contract storage operations include the following interfaces:
-
Storage.Find()
:traverses all records in the storage -
Storage.Get()
:returns a specific record according to the specified key -
Storage.Put()
:modifies or writes a new record according to the specified key -
Storage.Delete()
:deletes the record according to the specified key
Usually the contract can only read and write data in its own storage, but there are exceptions:
-
In the case that contracts invokes each other, the invoked contract can access the caller's storage via cross-domain requests if it has been authorized by the caller.
-
For the child contract that is dynamically created at contract runtime, the parent contract gets the read-write access to the child contract's storage immediately.
Declaring StorageMap
If the storage of a contract is equivalent to a database, then StorageMap is equivalent to the tables in that database.
To declare StorageMap:
or
Storage operations
Refer to the Storage and StorageMap classes. The class Helper provides StorageMap with extended methods for storage operations. Here are some code examples.
Write and modify
Without StorageMap:
With StorageMap:
Query
Without StorageMap:
With StorageMap:
Delete
Without StorageMap:
With StorageMap:
Traverse
Demo: a blockchain storage contract
This section we are going to write a simple blockchain storage contract using the Neo smart contract APIs such as Storage , StorageMap , Helper , and etc, and invoke it on the blockchain.
Writing the contract
This contract has a storage in the following structure:
-
key: message as string type;
-
value: block height as unit type
This contract contains these methods:
-
put
: Puts the message into the storage -
get
: Gets the message from the storage -
exists
: Checks if there is message in the storage
Here is the code:
Where [DisplayName("getSavedBlock")]
is for compatibility with the method naming rules of smart contracts (Camel) and C # method naming rules (Pascal).
The name in [DisplayName("getSavedBlock")]
can be found in the manifest.json file. It should be the same as the method name that determines a go-to in the main method.
In a smart contract, the number of cases in the Main() switch statement must not exceed 7, otherwise an error will be reported when the contract is invoked even it can be compiled through. In that case the if statement is recommended.
If you use StorageMap, you must declare StorageMap inside the method as a local variable, otherwise an error will be reported when the contract is invoked even it can be compiled through.
Invoking the contract
In Neo-CLI command line invoke the contract, as follows: