README.md 10.1 KB
Newer Older
Lukas Knittel's avatar
Lukas Knittel committed
1
# Transportvertrag RTB
Lukas Knittel's avatar
Lukas Knittel committed
2
Smart Legal Contract für den Transport Use Case im Industrie 4.0 Recht-Testbed.
Martin Böhmer's avatar
Martin Böhmer committed
3

Lukas Knittel's avatar
Lukas Knittel committed
4
# Vertrag erzeugen
Lukas Knittel's avatar
Lukas Knittel committed
5
6
- `npm install`
- `npm run build`
Lukas Knittel's avatar
Lukas Knittel committed
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

# Changelog
- 1.1.4 - Better Documentation, `*zeitraumEnde` to `DateTime`, removed `zustellungsbevollmächtigter*`
- 1.1.3 - Fix state order in favor of Empfaenger, as it cannot confirm the state which it cannot see
- 1.1.2 - Fix Timestamp formats in default values, add decorators for testing
- 1.1.1 - Standgeldworkflow updated
- 1.1.0 - Added Standgeld support, modified request payloads, added support for third-party data requests, Revert to cicero 0.21
- 1.0.6 - Added decorators with metadata
- 1.0.5 - Added optional feature for Schiedsrichter, removed zustellungsbevollmächtigte, fix DateTime time only bug
- 1.0.4 - second contract without Schiedsrichter, bump cicero 0.22.0, new Types
- 1.0.3 - add negotiation decorators
- 1.0.2 - initRequest is marked by decorator and role checked

# Request
- Hat ein Pflichtfeld `partei` vom Typ `AccordParty`
- Hat ein optionales Feld `geo` vom Typ `String` für geolocation informationen

## timeRTBRequest
Diese werden benutzt, wenn in dem Request ein Zeitstempel für ein Event vorgeschlagen werden soll, z.B. in `setLKW_BELADEBEREIT_FRACHTFUEHRER` der Zeitstempel für den Zeitpunkt,
an dem der LKW aus Sicht des Frachtfuehrers beladebereit war. Der Request hat dabei folgendes Format:
- `eventTimestamp`: ein Pflichtfeld vom Typ `DateTime` welches den Zeitstempel enthält

## timeConfirmationRTBRequest
Diese werden benutzt, wenn in dem Request ein Zeitstempel für ein Event bestätigt oder korrigiert werden soll. Also wenn bereits eine andere Sicht auf den Zeitstempel existiert.
Beispielsweise wird in `setLKW_BELADEBEREIT_VERSENDER` der Zeitstempel für den Zeitpunkt, an dem der LKW beladebereit war, bestätigt oder korrigiert. Der Request hat folgendes Format:
- `confirmEventTimestamp`: ein Pflichtfeld vom Typ `Boolean` welches auf `true` gesetzt wird, falls der bereits existierende Zeitstempel korrekt ist
- `correctedEventTimestamp`: Ein optionales Feld vom Typ `DateTime`, welches den korrigierten Zeitstempel enthält. Falls `confirmEventTimestamp = false` muss dieses Feld vorhanden sein


# Zustandsvariablen

`vertragsStatus`: Symbolisiert eine einfache State-Machine, die folgende Zustände in genau dieser Reihenfolge annehmen kann:
- `LKW_BELADEBEREIT_FRACHTFUEHRER`
- `LKW_BELADEBEREIT_VERSENDER`
- `BEGINN_BELADUNG_VERSENDER`
- `BEGINN_BELADUNG_FRACHTFUEHRER`
- `ABFAHRT_LKW_FRACHTFUEHRER`
- `ABFAHRT_LKW_VERSENDER`
- `LKW_ENTLADEBEREIT_EMPFAENGER`
- `LKW_ENTLADEBEREIT_FRACHTFUEHRER`
- `BEGINN_ENTLADUNG_EMPFAENGER`
- `BEGINN_ENTLADUNG_FRACHTFUEHRER`
- `ABSCHLUSS_ENTLADUNG_EMPFAENGER`
- `ABSCHLUSS_ENTLADUNG_FRACHTFUEHRER`

Die Zustandswechsel sind dabei nur in dieser Reihenfolge möglich. Die Requests heißen alle `setTARGETSTATE`, wobei `TARGETSTATE` einer der möglichen Zustände außer `INITIALISIERT` ist, da dieser anderweitig erreicht wird.

Zusätzlich gibt es noch eine Reihe von Zeitstempeln, die den jeweiligen Zuständen entsprechen, z.B. `LkwBeladebereitFrachtfuehrerZeitstempel`.

## Zustandsübergangsgraph
![Zustandsübergangsgraph](stategraph.png "Zustandsübergangsgraph")

# Rollen

Es gibt die Rollen `Versender, Frachtfuehrer, Empfaenger, Schiedsrichter`. In diese Werte wird der
Name der Organisation, die die jeweilige Rolle innehat, eingetragen. Z.B. `Org1` oder `A`.

Der Vertrag muss vom `Versender` deployed/instantiiert werden. Alle nachfolgenden Requests müssen mit der korrekten Rolle ausgeführt werden. Z.B `partei = Vertragsmanager@B` für den `setCONFIRMED` Request, falls `Frachtfuehrer = B` gilt.

Alle Rollen sind mit `decorator` als __public__  markiert, diese informationen sind also von jedem Blockchainteilnehmer sichtbar. `Versender`, `Frachtfuehrer` und `Schiedsrichter` sind weiterhin mit `decorator` als __participant__ markiert, die Organisationen dieser Teilnehmer speichern also in den _private Collections_ die Vertragsdaten und endorsen Transaktionen. Der `Empfaenger` kann da er nicht als __participant__ eingetragen ist keine der Daten einsehen.

Der `Schiedsrichter` darf keine Requests ausführen sondern nur die Daten einsehen und endorsen.


# Design Elemente

ThirdParty Requests sind mit einem Decorator versehen: `@RTB('{"allowExecutionByThirdParty" : true}')`. Falls die ThirdParty Felder des Requests mit Daten füllen können soll,
müssen diese Felder in dem Decorator angegeben werden: `@RTB('{"allowExecutionByThirdParty" : true, "thirdPartyModifyProperties": ["confirmTimestamp", "correctedTimestamp", "geo"]}')`\
_**Achtung**_: Es können nur Felder mit simplen Datentypen wie `Boolean`, `String`, `Integer`, `DateTime`, `Double`, `Long` angegeben werden, da sonst das ModelFile zu groß werden würde.

Der Bestätigungs-Request muss ebenfalls mit einem Decorator versehen sein: `@RTB('{"confirmationRequest" : true, "confirmationField": "fieldName"}')`\
Hierbei ist `fieldName` der Name des `Boolean` Feldes, das angibt ob der Vertrag angenommen oder abgelehnt wird.
Falls es dieses nicht gibt, wird ein leerer String eingetragen: `""`. Dann wird der Request nur bei gültiger Verifikation abgeschickt.

Damit überprüft werden kann, ob die richtige Rolle den Vertrag initialisiert, gibt es auch einen Initialisierungs-Request, der mit einem Decorator versehen ist:
`@RTB('{"initRequest" : true}')`

## Liste von Decorators
### Für Ausführung auf HLF zwingend notwendig:
- alle `@RTB` Decorator:
  - `@RTB('{ "participant" : true }')` muss an den __participants__ eingetragen werden, die als Organisation auf der Blockchain vorhanden sind.
  - `@RTB('{"initRequest" : true}')` muss an dem Request anhängen, der zum Initialisieren verwendet wird, falls so einer vorhanden ist.
  - `@RTB('{"confirmationRequest" : true, "confirmationField": ""}')`muss an dem Request anhängen, der zum Bestätigen verwendet wird. Näheres s.o.

### Für Ausführung in experimenteller Umgebung zwingend notwendig:
- `@Negotiator` teilt für die Verhandlung notwendige Informationen mit und muss an denjenigen Variablen stehen, die ausgehandelt werden sollen. Beispiel: `@Negotiator("Standgeld","Das Standgeld, das pro vom Versender verschuldeten Standtag an den Frachtführer zu entrichten ist", "[100.0, 500.0, 10.0]")`.
Der Docorator benötigt drei String-Parameter: Der erste Parameter beinhaltet den Display Namen der Variablen, welcher in der Experimentierfeld UI für diese Variable verwendet werden soll. Der zweite Parameter enthält eine Beschreibung zu der Bedeutung der Variable, welche ebenfalls für die Anzeige in der Experimentierfeld UI geeignet ist. Der dritte Parameter gibt weitere Informationen zur Verhandlungsdomäne an. Es gibt die folgenden Variationen für die Syntax des dritten Parameters:
  - Soll eine numerische Variable über ein (diskretisiertes) Intervall verhandelt werden, ist der dritte Parameter von der Form `"[x,y,z]"`, wobei `x` bzw. `y` die untere bzw. obere Intervallgrenze und `z`die Schrittweite für die Diskretisierung ist.
  - Soll eine Variable aus konkreten/diskreten Werte verhandelt werden (Enum), ist der dritte Parameter von der Form `"['a', 'b', 'c', 'd']"` (hier beispielhaft für 4 Werte), wobei alle möglichen Werte durch Kommata voneinander getrennt werden und in Anführungszeichen gesetzt sind. Damit die Variable tatsächlich in der Verhandlung berücksichtigt wird, müssen mindestens zwei Werte zur Auswahl stehen.
  - Für Variablen, die generell als potentiell verhandelbar gelten, aber in dieser speziellen Template Variation nicht ausgehandelt werden sollen, wird durch einen dritten Parameter der Form `"a"` ein konstanter Wert für die Variable gesetzt. Das heißt diese Variable wird nicht ausgehandelt, sondern der angegebene konstante Wert dafür verwendet.
- `@Metadata` liefert Informationen über das Template, welche für die Anzeige in der Experimentierfeld UI geeignet sind. Dieser Decorator steht über als optional gekennzeichneten Behelfsvariablen, die nur existieren, damit ihr Decorator ausgelesen werden kann. Um einheitlich mit dem `@Negotiator` Decorator zu bleiben, werden ebenfalls drei Parameter benötigt. Analog dazu enthält der erste bzw. zweite Parameter den Display Namen bzw. eine Beschreibung der Variable. Da es sich hier aber lediglich um eine Behelfsvariable handelt, werden diese Strings nicht in der Experimentierfeld UI angezeigt. Der dritte Parameter enthält den "Wert der Behelfsvariable", also der in der UI angezeigte String. Als Beispiel der Decorator an der optinalen Variable `templateDescription`:
`@Metadata("Template Beschreibung","Eine Beschreibung über den Inhalt und die Merkmale dieses Vertragstemplates","Dies ist ein Vertragstemplate zwischen einem Versender und einem Frachtführer in einem Transportszenario. Die Parteien verhandeln über die Frachtvergütung sowie das Standgeld.")`

### nicht zwingend notwendige, aber von HGI benutzte:
- `@FormEditor("hide", true)` versteckt einzelne Felder in Web UI (meint nicht die RTB Experimentierfeld UI)
- `@RolesForInitAndConfirm("<Rolle>@Versender", "<Rolle>@Frachtfuehrer")` für automatisiertes Testen
- `@StateTransition(<index>, "<Rolle>@<Org>")` für automatisiertes Testen

# Optional Schiedsrichter caveats

For some reason TemplateMark does not support `{{#with}}{{/with}}` statements inside of `{{#optional}}{{/optional}}` Statements, therefore the Schiedsrichter-party is optional as well. This means, one could add a incomplete Schiedsrichter who wouldn't have access to the private data, since the party was omitted.

# Testing Decorator
Um das Template automatisiert testen zu können, müssen Requests, Reihenfolge sowie auszuführende Rolle bekannt sein. Daher wurde der `@StateTransition(id, role)` Decorator eingeführt, wobei `id` dem fortlaufenden Index entspricht, der die Reihenfolge der Ausführung vorgibt und `role` den String, der im Request in dem `partei.partyId` stehen muss.

Da auch `setINITIALISIERT` und `setBESTAETIGT` eine Rolle brauchen, diese aber nicht direkt über die Transaktionen identifiziert werden, gibt es noch den `@RolesForInitAndConfirm(initRole, confirmRole)` Decorator. Dieser enthält die Rollen für diese beiden implizit ausgeführten Methoden und wird vor das Datenmodell des Contracts angehängt und nicht an einen Request.