実行環境
- Ubuntu16.04LTS
- Oracle Java 8
- Gradle 4.10.2
Scalar DLとは
Scalar社が開発した、ブロックチェーンにヒントを得た分散型台帳プラットフォームソフトウェア。
詳しく知りたい場合はこちら
Scalar DLT | Scalar, Inc.
Scalar DL Docs
emulatorとは
Scalar DL Emulator とは、Scalar社が提供するScalar DLのコントラクト、ファンクションの実行をエミュレーションするソフトウェア。
詳細はこちら
Scalar DL emulator - GitHub
Scalar DLのコントラクトを実行するためには、docker環境やSandbox環境で実行環境を用意してコントラクトを登録する必要があるが、コントラクトを登録・実行する場合、Scalar DLの制約としてコントラクトID・FunctionIDを一意にしなければならなかったり、登録したコントラクトの変更や削除ができなかったりする。そのためコントラクトやFunctionのちょっとした修正のたびに一意なIDの設定・登録の作業等が必要になり、開発・テストの効率が下がるという面があった。
しかし、emulatorを用いることでローカルのメモリ内で疑似的にScalar DLを実行できるので、Functionが操作する事前のスキーマ定義やコントラクトの再登録時の制約を(あまり)気にしなくてよくなり、emulatorを終了させると内容がクリアされるために気軽に何度もコントラクトの実行をテストすることができるようになる。
ただし、emulatorには実際のScalar DLにある改ざん検知機能がないなどいくつかの機能制限があり、また外部アプリケーションからの接続テストが出来ないという点には注意が必要である。
※Sandbox環境を利用すれば外部アプリケーションからコントラクトを実行可能だが、Functionは未対応。
Function
についての説明はこちら
Dockerを利用してScalar DLを使ってみた
環境構築
githubからemulatorをダウンロード
$ git clone https://github.com/scalar-labs/scalardl-tools.git
$ cd scalardl-tools-master/emulator
ツールのビルド
$ ./gradlew installDist
成功すると/build/install/emulator/bin
に実行可能ファイルが作成される
emulatorの起動
$ ./build/install/emulator/bin/emulator
emulatorコンソールが表示されれば成功
exit
またはCtrl+dで終了する
ファイルを指定しながらemulatorを起動することで、複数のコマンドを一度に実行することもできる
$ ./build/install/emulator/bin/emulator -f cmds.txt
ヘルプの表示
$ ./build/install/emulator/bin/emulator -h
またはemulatorコンソール上でhelp
サンプルコントラクト・Functionの実行
コントラクトの準備
サンプルとして最初からディレクトリに置かれているStateUpdater.java
を使用する
src/main/java/com/scalar/client/tool/emulator/contract/StateUpdater.java
Functionの準備
Functionを置くディレクトリを作成する
$ mkdir src/main/java/com/scalar/client/tool/emulator/function
$ vi src/main/java/com/scalar/client/tool/emulator/function/SchemaUpdater.java
package com.scalar.client.tool.emulator.function;
import com.scalar.database.api.Get;
import com.scalar.database.api.Put;
import com.scalar.database.api.Result;
import com.scalar.database.io.IntValue;
import com.scalar.database.io.Key;
import com.scalar.database.io.TextValue;
import com.scalar.ledger.database.MutableDatabase;
import com.scalar.ledger.udf.Function;
import java.util.Optional;
import javax.json.JsonObject;
public class SchemaUpdater extends Function {
@Override
public void invoke(
MutableDatabase database,
JsonObject contractArgument,
Optional<JsonObject> functionArgument) {
String userId = functionArgument.get().getString("user_id");
int state = contractArgument.getInt("state");
String assetId = contractArgument.getString("asset_id");
Get get =
new Get(
new Key(new TextValue("user_id",userId)),
new Key(new IntValue("state",state)))
.forNamespace("test")
.forTable("test_schema");
database.get(get);
Put put =
new Put(
new Key(new TextValue("user_id",userId)),
new Key(new IntValue("state",state)))
.withValue(new TextValue("value",assetId))
.forNamespace("test")
.forTable("test_schema");
database.put(put);
}
}
コントラクト・Functionの登録
コントラクトとFunctionはそれぞれ、実行前に一意なIDで登録しておく必要がある。登録にはID、クラス名、クラスファイルのパスが必要。
コントラクトの登録
scalar> register state-updater com.scalar.client.tool.emulator.contract.StateUpdater ./build/classes/java/main/com/scalar/client/tool/emulator/contract/StateUpdater.class
Functionの登録
scalar> register-function schema-updater com.scalar.client.tool.emulator.function.SchemaUpdater ./build/classes/java/main/com/scalar/client/tool/emulator/function/SchemaUpdater.class
コントラクトの実行
"_functions_"
に配列形式で実行するFunctionのIDを指定する。複数のFunctionを一度に実行することもできる。
scalar> execute state-updater {"asset_id": "XXX", "state": 1, "_functions_": ["schema-updater"]} -fa {"user_id":"test_user"}
※-fa(-function-argument)で指定するJSON文字列にはスペースを入れないこと。エラーが発生する。
コントラクトの実行結果の確認
emulatorにはget,put,scanの3つのコントラクトがデフォルトで登録されており、特別に定義をせずに使えるようになっている。
scalar> get XXX
"state": 1
と表示される
Functionの実行結果の確認
database
コマンドで登録された値を確認する
scalar> database -p={"user_id":"test_user"} -c={"state":1} -t=test_schema -n=test get
{"value":"XXX"}
と表示される