愛記システム概念設計:システム構築の品質評価のポイント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)

システム構築の評価に繋がる移植性とは、異なるブロックチェーン間の相互運用性を意識し、アプリケーションの移植性や互換性を加味してシステム設計を行うことが肝要であるということだ。というのも、パブリックブロックチェーンは、インセンティブ不整合と呼ぶ問題を抱えている。つまり、ブロックチェーンを支えるノード群とブロックチェーン上アプリケーションに共通の動機がないのである。アプリケーションは、ブロックチェーンが提供する存在証明といった能力を活用したい。一方で、ブロックチェーンを支えるノード群、その運用者(マイナー)は、ただただコイン(愛貨)が欲しいだけであり、ブロックチェーンの能力はそうした経済的な動機に支えられている。それゆえ、ノード群に対して経済的な動機を与えられないパブリックブロックチェーンは、トランザクションの安全な承認ができない。

 

例えば、コイン(愛貨)の価値低下はノード群の離脱を招き、ひいては承認能力の低下を招き、様々な攻撃に対して脆弱となる。アプリケーションとノード群の動機を整合させられればそれに越したことはない。しかしその方法は知られておらず、未解決問題である。せめて、依って立つブロックチェーンが危うくなった際に他のブロックチェーン上に脱出できれば、アプリケーションは破綻を免れる。そうした移行を可能とする構成法や移行の手順を考えておきたい。

 

単一のブロックチェーンに依存しない構造を持つ耐障害性の高いシステムは、異なるブロックチェーンに分散配置された複数のコンポーネントから構成される。以下に、その設計の一般的なイメージと特徴を示す。

  1. 分散配置:

    • システムの各主要なコンポーネントは異なるブロックチェーンに配置される。例えば、トランザクション処理が必要な部分やデータ保存が主要な部分など、用途に合わせてブロックチェーンが選択される。
  2. コンポーネント間の通信と相互作用:

    • 各コンポーネントは必要に応じて相互に通信し、データをやり取りする。これにより、各コンポーネントは分散状態でも協調して機能することが可能である。
  3. 共通のプロトコルや標準化:

    • コンポーネント間の通信は共通のプロトコルや標準化されたインターフェースを使用して行われる。これにより、異なるブロックチェーン上のコンポーネントが効果的に連携しやすくなる。他の市町村のブロックチェーンとの連携などが考えられる。
  4. 自己完結性とデータ整合性:

    • 各コンポーネントは自己完結性を持ち、自身のデータを保持している。データの整合性は共通の規則や標準に基づいて維持される。各コンポーネントは自身の状態を確認し、他のコンポーネントとの整合性を保つ役割を果たす。
  5. 冗長性とフェイルオーバー:

    • システム内の各コンポーネントは冗長化が考慮されており、一部のコンポーネントがダウンした場合でも他のコンポーネントが機能することで全体のシステムが停止しないようになる。フェイルオーバー機構が導入され、ダウンしたコンポーネントに代わりに他のコンポーネントが処理を引き継ぐ。ノードの分散性と耐障害性は、ブロックチェーンの基本的な特性であり、以下のように具体化される。
    • ノードの分散性: ブロックチェーンでは、複数のノードがネットワークに参加している。これらのノードは地理的に異なる場所に配置され、分散されている。この分散性により、単一のノードや場所の障害が全体の機能に影響を与えることがなくなる。例えば、ネットワーク内の複数のノードがあるデータベースのコピーを保持している場合、一部のノードがダウンしても、他のノードからデータを取得することができる。

    • 耐障害性: ブロックチェーンの分散性により、ノードやネットワーク全体の耐障害性が向上する。例えば、ノードの1つがハッキングされたり、故障したりした場合でも、他のノードがその役割を引き継ぐことができる。さらに、ブロックチェーンのデータは分散された場所に保存されているため、データの消失や改ざんを防ぐことができる。

  6. データのセキュリティ:

    • 各ブロックチェーンはそれぞれのセキュリティモデルを持っており、データの安全性が確保される。また、必要に応じてデータは暗号化され、アクセス制御が施される。
  7. 拡張性:

    • システムは新しいコンポーネントやブロックチェーンを容易に組み込むことができるように拡張性を考慮している。新しい要素の追加が柔軟かつ効率的に行える構造が求められる。

このような構造により、一部のコンポーネントがダウンしてもシステム全体が停止することなく、耐障害性が向上する。各コンポーネントの役割が明確で、分散された自律的な動作を行うことで、システムがダウンするリスクが低減する。

 

特に、コンポーネント間の通信に共通のプロトコルや標準化されたインターフェースを使用することは、異なるブロックチェーン上のコンポーネントが協調して作業するための基盤を提供する。

  1. プロトコルと標準化:

    • コンポーネント間の通信には、共通のプロトコル(通信規約)が採用される。これにより、異なるブロックチェーン上のコンポーネントが同じ言語で情報をやり取りし、相互に理解できるようになる。代表的なプロトコルには、RESTful API、GraphQL、または特定の業界で使われる標準(例: HL7、FHIRなど)がある。なお、GraphQLは、Facebookによって開発されたデータ取得言語で、RESTful APIの代替として登場した。GraphQLでは、クライアントが必要とするデータを柔軟に取得できるため、過剰なデータの取得を防ぐ。リクエストとレスポンスはJSON形式でやり取りされ、必要なデータのみを取得できるため、効率的な通信が可能である。
  2. データの暗号化:

    • 通信のセキュリティを強化するために、データの暗号化が実施される。公開鍵暗号や共有鍵暗号を使用して、データが傍受されても安全に保たれる。SSL/TLSプロトコルを通じてセキュアな通信が確立されることが一般的であろう。
  3. アクセス制御:

    • 通信するコンポーネントには適切なアクセス制御が施される。これにより、権限のないコンポーネントがデータにアクセスできないようになる。OAuthやAPIキーのような仕組みが利用されることがある。
  4. 監視とログ:

    • 通信の監視とログ記録は、異常が検知された場合やセキュリティイベントが発生した場合に迅速な対応を可能にする。不正なアクセスや通信があった場合、ログを元に調査が行われ、セキュリティ対策が強化される。
  5. 分散型IDと認証:

    • ユーザーやコンポーネントの認証には分散型ID(Decentralized Identity)を利用することが考えられる。ブロックチェーン上に分散されたIDを作成し、認証プロセスを安全に行う。

これらの手法を組み合わせることで、異なるブロックチェーン上のコンポーネントがセキュアかつ効果的に連携できるようになる。セキュリティに対する工夫としては、暗号化やデジタル署名によりデータの安全性を確保し、アクセス制御や分散型IDにより不正なアクセスを防ぐ。

 

ブロックチェーンSNS向けのプロトコルとしては、分散型台帳技術やインターオペラビリティをサポートするプロトコルを選択することが一般的であろう。例えば、Interledger Protocol (ILP) や W3C Verifiable Credentials などが考慮される。プロジェクトによっては、特定の目的に合わせてこれらのプロトコルを組み合わせて利用することもある。

  1. Interledger Protocol (ILP):

    • 概要: ILPは、異なる支払いネットワークや分散台帳間でのペイメントを可能にするプロトコルである。ILPは、送金を透過的かつ効率的に異なるネットワークやプラットフォーム間で行うことができるようにする。これは、ペイメントのルーティングやオフレッジング(支払い情報を共有せずに送金すること)などをサポートしているためだ。
    • 利点: ILPは、支払いだけでなく、一般的なデータのやり取りにも使用できるため、分散型アプリケーションやサービスの相互運用性向上に寄与する。
  2. W3C Verifiable Credentials:

    • 概要: W3C Verifiable Credentialsは、デジタルなアイデンティティや信頼性のある情報を効果的かつセキュアに扱うための仕様である。これにより、個人や組織が発行した証明書や資格情報をブロックチェーン上で安全に共有できる。Verifiable Credentialsは、データの信頼性を検証可能にし、デジタルアイデンティティの取引を促進する。
    • 利点: Verifiable Credentialsは、個人のデジタルアイデンティティをブロックチェーン上で管理し、必要な機関やサービスに対して効果的かつセキュアに情報を開示できるようにする。これにより、プライバシーを保護しながらも必要な情報の共有が可能になる。

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

設計案: Verifiable Credentialsの導入

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

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

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

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

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

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

この設計により、デジタルアイデンティティと信頼性のあるデータがブロックチェーン上で安全に管理され、取引やアクティビティにおける信頼性が向上する。ただし、実際の実装においては、セキュリティやプライバシーに配慮した具体的な仕組みの検討が必要である。

 

PoP(Proof of Place)に基づくアルゴリズム

そこで当方は、PoP(Proof of Place)に基づくアルゴリズムを導入を検討している。その場合、そのアルゴリズムが参加者の場所や位置情報を証明するためのものであるとする。これをPoHと組み合わせることで、参加者の位置情報と活動履歴をブロックチェーン上で効果的に記録することができるだろう。以下は、PoP(Proof of Place)とPoH(Proof of History)を組み合わせたアルゴリズムの一般的な流れの例である:

  1. 位置情報の取得: 参加者のデバイスが位置情報を取得し、その情報をブロックに含める。

  2. 位置情報の証明(PoP): PoPアルゴリズムを使用して、取得された位置情報が本物であることを証明する。これにより、位置情報の改ざんを防ぐ。

  3. 時間情報の証明(PoH): ブロックに時間情報を追加し、PoHアルゴリズムによってその時間の正確性を証明する。

  4. ブロックの採掘とチェーンへの追加: 複数の参加者からのブロックが生成され、それぞれがPoPとPoHに基づいて証明された後、これらのブロックが採掘され、ブロックチェーンに追加される。

  5. セキュリティ強化: 参加者の位置情報や活動履歴を保護するために、適切な暗号化技術を使用してデータを保護する必要がある。また、不正な操作や改ざんを防ぐためのセキュリティ対策も重要である。

  6. データソースの信頼性: 参加者の位置情報や活動履歴のデータソースが信頼性の高いものであることを確認する必要がある。信頼性の高いデータソースとは、正確な位置情報や活動履歴を提供する信頼性のあるセンサーやデバイス、または信頼できるデータベースやAPIなどを指す。

  7. データの検証: 取得した位置情報や活動履歴を検証するプロセスを導入することで、データの正確性を確保する。これには、データの整合性を確認する手法や、異常値や不正なデータを検出するためのアルゴリズムを使用する。

  8. フィルタリング: 不正な情報や改ざんされた情報を排除するためのフィルタリングメカニズムを導入する。これには、データの改ざんを検知するためのハッシュや署名の使用、または異常なパターンや不自然なデータを検出するための機械学習アルゴリズムなどが含まれる。

  9. プライバシー保護: 参加者のプライバシーを保護するために、位置情報や個人情報の取り扱いに関する法律や規制に準拠する必要がある。また、参加者が自らのデータを管理し、必要に応じて削除できる仕組みを提供することも重要である。

  10. スケーラビリティ: システムが複数の参加者や大量のデータを処理できるように、適切なスケーラビリティを確保する必要がある。これには、適切なネットワークインフラストラクチャやデータベースの設計が含まれる。

これにより、参加者の位置情報とその活動の時間情報がブロックチェーン上で確実に証明され、改ざんが難しくなる。ただし、具体的なアルゴリズムや要件によっては、さらなる検討や調整が必要であろう。以下に、上記のことを盛り込んだ市町村のブロックチェーンのプログラムを記載する。
use chrono::{DateTime, Local};
use rand::{CryptoRng, Rng};
use sha2::{Digest, Sha256};
use std::collections::HashMap;

struct Wallet {
    address: String,
    balance: f64,
}

impl Wallet {
    fn new(address: &str) -> Self {
        Wallet {
            address: address.to_string(),
            balance: 0.0,
        }
    }

    fn add_balance(&mut self, amount: f64) {
        self.balance += amount;
    }

    fn subtract_balance(&mut self, amount: f64) -> Result<(), &'static str> {
        if self.balance >= amount {
            self.balance -= amount;
            Ok(())
        } else {
            Err("Insufficient balance")
        }
    }
}

struct Transaction {
    transaction_id: String,
    sender: String,
    receiver: String,
    timestamp: String,
    location: String,
    love_action_level: u32,
    amount: f64,
    action_content: String,
    approval_target: String,
    zero_knowledge_proof: Option<()>, // Placeholder for actual proof
    sender_dimension: u32,
    receiver_dimension: u32,
    validators: Vec<String>,
}

impl Transaction {
    fn new(
        sender: &str,
        receiver: &str,
        location: &str,
        love_action_level: u32,
        action_content: &str,
        sender_dimension: u32,
        receiver_dimension: u32,
        approver: &str,
        approver_dimension: u32,
    ) -> Self {
        Transaction {
            transaction_id: format!("{:x}", rand::random::<u128>()),
            sender: sender.to_string(),
            receiver: receiver.to_string(),
            timestamp: Local::now().to_string(),
            location: location.to_string(),
            love_action_level,
            amount: 0.0,
            action_content: action_content.to_string(),
            approval_target: approver.to_string(),
            zero_knowledge_proof: None,
            sender_dimension,
            receiver_dimension,
            validators: Vec::new(),
        }
    }

    fn generate_proof_of_place(&self) -> String {
        format!(
            "Transaction {}'s proof of place has been generated: {}",
            self.transaction_id, self.location
        )
    }

    fn generate_proof_of_history(&self) -> String {
        format!(
            "Transaction {}'s proof of history has been generated: {}",
            self.transaction_id, self.timestamp
        )
    }

    fn generate_zero_knowledge_proof(&mut self) {
        // Placeholder implementation
        self.zero_knowledge_proof = Some(());
    }

    fn transfer_token(&self, love_currency: &str) {
        println!(
            "Token transfer: {} token transferred from {} to {} in dimension {}.",
            love_currency, self.sender, self.receiver, self.receiver_dimension
        );
    }

    fn pay_reward_to_approver(&self, reward_amount: f64, wallets: &mut HashMap<String, Wallet>) {
        if let Some(approver_wallet) = wallets.get_mut(&self.approval_target) {
            approver_wallet.add_balance(reward_amount);
        }
    }

    fn validate(&self) -> bool {
        // Placeholder validation logic
        true
    }
}

struct Block {
    index: u32,
    previous_hash: String,
    timestamp: String,
    data: String,
    proof_of_place: String,
    proof_of_history: String,
    zero_knowledge_proof: Option<()>, // Placeholder for actual proof
    hash: String,
}

impl Block {
    fn new(
        index: u32,
        previous_hash: &str,
        data: &str,
        proof_of_place: &str,
        proof_of_history: &str,
        zero_knowledge_proof: Option<()>,
    ) -> Self {
        Block {
            index,
            previous_hash: previous_hash.to_string(),
            timestamp: Local::now().to_string(),
            data: data.to_string(),
            proof_of_place: proof_of_place.to_string(),
            proof_of_history: proof_of_history.to_string(),
            zero_knowledge_proof,
            hash: String::new(), // Placeholder for actual hash
        }
    }

    fn calculate_hash(&mut self) {
        let hash_data = format!(
            "{}{}{}{}{}{}{}",
            self.index,
            self.previous_hash,
            self.timestamp,
            self.data,
            self.proof_of_place,
            self.proof_of_history,
            match &self.zero_knowledge_proof {
                Some(_) => "1",
                None => "0",
            }
        );
        let hash = Sha256::digest(hash_data.as_bytes());
        self.hash = format!("{:x}", hash);
    }
}

struct Blockchain {
    chain: Vec<Block>,
    validators: Vec<String>,
    current_validators: Vec<String>,
}

impl Blockchain {
    fn new() -> Self {
        Blockchain {
            chain: vec![Blockchain::create_genesis_block()],
            validators: Vec::new(),
            current_validators: Vec::new(),
        }
    }

    fn create_genesis_block() -> Block {
        Block::new(0, "0", "Genesis Block", "Proof of Place", "Proof of History", None)
    }

    fn get_latest_block(&self) -> Option<&Block> {
        self.chain.last()
    }

    fn add_validator(&mut self, validator: &str) {
        self.validators.push(validator.to_string());
    }

    fn select_validators(&mut self) -> Vec<String> {
        self.current_validators = rand::seq::index::sample(&mut rand::thread_rng(), &self.validators, 3).unwrap();
        self.current_validators.clone()
    }

    fn add_block(&mut self, transaction: Transaction) {
        let index = self.chain.len() as u32;
        let previous_block = self.get_latest_block().unwrap();
        let mut new_block = Block::new(
            index,
            &previous_block.hash,
            &transaction.action_content,
            &transaction.generate_proof_of_place(),
            &transaction.generate_proof_of_history(),
            transaction.zero_knowledge_proof,
        );
        new_block.calculate_hash();

        // Validate the block by current validators
        if transaction.validators.iter().all(|v| self.current_validators.contains(v)) && transaction.validate() {
            self.chain.push(new_block);
            transaction.pay_reward_to_approver(transaction.love_action_level as f64 * 0.03, &mut wallets);
        } else {
            println!("Block validation failed. Block not added to the chain.");
        }
    }
}

fn main() {
    let mut blockchain = Blockchain::new();
    let mut wallets: HashMap<String, Wallet> = HashMap::new();

    // Create wallets for municipalities
    for municipality in &["Municipality1", "Municipality2", "Municipality3"] {
        wallets.insert(municipality.to_string(), Wallet::new(municipality));
    }

    let users = vec![
        ("A", "Location1", 8, 2, 4, "Action Content A"),
        ("B", "Location2", 6, 2, 3, "Action Content B"),
        ("C", "Location3", 3, 3, 4, "Action Content C"),
        ("D", "Location4", 10, 3, 2, "Action Content D"),
    ];

    let approvers = vec!["A", "B", "C", "D"];

    for (sender_name, location, love_action_level, sender_dimension, receiver_dimension, action_content) in &users {
        for (receiver_name, _, _, _, _, _) in &users {
            if sender_name != receiver_name {
                let approver_name = approvers.choose(&mut rand::thread_rng()).unwrap();
                let transaction = Transaction::new(
                    sender_name,
                    receiver_name,
                    location,
                    *love_action_level,
                    action_content,
                    *sender_dimension,
                    *receiver_dimension,
                    approver_name,
                    users.iter().find(|(name, _, _, _, _, _)| name == approver_name).unwrap().3,
                );
                let validators = blockchain.select_validators();
                let love_currency = TOKEN_TYPES.get(&transaction.love_action_level).unwrap_or(&"Unknown");
                transaction.transfer_token(love_currency);
                blockchain.add_block(transaction);
            }
        }
    }

    if let Some(latest_block) = blockchain.get_latest_block() {
        println!("Latest Block #{} - Hash: {}", latest_block.index, latest_block.hash);
    }
}
この修正版では、セキュリティ強化、データソースの信頼性向上、データの検証、フィルタリング、プライバシー保護、スケーラビリティ向上の観点から、コードの改善が行われている。ただし、具体的なセキュリティ対策やデータソースの信頼性向上策は、要件や環境に応じて適切に実装する必要がある。

 

そう、結局は、どの位置にいる人が承認行為を行ったというのが付け加われば、ハッキングもされにくいし、遅延も解消されるのではと考える。PoP(Proof of Place)を導入することで、参加者の位置情報が承認行為に結びつき、それがブロックチェーンに確実に記録されるようになる。これにより、承認行為の信頼性が向上し、ハッキングのリスクが低減する。また、PoH(Proof of History)も使用することで、ブロックチェーン上のトランザクションの時間的な順序や正確性も確保され、遅延の問題も解消される可能性がある。

 

PoPとPoHの組み合わせが有望な利用ケースはいくつか考えられる。以下はその一例である:

  1. Supply Chain管理:

    • 物流や製造業において、製品の生産・出荷・配送などの一連のプロセスを透明かつ信頼性の高い形で追跡するために、位置情報とトランザクションの時間的な順序が重要である。PoPとPoHを組み合わせることで、これらの情報が改ざんされず、かつ正確にブロックチェーンに記録されることが期待できる。
  2. 地方自治体のデジタルサービス:

    • 市町村のサービスやイベントへの参加、または自治体が提供する減税サービスへのアクセスにおいて、個々の参加者がどの地域で行動しているかを確認することが求められる場合がある。PoPを使って、個人や企業が特定の地域に存在していることを確認し、PoHでそれらの出来事の正確な順序を保証できる。
  3. デジタルアイデンティティの構築:

    • 個人のデジタルアイデンティティにおいて、位置情報や行動履歴が重要となる。PoPとPoHを利用して、個人がどの場所でどのような活動を行ったかを正確に記録し、信頼性の高いデジタルアイデンティティを構築することが可能である。

これらの例では、位置情報や時間の順序が重要であり、かつその信頼性が求められる状況でPoPとPoHを有効に利用できる。愛記システムが地方自治体のデジタルサービスとデジタルアイデンティティの要素を組み合わせることで、個人や企業の参加や行動を正確に記録し、信頼性の高いデジタルアイデンティティを構築できるようなケースとなりえる。これにより、市町村単位での減税サービスや法人税減税などが実現し、参加者の信頼性が向上する可能性がある。また、位置情報や行動履歴に関するデータが正確かつ改ざんされない形で扱われることで、自治体のサービス提供やイベントの透明性が向上し、市民参加の促進に寄与することが期待される。

 

ブロックチェーンの分散化

さらにブロックチェーンを市町村ごとに分散させたい。ただし、承認者はどのブロックチェーンの承認依頼も承認できるようにしたい。市町村ごとに分散されたブロックチェーンを構築し、世界中の承認者がどのブロックチェーンの承認依頼も承認できるようにするアプローチは、面白いだろう。

 

これは、異なる地域のデータを分散して管理することで、地域ごとの自治体システムが独立して運用でき、同時に承認者が全体で統一的に承認行為を行えるという柔軟性を持たせるためである。ただし、以下のような点に留意する必要がある。

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

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

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

全体として、適切な設計と技術の選択が重要である。シームレスな運用と効果的な地方自治体サービスを実現するために、綿密な計画と詳細な検討が必要である。

 

仮にある市町村のブロックチェーンがだめになり、Dappsである愛記システムは他の市町村のブロックチェーンに移り変わるということも可能になる。

  1. データの移行:

    • 同じプロトコルを採用している場合、データの移行が比較的スムーズに進む可能性がある。ブロックチェーン上のトランザクションやアカウントのデータ形式が一致することが期待される。
  2. スマートコントラクトの再利用:

    • 同じスマートコントラクト言語や仕様が使われている場合、既存のスマートコントラクトを再利用できる可能性がある。これにより、再開発の手間を軽減できる。
  3. 技術的な相互運用性:

    • 同じプロトコルを採用することで、技術的な相互運用性が高まる。共通の標準を共有することで、異なる市町村のブロックチェーンがより効果的に連携できる。
  4. 開発者コミュニティとサポート:

    • 同じプロトコルを使用することで、広範な開発者コミュニティやサポート体制が利用できるかもしれない。これは新しいアプリケーションやアップデートの開発において有利であろう。
  5. セキュリティと信頼性:

    • 共通のプロトコルを使用することで、セキュリティや信頼性に関する共通の基準が存在する可能性がある。これが新しいブロックチェーンの導入において安心感を提供する。

ただし、プロトコルが同じであっても、個別の市町村のブロックチェーンは別々のネットワークとして機能するため、それぞれのブロックチェーンのガバナンスや運用方針は異なることに留意する必要がある。

 

共通のプロトコルを使用することで、セキュリティや信頼性に関する共通の基準が存在するということは、そのプロトコルが広く採用されているため、その分野でのベストプラクティスやセキュリティ基準が確立されている可能性が高いという意味であろう。したがって、新しいブロックチェーンが同じプロトコルを採用する場合、その新しいブロックチェーンも同様のセキュリティ基準やベストプラクティスに従った実装が可能となり、これが導入者や利用者にとって安心感をもたらす要因となる。

 

以下に、世界中の市町村のブロックチェーンをフェデレーションモデルで繋ぐメインチェーンのプログラムを、上記のことをふまえてやってみた。

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

// トランザクションの構造体
#[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(sha2::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 = sha2::Sha256::digest(message.as_bytes()).to_string();
            return *signature == calculated_signature;
        }
        false
    }
}

// 承認者の構造体
#[derive(Debug)]
struct Approver {
    name: String,
    is_selected: bool,
}

impl Approver {
    fn select_approver(approvers: &mut HashMap<String, Approver>) -> Option<String> {
        let mut selected_approver: Option<String> = None;
        for (name, approver) in approvers.iter_mut() {
            if !approver.is_selected {
                approver.is_selected = true;
                selected_approver = Some(name.clone());
                break;
            }
        }
        selected_approver
    }
}

// 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);
            // メインチェーンから自治体のブロックチェーンにデータを送信する処理を実装する
        } 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
    }
}

fn main() {
    let mut transaction_a = 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_a.calculate_location_hash();
    transaction_a.generate_signature();

    let mut transaction_b = Transaction {
        transaction_id: "654321".to_string(),
        municipality: "Kanazawa".to_string(),
        timestamp: Utc::now() + Duration::hours(1),
        location: "34.6937, 135.5023".to_string(), // 大阪市
        love_action_level: 3,
        amount: 0.0,
        action_content: "Received help carrying groceries".to_string(),
        is_local: false,
        close_flag: false,
        approval_target: None,
        signature: None,
        location_hash: Vec::new(),
        received_timestamp: None,
    };

    transaction_b.calculate_location_hash();
    transaction_b.generate_signature();

    let mut approvers: HashMap<String, Approver> = HashMap::new();
    approvers.insert("Approver1".to_string(), Approver { name: "Approver1".to_string(), is_selected: false });
    approvers.insert("Approver2".to_string(), Approver { name: "Approver2".to_string(), is_selected: false });

    if let Some(approver_name) = Approver::select_approver(&mut approvers) {
        transaction_a.approval_target = Some(approver_name.clone());
        println!("Transaction A approved by {}", approver_name);
    }

    if let Some(approver_name) = Approver::select_approver(&mut approvers) {
        transaction_b.approval_target = Some(approver_name.clone());
        println!("Transaction B approved by {}", approver_name);
    }

    transaction_b.amount = transaction_b.receive_love_currency();

    println!("Transaction A: {:?}", transaction_a);
    println!("Transaction B: {:?}", transaction_b);

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

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

    // メインチェーンから自治体のブロックチェーンにデータを送信する例
    api.send_data_to_municipality_chain(&transaction_a, "Saitama");
}
この修正により、メインチェーンのプログラムが修正され、市町村のブロックチェーンと整合性が取れるようになった。

 

 

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