Use Table-Oriented Generic Contracts
Table-oriented generic contracts in ScalarDL are a type of generic contract that provide a data model similar to the relational data model and a user-friendly interface for managing ledger data, enabling easy application development. This guide explains how to use table-oriented generic contracts.
The table-oriented generic contracts are currently in Private Preview, which means that future versions might have backward-incompatible updates.
Set up an environment
In this section, you'll set up the environment for using the table-oriented generic contracts through the ScalarDL client tools. If you want to interact with generic contracts and functions in your applications, you can use the ScalarDL Client SDK APIs. For details, see Write a ScalarDL Application with Generic Contracts. In addition, the SQL-based interface will be provided in the near future.
Install a JDK
In this guide, you'll only use a Java runtime environment for seeing how generic contracts and functions work. However, it is recommended that you install one of the following Java Development Kits (JDKs), which will be required to build your own ScalarDL application outside of this guide.
- Oracle JDK LTS version (8, 11, or 17)
- OpenJDK LTS version (8, 11, or 17)
Set up a ScalarDL environment
Set up a ScalarDL environment that meets your own requirements. If you want to deploy ScalarDL in a local test environment, you can deploy such an environment by using a sample Docker Compose configuration and Scalar Helm Chart. For details, see the following:
For a production environment, ScalarDL is available as container images. For details, see How to get the container images of Scalar products.
The table-oriented generic contracts are supported in ScalarDL version 3.11 or later versions.
Download the necessary tools and the generic contracts
Specify a ScalarDL version that is equal to or greater than 3.11.0 by running the following command. For available versions, see Tags.
VERSION=X.Y.Z
Also, specify the table-oriented generic contract version by running the following command. Use the following mapping table to identify the version corresponding to the ScalarDL version. Make sure to replace the separator .
to _
, for example, 1_0_0
for the version 1.0.0
.
ScalarDL Version | Table-Oriented Generic Contract Version |
---|---|
3.11.0 | 1.0.0 |
TGC_VERSION=X_Y_Z
Then, clone the client SDK repository and download the tools and the generic contracts by running the following commands:
git clone https://github.com/scalar-labs/scalardl-java-client-sdk.git
cd scalardl-java-client-sdk
git checkout v$VERSION
curl -OL https://github.com/scalar-labs/scalardl-java-client-sdk/releases/download/v$VERSION/scalardl-java-client-sdk-$VERSION.zip
unzip scalardl-java-client-sdk-$VERSION.zip
mv scalardl-java-client-sdk-$VERSION client
curl -OL https://github.com/scalar-labs/scalardl/releases/download/v$VERSION/scalardl-generic-contracts-$VERSION.zip
unzip scalardl-generic-contracts-$VERSION.zip
mv scalardl-generic-contracts-$VERSION generic-contracts
Register a certificate and the table-oriented generic contracts
This section describes how to register a certificate and the generic contracts.
Configure the properties
To interact with the ScalarDL components, you need to configure the client properties. For details, see Configure properties.
Register a certificate or secret
Prepare a certificate for registration. For details, see How to get a certificate.
Then, register your certificate by using the ScalarDL client CLI as follows:
client/bin/scalardl generic-contracts register-cert --properties client.properties
You can also use HMAC authentication instead of using a certificate. For details about HMAC authentication, see ScalarDL Authentication Guide.
Register the table-oriented generic contracts
After registering the certificate, you can register the table-oriented generic contracts by running the following commands:
client/bin/scalardl generic-contracts register-contracts --properties client.properties --contracts-file generic-contracts/conf/table-authenticity-management-contracts.toml
Interact with table-oriented generic contracts
Now you can execute the table-oriented generic contracts. In this section, you'll try the following functionalities through two sample tables (employee
and department
) that can be joined through the department IDs of employees.
Create and show tables
You can create the samples table by running the following commands:
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Create \
--contract-argument '{"name": "employee", "key": "id", "type": "string", "indexes": [{"key": "department", "type": "string"}]}'
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Create \
--contract-argument '{"name": "department", "key": "id", "type": "string"}'
When creating a table, you need to specify the name and the primary key. You can additionally specify the secondary indexes. string
, number
, and boolean
are supported as the data type of the primary key and index key.
You can show the created tables by running the following commands:
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.ShowTables \
--contract-argument '{}'
You should get a result like the following:
Contract result:
[ {
"name" : "employee",
"key" : "id",
"type" : "string",
"indexes" : [ {
"key" : "department",
"type" : "string"
} ]
}, {
"name" : "department",
"key" : "id",
"type" : "string",
"indexes" : [ ]
} ]
Insert records
Next, insert several employee
records by running the following commands:
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Insert \
--contract-argument '{"table": "employee", "values": {"id": "1001", "name": "Alice", "department": "sales", "salary": 654.3}}'
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Insert \
--contract-argument '{"table": "employee", "values": {"id": "1002", "name": "Bob", "department": "sales", "salary": 543.2}}'
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Insert \
--contract-argument '{"table": "employee", "values": {"id": "1003", "name": "Carol", "department": "engineering", "salary": 654.3}}'
Insert the corresponding department
records as well by running the following commands:
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Insert \
--contract-argument '{"table": "department", "values": {"id": "sales", "location": "Shinjuku", "phone": "000-1234"}}'
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Insert \
--contract-argument '{"table": "department", "values": {"id": "engineering", "location": "Shibuya", "phone": "000-4321"}}'
Select records
Then, check the inserted records. You need to specify at least a primary key or index key to select records. For example, you can get an employee
record by specifying the primary key by running the following commands:
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Select \
--contract-argument '{"table": "employee", "conditions": [ {"column": "id", "value": "1001", "operator": "EQ"} ], "projections": [ "id", "name", "department" ]}'
You can optionally project the columns by specifying top-level fields in the JSON record object. You should get a result like the following:
Contract result:
[ {
"id" : "1001",
"name" : "Alice",
"department" : "sales"
} ]
You can also specify an index key to select records by running the following commands:
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Select \
--contract-argument '{"table": "employee", "conditions": [ {"column": "department", "value": "sales", "operator": "EQ"} ], "projections": [ "id", "name", "department" ]}'
You should get a result like the following:
Contract result:
[ {
"id" : "1001",
"name" : "Alice",
"department" : "sales"
}, {
"id" : "1002",
"name" : "Bob",
"department" : "sales"
} ]
If you want to filter records, specify additional conditions by running the following commands:
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Select \
--contract-argument '{"table": "employee", "conditions": [ {"column": "department", "value": "sales", "operator": "EQ"}, {"column": "salary", "value": 600, "operator": "LT"} ]}'
For the additional filters, you can use operators: EQ
(equal), NE
(not equal), LT
(less than), LTE
(less than or equal), GT
(greater than), GTE
(greater than or equal), IS_NULL
, and IS_NOT_NULL
. You should get a result like the following:
Contract result:
[ {
"id" : "1002",
"name" : "Bob",
"department" : "sales",
"salary" : 543.2
} ]
You can also join the two tables by running the following commands:
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Select \
--contract-argument '{ "table": "employee", "joins": [ { "table": "department", "left": "employee.department", "right": "department.id" } ], "conditions": [ {"column": "employee.department", "value": "engineering", "operator": "EQ"} ] }'
You should get a result like the following:
Contract result:
[ {
"employee.id" : "1003",
"employee.name" : "Carol",
"employee.department" : "engineering",
"employee.salary" : 654.3,
"department.id" : "engineering",
"department.location" : "Shibuya",
"department.phone" : "000-4321"
} ]
Update records
You can update the employee
records by running the following commands:
client/bin/scalardl generic-contracts execute-contract --properties client.properties \
--contract-id table.v${TGC_VERSION}.Update \
--contract-argument '{ "table": "employee", "values": {"salary": 754.3}, "conditions": [ {"column": "department", "value": "sales", "operator": "EQ"} ] }'
Make sure to specify at least a primary key or an index key to update the records, in the same way as using the Select
contract.