[JAVA] Ich habe versucht, Scalar DL mit Docker zu verwenden

Der Text wurde überarbeitet, da der Name des UDF-Begriffs in Funktion geändert wurde. (2020/1/10)

Was ist Scalar DL?

Von Scalar entwickelte Blockchain-inspirierte Software für verteilte Hauptbuchplattformen.

(Referenz) Scalar DLT | Scalar, Inc. Scalar DL Docs

Ähnlich wie Blockchain, da es manipulationssicher und dezentral ist, verfügt Scalar DL über die folgenden zusätzlichen Funktionen:

Gleichzeitig werden einige Einschränkungen festgelegt, um ein unbeabsichtigtes Vertragsverhalten von Designern und Entwicklern zu verhindern.

Das Ausführungsergebnis des von Scalar DL ausgeführten Smart Contract wird von Scalar DB verwaltet, der vom Unternehmen entwickelten Software für die verteilte Datenbankverwaltung.

Versuchen Sie, Scalar DB unter WSL Ubuntu (Environment Construction) auszuführen

Dieses Mal wurde dieser Scalar DL aktualisiert, und es wurde gesagt, dass ein einzigartiger Mechanismus namens Function (später beschrieben), den andere Blockchains und ähnliche Dienste nicht haben, hinzugefügt wurde, also habe ich tatsächlich versucht, ihn mit Docker auszuführen.

Hinweis

** Ab Dezember 2019 wird Scalar DL nur noch als kommerzielle Lizenz angeboten. Sie müssen sich daher für die tatsächliche Verwendung separat an Scalar wenden. ** **.

Kontaktformular

Entwicklungsumgebung

Ubuntu16.04 LTS (basierend auf Windows 10 mit Hyper-V) Oracle Java 8

Vorbereitungen

Ein Docker-Container wird von Scalar als Ausführungsumgebung für Scalar DL bereitgestellt. https://scalardl.readthedocs.io/en/latest/installation-with-docker/

Docker Engine und Docker Compose sind erforderlich, um den Docker-Container zu starten. Installieren Sie ihn daher unter Bezugnahme auf die folgende Site. https://docs.docker.com/install/ https://docs.docker.com/compose/install/

Sie benötigen auch eine Java-Ausführungsumgebung.

$ apt update
$ sudo apt install openjdk-8-jdk

Vorbereiten der Ausführung von Scalar DL

Klon des Skalar-Samples-Repositorys

$ git clone https://github.com/scalar-labs/scalar-samples.git
$ cd scalar-samples

Einloggen

$ docker login

Service Build

$ sudo docker-compose build

Container starten

$ docker-compose up

Wenn Sie am Ende die Option -d hinzufügen, können Sie sie im Hintergrund starten. Da Sie jedoch keine weiteren Vorgänge ausführen können, bis der Start von Cassandra abgeschlossen ist, ist es besser, das Protokoll anzuzeigen und den Start zu überprüfen. Ist fertig.

Wenn während der Ausführung ein Fehler wie "Es gibt keine ausführbare Datei" angezeigt wird, überprüfen Sie die Ausführungsberechtigung der Datei und erteilen Sie die entsprechende Ausführungsberechtigung. $ chmod +x /path/to/file

Laden des anfänglichen Schemas

Sie müssen den Cassandra-Server mit dem anfänglichen Schema laden, das für die Verwendung von Scalar DL erforderlich ist. Dieser Befehl muss beim ersten Start nur einmal ausgeführt werden. $ docker-compose exec cassandra cqlsh -f /create_schema.cql

Behälter stoppen

Strg + C oder $ Docker-Compose Down

Eigenschaftendatei bearbeiten

Bearbeiten Sie scalar-samples / conf / client.properties und konfigurieren Sie die Eigenschaftendatei. Das Folgende sind die Mindesteinstellungen.

client.properties


# A host name of Scalar DL network server.
scalar.ledger.client.server_host=localhost

# An ID of a certificate holder. It must be configured for each private key and unique in the system.
scalar.ledger.client.cert_holder_id=foo

# A certificate file path to use.
scalar.ledger.client.cert_path=/path/to/foo.pem

# A private key file path to use. 
scalar.ledger.client.private_key_path=/path/to/foo-key.pem

Bearbeiten Sie die folgenden Elemente entsprechend Ihrer Umgebung

Vertrag erstellen

Der Scalar DL-Vertrag ist eine Java-Klasse, die die Contract-Klasse erweitert und die Aufrufmethode überschreibt. Dieses Mal wird als Beispiel, wenn Asset_ID und Status eingegeben werden, ein Beispielvertrag erstellt, der Status als Wert in dem von Asset_ID angegebenen Asset registriert.

$ vi src/main/java/com/org1/contract/StateUpdater.java

StateUpdater.java


package com.org1.contract;

import com.scalar.ledger.asset.Asset;
import com.scalar.ledger.contract.Contract;
import com.scalar.ledger.exception.ContractContextException;
import com.scalar.ledger.ledger.Ledger;
import java.util.Optional;
import javax.json.Json;
import javax.json.JsonObject;

public class StateUpdater extends Contract {
  @Override
  public JsonObject invoke(Ledger ledger, JsonObject argument, Optional<JsonObject> properties) {

    if (!argument.containsKey("asset_id") || !argument.containsKey("state")) {
      // ContractContextException is the only throwable exception in a contract and
      // it should be thrown when a contract faces some non-recoverable error
      throw new ContractContextException("please set asset_id and state in the argument");
    }

    String assetId = argument.getString("asset_id");
    int state = argument.getInt("state");

    Optional<Asset> asset = ledger.get(assetId);

    if (!asset.isPresent() || asset.get().data().getInt("state") != state) {
      ledger.put(assetId, Json.createObjectBuilder().add("state", state).build());
    }
    return null;
  }
}

Das Verfahren zum Kompilieren und Ausführen wird später beschrieben.

Erstellen einer Funktion und eines von der Funktion verwendeten Schemas

Was ist Funktion?

Es ist ein Programm, das in Java geschrieben ist. Get, Put und Delete können für Scalar DB innerhalb derselben Transaktion wie die Vertragsausführung ausgeführt werden.

Mit anderen Worten, was getan werden kann, ist, dass Function "sowohl die Verarbeitung unveränderlicher Daten, die Manipulationssicherheit erfordert, als auch die Verarbeitung veränderlicher Daten, die Änderungen in derselben Transaktion erfordern, realisieren kann". werden.

Beim Entwerfen und Implementieren ist es möglich, auf das Argument des Vertrags in der Funktion zu verweisen und es für die Verarbeitung zu verwenden. Es ist jedoch zu beachten, dass auf das Argument der Funktion auf der Vertragsseite nicht Bezug genommen werden kann.

Funktionsbeispiel

Holen Sie sich "Asset_ID" und "State" aus dem Argument des Vertrags, erhalten Sie "User_id" aus dem Argument der Funktion und erstellen Sie eine Funktion, die "Asset_ID" mit "User_id" und "State" als Schlüssel registriert.

$ vi src/main/java/com/scalar/ist/function/SchemaUpdater.java

SchemaUpdater.java


package com.scalar.ist.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);
  }
}

Erstellen eines Schemas zur Verwendung mit einer Funktion

Die Funktion erstellt ein Schema zum Registrieren von Werten in Scalar DB. Das hier erstellte Schema muss jedoch ein Schema sein, das der Transaktion entspricht. Referenz: Scalar DB Docs - Interne Metadaten in Scalar DB

Die Schemaerstellung erfolgt durch Eingabe von Befehlen aus der Cassandra-Shell

$ docker-compose exec cassandra cqlsh
cqlsh> create table test.test_schema	
 (
  user_id text,
  state int,
  value text,
  before_value text,

  before_tx_committed_at bigint,
  before_tx_id text,
  before_tx_prepared_at bigint,
  before_tx_state int,
  before_tx_version int,
  tx_committed_at bigint,
  tx_id text,
  tx_prepared_at bigint,
  tx_state int,
  tx_version int,
  primary key (user_id, state)
 );

Überprüfen Sie die erstellte Tabelle

cqlsh> use test;
cqlsh:test> describe tables;

test_schema

Registrierung / Ausführung von Verträgen und Funktionen

Um einen Vertrag oder eine Funktion auszuführen, muss für jeden Vertrag oder jede Funktion eine eindeutige ID angegeben, mit einem privaten Schlüssel signiert und in Scalar DL registriert werden. Mit diesem Mechanismus wird klar, wer ihn ausgeführt hat, und es ist möglich, die Ausführung nicht autorisierter Benutzer zu verhindern.

kompilieren

$ ./gradlew assemble

Die Vertragsklassendatei wird in build / classes / java / main / com / org1 / contract / StateUpdater.class erstellt.

Vertragsregistrierung

Es steht ein einfaches Tool zur Registrierung zur Verfügung. Verwenden Sie es also. Bei der Registrierung benötigen Sie den Pfad der Eigenschaftendatei, die ID des global eindeutigen Vertrags, den Binärnamen des Vertrags und den Pfad der Klassendatei.

$ client/bin/register-contract -properties conf/client.properties -contract-id StateUpdater -contract-binary-name com.org1.contract.StateUpdater -contract-class-file build/classes/java/main/com/org1/contract/StateUpdater.class

Bei Erfolg wird "Status: 200" angezeigt.

Funktionsregistrierung

Registrieren Sie sich mit demselben Tool wie im Vertrag. Gleiches gilt für den Eigenschaftendateipfad, die global eindeutige ID, den Binärnamen und den Klassendateipfad.

client/bin/register-function -properties conf/client.properties -function-id SchemaUpdater -function-binary-name com.scalar.ist.function.SchemaUpdater -function-class-file build/classes/java/main/com/scalar/ist/function/SchemaUpdater.class

Bei Erfolg wird "Status: 200" angezeigt.

Lauf

Führen Sie den im obigen Verfahren registrierten Vertrag und die Funktion aus. Es wird auch vom Tool ausgeführt, und das Argument des Vertrags wird durch die Option "-contract-argument" angegeben und hat das Format "functions": "Funktions-ID1", "Funktions-ID2", ... " Geben Sie die Funktion an, die in derselben Transaktion ausgeführt werden soll. In Function verwendete Argumente werden durch die Option -function-argument angegeben.

client/bin/execute-contract -properties conf/client.properties -contract-id StateUpdater -contract-argument '{"asset_id": "my_asset", "state": 1, "_functions_": ["SchemaUpdater"]}' -function-argument '{"user_id": "john"}'

Wenn die Ausführung erfolgreich ist, wird "Status: 200" angezeigt.

Beachten Sie, dass die Funktion das Schema auch nicht aktualisiert, wenn der Vertrag das Asset nicht aktualisiert.

Bestätigung

Überprüfen Sie nach der Ausführung des Vertrags, ob er problemlos ausgeführt wurde. Implementieren Sie für das Ausführungsergebnis des Vertrags den Vertrag, der den neuesten Wert des Vermögenswerts erfasst, registrieren Sie ihn, führen Sie ihn aus und überprüfen Sie ihn.

StateReader.java


package com.org1.contract;

import com.scalar.ledger.asset.Asset;
import com.scalar.ledger.asset.InternalAsset;
import com.scalar.ledger.contract.Contract;
import com.scalar.ledger.ledger.Ledger;

import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import java.util.Optional;

public class StateReader extends Contract {

  @Override
  public JsonObject invoke(Ledger ledger, JsonObject argument, Optional<JsonObject> properties) {
    String assetId = argument.getString("asset_id");

    Optional<Asset> asset = ledger.get(assetId);
    InternalAsset internal = (InternalAsset) asset.get();

    JsonObjectBuilder builder = Json.createObjectBuilder()
        .add("state", internal.data());

    return builder.build();
  }
}

Vertragsregistrierung

$ client/bin/register-contract -properties conf/client.properties -contract-id StateReader -contract-binary-name com.org1.contract.StateReader -contract-class-file build/classes/java/main/com/org1/contract/StateReader.class

Bei Erfolg wird "Status: 200" angezeigt.

Lauf

client/bin/execute-contract -properties conf/client.properties -contract-id StateReader -contract-argument '{"asset_id": "my_asset"}'

Bei korrekter Ausführung sollte "state": {"state": 1} "angezeigt werden.

Überprüfen Sie das Cassandra-Schema direkt, um die Ausführung der Funktion zu überprüfen.

$ docker-compose exec cassandra cqlsh
cqlsh> select * from test.test_schema;

Bei korrekter Ausführung sollten Sie ähnliche Ergebnisse erhalten (Werte wie "tx_id" sind wahrscheinlich unterschiedlich): image.png

Recommended Posts

Ich habe versucht, Scalar DL mit Docker zu verwenden
Ich habe BIND mit Docker ausprobiert
Ich habe versucht, JOOQ mit Gradle zu verwenden
Ich habe versucht, Realm mit Swift UI zu verwenden
Ich habe versucht, OnlineConverter mit SpringBoot + JODConverter zu verwenden
Ich habe versucht, OpenCV mit Java + Tomcat zu verwenden
Ich habe versucht, Gson zu benutzen
Ich habe versucht, TestNG zu verwenden
Ich habe versucht, Galasa zu benutzen
Ich habe versucht, AdoptOpenJDK 11 (11.0.2) mit dem Docker-Image zu überprüfen
Ich habe mit Ruby einen Blackjack gemacht (ich habe versucht, Minitest zu verwenden)
Ich habe DI mit Ruby versucht
Ich habe versucht, Azure Cloud-Init zu verwenden
Ich habe versucht, Apache Wicket zu verwenden
Ich habe versucht, Java REPL zu verwenden
Ich habe UPSERT mit PostgreSQL ausprobiert.
Verwenden von PlantUml mit Honkit [Docker]
Ich habe versucht, die Umgebung nach und nach mit Docker aufzubauen
Ich habe versucht, mit Docker eine Padrino-Entwicklungsumgebung zu erstellen
Ich habe versucht, mit Swagger mit Spring Boot zu beginnen
Ich habe versucht, die CameraX-Bibliothek mit Android Java Fragment zu verwenden
Ich habe jetzt versucht, Anakia + Jing zu verwenden
Ich habe versucht, Spring + Mybatis + DbUnit zu verwenden
Ich habe eine morphologische Analyse mit MeCab versucht
Ich habe versucht, mit Java zu interagieren
Ich habe versucht, UDP mit Java zu kommunizieren
Ich habe versucht, die Java8 Stream API zu verwenden
Ich habe versucht, JWT in Java zu verwenden
Ich habe GraphQL mit Spring Boot ausprobiert
[Android] Ich habe versucht, das Koordinatorlayout zu verwenden.
Ich habe Flyway mit Spring Boot ausprobiert
Ich habe versucht, Pari GP Container zu verwenden
Ich habe versucht, WebAssembly Stadio (Version 2018/4/17) zu verwenden.
Verwenden von cuda11.0 mit pytorch mit Docker
Ich habe versucht, Slim mit Scaffold anzupassen
Ich habe versucht, Java Memo LocalDate zu verwenden
Ich habe versucht, Google HttpClient von Java zu verwenden
Ich habe versucht, Docker und Maven / Netbean mit Jib gut zu integrieren
Ich habe versucht, mit Docker eine Plant UML Server-Umgebung zu erstellen
Ich habe versucht, mithilfe von JDBC Template mit Spring MVC eine Verbindung zu MySQL herzustellen
Ich habe versucht, die Elasticsearch-API in Java zu verwenden
Ich habe versucht, UICollectionViewListCell zu verwenden, das von Xcode12 hinzugefügt wurde.
Ich habe versucht, mit Web Assembly zu beginnen
Proxyserver durch Tintenfisch mit Docker-Image
Ich habe mit Studyplus zeitsparendes Management-Lernen versucht.
Es ist neu, aber ich habe versucht, Groonga zu verwenden
Ich habe versucht, ein wenig mit BottomNavigationView zu spielen ①
Ich habe Lazy Initialization mit Spring Boot 2.2.0 ausprobiert
GPU-Erkennung mit Docker mithilfe von WSL2 (August 2020)
Was ist Docker? Ich habe versucht zusammenzufassen