愛記システム概念設計:システム構築の品質評価のポイント4 移植性② | 続・ティール組織 研究会のブログ

続・ティール組織 研究会のブログ

ティール組織が話題になっているが、具現化するにはどうしたらよいか?
その研究を続けるにあたり、さらに次の形態である、続・ティール組織なるものまで視野に入れ、具体的な施策・行動内容を研究・支援する会。

先までは、"愛記"についての記載で、どのようにブロックチェーンSNSに組み込んで実装していけばよいのか、概念的なところからアプローチ方法を記載していった。大まかな概念としてはひとまず終えた。次は、ブロックチェーンの概念設計といえるところまで、基本設計書に着手できるようなところまで、概念を具体化していきたい。

愛記システムのシステム評価について

システム評価とは、つまりは、このシステムを導入して成功だったか失敗だったかという効果検証という意味だ。概念設計をする上で必ず抑えておくべきポイントということだ。それには各項目があり、それぞれの項目を見ていくことで、その結果が得られる。そのシステム評価項目を1つずつ見ていきたい。

システム構築の品質評価のポイント1:理解可能性(Understandability)

システム構築の品質評価のポイント2:完全性(Completeness)

システム構築の品質評価のポイント3:簡潔性(Conciseness)

システム構築の品質評価のポイント4:移植性(Portability)

システム構築の品質評価のポイント5:一貫性(Consistency)と構造化の度合い

システム構築の品質評価のポイント6:保守性(Maintainability)

システム構築の品質評価のポイント7:試験性(Testability)

システム構築の品質評価のポイント8:ユーザビリティ(Usability)

システム構築の品質評価のポイント9:効率性(Efficiency)

システム構築の品質評価のポイント10:セキュリティ(Security)

◆システム構築の品質評価のポイント4:移植性②(Portability)

システム構築の評価に繋がる移植性とは、異なるブロックチェーン間の相互運用性を意識し、アプリケーションの移植性や互換性を加味してシステム設計を行うことが肝要であるということだ。特に、コンポーネント間の通信に共通のプロトコルや標準化されたインターフェースを使用することは、異なるブロックチェーン上のコンポーネントが協調して作業するための基盤を提供する。

 

これらのプロトコルは、異なるブロックチェーンや分散型ネットワークが協力して動作するための基盤を提供し、相互運用性を高める。これにより、様々なシステムが連携しやすくなり、異なるデータソースやサービスを統合する際のハードルが低減する。これをDApps側である愛記システムと、愛貨をトークンとするブロックチェーンSNSの設計に用いた場合、どうなるか見てみよう。

 

設計案: Verifiable Credentialsの導入

  1. デジタルアイデンティティの管理:

    • ユーザーは、愛記システム内でデジタルアイデンティティを作成し、必要な属性や情報を登録する。
    • これには、Verifiable Credentialsに基づく信頼性の高いデジタルアイデンティティが含まれる。
  2. 信頼性の検証:

    • ユーザーが愛の行動やアクティビティを行うと、これに対するVerifiable Credentialsが生成される。例えば、愛の行動の詳細や評価レベル、日付、場所などが含まれる。
    • これらのCredentialsは、ブロックチェーン上で発行され、それにより情報の改ざんが防がれ、信頼性が確保される。
  3. データ共有:

    • ユーザーは、Verifiable Credentialsを他のユーザーや愛貨の取引相手と共有できる。
    • 共有されたCredentialsはブロックチェーン上に安全に格納され、他のユーザーが信頼性を検証できるようになる。
  4. 取引の透明性:

    • 愛貨のトランザクションに関連するVerifiable Credentialsは、透明性を確保し、信頼性の高い履歴としてブロックチェーン上に保存される。
  5. プライバシー保護:

    • ユーザーは、どのVerifiable Credentialsを共有するかを選択できるようにする。これにより、個々のユーザーがプライバシーを守りながら必要な情報を共有できる。

ユーザーは、Verifiable Credentialsを他のユーザーや愛貨の取引相手と共有できる。共有されたCredentialsはブロックチェーン上に安全に格納され、他のユーザーが信頼性を検証できるようになる。Verifiable Credentialsを共有し、ブロックチェーン上に安全に格納し、他のユーザーが信頼性を検証できるようにするプログラムは、以下のようになるだろう。

設計案:ブロックチェーンの分散化

さらにブロックチェーンを市町村ごとに分散させたい。ただし、承認者はどのブロックチェーンの承認依頼も承認できるようにしたい。市町村ごとに分散されたブロックチェーンを構築し、世界中の承認者がどのブロックチェーンの承認依頼も承認できるようにするアプローチは、面白いだろう。これは、異なる地域のデータを分散して管理することで、地域ごとの自治体システムが独立して運用でき、同時に承認者が全体で統一的に承認行為を行えるという柔軟性を持たせるためである。ただし、以下のような点に留意する必要がある。

  1. インターオペラビリティと標準化: 各ブロックチェーンが同じプロトコルや標準を採用している場合、承認者がどのブロックチェーンも承認できるようなシームレスなインターオペラビリティが実現できる。異なるブロックチェーンが異なるプロトコルを使用する場合、その統合は複雑になる。

  2. セキュリティとプライバシー: 各ブロックチェーンが異なる自治体のデータを管理するため、セキュリティとプライバシーの観点から十分な対策が必要である。また、承認者が異なる地域のデータにアクセスする場合、適切なアクセス制御が必要である。

  3. ネットワークの遅延: 分散されたブロックチェーンが異なる地域に配置される場合、ネットワークの遅延が発生する可能性がある。これに対処するためには、高いスループットや低い遅延を提供するブロックチェーン技術を選択するか、他の最適化手法を考慮する必要がある。

上記のような設計案を盛り込んで、メインチェーンのプログラムをやり直してみよう。以下に、メインチェーンのプログラムを記載する。

use chrono::{DateTime, Utc};
use sha2::{Digest, Sha256};
use std::collections::HashMap;
use std::time::Duration;

// トランザクション結果
#[derive(Debug)]
enum TransactionResult {
    Success,
    Failure,
}

// Verifiable Credentialの構造体
#[derive(Debug, Clone)]
struct VerifiableCredential {
    user_id: String,
    claim_data: HashMap<String, String>,
    timestamp: DateTime<Utc>,
}

// Blockchainトレイト
trait Blockchain {
    fn store_credential(&self, credential: &VerifiableCredential) -> Option<TransactionResult>;
    fn update_shared_credential(&self, recipient_id: &str, credential: &VerifiableCredential) -> Option<TransactionResult>;
}

// Blockchainのダミー実装
struct DummyBlockchain;

impl Blockchain for DummyBlockchain {
    fn store_credential(&self, _credential: &VerifiableCredential) -> Option<TransactionResult> {
        Some(TransactionResult::Success)
    }

    fn update_shared_credential(&self, _recipient_id: &str, _credential: &VerifiableCredential) -> Option<TransactionResult> {
        Some(TransactionResult::Success)
    }
}

// VerifiableCredentialManagerクラス
struct VerifiableCredentialManager<T: Blockchain> {
    blockchain: T,
    credentials: HashMap<String, VerifiableCredential>,
}

impl<T: Blockchain> VerifiableCredentialManager<T> {
    fn new(blockchain: T) -> Self {
        VerifiableCredentialManager {
            blockchain,
            credentials: HashMap::new(),
        }
    }

    fn create_verifiable_credential(&mut self, user_id: String, claim_data: HashMap<String, String>) {
        let credential = VerifiableCredential {
            user_id: user_id.clone(),
            claim_data: claim_data.clone(),
            timestamp: Utc::now(),
        };

        if let Some(transaction_result) = self.blockchain.store_credential(&credential) {
            self.credentials.insert(user_id, credential.clone());
            println!("Verifiable Credential created and stored for user {}.", user_id);
        } else {
            println!("Failed to store Verifiable Credential.");
        }
    }

    fn share_verifiable_credential(&mut self, user_id: &str, recipient_id: &str) {
        if let Some(credential_to_share) = self.credentials.get(user_id) {
            if let Some(update_result) = self.blockchain.update_shared_credential(recipient_id, credential_to_share) {
                println!("Verifiable Credential shared with user {}.", recipient_id);
            } else {
                println!("Failed to share Verifiable Credential.");
            }
        } else {
            println!("No Verifiable Credential found for user {}.", user_id);
        }
    }
}

// APIの実装
struct LoveCurrencyApi;

impl LoveCurrencyApi {
    // メインチェーンから自治体のブロックチェーンにデータを送信するメソッド
    fn send_data_to_municipality_chain(transaction: &Transaction, municipality: &str) {
        if transaction.verify_signature() {
            println!("Sending data to municipality chain: {:?}", transaction);
            // メインチェーンから自治体のブロックチェーンにデータを送信する処理を実装する
            // ここで自治体のブロックチェーンにデータを送信する処理を実装する
            let mut dummy_blockchain = DummyBlockchain;
            dummy_blockchain.store_credential(&VerifiableCredential {
                user_id: "UserA".to_string(),
                claim_data: HashMap::new(),
                timestamp: Utc::now(),
            });
        } else {
            println!("Failed to send data: Invalid signature");
        }
    }

    // 新しい自治体を登録するメソッド
    fn register_new_municipality(municipality_name: &str) {
        println!("Registering new municipality: {}", municipality_name);
        // 新しい自治体を登録する処理を実装する
    }

    // APIの初期化処理
    fn init() -> Self {
        LoveCurrencyApi
    }

    // 新しいエンドポイントを追加して、リクエストを受け取ってからapprove_requestメソッドを呼び出す
    fn approve_request_from_municipality(data: &Transaction) {
        if data.verify_signature() {
            println!("Received approval request from municipality: {:?}", data);
            let mut dummy_blockchain = DummyBlockchain;
            dummy_blockchain.store_credential(&VerifiableCredential {
                user_id: "UserA".to_string(),
                claim_data: HashMap::new(),
                timestamp: Utc::now(),
            });
            // 実際には、リクエストを処理するロジックを実装する
        } else {
            println!("Failed to approve request: Invalid signature");
        }
    }
}

// トランザクションの構造体
#[derive(Debug)]
struct Transaction {
    transaction_id: String,
    municipality: String,
    timestamp: DateTime<Utc>,
    location: String,
    love_action_level: u32,
    amount: f64,
    action_content: String,
    is_local: bool,
    close_flag: bool,
    approval_target: Option<String>,
    signature: Option<String>,
    location_hash: Vec<u8>,
    received_timestamp: Option<DateTime<Utc>>,
}

impl Transaction {
    fn calculate_location_hash(&mut self) {
        let mut hasher = Sha256::new();
        hasher.update(self.location.clone());
        self.location_hash = hasher.finalize().to_vec();
    }

    fn generate_signature(&mut self) {
        let message = format!(
            "{}{}{}{}{}{}{}{}",
            self.transaction_id,
            self.municipality,
            self.timestamp.to_rfc3339(),
            self.location,
            self.love_action_level,
            self.amount,
            self.action_content,
            String::from_utf8_lossy(&self.location_hash)
        );
        self.signature = Some(Sha256::digest(message.as_bytes()).to_string());
    }

    fn receive_love_currency(&mut self) -> f64 {
        if self.received_timestamp.is_none() {
            self.received_timestamp = Some(Utc::now());
        }
        let time_diff = Utc::now() - self.received_timestamp.unwrap();
        let hours_diff = time_diff.num_hours() as f64;
        let decreased_amount = self.amount - (hours_diff * 0.05); // 1時間ごとに5%ずつ減少
        self.amount = decreased_amount.max(0.0); // 愛貨が0未満にならないようにする
        self.amount
    }

    fn verify_signature(&self) -> bool {
        if let Some(signature) = &self.signature {
            let message = format!(
                "{}{}{}{}{}{}{}{}",
                self.transaction_id,
                self.municipality,
                self.timestamp.to_rfc3339(),
                self.location,
                self.love_action_level,
                self.amount,
                self.action_content,
                String::from_utf8_lossy(&self.location_hash)
            );
            let calculated_signature = Sha256::digest(message.as_bytes()).to_string();
            return *signature == calculated_signature;
        }
        false
    }
}

fn main() {
    let blockchain = DummyBlockchain;
    let mut credential_manager = VerifiableCredentialManager::new(blockchain);

    // ユーザーAがCredentialを作成
    let mut claim_data = HashMap::new();
    claim_data.insert("name".to_string(), "Satoshi".to_string());
    claim_data.insert("age".to_string(), "50".to_string());
    credential_manager.create_verifiable_credential("UserA".to_string(), claim_data.clone());

    // ユーザーAがユーザーBとCredentialを共有
    credential_manager.share_verifiable_credential("UserA", "UserB");

    // APIを初期化
    let api = LoveCurrencyApi::init();

    // 新しい自治体を登録する例
    api.register_new_municipality("Saitama");

    // メインチェーンから自治体のブロックチェーンにデータを送信する例
    let transaction = Transaction {
        transaction_id: "123456".to_string(),
        municipality: "Kaga".to_string(),
        timestamp: Utc::now(),
        location: "35.4436, 139.6372".to_string(),
        love_action_level: 3,
        amount: 100.0,
        action_content: "Helped someone carry groceries".to_string(),
        is_local: false,
        close_flag: false,
        approval_target: None,
        signature: None,
        location_hash: Vec::new(),
        received_timestamp: None,
    };
    transaction.calculate_location_hash();
    transaction.generate_signature();
    api.send_data_to_municipality_chain(&transaction, "Saitama");
}
 

このようにすることで、世界中の市町村のリクエストに対して承認ができるようになる。ただし、実際には各自治体のブロックチェーンにデータを送信する処理やリクエストを処理するロジックを実装する必要がある。

 

 

いかがであろうか、システム評価の移植性について記載した。各市町村のブロックチェーンが独立して運用しつつ、共通のプロトコルを使用することで、承認者は全体の承認が可能となるというような設計にすることで、移植性を確保したいし、セキュリティも確保したい。このような設計案を具現化していきたい。