Skip to content

Commit 4a726ff

Browse files
AUTO: Docs repo sync - ScalarDL (#752)
* AUTO: Sync ScalarDL docs in English to docs site repo * Add tutorial about writing apps with generic contracts --------- Co-authored-by: josh-wong <joshua.wong@scalar-labs.com> Co-authored-by: Josh Wong <23216828+josh-wong@users.noreply.github.com>
1 parent 76bc4a8 commit 4a726ff

File tree

5 files changed

+279
-30
lines changed

5 files changed

+279
-30
lines changed

docs/generic-contracts-reference.mdx

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ A null value is returned if it is successful.
4545
### Examples
4646

4747
```console
48-
scalardl execute-contract --properties client.properties \
48+
scalardl generic-contracts execute-contract --properties client.properties \
4949
--contract-id object.Put \
5050
--contract-argument '{"objct_id": "a.txt", "hash_value": "a3ae11", "metadata": {"note": "something"}}'
5151
```
@@ -81,7 +81,7 @@ A null value is returned if it is successful.
8181
### Examples
8282

8383
```console
84-
scalardl execute-contract --properties client.properties \
84+
scalardl generic-contracts execute-contract --properties client.properties \
8585
--contract-id object.Put \
8686
--contract-argument '{"object_id": "a.txt", "hash_value": "a3ae11"}' \
8787
--function-id object.PutToMutableDatabase \
@@ -134,7 +134,7 @@ A JSON object that has the following fields is returned.
134134
### Examples
135135

136136
```console
137-
scalardl execute-contract --properties client.properties \
137+
scalardl generic-contracts execute-contract --properties client.properties \
138138
--contract-id object.Get \
139139
--contract-argument '{"objct_id": "a.txt"}'
140140

@@ -184,7 +184,7 @@ Each JSON object for `faulty_versions` and `corresponding_given_versions` has th
184184
If all specified hash values are the same as the ones in Ledger, the following result is returned.
185185

186186
```console
187-
scalardl execute-contract --properties client.properties \
187+
scalardl generic-contracts execute-contract --properties client.properties \
188188
--contract-id object.Validate \
189189
--contract-argument \
190190
'{"object_id": "a.txt",
@@ -206,7 +206,7 @@ Contract result:
206206
If a different hash values is found, the following result is returned.
207207

208208
```console
209-
scalardl execute-contract --properties client.properties \
209+
scalardl generic-contracts execute-contract --properties client.properties \
210210
--contract-id object.Validate \
211211
--contract-argument \
212212
'{"object_id": "a.txt",
@@ -228,7 +228,7 @@ Contract result:
228228
If the `verbose` option is specified and a different hash value and metadata are found, the following result is returned.
229229

230230
```console
231-
scalardl execute-contract --properties client.properties \
231+
scalardl generic-contracts execute-contract --properties client.properties \
232232
--contract-id object.Validate \
233233
--contract-argument \
234234
'{"object_id": "a.txt",
@@ -257,7 +257,7 @@ Contract result:
257257
If the `all` option is specified and the number of given versions are different from the number of versions stored in ScalarDL, the following result is returned.
258258

259259
```console
260-
scalardl execute-contract --properties client.properties \
260+
scalardl generic-contracts execute-contract --properties client.properties \
261261
--contract-id object.Validate \
262262
--contract-argument \
263263
'{"object_id": "a.txt",
@@ -297,7 +297,7 @@ A null value is returned if it is successful.
297297
### Examples
298298

299299
```console
300-
scalardl execute-contract --properties client.properties \
300+
scalardl generic-contracts execute-contract --properties client.properties \
301301
--contract-id collection.Create \
302302
--contract-argument '{"collection_id": "audit_set", "object_ids": ["a.txt"]}'
303303
```
@@ -323,7 +323,7 @@ A null value is returned if it is successful.
323323
### Examples
324324

325325
```console
326-
scalardl execute-contract --properties client.properties \
326+
scalardl generic-contracts execute-contract --properties client.properties \
327327
--contract-id collection.Add \
328328
--contract-argument '{"collection_id": "audit_set", "object_ids": ["a.txt"], "options": {"force": true}}'
329329
```
@@ -349,7 +349,7 @@ A null value is returned if it is successful.
349349
### Examples
350350

351351
```console
352-
scalardl execute-contract --properties client.properties \
352+
scalardl generic-contracts execute-contract --properties client.properties \
353353
--contract-id collection.Remove \
354354
--contract-argument '{"collection_id": "audit_set", "object_ids": ["a.txt"], "options": {"force": true}}'
355355
```
@@ -377,7 +377,7 @@ A JSON object that has the following field is returned.
377377
### Examples
378378

379379
```console
380-
scalardl execute-contract --properties client.properties \
380+
scalardl generic-contracts execute-contract --properties client.properties \
381381
--contract-id collection.Get \
382382
--contract-argument '{"collection_id": "audit_set"}'
383383

@@ -410,7 +410,7 @@ A JSON object that has the following fields is returned.
410410
### Examples
411411

412412
```console
413-
scalardl execute-contract --properties client.properties \
413+
scalardl generic-contracts execute-contract --properties client.properties \
414414
--contract-id collection.GetHistory \
415415
--contract-argument '{"collectionId": "audit_set", "options": {"limit": 2}}'
416416

@@ -467,7 +467,7 @@ A JSON object that has the following field is returned.
467467
### Examples
468468

469469
```console
470-
scalardl execute-contract --properties client.properties \
470+
scalardl generic-contracts execute-contract --properties client.properties \
471471
--contract-id collection.GetCheckpointInterval \
472472
--contract-argument '{}'
473473

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
---
2+
tags:
3+
- Community
4+
- Enterprise
5+
displayed_sidebar: docsEnglish
6+
---
7+
8+
# Write a ScalarDL Application with Generic Contracts
9+
10+
import JavadocLink from "/src/theme/JavadocLink.js";
11+
12+
This document explains how to write ScalarDL applications with generic contracts. You will learn how to interact with ScalarDL in your applications, handle errors, and validate your data when using generic contracts in ScalarDL.
13+
14+
## Use the ScalarDL Client SDK for generic contracts
15+
16+
You have two options to interact with ScalarDL when using generic contracts:
17+
18+
- Using [commands](scalardl-command-reference.mdx), as shown in [Use Generic Contracts and Functions](use-generic-contracts.mdx)
19+
- Using the [Java Client SDK](scalardl-java-client-sdk/README.mdx)
20+
21+
Using commands is convenient because you don't need to write applications. However, they invoke a process for each execution, which is slow, so they are mainly for quickly testing generic contracts. Instead, using the Client SDK is usually recommended when you write ScalarDL-based applications because it is more efficient.
22+
23+
The Client SDK is available on [Maven Central](https://search.maven.org/search?q=a:scalardl-java-client-sdk). You can install it in your application by using a build tool such as Gradle. For example in Gradle, you can add the following dependency to `build.gradle`, replacing `VERSION` with the version of ScalarDL that you want to use.
24+
25+
```gradle
26+
dependencies {
27+
implementation group: 'com.scalar-labs', name: 'scalardl-java-client-sdk', version: '<VERSION>'
28+
}
29+
```
30+
31+
The Client SDK APIs for generic contracts are provided by a service class called <JavadocLink packageName="scalardl-java-client-sdk" path="com/scalar/dl/client/service" className="GenericContractClientService" />. The following is a code snippet that shows how to use `GenericContractClientService` to execute a contract.
32+
33+
```java
34+
// ClientServiceFactory should always be reused.
35+
ClientServiceFactory factory = new ClientServiceFactory();
36+
37+
// ClientServiceFactory creates a new GenericContractClientService object in every create method call
38+
// but reuses the internal objects and connections as much as possible for better performance and resource usage.
39+
GenericContractClientService service = factory.createForGenericContracts(new ClientConfig(new File(properties));
40+
try {
41+
// create an application-specific argument that matches the generic contract specification
42+
JsonNode jsonArgument = ...;
43+
ContractExecutionResult result = service.executeContract(contractId, jsonArgument);
44+
result.getContractResult().ifPresent(System.out::println);
45+
} catch (ClientException e) {
46+
System.err.println(e.getStatusCode());
47+
System.err.println(e.getMessage());
48+
}
49+
50+
factory.close();
51+
```
52+
53+
You should always use `ClientServiceFactory` to create `GenericContractClientService` objects. `ClientServiceFactory` caches objects that are required to create `GenericContractClientService` and reuses them on the basis of the given configurations, so `ClientServiceFactory` object should always be reused.
54+
55+
`GenericContractClientService` is a thread-safe client that interacts with ScalarDL components, like Ledger and Auditor, to register certificates, register contracts, execute contracts, and validate data. When you execute a generic contract, you need to specify a `JsonNode` argument. For details about the specification of the input argument, see [Generic Contracts and Functions Reference Guide](generic-contracts-reference.mdx).
56+
57+
:::warning
58+
59+
Do not register and execute your custom contracts through `GenericContractClientService`. Using the generic contracts and your original contracts together is not supported because the proper asset management cannot be guaranteed.
60+
61+
:::
62+
63+
For more information about `ClientServiceFactory` and `GenericContractClientService`, see the [`scalardl-java-client-sdk` Javadoc](https://javadoc.io/doc/com.scalar-labs/scalardl-java-client-sdk/latest/index.html).
64+
65+
## Handle errors
66+
67+
If an error occurs in your application, the Client SDK will return an exception with a status code and an error message with an error code. You should check the status code and the error code to identify the cause of the error. For details about the status code and the error codes, see [Status codes](how-to-write-applications.mdx#status-codes) and [Error codes](how-to-write-applications.mdx#error-codes).
68+
69+
### Implement error handling
70+
71+
The SDK throws <JavadocLink packageName="scalardl-java-client-sdk" path="com/scalar/dl/client/exception" className="ClientException" /> when an error occurs. You can handle errors by catching the exception as follows:
72+
73+
```java
74+
GenericContractClientService clientService = ...;
75+
try {
76+
// interact with ScalarDL through a ClientService object
77+
} catch (ClientException) {
78+
// e.getStatusCode() returns the status of the error
79+
}
80+
```
81+
82+
## Validate your data
83+
84+
In ScalarDL, you occasionally need to validate your data to make sure all the data is in a valid state. Since you can learn the basics of how ScalarDL validates your data in [Write a ScalarDL Application in Java](how-to-write-applications.mdx#validate-your-data), this section mainly describes differences between the `validateLedger` method in the regular `ClientService` and the `validateLedger` method in `GenericContractClientService`.
85+
86+
When validating assets created by generic contracts, you need to specify the type of the asset and a list of keys to identify the asset. Currently, generic contracts create two types of assets: an object (`AssetType.OBJECT`) and a collection (`AssetType.COLLECTION`). For keys, you can specify the object ID or collection ID.
87+
88+
An example code for validating an object is as follows:
89+
90+
```java
91+
GenericContractClientService service = ...
92+
try {
93+
LedgerValidationResult result = service.validateLedger(AssetType.OBJECT, ImmutableList.of("an_object_ID"));
94+
// You can also specify age range.
95+
// LedgerValidationResult result = service.validateLedger(AssetType.OBJECT, ImmutableList.of("an_object_ID"), startAge, endAge);
96+
} catch (ClientException e) {
97+
}
98+
```
99+
100+
:::note
101+
102+
Generic contracts internally assign a dedicated asset ID to an [asset record](data-modeling.mdx#asset-record) that represents an object or a collection. The asset ID consists of a prefix for the asset type and keys; for example, a prefix `o_` and an object ID for `AssetType.OBJECT`. Therefore, you will see such raw asset IDs in `AssetProof` in `LedgerValidationResult`.
103+
104+
:::
105+
106+
## Use other languages
107+
108+
To interact with ScalarDL in languages other than Java, you can use ScalarDL Gateway.
109+
110+
:::note
111+
112+
Documentation for ScalarDL Gateway is currently being created and will be ready in the near future.
113+
114+
:::

docs/scalardl-command-reference.mdx

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ This page introduces `scalardl`, which is a client command for interacting with
2424
- [`list-contracts`](#list-contracts): List registered contracts.
2525
- **Validate a ledger**
2626
- [`validate-ledger`](#validate-ledger): Validate a specified asset in a ledger.
27+
- **Run commands for generic-contracts**
28+
- [`generic-contracts`](#generic-contracts): Run commands for a generic-contracts-based setup.
2729

2830
## `register-cert`
2931

@@ -255,6 +257,132 @@ Validate an asset from age 0 to age 10 only.
255257
scalardl validate-ledger --properties client.properties --asset-id 'some_asset,0,10'
256258
```
257259

260+
## `generic-contracts`
261+
262+
Run commands for a generic-contracts-based setup, which are almost the same subcommands for the `scalardl` command. The only difference is in the `validate-ledger` subcommand, where you can specify assets by object IDs of the generic-contracts context instead of the raw asset IDs. For the other subcommands, see each corresponding command in the following [Subcommands](#subcommands) section.
263+
264+
:::tip
265+
266+
You can also use the `scalardl-gc` top-level command and the `gc` subcommand as aliases of the `generic-contracts` subcommand.
267+
268+
:::
269+
270+
### Subcommands
271+
272+
| Subcommand | Description |
273+
|:------------------------------------------------------------|:----------------------------------------|
274+
| [`register-cert`](#register-cert) | Register a specified certificate. |
275+
| [`register-secret`](#register-secret) | Register a specified secret. |
276+
| [`register-contract`](#register-contract) | Register a specified contract. |
277+
| [`register-contracts`](#register-contracts) | Register multiple specified contracts. |
278+
| [`register-function`](#register-function) | Register a specified function. |
279+
| [`register-functions`](#register-functions) | Register multiple specified functions. |
280+
| [`execute-contract`](#execute-contract) | Execute a specified contract. |
281+
| [`list-contracts`](#list-contracts) | List the registered contracts. |
282+
| [`validate-ledger`](#validate-ledger-for-generic-contracts) | Validate a specified asset in a ledger. |
283+
284+
### `validate-ledger` for generic contracts
285+
286+
Validate a specified [asset](data-modeling.mdx#asset) in a ledger.
287+
288+
:::note
289+
290+
Generic contracts internally assign a dedicated asset ID to an [asset record](data-modeling.mdx#asset-record) that represents an object or collection. The asset ID consists of a prefix for the asset type and keys; for example, a prefix `o_` and an object ID for an object. Therefore, you will see such raw asset IDs after running the `validate-ledger` command.
291+
292+
:::
293+
294+
#### Options
295+
296+
| Option | Description |
297+
|:---------------------------|:---------------------------------------------------------------------|
298+
| `--config`, `--properties` | A configuration file in the .properties format. |
299+
| `--object-id` | The ID of an object created by the `object.Put` contract. |
300+
| `--collection-id` | The ID of a collection created by the `collection.Create` contract. |
301+
| `--start-age` | The validation start age of the asset (optional). |
302+
| `--end-age` | The validation end age of the asset (optional). |
303+
304+
[Common utility options](#common-utility-options) are also available.
305+
306+
### Examples for using subcommands
307+
308+
Register a specified certificate. For available options, see [`register-cert`](#register-cert).
309+
310+
```console
311+
scalardl generic-contracts register-cert --properties client.properties
312+
```
313+
314+
Register a specified secret. For available options, see [`register-secret`](#register-secret).
315+
316+
```console
317+
scalardl generic-contracts register-secret --properties client.properties
318+
```
319+
320+
Register a specified contract. For available options, see [`register-contract`](#register-contract).
321+
322+
```console
323+
scalardl generic-contracts register-contract --properties client.properties --contract-id StateUpdater --contract-binary-name com.org1.contract.StateUpdater --contract-class-file build/classes/java/main/com/org1/contract/StateUpdater.class
324+
```
325+
326+
Register specified contracts. For available options, see [`register-contracts`](#register-contracts).
327+
328+
```console
329+
scalardl generic-contracts register-contracts --properties client.properties --contracts-file /path/to/contracts-file
330+
```
331+
332+
Register a specified function. For available options, see [`register-function`](#register-function).
333+
334+
```console
335+
scalardl generic-contracts register-function --properties client.properties --function-id test-function --function-binary-name com.example.function.TestFunction --function-class-file /path/to/TestFunction.class
336+
```
337+
338+
Register specified functions. For available options, see [`register-functions`](#register-functions).
339+
340+
```console
341+
scalardl generic-contracts register-functions --properties client.properties --functions-file /path/to/functions-file
342+
```
343+
344+
Execute a specified contract. For available options, see [`execute-contract`](#execute-contract).
345+
346+
```console
347+
scalardl generic-contracts execute-contract --properties client.properties --contract-id object.Put --contract-argument '{"object_id": "a.txt", "hash_value": "b97a42c87a46ffebe1439f8c1cd2f86e2f9b84dad89c8e9ebb257a19b6fdfe1c", "metadata": {"note": "updated"}}'
348+
```
349+
350+
List registered contracts. For available options, see [`list-contracts`](#list-contracts).
351+
352+
```console
353+
scalardl generic-contracts execute-contract --properties client.properties
354+
```
355+
356+
Validate an object for all ages.
357+
358+
```console
359+
scalardl generic-contracts validate-ledger --properties client.properties --object-id 'a.txt'
360+
```
361+
362+
Validate an object from age 0 to age 10 only.
363+
364+
```console
365+
scalardl generic-contracts validate-ledger --properties client.properties --object-id 'a.txt' --start-age 0 --end-age 10
366+
```
367+
368+
Validate a collection for all ages.
369+
370+
```console
371+
scalardl generic-contracts validate-ledger --properties client.properties --collection-id 'audit_set'
372+
```
373+
374+
Use the top-level command `scalardl-gc` as the alias of `scalardl generic-contracts`.
375+
376+
```console
377+
scalardl-gc validate-ledger --properties client.properties --object-id 'a.txt'
378+
```
379+
380+
Use the subcommand `scalardl gc` as the alias of `scalardl generic-contracts`.
381+
382+
```console
383+
scalardl gc validate-ledger --properties client.properties --object-id 'a.txt'
384+
```
385+
258386
## Common utility options
259387

260388
You can use the following options in all the commands above.

0 commit comments

Comments
 (0)