# Table

# The Features of Table

Miyabi uses permissioned tables to manage data in the world state like in most database software. Miyabi stores the world state by tables while keeping all the blocks as a record for all transactions. Each table has a unique table name for identification. The fundamental structure of the table is the Key-value pair, where the key is unique for searching values.

Each table maintains a TableDescriptor which defines various attributes of a Miyabi table. It contains metadata about the table, for example, name of the table, tracking changes to the table etc. All tables in Miyabi inherit from the TableDescriptor base class which contains three members - table name, a Boolean flag indicating whether to support the state proof generation for table data or not, and another Boolean flag which enables/disables the table history tracking.

In Miyabi, various extensions provide out of the box implementations for custom tables which can be used to store different types of data:

  • Asset Table stores the balance of each address.
  • Binary Table stores arbitrary value for arbitrary keys.
  • Entity Table contains the entity and its parent-child relationship with other entity by key.
  • NFT Table stores the owner of each non-fungible token.
  • Private Data Table stores the evidence of private data shared between nodes over a private channel.

# Permission Models

Each permissioned table in Miyabi follows a PermissionModel to execute Insert, Update (Delete is part of Update operation) and Read operation. Miyabi has Table Level and Row Level Permission. A PermissionModel is defined for each table as a combination of above two models:

PermissionModel Behavior
PermissionLess No check
CheckRowOnly Only need to pass row level check
CheckTableOnly Only need to pass table level check
TableOrRow Either table level check or row level check should pass
TableAndRow Both table level check and row level check should pass

# Table Level Permission

All custom tables are permissioned and have table-level permissions, which is defined through the TableAccessControlList in the PermissionedTableDescriptor. A TableAccessControlList stores a set of explicitly allowed addresses for each operation. For a given set of credentials, TableAccessControlList can evaluate whether permission is granted for a given operation.

# Table Owner

For any PermissionModel, all table level permissions will be granted to TableOwners. TableAccessControlList maintains non-empty list of addresses for the TableOwner, who has permission to delete this table and grant permissions to other addresses.

# Row Level Permission

Each permissioned table can define row-level permission to validate reading, updating and deletion of a row. A row-level check function is explicitly required for all permissioned tables.

# Row Owners

Row owner's signature is required to validate the row level permission check in a table.

To be noted, insert permission belongs to the table, hence if a table has PermissionModel set to CheckRowOnly, any address can create a new row, but only the row owners, if defined, can update it.

# Custom Table Permission

The CustomTablePermission includes insert, update, and read permissions. TableAccessControlList stores a collection of GrantedAddress, which stores the CustomTablePermissiongranted to various addresses. For any action if the table-level permission check is required, then apart from table owners, only the addresses stored in GrantedAddress corresponding to that action can pass the validation.

CustomTablePermissionModel AssignedBinaryValue
None 0000
Insert 0001
Update 0010
Read 0100
All 0111

# Read Restricted

A boolean ReadRestricted is presented to control the read permission check for each row. If a table is not read restricted, read permission will not be checked no matter which PermissionModel is selected. Otherwise, read operation will trigger permission checks based on the PermissionModel of the table.

# Token Table Permission

Token table (Asset Table and NFT Table) has two additional roles: TokenAdmins and TrustedEntities (AKA TrustedAddress). Token admin can generate tokens from void address, while TrustedEntities can withdraw any tokens from any user address to its address. Only table owners can grant these two roles to an address.

# Permissioned Table Descriptor

Descriptor (metadata) of all permissioned tables in Miyabi inherits from a permissioned table descriptor. It defines following properties:

Parameters Type description
TableACL TableAccessControlList Defines the table owner and other addresses' table level permissions
Name string Unique name for the table
Tracked bool Tracks the detailed transaction history of table
SupportProofs bool Allows generating the proof of an entry that can be verified by state proof
IsReadRestricted bool Defines if read permission should be checked or not
PermissionModel PermissionModel Defines how permission should be checked when updating the contents of permissioned table

# Table Interfaces

Tables are exposed through the following interfaces in smart contracts. Each table can be exposed as a reader and writer according to the context and requirements. These interfaces are available in the related module models. (i.e. Miyabi.Asset.Models)

tableInterface
Table Interfaces

# Asset Table

# Basic Information

The asset table is the table designed for recording decimal assets like digital coins. In the asset table, the key is the public key of the asset owner, and the value is asset balance in decimal.

The data stored in Asset table is as follows:

Field Description Type
Key address of the asset owner Address
Value amount of assets owned by asset owner Decimal

An asset table descriptor has the following parameters in addition to general table descriptors.

Parameters Type description
TokenAdmins IReadOnlyList<Address> Addresses that can mint token
TrustedEntities IReadOnlyList<Address> Addresses that can withdraw token from other addresses without permission checks
Rules IReadOnlyList<ValidationRule> Restrictions to the table, which will be examined by an independent verifier Kotowari
VoidAddress Address Address that is kept as a source of tokens.
Granularity AssetGranularity Includes the maximum, minimum as well as the unit of value for each move. By default, they are (, 0.01, 0.01).

# Validation Rule

The validation rule is some policies set for a table. Whenever a transaction tries to access an asset table, Kotowari will check if the operation to the table violates the validation rules. If the validation failed, all changes introduced by this transaction will be discarded.

Rule Description
Sum equal zero (default) The sum of all values in the table should be zero. E.g. balance sheet
No Negative (default) All value should not be negative (except for VoidAddress). E.g. bank account deposit
Prevent Admin Trustee (default) Prevent admins from adjusting the balances of other addresses.
Prevent Trusted Withdrawals Prevent trusted entities (listed in TrustedEntities) to withdraw from other addresses.

Each table will reserve one void address, which can only be touched by TokenAdmins to mint tokens. The void address can pump out infinity tokens, and send them to any addresses. The void address is the only address can have negative value under No Negative rule. According to the Sum Equal Zero rule, , Kotowari only need to checks . In this situation, the absolute value of all address should be equal to the absolute value of void address in any case.

The basic operations on the asset table are moving assets from one address to another address. Usually, move assets from one address require the signature of that address. TokenAdmin can move an arbitrary asset from void address to arbitrary address if Prevent Admin Trustee is not applied. The trusted address can withdraw assets from arbitrary addresses except for the void address. Also, a smart contract can use its instance Id to create an asset table and only the smart contract can modify its entry.

# Examples

An example of using asset table which includes the following operations is illustrated in Figure 11:

  1. Create an Asset table
  2. Generate assets from void address
  3. Move assets to another address

If No Negative rule is applied, all addresses other than the void address cannot have a negative value. Hence, the table owner will generate assets by moving assets from the void address which requires asset admin permission. For moving assets, either the signature of the source address is provided or the trusted address has signed the transaction. If Prevent Admin Trusted is not applied, the admin signature can also withdraw assets from arbitrary addresses.

example_of_asset_table
Figure 11. Example of Asset table usage

# Permission Model of Asset Table

For an asset table, the row permission check cannot be skipped. Hence, only CheckRowOnly and TableAndRow are allowed as the PermissionModel. For TableAndRow model asset table, two additional operations are allowed called RegisterAccount and DeleteAccount. These two operations are defined in IPermissionedAssetTableWriter which allows creating a new row for a specific address with 0 balance. This operation is not needed in CheckRowOnly model because a row can be inserted or deleted whenever someone transfers tokens to that address or the balance of the address return to 0. However, in the TableAndRow model, a row cannot be created or deleted without insert or update permission.

# Binary Table

# Basic Information

A binary table is a simple permissioned data table. In a binary table, key and value are ByteString. The value is stored within a PermissionedData together with a list of addresses who are treated as the owner of this row. If there is no owner for a row, the row permission check will always return true.

The data stored in binary table is as follows:

Field Description Type
Key Arbitrary ByteString key ByteString
Value Permissioned data containing value and owner PermissionedData<ByteString>

BinaryTableDescriptor has the same definition as PermissionedTableDescriptor

Binary tables support a special operation called UpsertRow, which will insert a row if it does not exist, otherwise update it with the new value. The permissions to be checked depending on the actual behavior is insert or update.

# Entity Table

# Basic Information

An entity table is an extended binary table optimized for storing the relationships between different entries. Each entry may link to multiple parent entries and multiple children entries to form a graph within the same table or across different entity tables. The storage rule and command for creating tables are the same as the binary table.

Field Description Type
Key Arbitrary ByteString key ByteString
Value Permissioned data containing value and owner PermissionedData<ByteString>

An entity table supports creating a link between different entity values in different entity tables. These links can be used to split data into pieces for complex management like:

  1. Grant permission arbitrarily small

    Like binary tables, each row has row owners. Since an entity table allows links to manage different rows, the user can divide one binary value into several rows and grant them to different owners.

  2. Store notes of a specific row

    Users can create rows to store notes of another row and add the row as the parent of the note rows.

  3. Optimize update only a part of a row

    According to the frequency of updating data, one user can split data into different tables and use different keys to manage the update process. The integrity of the data is guaranteed by links. One link has two components

Item Description
Parent the table name and key of the parent row
Tag identifier for a unique parent-child relationship

When a parent-child relationship is created, Miyabi will automatically add several rows to store the relationship information. In case of a parent entity, all children and corresponding tags information will be stored. Similarly, for child entity, references to the parent entity corresponding to the respective tags will be stored. The entities can form a graph of parent child relationship across different entity tables.

EntityTableDescriptor has the same definition as PermissionedTableDescriptor

# Example for Entity Table

Figure 12 shows an example of the entity table's structure.

example_of_entity_table
Figure 12. Example of Entity Table's Structure

# NFT Table

# Basic Information

A non-fungible token (NFT), is a special type of asset, which represents something unique. In Miyabi, we implement a NFT module to support NFT. NFT table stores a token Id as key and its owner as of the value.

The data stored in NFT table is as follows:

Field Description Type
Key Token Id of NFT String
Value Address of the token owner. Address

An NFT table descriptor has the following in addition to general table descriptors.

Parameters Type description
TokenAdmins IReadOnlyList<Address> Addresses that can mint token and move token arbitrarily
TrustedEntities IReadOnlyList<Address> Addresses that can claim arbitrary token

NFT table supports ERC-721 (opens new window) and provide a set of address to be trusted address like asset table. TokenAdmins can mint NFT and move token arbitrarily. In addition, TrustedEntities can change an arbitrary token's owner to itself.

Currently, the balance of an address is the number of tokens it owned. NFT table has implemented an inner table optimization for speeding up checks of the balance of one address.

# Private Data Table

# Basic Information

The Private Data module extension of Miyabi allows a subset of nodes to privately share the data among themselves. The private data is stored in the PrivateState while the hash of this private data is stored in WorldState under the "Private Data table". The hash stored in WorldState can be used to audit the existence of the actual private data in PrivateState.

The Private Data table is a permissioned table which stores the keys and values as raw ByteString. The key-value in this table is the key-value of the actual private data.

The node operators can create their own private data channel to define the members which will participate in the private data sharing. These members are called "Private Data Owners (PDOs)". The PDO members must all individually sign transactions before updating the Private State and these PDO members can be used to retrieve the raw values of the private data.

A Private transaction (different from a normal Miyabi transaction) contains a Miyabi transaction (to update the WorldState) and a payload (to update the PrivateState), where Payload represents the raw private data sent to one of the Private Data Owners.

The raw data stored in the private state of PDO members is as follows:

Field Description Type
Key Arbitrary ByteString key ByteString
Value Permissioned data containing value and owner PermissionedData<ByteString>

The hash data stored in the world state is as follows:

Field Description Type
Key Hash of the ByteString key ByteString
Value Hash of the ByteString value ByteString

A Private Data table descriptor has the following parameters in addition to general table descriptors.

Parameters Type description
PrivateDataOwners IReadOnlyList<Address> Addresses that store the evidence of private data