SlideShare a Scribd company logo
1
Rablock Ver.2
アプリケーション開発ガイド
Ver.1.2.0
2
本ガイドに関して
本ガイドは、プライベートブロックチェーン Rablock を使用したアプリケーションの開発に関する知
識を習得していただくためのものです。
必要に応じてハンズオン形式で実際に動作、挙動を確認していただきながら進んでください。
本ガイドでは、参考として出勤時間と退社時間の記録と管理を行う勤怠管理システムのサンプルアプリ
ケーションを基にします。
アプリケーション環境
勤怠管理システムは、Spring Boot を利用して書かれた Java アプリケーションです。
以下に稼働です。
図 0-1 勤怠管理システム稼働環境
稼働要件
バージョン
Java 1.8
MongoDB 3.4.7
3
目次
本ガイドに関して......................................................................................................................................... 2
アプリケーション環境.............................................................................................................................. 2
1. Rablock 接続の基本............................................................................................................................. 5
1.1. HTTP ダイジェスト認証............................................................................................................... 5
1.2. Rablcok UI の呼び出し ................................................................................................................ 7
1.2.1. コールする Rablock UI の URL を作成します。 ............................................................... 7
1.2.2. HTTP コネクションオブジェクトの作成.............................................................................. 7
1.2.3. 接続設定(メソッドの決定,ヘッダー値等).......................................................................... 7
1.2.4. JSON データの準備(リクエストボディの書き込み) ............................................................ 8
1.2.5. コネクションを開く............................................................................................................... 8
1.2.6. レスポンスの読み出し ........................................................................................................... 9
1.2.7. コネクションのクローズ........................................................................................................ 9
2. Spring Boot ........................................................................................................................................ 10
3. MVC.................................................................................................................................................... 11
4. STS でハンズオン.............................................................................................................................. 12
4.1. HelloWorld .................................................................................................................................. 12
5. Rablock アプリケーション開発ハンズオンのため準備 .................................................................... 13
5.1. Java (1.8) のインストール ......................................................................................................... 13
5.2. PostgreSQL のインストール ...................................................................................................... 13
5.3. PostgreSQL の設定..................................................................................................................... 13
5.3.1. 初期化................................................................................................................................... 13
5.3.2. DB 操作用アカウントと DB 作成........................................................................................ 13
5.3.3. 設定ファイル postgresql.conf の編集 ................................................................................ 14
5.3.4. 設定ファイル pg_hba.confi の編集 .................................................................................... 14
5.3.5. PostgreSQL の再起動 ......................................................................................................... 14
5.4. テーブルの作成............................................................................................................................ 15
5.5. DB 認証の有効化設定.................................................................................................................. 16
5.6. その他 .......................................................................................................................................... 16
5.7. Rablock サーバ接続の設定.......................................................................................................... 17
6. Rablock アプリケーションハンズオン............................................................................................... 18
6.1. データ登録処理の例 .................................................................................................................... 18
6.2. データ全件取得処理 .................................................................................................................... 20
6.3. データ取得処理............................................................................................................................ 23
7. Rablock UI.......................................................................................................................................... 25
7.1. Rablock UI リファレンス........................................................................................................... 25
4
7.2. ブロック生成 UI......................................................................................................................... 26
7.3. データ取得................................................................................................................................... 28
7.4. データ登録................................................................................................................................... 29
7.5. トランザクションの伝播............................................................................................................. 30
7.6. 他ノード連携 ............................................................................................................................... 30
8. プロパティファイル............................................................................................................................ 31
8.1. Rablock プロパティファイル...................................................................................................... 31
8.2. Mining プロパティファイル ....................................................................................................... 32
8.3. 画面プロパティファイル............................................................................................................. 33
9. 参考資料.............................................................................................................................................. 34
9.1. アノテーション............................................................................................................................ 34
9.2. pom.xml について ....................................................................................................................... 35
改訂履歴 ..................................................................................................................................................... 36
5
1. Rablock 接続の基本
アプリケーションプログラムから Rablock に接続し操作を行うためには Rablock UI を使用します。
Rablock UI を使用する手順は、次の手順となります。
1. HTTP ダイジェスト認証
2. Rablock UI のコール(REST コール)
3. 結果の読出し
4. コネクションのクローズ
1.1. HTTP ダイジェスト認証
Rablock UI の多くは、ユーザ名とパスワードを使用して HTTP ダイジェスト認証方式により認証され、
その実行が認可されます。
Java から Rablock UI を次のようなコードで認証を行います。
※ダイジェスト認証とは、HTTP の認証方法の一つ。ユーザ名とパスワードを MD5 でハッシュ
(ダイジェスト)化して送る。Basic 認証では防げなかった盗聴や改竄を防ぐために考案され
た。
// ユーザ認証情報の設定
//
import java.net.Authenticator;
//
HttpAuthenticator httpAuth = new HttpAuthenticator(userName, userPass);
Authenticator.setDefault(httpAuth);
6
※ダイジェスト認証の仕組み
①あらかじめサーバ側にパスワードの MD5 メッセージダイジェストを保存しておきます (ユーザ登録
に相当)。
②クライアントが Digest 認証を行うページにやってくると、サーバはクライアントにランダムな文字
列を渡します。
③クライアントはパスワードの MD5 メッセージダイジェストを生成します。
④さらにクライアントは、生成したメッセージダイジェストの末尾に、サーバから受け取ったランダム
な文字列をくっつけて、 ひとつの文字列にします。
⑤クライアントは、生成した文字列全体の MD5 メッセージダイジェストをサーバに送信します。 な
お、このときサーバから送られてきたランダムな文字列もそのまま送り返します。
⑥サーバは、あらかじめ用意してあったパスワードの MD5 メッセージダイジェストの末尾に、 クラ
イアントから送られてきたランダムな文字列 (元々はサーバが生成したもの) をくっつけて、 ひとつの
文字列にします。
⑦サーバは、この文字列全体の MD5 メッセージダイジェストを生成し、 クライアントから送信され
てきたメッセージダイジェストと比較します。 もし一致したら認証成功・一致しなかったら失敗で
す。
Basic 認証とは異なり、ネットワーク上を生パスワードが流れることはありませんので、 盗聴に対し
て安全です。また、サーバ側に生パスワードを保存する必要がないのもポイントです。
7
1.2. Rablcok UI の呼び出し
Rablock UI は、REST API です。
例では、Rablock にデータを登録するために /post/json をコールするまでの一連の手順を説明します。
1.2.1. コールする Rablock UI の URL を作成します。
ここでは、/post/json です
URL 文字列のサーバ名、ポートなどは各自の環境に応じて修正してください。
...には Rablock サーバを指定してください。
1.2.2. HTTP コネクションオブジェクトの作成
con は、HttpURLConnection con = null; として有効域内で定義されている変数です。
1.2.3. 接続設定(メソッドの決定,ヘッダー値等)
// RaBlock へデータを登録するコールの URL の作成
URL connectUrl = new URL("http://.../post/json/");
// コネクションオブジェクトの作成
con = (HttpURLConnection) connectUrl.openConnection();
// HTTP コネクションの設定(POST コールで JSON 文字列を送信する設定など)
con.setDoOutput(true);
con.setRequestMethod("POST");
con.setRequestProperty("Accept-Language", "jp");
// データが JSON であること、エンコードを指定する
con.setRequestProperty("Content-Type", "application/JSON; charset=utf-8");
// POST データの長さを設定
con.setRequestProperty("Content-Length", String.valueOf(json.length()));
8
1.2.4. JSON データの準備(リクエストボディの書き込み)
out.write() の引数 json は、任意の JSON テキストがセットされている String 変数です。
1.2.5. コネクションを開く
接続することで POST リクエストが実行され、アウトプットストリームが生成されます。
アウトプットを読みこんで必要な処理を行い、最後に HTTP の接続を切断します。
// リクエストの body に JSON 文字列を書き込む
OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream());
out.write(json);
out.flush();
out.close();
con.connect();
9
1.2.6. レスポンスの読み出し
1.2.7. コネクションのクローズ
// 切断
if (con != null) {
con.disconnect();
}
int status = con.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
// 通信に成功した
// テキストを取得する
final InputStream in = con.getInputStream();
String encoding = con.getContentEncoding();
if (null == encoding) {
encoding = "UTF-8";
}
final InputStreamReader inReader = new InputStreamReader(in, encoding);
final BufferedReader bufReader = new BufferedReader(inReader);
String line = null;
// 1 行ずつテキストを読み込む
while ((line = bufReader.readLine()) != null) {
result.append(line);
}
bufReader.close();
inReader.close();
in.close();
}
10
2. Spring Boot
Spring Boot は、Spring Framework ベースの Java アプリケーションを簡易に行うことができる開
発フレームワークであり、MVC を基にした Spring MVC フレームワークの膨大なライブラリや複雑
な設定を簡単に開発することが出来るように作られています。
Spring Framework の開発グループが提供している統合開発環境 STS(Spring Tool Suite)を利用するこ
とでさらに開発を手軽に行うことができます。
STS は、Eclipse ベースの IDE で Spring Framework ベースのアプリケーションの開発のための機
能が豊富に用意されています。
Spring Boot では、設定ファイルの記述量の軽減、多数に定義された有用なアノテーションの利用、
Web コンテナ(デフォルトでは Tomcat)を含んだ jar ファイルの生成が出来るなど、コーディング負
荷を大幅に軽減することができるようになっています。
11
3. MVC
MVC は、Web アプリケーションを含め画面をもつアプリケーションのためのフレームワークです。
Model、View、Controller の頭文字をとって MVC となっています。
Model: 使用するデータ(データモデル)を制御するブロックで、データクラス、外部ファイル、外部
データベースとの入出力を行います。
View: 画面の表現と動作、入出力を制御するブロックです。Web アプリケーションであれば、ページ
テンプレート、スタイルシート、フォームを含むページ本体(HTML 等)、ページの動作制御のための
JavaScript コード等は View に相当します。
Controller: View からデータもしくはイベントを受け取り、適切に Model に処理させるための指示を
行い、その結果の View への返答を制御します。Model と View の間に入りデータの送受信制御と
アプリケーションロジックを記述します。
MVC では、これらの Model, View, Controller をそれぞれの部分の役割を区分し開発を行います。
12
4. STS でハンズオン
ここでは、STS を実際に使用して、簡単はプログラムを作ってみます。
4.1. HelloWorld
手順:
1. Java のインストール
2. STS のインストール
3. STS の起動
4. 新規プロジェクトの作成
5. コントローラーの作成
6. HTML ファイルの作成
7. 実行
詳細手順は、別にお配りするハンドアウトを参照して下さい。
13
5. Rablock アプリケーション開発ハンズオンのため準備
5.1. Java (1.8) のインストール
5.2. PostgreSQL のインストール
5.3. PostgreSQL の設定
5.3.1. 初期化
5.3.2. DB 操作用アカウントと DB 作成
$ sudo yum install -y java
$ sudo yum install -y postgresql-jdbc postgresql-server
$ sudo postgresql-setup initdb
$ sudo systemctl start postgresql
$ sudo systemctl enable postgresq
$ sudo adduser attendance
$ sudo su - postgres
-bash-4.2$ createuser attendance
-bash-4.2$ createdb -O attendance attendance
-bash-4.2$ exit
14
5.3.3. 設定ファイル postgresql.conf の編集
postgresql.conf の listen_addresses に’*’を指定します。
5.3.4. 設定ファイル pg_hba.confi の編集
pg_hba.conf に 0.0.0.0 のエントリを追記します。
5.3.5. PostgreSQL の再起動
$ sudo vi /var/lib/pgsql/data/postgresql.conf
$ sudo vi /var/lib/pgsql/data/pg_hba.conf
$ sudo systemctl restart postgresql
listen_addresses = '*' # what IP address(es) to listen on;
# comma-separated list of addresses;
# defaults to 'localhost'; use '*' for all
...
…
host all all 0.0.0.0/0 md5
…
15
5.4. テーブルの作成
PostgreSQL で使用するテーブルを作成します。(psql を使用する例)
$ sudo su - attendance
$ psql -d attendance
ALTER ROLE attendance WITH PASSWORD ‘uj9woRzLWS6h7VAh3iOI2GxfXlitbM3m’;
CREATE TABLE user_account(
id SERIAL
, user_id VARCHAR(64) PRIMARY KEY
, user_name VARCHAR(64)
, department VARCHAR(128)
);
CREATE TABLE user_summary(
id SERIAL
, user_id VARCHAR(64)
, year VARCHAR(8)
, month VARCHAR(8)
, total VARCHAR(8)
,PRIMARY KEY(user_id,year,month));
CREATE TABLE user_info(
id SERIAL
, user_id VARCHAR(64) PRIMARY KEY
, password VARCHAR(128)
, role VARCHAR(32)
, enabled INT
);
$ exit
psql は、【¥q】 で終了します。
16
5.5. DB 認証の有効化設定
5.6. その他
zip ファイルを展開し、必要なファイルを取り出します
$ sudo vi /var/lib/pgsql/data/pg_hba.conf
# "local" is for Unix domain socket connections only
local all all md5
# IPv4 local connections:
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all ::1/128 md5
...
$ sudo systemctl restart postgresql
$ cd ~
$ mkdir apps
$ unzip -q 20181004.zip
$ cd 20181004/history
$ mv * ~/apps/
$ cd ~
17
5.7. Rablock サーバ接続の設定
$ cd apps
$ vi ip-history.properties
blockchain_ip.value=<Rablock サーバ 1 台目のプライベート IP>
…
login_user.value=<管理者のユーザ名>
login_password.value=<管理者のパスワード>
18
6. Rablock アプリケーションハンズオン
Rablock に対するコールは、Spring Boot では、controller にコードを記述します。
デモサンプルでは、SendBlockChain クラスにすべての Rablock に対するコールを各メソッドに記述
しています。
6.1. データ登録処理の例
SendBlockChain クラスの restSubmit メソッドは、引数に渡された JSON テキストをデータとして
Rablock にトランザクションデータを送信します。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
public String restSubmit(String json, String ip, String port) throws IOException {
StringBuffer result = new StringBuffer();
HttpURLConnection con = null;
try {
String apiUrl = "http://" + ip + ":" + port + "/post/json/";
URL connectUrl = new URL(apiUrl);
con = (HttpURLConnection) connectUrl.openConnection();
con.setDoOutput(true);
con.setRequestMethod("POST");
con.setRequestProperty("Accept-Language", "jp");
// データが JSON であること、エンコードを指定する
con.setRequestProperty("Content-Type", "application/JSON; charset=utf-8");
// POST データの長さを設定
con.setRequestProperty("Content-Length", String.valueOf(json.length()));
19
// リクエストの body に JSON 文字列を書き込む
OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream());
out.write(json);
out.flush();
out.close();
con.connect();
int status = con.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
// 通信に成功した
// テキストを取得する
final InputStream in = con.getInputStream();
String encoding = con.getContentEncoding();
if (null == encoding) {
encoding = "UTF-8";
}
final InputStreamReader inReader = new InputStreamReader(in, encoding);
final BufferedReader bufReader = new BufferedReader(inReader);
String line = null;
// 1 行ずつテキストを読み込む
while ((line = bufReader.readLine()) != null) {
result.append(line);
}
bufReader.close();
inReader.close();
in.close();
} else {
// 通信が失敗した場合のレスポンスコードを表示
System.out.println("status" + status);
}
} finally {
if (con != null) {
// コネクションを切断
con.disconnect();
}
}
return result.toString();
}
20
6.2. データ全件取得処理
Rablock に格納されているデータ(サーバープール、ブロック)を取得するコードの例です。
import java.net.Authenticator;
public String getAll(String ip, String port) throws IOException {
StringBuffer result = new StringBuffer();
HttpURLConnection con = null;
try {
String apiUrl = "http://" + ip + ":" + port + "/get/alltxdata";
URL connectUrl = new URL(apiUrl);
// ユーザ認証情報の設定
HttpAuthenticator httpAuth =
new HttpAuthenticator(DIGEST_USERNAME, DIGEST_PASS);
Authenticator.setDefault(httpAuth);
con = (HttpURLConnection) connectUrl.openConnection();
con.setDoOutput(true);
con.setInstanceFollowRedirects(true);
int status = con.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
// 通信に成功した
// テキストを取得する
final InputStream in = con.getInputStream();
String encoding = con.getContentEncoding();
if (null == encoding) {
encoding = "UTF-8";
}
final InputStreamReader inReader =
new InputStreamReader(in, encoding);
final BufferedReader bufReader = new BufferedReader(inReader);
次ページに続く
21
String line = null;
// 1 行ずつテキストを読み込む
while ((line = bufReader.readLine()) != null) {
result.append(line);
}
bufReader.close();
inReader.close();
in.close();
} else {
// 通信が失敗した場合のレスポンスコードを表示
System.out.println(status);
}
} finally {
if (con != null) {
// コネクションを切断
con.disconnect();
}
}
return result.toString();
}
22
HttpAuthenticator クラス
import java.net.Authenticator;
import java.net.PasswordAuthentication;
public class HttpAuthenticator extends Authenticator {
private final String username;
private final String password;
public HttpAuthenticator(String username, String password) {
if (username == null || password == null)
throw new IllegalArgumentException("username or password is null.");
this.username = username;
this.password = password;
}
public String getUsername() {
return this.username;
}
public String getPassword() {
return this.password;
}
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(this.username, this.password.toCharArray());
}
}
23
6.3. 任意の項目と値でデータ取得処理
public String getByJson(String json, String ip, String port) throws IOException {
StringBuffer result = new StringBuffer();
HttpURLConnection con = null;
try {
String apiUrl = "http://" + ip + ":" + port + "/get/json";
URL connectUrl = new URL(apiUrl);
// ユーザ認証情報の設定
HttpAuthenticator httpAuth = new
HttpAuthenticator(DIGEST_USERNAME, DIGEST_PASS);
Authenticator.setDefault(httpAuth);
con = (HttpURLConnection) connectUrl.openConnection();
con.setInstanceFollowRedirects(true);
con.setRequestMethod("GET");
con.setDoOutput(true);
con.setRequestProperty("Accept-Language", "jp");
con.setRequestProperty("Content-Type", "application/JSON; charset=utf-8");
con.setRequestProperty("Content-Length", String.valueOf(json.length()));
// リクエストの body に JSON 文字列を書き込む
OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream());
out.write(json);
out.flush();
out.close();
con.connect();
int status = con.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
// 通信に成功した
// テキストを取得する
final InputStream in = con.getInputStream();
String encoding = con.getContentEncoding();
if (null == encoding) {
encoding = "UTF-8";
}
final InputStreamReader inReader = new
InputStreamReader(in, encoding);
次ページに続く
24
// 通信に成功した
// テキストを取得する
final InputStream in = con.getInputStream();
String encoding = con.getContentEncoding();
if (null == encoding) {
encoding = "UTF-8";
}
final InputStreamReader inReader = new
InputStreamReader(in, encoding);
final BufferedReader bufReader = new
BufferedReader(inReader);
String line = null;
// 1 行ずつテキストを読み込む
while ((line = bufReader.readLine()) != null) {
result.append(line);
}
bufReader.close();
inReader.close();
in.close();
} else {
// 通信が失敗した場合のレスポンスコードを表示
System.out.println(status);
}
} finally {
if (con != null) {
// コネクションを切断
con.disconnect();
}
}
return result.toString();
}
} }
25
7. Rablock UI
7.1. Rablock UI リファレンス
Rablock に対する操作は Rablock UI をコールすることで行います。
Rablock UI は、Web API で、REST に基づいて実装されています
UI 一覧
カテゴリ UI 名 メソッド 説明
ブロック生成 /mining POST 新規ブロックを生成する。
データ取得 /get/json GET 任意の項目と値(JSON)でデータ取得(更
新・削除対象のデータは除く)
/get/searchoid/{$oid} GET 指定されたオブジェクト ID($oid)のトラ
ンザクションデータを取得。
/get/alltxdata GET 全てのトランザクションデータ全件取得。
/get/block GET 全てのブロックを取得。
/get/pool GET トランザクションプールにあるトランザ
クションデータ全件取得。
/get/lastblock GET 最後のブロックのヘッダー情報を取得。
/get/deliveredpool GET 伝搬済みのトランザクションデータを取
得
/get/totalnumber GET ブロック内のデータ件数の合計を取得
history/{$oid} GET 指定されたオブジェクト ID($oid)のトラ
ンザクションデータを削除、更新も含め取
得。
データ登録 /post/json POST テキストデータを登録する。
伝搬 /delivery/deliverypool POST トランザクションプールを伝搬する。
他ノード連携 /sync/gen POST ジェネシスブロックを生成し、各ノードに
伝播する。
/sync/poolsync POST トランザクションプールの同期処理をす
る。
/sync/blocksync POST ブロックテーブルの同期処理をする。
26
7.2. ブロック生成 UI
/mining は、Rablock のブロックチェーンに新たなブロックを生成して加えるコマンドです。
Rablock は、トランザクションプールが保持しているトランザクションを収集し、ブロックを生成し
ます。
ブロックの生成に成功した後に、トランザクションプールからブロックに格納したトランザクション
データを消去します。
各 Rablock サーバには、crontab により定期的に /mining が実行するように設定されています。
次ページは、/mining が生成したブロックのサンプルです。
Rablock サーバの crontab に次の一行が追加されていれば、定期的にブロックマイナーが起動し、新
たなブロックを生成します。
... には Rablock サーバを指定してください。
毎時 0 分、10 分、20 分、30 分、40 分、50 分と 10 分間隔でマイニングが行われる設定です。
他のサーバで同時刻にマイニングが発生するとほぼ同じブロックが生成され、ブロックがフォークし
ます。フォークは定期処理によって解消されます。
動作上は問題ありませんが、無駄な処理になりますので、他のサーバでは、同じ 10 分間隔であっても
異なった時間を指定します。
0,10,20,30,40,50 * * * * curl -X POST http://.../mining
27
{
_id : ObjectId("5b5ea33d3ff7d81ef5794313"),
height : 1,
size : 2,
data : [
{
_id : ObjectId("5b5ea2fa3ff7d81ef579430a"),
type : "modify",
original_id : "5b5e77e23ff7d80f20bbcf2a",
user_id : "T003",
startDate : "2018/07/30",
startTime : "11:00:00",
endDate : "2018/07/30",
endTime : "18:00:00",
note : "",
settime : "2018/07/30 14:32:42",
deliveryF : true
},
{
_id : ObjectId("5b5ea3023ff7d81ef579430c"),
type : "new",
user_id : "T003",
startDate : "2018/07/30",
startTime : "14:32:00",
endDate : "2018/07/30",
endTime : "18:00:00",
note : "",
settime : "2018/07/30 14:32:50",
deliveryF : true
}
],
settime : "2018/07/30 14:33:48",
timestamp : "1532928828900",
prev_hash : "403e0e78a0fbb5f47c7b16da49289e529f02cf2f567b3e1690e800bf3412401",
hash : "ae4c2c773a9e1e4fdc3e0b4e00c75277fd193bfb25f4d7f06d3a31cfc280f4f0"
}
28
7.3. データ取得
アプリケーションプログラムからコールすることが最も多いのがデータ取得系のコマンドです。
取得したデータは、JSON 形式のトランザクションデータです。
/get/json で取得したトランザクションデータの例
{
_id : ObjectId("5b5ea2fa3ff7d81ef579430a"),
type : "modify",
original_id : "5b5e77e23ff7d80f20bbcf2a",
user_id : "T003",
startDate : "2018/07/30",
startTime : "11:00:00",
endDate : "2018/07/30",
endTime : "18:00:00",
note : "",
settime : "2018/07/30 14:32:42",
deliveryF : true
},
{
_id : ObjectId("5b5ea3023ff7d81ef579430c"),
type : "new",
user_id : "T003",
startDate : "2018/07/30",
startTime : "14:32:00",
endDate : "2018/07/30",
endTime : "18:00:00",
note : "",
settime : "2018/07/30 14:32:50",
deliveryF : true
}
29
7.4. データ登録
Rablock にトランザクションデータを投入するコマンド /post/json です。
POST メソッドの送信データには JSON 形式のトランザクションデータを渡します。
トランザクションデータは、type, user_id (type の値が modify, delete の場合は、original _id 要素
が必要)に続けて JSON 要素をアプリケーション設計で定義したデータモデルに合うように記述しま
す。
例)
{type: “new”, user_id: 999, …………..}
Rablock へのトランザクションデータの登録は、通常は新規データとして登録されますが、論理更新、
論理削除としてデータを登録することが出来ます。
データの論理更新、論理削除には、type 要素をそれぞれ modify、delete を指定し、続く original_id
要素に対象となるトランザクションデータの _id を指定します。
論理更新のトランザクションデータの例
{
type: "modify",
original_id: "5b3c72f2702ac809b8812921",
user_id : 456
startDate : "2018/07/18",
startTime : "9:50",
endDate : "2018/07/18",
endTime : "21:00",
}
30
7.5. トランザクションの伝播
/delivery/deliverypool コマンドは、トランザクションプールに保存されたトランザクションデータを
他ノードに伝播します。
伝播先のサーバは、受け取ったトランザクションデータを自身のトランザクションプールに保存しま
す。
このコマンドは、各サーバの crontab で一定間隔ごとに実行されるように設定されており、管理者が
手動で発行する必要はありません。
...には Rablock サーバを指定してください。
7.6. 他ノード連携
/sync/gen、/sync/poolsync、/sync/ blocksync の 3 コマンドは、他のノードとの間で保持しているブロ
ックの同期を行うコマンドです。
/sync/gen は、Rablock の導入後に 1 度だけ実行し、ブロックチェーンの最初のブロックを生成し、そ
れを他ノードに伝播します。
/sync/poolsync は、トランザクションプールの同期をとります。
自ノードに存在しない伝搬フラグが True のデータを、他ノードを参照し、追加します。
/sync/blocksync は、以下の3つの処理を実行しブロックチェーンの同期をとります。
1. 破損もしくは改竄されたブロックを必要に応じて他ノードを参照し、修復します。
2. 自ノードの過不足なブロックを他ノードを参照し、削除、または追加します。
3. ブロックチェーンの枝分かれ(fork)を検知し、優先順位の高い枝を選択し、それ以外の枝にあ
るブロックのトランザクションデータのうち、選択した枝に存在していないトランザクションを
トランザクションプールに戻すことで枝分かれを修復し、他ノードにも修復を伝播します。
0,5,10,15,20,25,30,35,40,45,50,55 * * * * curl -X POST http://.../delivery/deliverypool
31
8. プロパティファイル
Rablock システムには、2 つのプロパティファイルがあります。
1 つは、Rablock サーバ本体の設定用、もう一つは、ブロック生成モジュール(ブロックマイナー)の
設定用です。
また、本ガイドで使用しているサンプルアプリケーションでは、アプリケーションの設定のプロパティ
ファイルを使用しています。
8.1. Rablock プロパティファイル
設定項目 備考
server.port=9000 Rablock を起動するポート
#mongo setting (MongoDB の設定)
spring.data.mongodb.port=27017 MongoDB のポート
spring.data.mongodb.database=bcdb 使用データベース名
spring.data.mongodb.username=bcuser MongoDB のユーザー名
spring.data.mongodb.password=1234 MongoDB のパスワード
spring.data.mongodb.collection.pool=pool プールのコレクション名
spring.data.mongodb.collection.block=block ブロックのコレクション名
#auth setting (ダイジェスト認証の設定)
digest.username=AAA ユーザー名
digest.pass=BBB パスワード
#ip setting (Rablock の連携設定)
send.ip[0] =12.345.678.910 連携ノードの IP #1
send.ip[1]=56.789.101.234 連携ノードの IP #2
send.port[0] =9000 連携ノードのポート #1
send.port[1]=9000 連携ノードのポート #2
#log setting (ログの設定)
次ページに続く
32
設定項目 備考
#spring.profiles.active=production この項目を指定しない場合標準出力(コメントに
するか削除)
spring.profiles.active=production この項目がある場合、指定した場所にログファイ
ルを出力
logging.file=/home/ec2-user/controller.log spring.profiles.active=production の時のみ有効。
出力先を指定
#crypto setting (暗号化の設定)
crypto.status=OFF 暗号化 OFF
key.file=null 鍵ファイル必要ないため null を設定
#crypto.status=ON 暗号化 ON
#key.file=/xxx/xxxx/private_key.pk8 秘密鍵のパスを指定
#node setting (ノードモードの設定)
send.nodemode=multi 複数ノードモードの場合「multi」を設定
#send.nodemode=single 単一ノードモードの場合「single」を設定
8.2. Mining プロパティファイル
設定項目 備考
server.port=8000 Mining プログラムを起動するポート
server_name.value=#1 サーバ名 ※ブロックを生成したサーバ名を項目
に設定する際に使用
#ip setting (Rablock の設定)
blockchain_ip.value=127.0.0.1 起動している Rablock の IP アドレス
blockchain_port.value=9000 起動している Rablock のポート番号
33
8.3. 画面プロパティファイル
設定項目 備考
server.port=8080 画面アプリを起動するポート
#login setting (ログインの設定)
login_user.value=loginuser 管理者のユーザ名
login_password.value=loginpass パスワード
#DataSource settings for Postgesql (Postgres の設定)
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=postgres
#Rablock setting (Rablock の設定)
blockchain_ip.value=18.222.254.199 起動している Rablock の IP アド
レス
blockchain_port.value=9000 起動している Rablock のポート番
号
#crypto setting (暗号化の設定 Rablock が ON の
場合画面も ON、OFF なら OFF)
crypto.status=OFF 暗号化 OFF
private.key.file =null 鍵ファイル必要ないため null を設
定
public.key.file =null 鍵ファイル必要ないため null を設
定
#crypto.status=ON 暗号化 ON
# private.key.file =/xxx/xxxxx/private_key.pk8 復号化するための秘密鍵のパスを
指定
# public.key.file =/xxx/xxxxx/public_key.der 暗号化するための公開鍵のパスを
指定
34
9. 参考資料
9.1. アノテーション
アノテーション 説明
@SpringBootApplication @SpringBootApplication を付与したクラスは自身が Spring Boot ア
プリケーションであることを示します。
@Controller Web ページ用のコントローラで使用する。
Web ページ用コントローラは JSP やテンプレートエンジンの View に
遷移してレスポンスの HTML を生成するので、基本的にメソッドの戻
り値は View の遷移先を指定するのに使用します。
@RequestMapping クライアントからのリクエストに対してメソッドやハンドラをマッピ
ングします。
@GetMapping @RequestMapping の GET リクエスト用のアノテーション
@PostMapping @RequestMapping の POST リクエスト用のアノテーション
@Configuration Configuration クラスであることを表します。
@PropertySource プロパティファイルを読み込むアノテーション
@Value フィールド単位で付与するアノテーションです。
@Value が付与されたフィールドは、プロパティファイルの設定値が代
入されます。
@Service ビジネスロジックを記述するクラスに付与します。Spirng のコンポー
ネントとして認識され、ApplicationContext に登録されることで、DI
対象のクラスとなります。
@Autowired 付与されたフィールドの型と合う Bean を自動的に Injection してくれ
ます。
@PostConstruct コンテナの初期化時に実行させたいメソッドに付加する。
@Repository DAO クラスに付与するアノテーション
@ModelAttribute 指定したクラスにリクエストパラメータをバインドします。
35
9.2. pom.xml について
pom.xml の<dependency>タグにプロジェクトで使用したい JAR ライブラリ名及びバージョンを指
定することで、外部サイトで集中管理されている JAR を自動ダウンロードし、ローカルでビルドに
使用することができる。JAR を手動でひとつずつダウンロードして設定する旧来の手法と比較し
て、容易にライブラリを管理・アップデートできる。例えば、開発チームでプロジェクトを共有したい
とき、pom.xml ファイルと必要なソースコード、リポジトリに登録されていない JAR ファイルを配布
するだけで済むようになる。
例
Thymeleaf による画面表示のための設定
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Web アプリを作るための設定
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Postgres を使用するための設定
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
データベースのテーブルのレコードと Java のオブジェクト間の相互変換
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
36
改訂履歴
バージョン 日付 担当 補足
V1.0.0 2018/10/17 kitayama@tech-arts.co.jp
V1.1.0 2018/11/13 arai@tech-arts.co.jp ノード可変対応に基づく修正
V1.2.0 2019/05/09 arai@tech-arts.co.jp ロゴ更新
7.1 UI リファレンス修正
7.6 他ノード連携修正
8.1 Rablock プロパティファイル
・auth setting
・node setting 追加

More Related Content

PDF
20150221 めとべや東京-プライベートコード共有サービス
PDF
マイクロフレームワークEnkan(とKotowari)ではじめるREPL駆動開発
PPTX
フリーでできるWebセキュリティ(burp編)
PPTX
20111203
PPT
20061125
PDF
WebSocket Chat App Hands On on Microsoft Azure
PPT
webstart-maven-pugin + 無償で正統?なコード署名証明書を入手する方法
PDF
owasp_evening_okinawa_7_owasp_top_10-2017_injection
20150221 めとべや東京-プライベートコード共有サービス
マイクロフレームワークEnkan(とKotowari)ではじめるREPL駆動開発
フリーでできるWebセキュリティ(burp編)
20111203
20061125
WebSocket Chat App Hands On on Microsoft Azure
webstart-maven-pugin + 無償で正統?なコード署名証明書を入手する方法
owasp_evening_okinawa_7_owasp_top_10-2017_injection

What's hot (20)

PDF
Vue.js で XSS
PDF
勉強会キット Windows Server 2012 R2 評価版 BYOD 編 v2 20131020 版
PDF
サーバレスを可能にするAWSサービスの概要
PDF
AWSを利用したアプリ開発
PDF
Spring bootでweb セキュリティ(ログイン認証)編
PDF
HTML5のセキュリティ もうちょい詳しく- HTML5セキュリティその3 : JavaScript API
PDF
Payara Scale (Hazelcast Enterprise) on Azure
PDF
Malwat4 20130223 analyzing_android_malware
PDF
SpringMVC
PDF
Rails3+devise,nginx,fluent,S3構成でのアクセスログ収集と蓄積
PDF
XSS再入門
PDF
flaws.cloudに挑戦しよう!
PDF
JAZUG女子部 第2回勉強会 ハンズオン
PDF
体系的に学ばないXSSの話
PDF
iOS の通信における認証の種類とその取り扱い
PPTX
はじめてのSpring Boot
PPT
【17-C-2】 クラウド上でのエンタープライズアプリケーション開発
PDF
Azure ADとIdentity管理
PPTX
Webアプリのセキュリティ対策入門(仮)
PDF
JavaScript.Next
Vue.js で XSS
勉強会キット Windows Server 2012 R2 評価版 BYOD 編 v2 20131020 版
サーバレスを可能にするAWSサービスの概要
AWSを利用したアプリ開発
Spring bootでweb セキュリティ(ログイン認証)編
HTML5のセキュリティ もうちょい詳しく- HTML5セキュリティその3 : JavaScript API
Payara Scale (Hazelcast Enterprise) on Azure
Malwat4 20130223 analyzing_android_malware
SpringMVC
Rails3+devise,nginx,fluent,S3構成でのアクセスログ収集と蓄積
XSS再入門
flaws.cloudに挑戦しよう!
JAZUG女子部 第2回勉強会 ハンズオン
体系的に学ばないXSSの話
iOS の通信における認証の種類とその取り扱い
はじめてのSpring Boot
【17-C-2】 クラウド上でのエンタープライズアプリケーション開発
Azure ADとIdentity管理
Webアプリのセキュリティ対策入門(仮)
JavaScript.Next
Ad

Similar to Rablock applicatin dev_guide_v1.2 (20)

PDF
20120528 aws meister-reloaded-awssd-kforjava-public
PDF
Building React, Flutter and Blazor development and debugging environment with...
PDF
jQuery と MVC で実践する標準志向 Web 開発
PDF
How to Make Own Framework built on OWIN
PDF
Right scaleの利用効果、苦労話 クラウドマネジメントツール勉強会
PPTX
msal.js v2を触る
PDF
SDLoader SeasarCon 2009 Whire
PPTX
Jhs portfolio
PDF
Aws elastic beanstalk-handson-summit2012
PPT
Iss seminar 2010709#1-upload
PDF
WebDriverで始めるUIスモークテスティング入門
PPTX
Hands on ARM template
PDF
Wakame-VDC / Open Source Conferense 2012 - Cloud (JP)
PPTX
Cloud Native Application on DEIS by using 12 factor
PDF
クラウド開発に役立つ OSS あれこれ
PDF
Vagrant on SoftLayer
PPTX
クラウド移行で改善するガバナンスファーストのWebサービス障害対策について
PPTX
microPCFを使ってみよう
PDF
クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)
PDF
とある診断員と色々厄介な脆弱性達
20120528 aws meister-reloaded-awssd-kforjava-public
Building React, Flutter and Blazor development and debugging environment with...
jQuery と MVC で実践する標準志向 Web 開発
How to Make Own Framework built on OWIN
Right scaleの利用効果、苦労話 クラウドマネジメントツール勉強会
msal.js v2を触る
SDLoader SeasarCon 2009 Whire
Jhs portfolio
Aws elastic beanstalk-handson-summit2012
Iss seminar 2010709#1-upload
WebDriverで始めるUIスモークテスティング入門
Hands on ARM template
Wakame-VDC / Open Source Conferense 2012 - Cloud (JP)
Cloud Native Application on DEIS by using 12 factor
クラウド開発に役立つ OSS あれこれ
Vagrant on SoftLayer
クラウド移行で改善するガバナンスファーストのWebサービス障害対策について
microPCFを使ってみよう
クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)
とある診断員と色々厄介な脆弱性達
Ad

Rablock applicatin dev_guide_v1.2

  • 3. 3 目次 本ガイドに関して......................................................................................................................................... 2 アプリケーション環境.............................................................................................................................. 2 1. Rablock 接続の基本............................................................................................................................. 5 1.1. HTTP ダイジェスト認証............................................................................................................... 5 1.2. Rablcok UI の呼び出し ................................................................................................................ 7 1.2.1. コールする Rablock UI の URL を作成します。 ............................................................... 7 1.2.2. HTTP コネクションオブジェクトの作成.............................................................................. 7 1.2.3. 接続設定(メソッドの決定,ヘッダー値等).......................................................................... 7 1.2.4. JSON データの準備(リクエストボディの書き込み) ............................................................ 8 1.2.5. コネクションを開く............................................................................................................... 8 1.2.6. レスポンスの読み出し ........................................................................................................... 9 1.2.7. コネクションのクローズ........................................................................................................ 9 2. Spring Boot ........................................................................................................................................ 10 3. MVC.................................................................................................................................................... 11 4. STS でハンズオン.............................................................................................................................. 12 4.1. HelloWorld .................................................................................................................................. 12 5. Rablock アプリケーション開発ハンズオンのため準備 .................................................................... 13 5.1. Java (1.8) のインストール ......................................................................................................... 13 5.2. PostgreSQL のインストール ...................................................................................................... 13 5.3. PostgreSQL の設定..................................................................................................................... 13 5.3.1. 初期化................................................................................................................................... 13 5.3.2. DB 操作用アカウントと DB 作成........................................................................................ 13 5.3.3. 設定ファイル postgresql.conf の編集 ................................................................................ 14 5.3.4. 設定ファイル pg_hba.confi の編集 .................................................................................... 14 5.3.5. PostgreSQL の再起動 ......................................................................................................... 14 5.4. テーブルの作成............................................................................................................................ 15 5.5. DB 認証の有効化設定.................................................................................................................. 16 5.6. その他 .......................................................................................................................................... 16 5.7. Rablock サーバ接続の設定.......................................................................................................... 17 6. Rablock アプリケーションハンズオン............................................................................................... 18 6.1. データ登録処理の例 .................................................................................................................... 18 6.2. データ全件取得処理 .................................................................................................................... 20 6.3. データ取得処理............................................................................................................................ 23 7. Rablock UI.......................................................................................................................................... 25 7.1. Rablock UI リファレンス........................................................................................................... 25
  • 4. 4 7.2. ブロック生成 UI......................................................................................................................... 26 7.3. データ取得................................................................................................................................... 28 7.4. データ登録................................................................................................................................... 29 7.5. トランザクションの伝播............................................................................................................. 30 7.6. 他ノード連携 ............................................................................................................................... 30 8. プロパティファイル............................................................................................................................ 31 8.1. Rablock プロパティファイル...................................................................................................... 31 8.2. Mining プロパティファイル ....................................................................................................... 32 8.3. 画面プロパティファイル............................................................................................................. 33 9. 参考資料.............................................................................................................................................. 34 9.1. アノテーション............................................................................................................................ 34 9.2. pom.xml について ....................................................................................................................... 35 改訂履歴 ..................................................................................................................................................... 36
  • 5. 5 1. Rablock 接続の基本 アプリケーションプログラムから Rablock に接続し操作を行うためには Rablock UI を使用します。 Rablock UI を使用する手順は、次の手順となります。 1. HTTP ダイジェスト認証 2. Rablock UI のコール(REST コール) 3. 結果の読出し 4. コネクションのクローズ 1.1. HTTP ダイジェスト認証 Rablock UI の多くは、ユーザ名とパスワードを使用して HTTP ダイジェスト認証方式により認証され、 その実行が認可されます。 Java から Rablock UI を次のようなコードで認証を行います。 ※ダイジェスト認証とは、HTTP の認証方法の一つ。ユーザ名とパスワードを MD5 でハッシュ (ダイジェスト)化して送る。Basic 認証では防げなかった盗聴や改竄を防ぐために考案され た。 // ユーザ認証情報の設定 // import java.net.Authenticator; // HttpAuthenticator httpAuth = new HttpAuthenticator(userName, userPass); Authenticator.setDefault(httpAuth);
  • 6. 6 ※ダイジェスト認証の仕組み ①あらかじめサーバ側にパスワードの MD5 メッセージダイジェストを保存しておきます (ユーザ登録 に相当)。 ②クライアントが Digest 認証を行うページにやってくると、サーバはクライアントにランダムな文字 列を渡します。 ③クライアントはパスワードの MD5 メッセージダイジェストを生成します。 ④さらにクライアントは、生成したメッセージダイジェストの末尾に、サーバから受け取ったランダム な文字列をくっつけて、 ひとつの文字列にします。 ⑤クライアントは、生成した文字列全体の MD5 メッセージダイジェストをサーバに送信します。 な お、このときサーバから送られてきたランダムな文字列もそのまま送り返します。 ⑥サーバは、あらかじめ用意してあったパスワードの MD5 メッセージダイジェストの末尾に、 クラ イアントから送られてきたランダムな文字列 (元々はサーバが生成したもの) をくっつけて、 ひとつの 文字列にします。 ⑦サーバは、この文字列全体の MD5 メッセージダイジェストを生成し、 クライアントから送信され てきたメッセージダイジェストと比較します。 もし一致したら認証成功・一致しなかったら失敗で す。 Basic 認証とは異なり、ネットワーク上を生パスワードが流れることはありませんので、 盗聴に対し て安全です。また、サーバ側に生パスワードを保存する必要がないのもポイントです。
  • 7. 7 1.2. Rablcok UI の呼び出し Rablock UI は、REST API です。 例では、Rablock にデータを登録するために /post/json をコールするまでの一連の手順を説明します。 1.2.1. コールする Rablock UI の URL を作成します。 ここでは、/post/json です URL 文字列のサーバ名、ポートなどは各自の環境に応じて修正してください。 ...には Rablock サーバを指定してください。 1.2.2. HTTP コネクションオブジェクトの作成 con は、HttpURLConnection con = null; として有効域内で定義されている変数です。 1.2.3. 接続設定(メソッドの決定,ヘッダー値等) // RaBlock へデータを登録するコールの URL の作成 URL connectUrl = new URL("http://.../post/json/"); // コネクションオブジェクトの作成 con = (HttpURLConnection) connectUrl.openConnection(); // HTTP コネクションの設定(POST コールで JSON 文字列を送信する設定など) con.setDoOutput(true); con.setRequestMethod("POST"); con.setRequestProperty("Accept-Language", "jp"); // データが JSON であること、エンコードを指定する con.setRequestProperty("Content-Type", "application/JSON; charset=utf-8"); // POST データの長さを設定 con.setRequestProperty("Content-Length", String.valueOf(json.length()));
  • 8. 8 1.2.4. JSON データの準備(リクエストボディの書き込み) out.write() の引数 json は、任意の JSON テキストがセットされている String 変数です。 1.2.5. コネクションを開く 接続することで POST リクエストが実行され、アウトプットストリームが生成されます。 アウトプットを読みこんで必要な処理を行い、最後に HTTP の接続を切断します。 // リクエストの body に JSON 文字列を書き込む OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream()); out.write(json); out.flush(); out.close(); con.connect();
  • 9. 9 1.2.6. レスポンスの読み出し 1.2.7. コネクションのクローズ // 切断 if (con != null) { con.disconnect(); } int status = con.getResponseCode(); if (status == HttpURLConnection.HTTP_OK) { // 通信に成功した // テキストを取得する final InputStream in = con.getInputStream(); String encoding = con.getContentEncoding(); if (null == encoding) { encoding = "UTF-8"; } final InputStreamReader inReader = new InputStreamReader(in, encoding); final BufferedReader bufReader = new BufferedReader(inReader); String line = null; // 1 行ずつテキストを読み込む while ((line = bufReader.readLine()) != null) { result.append(line); } bufReader.close(); inReader.close(); in.close(); }
  • 10. 10 2. Spring Boot Spring Boot は、Spring Framework ベースの Java アプリケーションを簡易に行うことができる開 発フレームワークであり、MVC を基にした Spring MVC フレームワークの膨大なライブラリや複雑 な設定を簡単に開発することが出来るように作られています。 Spring Framework の開発グループが提供している統合開発環境 STS(Spring Tool Suite)を利用するこ とでさらに開発を手軽に行うことができます。 STS は、Eclipse ベースの IDE で Spring Framework ベースのアプリケーションの開発のための機 能が豊富に用意されています。 Spring Boot では、設定ファイルの記述量の軽減、多数に定義された有用なアノテーションの利用、 Web コンテナ(デフォルトでは Tomcat)を含んだ jar ファイルの生成が出来るなど、コーディング負 荷を大幅に軽減することができるようになっています。
  • 11. 11 3. MVC MVC は、Web アプリケーションを含め画面をもつアプリケーションのためのフレームワークです。 Model、View、Controller の頭文字をとって MVC となっています。 Model: 使用するデータ(データモデル)を制御するブロックで、データクラス、外部ファイル、外部 データベースとの入出力を行います。 View: 画面の表現と動作、入出力を制御するブロックです。Web アプリケーションであれば、ページ テンプレート、スタイルシート、フォームを含むページ本体(HTML 等)、ページの動作制御のための JavaScript コード等は View に相当します。 Controller: View からデータもしくはイベントを受け取り、適切に Model に処理させるための指示を 行い、その結果の View への返答を制御します。Model と View の間に入りデータの送受信制御と アプリケーションロジックを記述します。 MVC では、これらの Model, View, Controller をそれぞれの部分の役割を区分し開発を行います。
  • 12. 12 4. STS でハンズオン ここでは、STS を実際に使用して、簡単はプログラムを作ってみます。 4.1. HelloWorld 手順: 1. Java のインストール 2. STS のインストール 3. STS の起動 4. 新規プロジェクトの作成 5. コントローラーの作成 6. HTML ファイルの作成 7. 実行 詳細手順は、別にお配りするハンドアウトを参照して下さい。
  • 13. 13 5. Rablock アプリケーション開発ハンズオンのため準備 5.1. Java (1.8) のインストール 5.2. PostgreSQL のインストール 5.3. PostgreSQL の設定 5.3.1. 初期化 5.3.2. DB 操作用アカウントと DB 作成 $ sudo yum install -y java $ sudo yum install -y postgresql-jdbc postgresql-server $ sudo postgresql-setup initdb $ sudo systemctl start postgresql $ sudo systemctl enable postgresq $ sudo adduser attendance $ sudo su - postgres -bash-4.2$ createuser attendance -bash-4.2$ createdb -O attendance attendance -bash-4.2$ exit
  • 14. 14 5.3.3. 設定ファイル postgresql.conf の編集 postgresql.conf の listen_addresses に’*’を指定します。 5.3.4. 設定ファイル pg_hba.confi の編集 pg_hba.conf に 0.0.0.0 のエントリを追記します。 5.3.5. PostgreSQL の再起動 $ sudo vi /var/lib/pgsql/data/postgresql.conf $ sudo vi /var/lib/pgsql/data/pg_hba.conf $ sudo systemctl restart postgresql listen_addresses = '*' # what IP address(es) to listen on; # comma-separated list of addresses; # defaults to 'localhost'; use '*' for all ... … host all all 0.0.0.0/0 md5 …
  • 15. 15 5.4. テーブルの作成 PostgreSQL で使用するテーブルを作成します。(psql を使用する例) $ sudo su - attendance $ psql -d attendance ALTER ROLE attendance WITH PASSWORD ‘uj9woRzLWS6h7VAh3iOI2GxfXlitbM3m’; CREATE TABLE user_account( id SERIAL , user_id VARCHAR(64) PRIMARY KEY , user_name VARCHAR(64) , department VARCHAR(128) ); CREATE TABLE user_summary( id SERIAL , user_id VARCHAR(64) , year VARCHAR(8) , month VARCHAR(8) , total VARCHAR(8) ,PRIMARY KEY(user_id,year,month)); CREATE TABLE user_info( id SERIAL , user_id VARCHAR(64) PRIMARY KEY , password VARCHAR(128) , role VARCHAR(32) , enabled INT ); $ exit psql は、【¥q】 で終了します。
  • 16. 16 5.5. DB 認証の有効化設定 5.6. その他 zip ファイルを展開し、必要なファイルを取り出します $ sudo vi /var/lib/pgsql/data/pg_hba.conf # "local" is for Unix domain socket connections only local all all md5 # IPv4 local connections: host all all 127.0.0.1/32 md5 # IPv6 local connections: host all all ::1/128 md5 ... $ sudo systemctl restart postgresql $ cd ~ $ mkdir apps $ unzip -q 20181004.zip $ cd 20181004/history $ mv * ~/apps/ $ cd ~
  • 17. 17 5.7. Rablock サーバ接続の設定 $ cd apps $ vi ip-history.properties blockchain_ip.value=<Rablock サーバ 1 台目のプライベート IP> … login_user.value=<管理者のユーザ名> login_password.value=<管理者のパスワード>
  • 18. 18 6. Rablock アプリケーションハンズオン Rablock に対するコールは、Spring Boot では、controller にコードを記述します。 デモサンプルでは、SendBlockChain クラスにすべての Rablock に対するコールを各メソッドに記述 しています。 6.1. データ登録処理の例 SendBlockChain クラスの restSubmit メソッドは、引数に渡された JSON テキストをデータとして Rablock にトランザクションデータを送信します。 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; public String restSubmit(String json, String ip, String port) throws IOException { StringBuffer result = new StringBuffer(); HttpURLConnection con = null; try { String apiUrl = "http://" + ip + ":" + port + "/post/json/"; URL connectUrl = new URL(apiUrl); con = (HttpURLConnection) connectUrl.openConnection(); con.setDoOutput(true); con.setRequestMethod("POST"); con.setRequestProperty("Accept-Language", "jp"); // データが JSON であること、エンコードを指定する con.setRequestProperty("Content-Type", "application/JSON; charset=utf-8"); // POST データの長さを設定 con.setRequestProperty("Content-Length", String.valueOf(json.length()));
  • 19. 19 // リクエストの body に JSON 文字列を書き込む OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream()); out.write(json); out.flush(); out.close(); con.connect(); int status = con.getResponseCode(); if (status == HttpURLConnection.HTTP_OK) { // 通信に成功した // テキストを取得する final InputStream in = con.getInputStream(); String encoding = con.getContentEncoding(); if (null == encoding) { encoding = "UTF-8"; } final InputStreamReader inReader = new InputStreamReader(in, encoding); final BufferedReader bufReader = new BufferedReader(inReader); String line = null; // 1 行ずつテキストを読み込む while ((line = bufReader.readLine()) != null) { result.append(line); } bufReader.close(); inReader.close(); in.close(); } else { // 通信が失敗した場合のレスポンスコードを表示 System.out.println("status" + status); } } finally { if (con != null) { // コネクションを切断 con.disconnect(); } } return result.toString(); }
  • 20. 20 6.2. データ全件取得処理 Rablock に格納されているデータ(サーバープール、ブロック)を取得するコードの例です。 import java.net.Authenticator; public String getAll(String ip, String port) throws IOException { StringBuffer result = new StringBuffer(); HttpURLConnection con = null; try { String apiUrl = "http://" + ip + ":" + port + "/get/alltxdata"; URL connectUrl = new URL(apiUrl); // ユーザ認証情報の設定 HttpAuthenticator httpAuth = new HttpAuthenticator(DIGEST_USERNAME, DIGEST_PASS); Authenticator.setDefault(httpAuth); con = (HttpURLConnection) connectUrl.openConnection(); con.setDoOutput(true); con.setInstanceFollowRedirects(true); int status = con.getResponseCode(); if (status == HttpURLConnection.HTTP_OK) { // 通信に成功した // テキストを取得する final InputStream in = con.getInputStream(); String encoding = con.getContentEncoding(); if (null == encoding) { encoding = "UTF-8"; } final InputStreamReader inReader = new InputStreamReader(in, encoding); final BufferedReader bufReader = new BufferedReader(inReader); 次ページに続く
  • 21. 21 String line = null; // 1 行ずつテキストを読み込む while ((line = bufReader.readLine()) != null) { result.append(line); } bufReader.close(); inReader.close(); in.close(); } else { // 通信が失敗した場合のレスポンスコードを表示 System.out.println(status); } } finally { if (con != null) { // コネクションを切断 con.disconnect(); } } return result.toString(); }
  • 22. 22 HttpAuthenticator クラス import java.net.Authenticator; import java.net.PasswordAuthentication; public class HttpAuthenticator extends Authenticator { private final String username; private final String password; public HttpAuthenticator(String username, String password) { if (username == null || password == null) throw new IllegalArgumentException("username or password is null."); this.username = username; this.password = password; } public String getUsername() { return this.username; } public String getPassword() { return this.password; } @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(this.username, this.password.toCharArray()); } }
  • 23. 23 6.3. 任意の項目と値でデータ取得処理 public String getByJson(String json, String ip, String port) throws IOException { StringBuffer result = new StringBuffer(); HttpURLConnection con = null; try { String apiUrl = "http://" + ip + ":" + port + "/get/json"; URL connectUrl = new URL(apiUrl); // ユーザ認証情報の設定 HttpAuthenticator httpAuth = new HttpAuthenticator(DIGEST_USERNAME, DIGEST_PASS); Authenticator.setDefault(httpAuth); con = (HttpURLConnection) connectUrl.openConnection(); con.setInstanceFollowRedirects(true); con.setRequestMethod("GET"); con.setDoOutput(true); con.setRequestProperty("Accept-Language", "jp"); con.setRequestProperty("Content-Type", "application/JSON; charset=utf-8"); con.setRequestProperty("Content-Length", String.valueOf(json.length())); // リクエストの body に JSON 文字列を書き込む OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream()); out.write(json); out.flush(); out.close(); con.connect(); int status = con.getResponseCode(); if (status == HttpURLConnection.HTTP_OK) { // 通信に成功した // テキストを取得する final InputStream in = con.getInputStream(); String encoding = con.getContentEncoding(); if (null == encoding) { encoding = "UTF-8"; } final InputStreamReader inReader = new InputStreamReader(in, encoding); 次ページに続く
  • 24. 24 // 通信に成功した // テキストを取得する final InputStream in = con.getInputStream(); String encoding = con.getContentEncoding(); if (null == encoding) { encoding = "UTF-8"; } final InputStreamReader inReader = new InputStreamReader(in, encoding); final BufferedReader bufReader = new BufferedReader(inReader); String line = null; // 1 行ずつテキストを読み込む while ((line = bufReader.readLine()) != null) { result.append(line); } bufReader.close(); inReader.close(); in.close(); } else { // 通信が失敗した場合のレスポンスコードを表示 System.out.println(status); } } finally { if (con != null) { // コネクションを切断 con.disconnect(); } } return result.toString(); } } }
  • 25. 25 7. Rablock UI 7.1. Rablock UI リファレンス Rablock に対する操作は Rablock UI をコールすることで行います。 Rablock UI は、Web API で、REST に基づいて実装されています UI 一覧 カテゴリ UI 名 メソッド 説明 ブロック生成 /mining POST 新規ブロックを生成する。 データ取得 /get/json GET 任意の項目と値(JSON)でデータ取得(更 新・削除対象のデータは除く) /get/searchoid/{$oid} GET 指定されたオブジェクト ID($oid)のトラ ンザクションデータを取得。 /get/alltxdata GET 全てのトランザクションデータ全件取得。 /get/block GET 全てのブロックを取得。 /get/pool GET トランザクションプールにあるトランザ クションデータ全件取得。 /get/lastblock GET 最後のブロックのヘッダー情報を取得。 /get/deliveredpool GET 伝搬済みのトランザクションデータを取 得 /get/totalnumber GET ブロック内のデータ件数の合計を取得 history/{$oid} GET 指定されたオブジェクト ID($oid)のトラ ンザクションデータを削除、更新も含め取 得。 データ登録 /post/json POST テキストデータを登録する。 伝搬 /delivery/deliverypool POST トランザクションプールを伝搬する。 他ノード連携 /sync/gen POST ジェネシスブロックを生成し、各ノードに 伝播する。 /sync/poolsync POST トランザクションプールの同期処理をす る。 /sync/blocksync POST ブロックテーブルの同期処理をする。
  • 26. 26 7.2. ブロック生成 UI /mining は、Rablock のブロックチェーンに新たなブロックを生成して加えるコマンドです。 Rablock は、トランザクションプールが保持しているトランザクションを収集し、ブロックを生成し ます。 ブロックの生成に成功した後に、トランザクションプールからブロックに格納したトランザクション データを消去します。 各 Rablock サーバには、crontab により定期的に /mining が実行するように設定されています。 次ページは、/mining が生成したブロックのサンプルです。 Rablock サーバの crontab に次の一行が追加されていれば、定期的にブロックマイナーが起動し、新 たなブロックを生成します。 ... には Rablock サーバを指定してください。 毎時 0 分、10 分、20 分、30 分、40 分、50 分と 10 分間隔でマイニングが行われる設定です。 他のサーバで同時刻にマイニングが発生するとほぼ同じブロックが生成され、ブロックがフォークし ます。フォークは定期処理によって解消されます。 動作上は問題ありませんが、無駄な処理になりますので、他のサーバでは、同じ 10 分間隔であっても 異なった時間を指定します。 0,10,20,30,40,50 * * * * curl -X POST http://.../mining
  • 27. 27 { _id : ObjectId("5b5ea33d3ff7d81ef5794313"), height : 1, size : 2, data : [ { _id : ObjectId("5b5ea2fa3ff7d81ef579430a"), type : "modify", original_id : "5b5e77e23ff7d80f20bbcf2a", user_id : "T003", startDate : "2018/07/30", startTime : "11:00:00", endDate : "2018/07/30", endTime : "18:00:00", note : "", settime : "2018/07/30 14:32:42", deliveryF : true }, { _id : ObjectId("5b5ea3023ff7d81ef579430c"), type : "new", user_id : "T003", startDate : "2018/07/30", startTime : "14:32:00", endDate : "2018/07/30", endTime : "18:00:00", note : "", settime : "2018/07/30 14:32:50", deliveryF : true } ], settime : "2018/07/30 14:33:48", timestamp : "1532928828900", prev_hash : "403e0e78a0fbb5f47c7b16da49289e529f02cf2f567b3e1690e800bf3412401", hash : "ae4c2c773a9e1e4fdc3e0b4e00c75277fd193bfb25f4d7f06d3a31cfc280f4f0" }
  • 28. 28 7.3. データ取得 アプリケーションプログラムからコールすることが最も多いのがデータ取得系のコマンドです。 取得したデータは、JSON 形式のトランザクションデータです。 /get/json で取得したトランザクションデータの例 { _id : ObjectId("5b5ea2fa3ff7d81ef579430a"), type : "modify", original_id : "5b5e77e23ff7d80f20bbcf2a", user_id : "T003", startDate : "2018/07/30", startTime : "11:00:00", endDate : "2018/07/30", endTime : "18:00:00", note : "", settime : "2018/07/30 14:32:42", deliveryF : true }, { _id : ObjectId("5b5ea3023ff7d81ef579430c"), type : "new", user_id : "T003", startDate : "2018/07/30", startTime : "14:32:00", endDate : "2018/07/30", endTime : "18:00:00", note : "", settime : "2018/07/30 14:32:50", deliveryF : true }
  • 29. 29 7.4. データ登録 Rablock にトランザクションデータを投入するコマンド /post/json です。 POST メソッドの送信データには JSON 形式のトランザクションデータを渡します。 トランザクションデータは、type, user_id (type の値が modify, delete の場合は、original _id 要素 が必要)に続けて JSON 要素をアプリケーション設計で定義したデータモデルに合うように記述しま す。 例) {type: “new”, user_id: 999, …………..} Rablock へのトランザクションデータの登録は、通常は新規データとして登録されますが、論理更新、 論理削除としてデータを登録することが出来ます。 データの論理更新、論理削除には、type 要素をそれぞれ modify、delete を指定し、続く original_id 要素に対象となるトランザクションデータの _id を指定します。 論理更新のトランザクションデータの例 { type: "modify", original_id: "5b3c72f2702ac809b8812921", user_id : 456 startDate : "2018/07/18", startTime : "9:50", endDate : "2018/07/18", endTime : "21:00", }
  • 30. 30 7.5. トランザクションの伝播 /delivery/deliverypool コマンドは、トランザクションプールに保存されたトランザクションデータを 他ノードに伝播します。 伝播先のサーバは、受け取ったトランザクションデータを自身のトランザクションプールに保存しま す。 このコマンドは、各サーバの crontab で一定間隔ごとに実行されるように設定されており、管理者が 手動で発行する必要はありません。 ...には Rablock サーバを指定してください。 7.6. 他ノード連携 /sync/gen、/sync/poolsync、/sync/ blocksync の 3 コマンドは、他のノードとの間で保持しているブロ ックの同期を行うコマンドです。 /sync/gen は、Rablock の導入後に 1 度だけ実行し、ブロックチェーンの最初のブロックを生成し、そ れを他ノードに伝播します。 /sync/poolsync は、トランザクションプールの同期をとります。 自ノードに存在しない伝搬フラグが True のデータを、他ノードを参照し、追加します。 /sync/blocksync は、以下の3つの処理を実行しブロックチェーンの同期をとります。 1. 破損もしくは改竄されたブロックを必要に応じて他ノードを参照し、修復します。 2. 自ノードの過不足なブロックを他ノードを参照し、削除、または追加します。 3. ブロックチェーンの枝分かれ(fork)を検知し、優先順位の高い枝を選択し、それ以外の枝にあ るブロックのトランザクションデータのうち、選択した枝に存在していないトランザクションを トランザクションプールに戻すことで枝分かれを修復し、他ノードにも修復を伝播します。 0,5,10,15,20,25,30,35,40,45,50,55 * * * * curl -X POST http://.../delivery/deliverypool
  • 31. 31 8. プロパティファイル Rablock システムには、2 つのプロパティファイルがあります。 1 つは、Rablock サーバ本体の設定用、もう一つは、ブロック生成モジュール(ブロックマイナー)の 設定用です。 また、本ガイドで使用しているサンプルアプリケーションでは、アプリケーションの設定のプロパティ ファイルを使用しています。 8.1. Rablock プロパティファイル 設定項目 備考 server.port=9000 Rablock を起動するポート #mongo setting (MongoDB の設定) spring.data.mongodb.port=27017 MongoDB のポート spring.data.mongodb.database=bcdb 使用データベース名 spring.data.mongodb.username=bcuser MongoDB のユーザー名 spring.data.mongodb.password=1234 MongoDB のパスワード spring.data.mongodb.collection.pool=pool プールのコレクション名 spring.data.mongodb.collection.block=block ブロックのコレクション名 #auth setting (ダイジェスト認証の設定) digest.username=AAA ユーザー名 digest.pass=BBB パスワード #ip setting (Rablock の連携設定) send.ip[0] =12.345.678.910 連携ノードの IP #1 send.ip[1]=56.789.101.234 連携ノードの IP #2 send.port[0] =9000 連携ノードのポート #1 send.port[1]=9000 連携ノードのポート #2 #log setting (ログの設定) 次ページに続く
  • 32. 32 設定項目 備考 #spring.profiles.active=production この項目を指定しない場合標準出力(コメントに するか削除) spring.profiles.active=production この項目がある場合、指定した場所にログファイ ルを出力 logging.file=/home/ec2-user/controller.log spring.profiles.active=production の時のみ有効。 出力先を指定 #crypto setting (暗号化の設定) crypto.status=OFF 暗号化 OFF key.file=null 鍵ファイル必要ないため null を設定 #crypto.status=ON 暗号化 ON #key.file=/xxx/xxxx/private_key.pk8 秘密鍵のパスを指定 #node setting (ノードモードの設定) send.nodemode=multi 複数ノードモードの場合「multi」を設定 #send.nodemode=single 単一ノードモードの場合「single」を設定 8.2. Mining プロパティファイル 設定項目 備考 server.port=8000 Mining プログラムを起動するポート server_name.value=#1 サーバ名 ※ブロックを生成したサーバ名を項目 に設定する際に使用 #ip setting (Rablock の設定) blockchain_ip.value=127.0.0.1 起動している Rablock の IP アドレス blockchain_port.value=9000 起動している Rablock のポート番号
  • 33. 33 8.3. 画面プロパティファイル 設定項目 備考 server.port=8080 画面アプリを起動するポート #login setting (ログインの設定) login_user.value=loginuser 管理者のユーザ名 login_password.value=loginpass パスワード #DataSource settings for Postgesql (Postgres の設定) spring.datasource.driver-class-name=org.postgresql.Driver spring.datasource.url=jdbc:postgresql://localhost:5432/postgres spring.datasource.username=postgres spring.datasource.password=postgres #Rablock setting (Rablock の設定) blockchain_ip.value=18.222.254.199 起動している Rablock の IP アド レス blockchain_port.value=9000 起動している Rablock のポート番 号 #crypto setting (暗号化の設定 Rablock が ON の 場合画面も ON、OFF なら OFF) crypto.status=OFF 暗号化 OFF private.key.file =null 鍵ファイル必要ないため null を設 定 public.key.file =null 鍵ファイル必要ないため null を設 定 #crypto.status=ON 暗号化 ON # private.key.file =/xxx/xxxxx/private_key.pk8 復号化するための秘密鍵のパスを 指定 # public.key.file =/xxx/xxxxx/public_key.der 暗号化するための公開鍵のパスを 指定
  • 34. 34 9. 参考資料 9.1. アノテーション アノテーション 説明 @SpringBootApplication @SpringBootApplication を付与したクラスは自身が Spring Boot ア プリケーションであることを示します。 @Controller Web ページ用のコントローラで使用する。 Web ページ用コントローラは JSP やテンプレートエンジンの View に 遷移してレスポンスの HTML を生成するので、基本的にメソッドの戻 り値は View の遷移先を指定するのに使用します。 @RequestMapping クライアントからのリクエストに対してメソッドやハンドラをマッピ ングします。 @GetMapping @RequestMapping の GET リクエスト用のアノテーション @PostMapping @RequestMapping の POST リクエスト用のアノテーション @Configuration Configuration クラスであることを表します。 @PropertySource プロパティファイルを読み込むアノテーション @Value フィールド単位で付与するアノテーションです。 @Value が付与されたフィールドは、プロパティファイルの設定値が代 入されます。 @Service ビジネスロジックを記述するクラスに付与します。Spirng のコンポー ネントとして認識され、ApplicationContext に登録されることで、DI 対象のクラスとなります。 @Autowired 付与されたフィールドの型と合う Bean を自動的に Injection してくれ ます。 @PostConstruct コンテナの初期化時に実行させたいメソッドに付加する。 @Repository DAO クラスに付与するアノテーション @ModelAttribute 指定したクラスにリクエストパラメータをバインドします。
  • 35. 35 9.2. pom.xml について pom.xml の<dependency>タグにプロジェクトで使用したい JAR ライブラリ名及びバージョンを指 定することで、外部サイトで集中管理されている JAR を自動ダウンロードし、ローカルでビルドに 使用することができる。JAR を手動でひとつずつダウンロードして設定する旧来の手法と比較し て、容易にライブラリを管理・アップデートできる。例えば、開発チームでプロジェクトを共有したい とき、pom.xml ファイルと必要なソースコード、リポジトリに登録されていない JAR ファイルを配布 するだけで済むようになる。 例 Thymeleaf による画面表示のための設定 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> Web アプリを作るための設定 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> Postgres を使用するための設定 <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> データベースのテーブルのレコードと Java のオブジェクト間の相互変換 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
  • 36. 36 改訂履歴 バージョン 日付 担当 補足 V1.0.0 2018/10/17 kitayama@tech-arts.co.jp V1.1.0 2018/11/13 arai@tech-arts.co.jp ノード可変対応に基づく修正 V1.2.0 2019/05/09 arai@tech-arts.co.jp ロゴ更新 7.1 UI リファレンス修正 7.6 他ノード連携修正 8.1 Rablock プロパティファイル ・auth setting ・node setting 追加