先までは、"愛記"についての記載で、どのようにブロックチェーンSNSに組み込んで実装していけばよいのか、概念的なところからアプローチ方法を記載していった。大まかな概念としてはひとまず終えた。次は、ブロックチェーンの概念設計といえるところまで、基本設計書に着手できるようなところまで、概念を具体化していきたい。
愛記システムのシステム評価について
システム評価とは、つまりは、このシステムを導入して成功だったか失敗だったかという効果検証という意味だ。概念設計をする上で必ず抑えておくべきポイントということだ。それには各項目があり、それぞれの項目を見ていくことで、その結果が得られる。そのシステム評価項目を1つずつ見ていきたい。
システム構築の品質評価のポイント1:理解可能性(Understandability)
システム構築の品質評価のポイント2:完全性(Completeness)
システム構築の品質評価のポイント3:簡潔性(Conciseness)
システム構築の品質評価のポイント4:移植性(Portability)
システム構築の品質評価のポイント5:一貫性(Consistency)と構造化の度合い
システム構築の品質評価のポイント6:保守性(Maintainability)
システム構築の品質評価のポイント7:試験性(Testability)
システム構築の品質評価のポイント8:ユーザビリティ(Usability)
システム構築の品質評価のポイント9:効率性(Efficiency)
システム構築の品質評価のポイント10:セキュリティ(Security)
システム構築の品質評価のポイント7:試験性④(Testability)
システム構築の品質評価ポイントとなっている試験性とは、不具合があるかどうかを確認するための各種テスト項目が簡単に実施できるかどうかである。不具合があった際にその不具合が階層まで調査する必要があり、見つけるまで非常に時間がかかるのは問題である。この試験性は先ほど記載した保守性と非常に関連性があり、試験性の高さは保守性の高さに繋がる。逆に低いと保守性の品質評価も下がる。
さて、試験性の定義として、7つの特性があるのでそれぞれについて見ていこう。
- 実行円滑性(Operability)
- 観測容易性(Observability)
- 制御容易性(Controllability)
- 分解容易性(Decomposability)
- 単純性(Simplicity)
- 安定性(Stability)
- 理解容易性(Understandability)
これらの特性はJames Bach著『ソフトウェアテスト293の法則』やRoger S. Pressman著『実践ソフトウェアエンジニアリング』 で挙げられている。
6. 安定性(Stability)
同じ条件や環境で何度テストしても、一貫した振る舞いができるかという特性である。なお、コンポーネントの安定度についても、実行結果が不安定ではないことを含む。例えば次のような状況は、安定性が低い。
・変更が頻繁で、テストへの影響が大きい
・外部環境へアクセスしたり、乱数や時刻を使用したりして、同じ条件下でも結果が安定しない
ここもまさにであり、安定性が低いと言える。バリデーター問題など、常に不安定な中で如何に安定させるかということが課題となる。
安定性を確保するために、バリデーターのコンポーネントが変更に頻繁に対応することなく、テストの影響を最小限に抑えつつ、外部環境の不確実性に対処する方法を検討する。以下は、この課題に対処するためのアプローチの例である。
-
変更の最小化: バリデーターのコンポーネントが変更に強くなるように、コードのモジュラリティを高め、機能を適切な粒度に分割する。これにより、変更が頻繁に発生しても、影響範囲を限定できる。
-
テストの自動化: バリデーターのコンポーネントに対して十分なテストカバレッジを確保し、変更が行われた際に影響を検知できるようにする。これにより、変更があってもテストが早期にフィードバックを提供し、不安定性を減少させる。
-
外部環境の制御: 外部環境へのアクセスや乱数、時刻の使用に関しては、これらを制御可能な形に変更する。外部依存を最小限にし、制御できるパラメータや設定を導入することで、同じ条件下での結果の安定性を向上させる。
以下は、この例では、perform_validationメソッド内で外部環境に依存せず、内部で乱数を生成している。これにより、外部環境の変動に対してコンポーネントが安定した振る舞いを示すことが期待される。
# フェデレーションモデルにおける安定性向上のプログラミング例
import random
class Validator:
def __init__(self, validator_id):
self.validator_id = validator_id
self.stability_threshold = 0.95 # 安定性のしきい値
def validate_transaction(self, transaction):
# トランザクションの検証ロジック
validation_result = self.perform_validation(transaction)
# 安定性の計算と判断
stability = self.calculate_stability(validation_result)
if stability >= self.stability_threshold:
return True # トランザクションが安定している場合は承認
else:
return False # トランザクションが不安定な場合は非承認
def perform_validation(self, transaction):
# 実際のトランザクション検証ロジック
# 例えば、外部環境に依存せず、内部で乱数を生成するなど
random_value = self.generate_random_value()
if random_value > 0.5:
return True
else:
return False
def calculate_stability(self, validation_result):
# 安定性の計算ロジック
# 例えば、過去の検証結果を利用して安定性を算出するなど
pass
def generate_random_value(self):
# 外部環境に依存しない乱数生成
return random.uniform(0, 1)
# 利用例
# バリデーターのインスタンス化
validator_A = Validator("Validator A")
# 安定性が高い場合のトランザクション
stable_transaction = {...} # トランザクションデータの例
result_stable = validator_A.validate_transaction(stable_transaction)
print("安定性が高いトランザクション:", result_stable)
# 安定性が低い場合のトランザクション
unstable_transaction = {...} # トランザクションデータの例
result_unstable = validator_A.validate_transaction(unstable_transaction)
print("安定性が低いトランザクション:", result_unstable)
7. 理解容易性(Understandability)
ソフトウェアの構造と動作をどれだけ容易に理解できるかという特性である。例えば次のような状況は、安定性が低い。
・適切ではない命名
・過剰な複雑性
・ドキュメントやコメントの不足
理解することすら難しいPoHやPoSというアルゴリズムだけでなく、ネットワークも複雑に絡んでいくため、容易に理解できない。極めて難しいシステムと言える。理解可能性の向上のために、以下のアプローチが取られることがある。これをフェデレーションモデルに適用すると、コンポーネントやアルゴリズムの理解を助ける手段となる。
-
適切な命名規則の採用: 適切な変数や関数の命名規則を採用し、コード内の各要素が意味を持つようにする。例えば、PoH(Proof of History)やPoS(Proof of Stake)に関連するコンポーネントには、その機能や役割に応じた具体的な名前を与える。
-
過剰な複雑性の排除: コードやアルゴリズムが過剰に複雑であれば、それをシンプルな構造に再設計する。特に、関数やモジュールの分割、コードのリファクタリング、不要な機能の削除などが有効である。
-
ドキュメントとコメントの追加: コードには十分なコメントとドキュメンテーションを追加する。アルゴリズムやコンポーネントの動作、特にPoHやPoSなどの複雑なアルゴリズムに関する詳細な説明を提供する。これにより、他の開発者やメンテナンス担当者が理解しやすくなる。
-
教育とトレーニング: チームメンバーに対して、新しい概念やアルゴリズムについての教育とトレーニングを提供する。特に、新しい技術やアルゴリズムを導入する際には、関連するトレーニングプログラムを利用することが役立つ。
以下の例では、まずは定期的にDPoSで承認者である市町村の代表者を選出する。たとえば、3か月ごととか。選ばれた代表はフェデレーションモデルでメインブロックチェーンにあがってくる各市町村からのブロックを承認する。その承認プロセスは、各市町村は独立したブロックチェーンであり、Proof of Placeで行為者の場所を特定しつつトランザクションが形成され、そのトランザクションにPoHにてタイムスタンプが組み合わされてトランザクションが次に送られる。 -
Proof of Place (PoP):
- ユーザーがトランザクションを送信するときに、位置情報を収集し、それをPoPによってブロックチェーンに登録します。これにより、トランザクションが特定の場所で実行されたことが証明される。この位置情報を加えることで、ハッキングするにも特定の位置に居なければならないため、遠隔操作でのハッキングは極めて難しくなり、セキュリティが向上する。なお、以下に、提供されたトランザクションデータの構造について説明しよう。
-
トランザクションID(Transaction ID):
- 機能: トランザクションを一意に識別するためのユニークなID。
- データ型: 文字列(String)
-
ユーザーアカウント(User Account):
- 機能: トランザクションを送信したユーザーのアカウント情報。
- データ型: アカウント情報(例: ユーザー名、アカウント番号など)
-
署名(Signature):
- 機能: トランザクションが有効であることを確認するためのデジタル署名。
- データ型: デジタル署名データ(例: RSA、ECDSAなど)
-
トランザクションの前提条件(Preconditions):
- 機能: トランザクションが実行される前に満たされている必要がある条件。
- データ型: 条件に関する情報
-
位置(GIS):
- 機能: トランザクションが作成されたときの位置情報。
- データ型: 地理情報システム(GIS)データ(例: 緯度経度、住所など)
-
愛の行動レベル(Love Action Level):
- 機能: トランザクションの愛に関する行動のレベルを示す数値と科目。
- データ型: 数値やカテゴリ情報
-
次元(Dimension):
- 機能: 生命体の次元を表す識別子やカテゴリ。
- データ型: 識別子やカテゴリ情報(例: 次元ID)
-
愛貨額(Amount):
- 機能: 提案されたトランザクションの愛貨額。
- データ型: 数値(例: 愛貨額)
-
行動内容(Action Content):
- 機能: 実際の行動や提案された行動の詳細な説明。
- データ型: 文字列やテキスト
-
承認相手(Approval Target):
- 機能: 行動の承認を得る対象のアドレスやID。
- データ型: アカウント情報
-
ゆらぎ(Fluctuation):
- 機能: 新たな生命体の発起活動。
- データ型: 活動や変化に関する情報
-
各要素はトランザクションの特定の側面を表しており、これらのデータを組み合わせてトランザクション全体を形成する。この構造は、特定のシステムやプロトコルに応じて変更される可能性がある。
-
Proof of History (PoH):
- 続いて、トランザクションのタイムスタンプ情報を利用して、PoHを生成する。これにより、トランザクションが時間の流れに沿って順序付けられ、過去のトランザクションの履歴がブロックチェーンに確実に反映される。
-
Delegated Proof of Stake (DPoS):
- ネットワークのブロック生成者や承認者を選出するためにDPoSを導入する。DPoSでは、ネットワークの一部のノードがブロック生成の権限を持ち、これらのノードが投票によって選出される。これにより、ブロック生成者が分散されつつも、一定の効率とスケーラビリティを確保できる。
-
メインチェインでの承認:
- DPoSによって選ばれた代表者がトランザクションをブロックにまとめ、メインチェインに提出する。メインチェイン上でトランザクションが承認され、ブロックが追加される。このようなアルゴリズムを組み合わせることで、位置情報、時間の経過、代表者の選出によりトランザクションの信頼性を高めつつ、分散型で効率的なブロックチェーンネットワークを構築できる。ただし、これらの要素を組み合わせる際には、セキュリティやパフォーマンスに関する検討が重要である。
import hashlib
import datetime
import random
class Transaction:
def __init__(self, municipality, user_account, location, love_action_level, amount, action_content):
self.transaction_id = hashlib.sha256(str(random.getrandbits(256)).encode()).hexdigest()
self.municipality = municipality
self.user_account = user_account
self.timestamp = str(datetime.datetime.now())
self.location = location
self.love_action_level = love_action_level
self.amount = amount
self.action_content = action_content
self.approval_target = None # DPoSによる承認者
def generate_proof_of_place(self):
# PoPを模擬: 位置情報を使用してPoPを生成
return f"トランザクション {self.transaction_id} の位置情報のPoPが生成されました: {self.location}"
def generate_proof_of_history(self):
# PoHを模擬: タイムスタンプを使用してPoHを生成
return f"トランザクション {self.transaction_id} の履歴のPoHが生成されました: {self.timestamp}"
class DPoS:
def __init__(self, municipalities):
self.municipalities = municipalities
self.approved_representative = None
def elect_representative(self):
# DPoSを模擬: 代表者をランダムに選出
self.approved_representative = random.choice(self.municipalities)
return f"{self.approved_representative} が代表者に選出されました"
def approve_transaction(self, transaction):
# DPoSによる承認を模擬
transaction.approval_target = self.approved_representative
return f"{self.approved_representative} によってトランザクション {transaction.transaction_id} が承認されました"
class MainChain:
def __init__(self):
self.transactions = []
def process_transaction(self, transaction):
# メインチェーンでのトランザクション処理を模擬
self.transactions.append(transaction)
return f"トランザクション {transaction.transaction_id} がメインチェーンに追加されました"
# 例の使用
municipalities = ["市町村1", "市町村2", "市町村3"]
dpos = DPoS(municipalities)
main_chain = MainChain()
# 各市町村のトランザクションをシミュレート
for municipality in municipalities:
for _ in range(5): # 各市町村に対して5つのトランザクションをシミュレート
user_account = f"{municipality}_ユーザー"
location = f"場所_{random.randint(1, 10)}"
love_action_level = random.randint(1, 10)
amount = random.randint(50, 200)
action_content = f"{municipality} でのアクション"
transaction = Transaction(municipality, user_account, location, love_action_level, amount, action_content)
# PoPとPoHを生成
transaction_proof_of_place = transaction.generate_proof_of_place()
transaction_proof_of_history = transaction.generate_proof_of_history()
# DPoS: 代表者を選出し、トランザクションを承認
dpos_election_result = dpos.elect_representative()
dpos_approval_result = dpos.approve_transaction(transaction)
# メインチェーン: トランザクションを処理
main_chain_result = main_chain.process_transaction(transaction)
# 結果を表示
print(transaction_proof_of_place)
print(transaction_proof_of_history)
print(dpos_election_result)
print(dpos_approval_result)
print(main_chain_result)
print("\n---\n")
- DPoSによって選ばれた代表者がトランザクションをブロックにまとめ、メインチェインに提出する。メインチェイン上でトランザクションが承認され、ブロックが追加される。このようなアルゴリズムを組み合わせることで、位置情報、時間の経過、代表者の選出によりトランザクションの信頼性を高めつつ、分散型で効率的なブロックチェーンネットワークを構築できる。ただし、これらの要素を組み合わせる際には、セキュリティやパフォーマンスに関する検討が重要である。
いかがであろうか、試験性が高い/低いとはどういう状態なのか?という点を整理してみたが、ブロックチェーンシステムの場合、試験性が極めて悪いと言える。ここがサーバーと大きな違いであろう。多くの人が介在して成り立つシステムであるがゆえ、実践環境でしか、本当のトラブルは発生しない。どんなに対処しても、人の悪行の問題も常につきまとう。こう考えると、やはり小規模から始めて徐々に規模を拡大していくしか、方法は無いようにも思える。