先までは、"愛記"についての記載で、どのようにブロックチェーンSNSに組み込んで実装していけばよいのか、概念的なところからアプローチ方法を記載していった。大まかな概念としてはひとまず終えた。次は、ブロックチェーンの概念設計といえるところまで、基本設計書に着手できるようなところまで、概念を具体化していきたい。
Proof of Place(PoP)アルゴリズム⑥
市町村のブロックチェーンのプログラム
市町村のブロックチェーンのプログラムは、トランザクション処理とブロックチェーンの管理を行うために設計されている。このプログラムには、Paillier暗号方式、ゼロ知識証明、トランザクション処理パイプライン、そして複数のクラスと構造体が含まれている。以下に、プログラムの主要な部分とその動作について解説しよう。
プログラムの主要部分:
-
Paillier暗号方式
- generate_key: Paillier暗号方式の鍵生成関数。公開鍵(n, g)と秘密鍵(lam)を生成する。
- encrypt: Paillier暗号方式の暗号化関数。メッセージmを暗号化する。
- decrypt: Paillier暗号方式の復号関数。暗号文cを復号する。
-
ゼロ知識証明
- generate_challenge: チャレンジ値を生成する。
- generate_proof: チャレンジと秘密値を使って証明を生成する。
- verify_proof: 証明を検証する。
-
トランザクション処理パイプライン
- fetch_transactions: 保留中のトランザクションを取得する。
- verify_transactions: トランザクションの署名を検証する。
- execute_transactions: トランザクションを実行する。
- store_transactions: トランザクションをブロックチェーンに保存する。
- run_pipeline: 上記の関数を連続的に実行することで、トランザクション処理を行う。
-
トランザクション、ブロック、ブロックチェーンの構造体
- Transaction: トランザクションのデータ構造。
- Block: ブロックのデータ構造。
- Blockchain: ブロックチェーンのデータ構造。ブロックのチェーンと保留中のトランザクションを管理する。
-
その他のクラス
- VerifiableCredentialManager: Verifiable Credentialを管理するクラス。
- GulfStream: トランザクションを転送するクラス。
- LoveCurrencyApi: ブロックチェーンと通信するAPIクラス。
- DPoS: Delegated Proof of Stakeを実装するクラス。
- ProofOfHistory: 履歴の証明を生成するクラス。
プログラムの動作:
-
初期化
- LoveCurrencyApiクラスのインスタンスを初期化し、新しい自治体を登録する。
- Blockchainクラスのインスタンスを初期化し、Genesisブロック(初期ブロック)を追加する。
-
トランザクションの作成と送信
- 新しいトランザクションを作成し、自治体のブロックチェーンに送信する。
- VerifiableCredentialManagerクラスを使って、Verifiable Credentialを作成し、管理する。
-
トランザクション処理パイプラインの実行
- run_pipeline関数を別スレッドで実行し、トランザクション処理パイプラインを開始する。
- メインスレッドでは追加のトランザクションを処理する。
-
Paillier暗号方式とゼロ知識証明のテスト
- Paillier暗号方式の鍵生成、暗号化、復号をテストする。
- ゼロ知識証明の生成と検証をテストする。
-
GulfStreamのテスト
- GulfStreamクラスを使ってトランザクションを転送する。
実行例:
-
初期化
api = LoveCurrencyApi.init()
api.register_new_municipality("MunicipalityA")
blockchain = Blockchain()
-
トランザクションの作成と送信
transaction = Transaction(
"txn_123",
"MunicipalityA",
(35.65, 139.7),
8,
100.0,
"Helping others",
"SenderPublicKey",
"ReceiverPublicKey"
)
api.send_data_to_municipality_chain(transaction, "MunicipalityA")
-
トランザクション処理パイプラインの実行
pipeline_thread = Thread(target=run_pipeline, args=(blockchain,))
pipeline_thread.start()
blockchain.add_pending_transaction(transaction)
-
Paillier暗号方式とゼロ知識証明のテスト
n, g, lam = generate_key()
private_key = (n, g, lam)
message = 12345
encrypted_message = encrypt(message, n, g)
decrypted_message = decrypt(encrypted_message, private_key)
secret = 42
public_value = secret * 2
challenge = generate_challenge()
proof = generate_proof(secret, challenge)
is_valid = verify_proof(proof, challenge, public_value)
-
GulfStreamのテスト
gulf_stream = GulfStream()
gulf_stream.forward_transactions([transaction])
このプログラムは、トランザクションの作成からブロックチェーンへの追加、暗号化と証明の検証、さらには並列処理まで、複数の機能を包括的に実装している。
SolanaのSealevelの実装
実際のSolanaのSealevelは、さらに高度な技術を使っており、以下のような特徴がある:
- 依存関係の解析とスケジューリング: トランザクション間の依存関係を解析し、競合しないトランザクションを同時にスケジュールする。
- 高度なリソース管理: 各トランザクションがアクセスするリソースを効率的に管理し、リソース競合を最小限に抑える。
- 並列処理エンジン: 高度な並列処理エンジンを使用して、複数のトランザクションを同時に実行し、全体のスループットを最大化する。
Sealevelのような並列処理エンジンにより、Solanaは非常に高いパフォーマンスとスループットを実現している。これにより、他のブロックチェーンと比較して大幅な速度向上と効率化が可能になっている。
以下に、市町村のブロックチェーンのプログラムを、上記のメインチェーンのプログラムにつながるように修正した完全なコードを示す。
//以下は最新の市町村のブロックチェーンのプログラムである。
use num_bigint::{BigUint, RandBigInt, ToBigUint};
use num_traits::{One, Zero};
use rand::thread_rng;
use sha2::{Sha256, Digest};
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::{SystemTime};
use chrono::{Utc, DateTime};
use rand::seq::SliceRandom;
use hex;
use num_integer::Integer;
// トークンタイプの定義
const TOKEN_TYPES: [&str; 10] = [
"AIR(Root)", "AIS(Sacral)", "AIP(Solar Plexus)", "AIH(Heart)",
"AIT(Throat)", "AII(Third Eye)", "AIC(Crown)", "AIU(Universal)",
"AIE(Earth Star)", "AIM(Solar Matrix)"
];
// Paillier暗号方式の鍵生成関数
fn generate_key() -> (BigUint, BigUint, BigUint) {
let p = 499.to_biguint().unwrap();
let q = 547.to_biguint().unwrap();
let n = &p * &q;
let lam = (&p - 1.to_biguint().unwrap()) * (&q - 1.to_biguint().unwrap());
let g = 2.to_biguint().unwrap();
(n, g, lam)
}
// Paillier暗号方式の暗号化関数
fn encrypt(m: &BigUint, n: &BigUint, g: &BigUint) -> BigUint {
let mut rng = thread_rng();
let r = rng.gen_biguint_below(n);
let n_squared = n * n;
(g.modpow(m, &n_squared) * r.modpow(n, &n_squared)) % &n_squared
}
// Paillier暗号方式の復号関数
fn decrypt(c: &BigUint, private_key: &(BigUint, BigUint, BigUint)) -> BigUint {
let (n, g, lam) = private_key;
let n_squared = n * n;
let x = c.modpow(lam, &n_squared) - 1.to_biguint().unwrap();
(x / n * g.modpow(&(lam.clone().mod_inverse(n).unwrap()), n) % n).modpow(&1.to_biguint().unwrap(), n)
}
// チャレンジ生成関数
fn generate_challenge() -> u32 {
rand::thread_rng().gen()
}
// 証明生成関数
fn generate_proof(secret: u32, challenge: u32) -> u32 {
secret + challenge
}
// 証明検証関数
fn verify_proof(proof: u32, challenge: u32, public_value: u32) -> bool {
proof == public_value + challenge
}
// トランザクション結果
#[derive(Debug)]
enum TransactionResult {
Success,
Failure,
}
// Verifiable Credentialの構造体
#[derive(Debug, Clone)]
struct VerifiableCredential {
user_id: String,
claim_data: HashMap<String, String>,
timestamp: SystemTime,
}
impl VerifiableCredential {
fn new(user_id: String, claim_data: HashMap<String, String>) -> Self {
VerifiableCredential {
user_id,
claim_data,
timestamp: SystemTime::now(),
}
}
}
// Blockchainトレイト
trait Blockchain {
fn store_credential(&self, credential: VerifiableCredential) -> Option<TransactionResult>;
fn update_shared_credential(&self, recipient_id: &str, credential: VerifiableCredential) -> Option<TransactionResult>;
fn select_block_producers(&self) -> Vec<String>;
}
// 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)
}
fn select_block_producers(&self) -> Vec<String> {
vec!["Producer1".to_string(), "Producer2".to_string()]
}
}
// VerifiableCredentialManagerクラス
struct VerifiableCredentialManager {
blockchain: Box<dyn Blockchain>,
credentials: HashMap<String, VerifiableCredential>,
}
impl VerifiableCredentialManager {
fn new(blockchain: Box<dyn Blockchain>) -> Self {
VerifiableCredentialManager {
blockchain,
credentials: HashMap::new(),
}
}
fn create_verifiable_credential(&mut self, user_id: String, claim_data: HashMap<String, String>) {
let credential = VerifiableCredential::new(user_id.clone(), claim_data);
match self.blockchain.store_credential(credential.clone()) {
Some(TransactionResult::Success) => {
self.credentials.insert(user_id.clone(), credential);
println!("Verifiable Credential created and stored for user {}.", user_id);
},
_ => println!("Failed to store Verifiable Credential."),
}
}
fn share_verifiable_credential(&self, user_id: &str, recipient_id: &str) {
if let Some(credential_to_share) = self.credentials.get(user_id) {
match self.blockchain.update_shared_credential(recipient_id, credential_to_share.clone()) {
Some(TransactionResult::Success) => println!("Verifiable Credential shared with user {}.", recipient_id),
_ => println!("Failed to share Verifiable Credential."),
}
} else {
println!("No Verifiable Credential found for user {}.", user_id);
}
}
}
// Gulf Stream機能の実装
struct GulfStream;
impl GulfStream {
fn forward_transactions(&self, transactions: Vec<Transaction>) {
for transaction in transactions {
println!("Forwarding transaction: {:?}", transaction);
}
}
}
// LoveCurrency APIの実装
struct LoveCurrencyApi {
blockchain_client: DummyBlockchain,
federated_blockchains: HashMap<String, DummyBlockchain>,
}
impl LoveCurrencyApi {
fn new(blockchain_client: DummyBlockchain) -> Self {
LoveCurrencyApi {
blockchain_client,
federated_blockchains: HashMap::new(),
}
}
// メインチェーンから自治体のブロックチェーンにデータを送信するメソッド
fn send_data_to_municipality_chain(&self, transaction: &Transaction, municipality: &str) {
if transaction.verify_signature() {
println!("Sending data to municipality chain: {:?}", transaction);
println!("Data sent successfully.");
} else {
println!("Failed to send data: Invalid signature");
}
}
// 新しい自治体を登録するメソッド
fn register_new_municipality(&mut self, municipality_name: String) {
println!("Registering new municipality: {}", municipality_name);
self.federated_blockchains.insert(municipality_name, DummyBlockchain);
}
// APIの初期化処理
fn init() -> Self {
let dummy_blockchain = DummyBlockchain;
LoveCurrencyApi::new(dummy_blockchain)
}
// 新しいエンドポイントを追加して、リクエストを受け取ってからapprove_requestメソッドを呼び出す
fn approve_request_from_municipality(&self, data: &Transaction) {
if data.verify_signature() {
println!("Received approval request from municipality: {:?}", data);
} else {
println!("Failed to approve request: Invalid signature");
}
}
}
// トランザクションの構造体
#[derive(Debug, Clone)]
struct Transaction {
transaction_id: String,
municipality: String,
timestamp: DateTime<Utc>,
location: (f64, f64),
love_action_level: i32,
amount: f64,
action_content: String,
is_local: bool,
close_flag: bool,
approval_target: Option<String>,
sender_public_key: String,
receiver_public_key: String,
signature: String,
location_hash: Vec<u8>,
received_timestamp: Option<DateTime<Utc>>,
recipient_location: Option<(f64, f64)>,
fee: f64,
}
impl Transaction {
fn new(
transaction_id: String,
municipality: String,
location: (f64, f64),
love_action_level: i32,
amount: f64,
action_content: String,
sender_public_key: String,
receiver_public_key: String,
) -> Self {
let mut transaction = Transaction {
transaction_id,
municipality,
timestamp: Utc::now(),
location,
love_action_level,
amount,
action_content,
is_local: true,
close_flag: false,
approval_target: None,
sender_public_key,
receiver_public_key,
signature: String::new(),
location_hash: Vec::new(),
received_timestamp: None,
recipient_location: None,
fee: 0.0,
};
transaction.calculate_location_hash();
transaction.generate_signature();
transaction
}
fn calculate_location_hash(&mut self) {
let mut hasher = Sha256::new();
hasher.update(format!("{:?}", self.location).as_bytes());
self.location_hash = hasher.finalize().to_vec();
}
fn calculate_fee(&self) -> f64 {
self.amount * 0.01
}
fn display_fee(&self) {
let fee = self.calculate_fee();
println!("Transaction fee: {} 愛貨", fee);
}
fn generate_signature(&mut self) {
let message = format!(
"{}{}{}{}{}{}{}{}{}{}",
self.transaction_id,
self.municipality,
self.timestamp.to_rfc3339(),
format!("{:?}", self.location),
self.love_action_level,
self.amount,
self.action_content,
hex::encode(&self.location_hash),
self.sender_public_key,
self.receiver_public_key
);
self.signature = hex::encode(Sha256::digest(message.as_bytes()));
}
fn verify_signature(&self) -> bool {
let message = format!(
"{}{}{}{}{}{}{}{}{}{}",
self.transaction_id,
self.municipality,
self.timestamp.to_rfc3339(),
format!("{:?}", self.location),
self.love_action_level,
self.amount,
self.action_content,
hex::encode(&self.location_hash),
self.sender_public_key,
self.receiver_public_key
);
let computed_signature = hex::encode(Sha256::digest(message.as_bytes()));
self.signature == computed_signature
}
fn receive_love_currency(&mut self) -> f64 {
if self.received_timestamp.is_none() {
self.received_timestamp = Some(Utc::now());
}
let time_diff = Utc::now().signed_duration_since(self.received_timestamp.unwrap());
let hours_diff = time_diff.num_hours() as f64;
let decreased_amount = self.amount - (hours_diff * 0.05);
decreased_amount
}
fn set_recipient_location(&mut self, location: (f64, f64)) {
self.recipient_location = Some(location);
}
fn generate_proof_of_place(&self) -> String {
hex::encode(&self.location_hash)
}
fn generate_proof_of_history(&self) -> String {
let mut hasher = Sha256::new();
hasher.update(format!("{:?}", self.timestamp).as_bytes());
hex::encode(hasher.finalize())
}
}
// DPoS構造体
struct DPoS {
municipalities: Vec<String>,
approved_representative: Option<String>,
}
impl DPoS {
fn new(municipalities: Vec<String>) -> Self {
Self {
municipalities,
approved_representative: None,
}
}
fn elect_representative(&mut self) -> String {
let representative = self.municipalities.choose(&mut rand::thread_rng()).unwrap().clone();
self.approved_representative = Some(representative.clone());
representative
}
fn approve_transaction(&self, transaction: &mut Transaction) -> Result<&str, &str> {
if let Some(representative) = &self.approved_representative {
transaction.approval_target = Some(representative.clone());
Ok("Transaction approved")
} else {
Err("No representative elected")
}
}
}
// Block構造体
#[derive(Debug)]
struct Block {
index: usize,
previous_hash: String,
timestamp: DateTime<Utc>,
data: Transaction,
proof_of_place: String,
proof_of_history: String,
zero_knowledge_proof: Option<String>,
hash: String,
}
impl Block {
fn new(index: usize, previous_hash: &str, data: Transaction) -> Self {
let timestamp = Utc::now();
let proof_of_place = data.generate_proof_of_place();
let proof_of_history = data.generate_proof_of_history();
let zero_knowledge_proof = data.zero_knowledge_proof.clone();
let hash = calculate_hash(index, previous_hash, ×tamp, &proof_of_place, &proof_of_history, &zero_knowledge_proof);
Self {
index,
previous_hash: previous_hash.to_string(),
timestamp,
data,
proof_of_place,
proof_of_history,
zero_knowledge_proof,
hash,
}
}
}
fn calculate_hash(index: usize, previous_hash: &str, timestamp: &DateTime<Utc>, proof_of_place: &str, proof_of_history: &str, zero_knowledge_proof: &Option<String>) -> String {
let mut hasher = Sha256::new();
hasher.update(index.to_string());
hasher.update(previous_hash);
hasher.update(timestamp.to_string());
hasher.update(proof_of_place);
hasher.update(proof_of_history);
if let Some(proof) = zero_knowledge_proof {
hasher.update(proof);
}
hex::encode(hasher.finalize())
}
// Blockchain構造体
struct Blockchain {
chain: Vec<Block>,
pending_transactions: Arc<Mutex<Vec<Transaction>>>,
}
impl Blockchain {
fn new() -> Self {
let mut blockchain = Self {
chain: Vec::new(),
pending_transactions: Arc::new(Mutex::new(Vec::new()))
};
blockchain.chain.push(Block::new(0, "0", Transaction::new(
"Genesis".to_string(),
"Genesis".to_string(),
(0.0, 0.0),
0,
0.0,
"Genesis Block".to_string(),
"None".to_string(),
"None".to_string()
)));
blockchain
}
fn get_latest_block(&self) -> &Block {
self.chain.last().unwrap()
}
fn add_block(&mut self, transaction: Transaction) {
let latest_block = self.get_latest_block();
let new_block = Block::new(self.chain.len(), &latest_block.hash, transaction);
self.chain.push(new_block);
}
fn add_pending_transaction(&self, transaction: Transaction) {
let mut pending_transactions = self.pending_transactions.lock().unwrap();
pending_transactions.push(transaction);
}
fn process_pending_transactions(&self) {
let mut pending_transactions = self.pending_transactions.lock().unwrap();
while let Some(transaction) = pending_transactions.pop() {
self.add_block(transaction);
}
}
}
// Proof of History 構造体
struct ProofOfHistory {
sequence: Vec<String>,
}
impl ProofOfHistory {
fn new() -> Self {
ProofOfHistory { sequence: Vec::new() }
}
fn add_event(&mut self, event: &str) {
self.sequence.push(event.to_string());
}
fn generate_hash(&self) -> String {
let mut hasher = Sha256::new();
for event in &self.sequence {
hasher.update(event.as_bytes());
}
hex::encode(hasher.finalize())
}
}
// トランザクション処理パイプラインの各ステージの関数
fn fetch_transactions(pending_transactions: Arc<Mutex<Vec<Transaction>>>) -> Vec<Transaction> {
let mut fetched_transactions = Vec::new();
{
let mut pending = pending_transactions.lock().unwrap();
while let Some(tx) = pending.pop() {
fetched_transactions.push(tx);
}
}
fetched_transactions
}
fn verify_transactions(transactions: Vec<Transaction>) -> Vec<Transaction> {
transactions.into_iter()
.filter(|tx| tx.verify_signature())
.collect()
}
fn execute_transactions(transactions: Vec<Transaction>) -> Vec<Transaction> {
transactions.into_iter()
.map(|mut tx| {
tx.receive_love_currency();
tx
})
.collect()
}
fn store_transactions(blockchain: &mut Blockchain, transactions: Vec<Transaction>) {
for tx in transactions {
blockchain.add_block(tx);
}
}
// トランザクション処理パイプラインを実行する関数
fn run_pipeline(blockchain: Arc<Mutex<Blockchain>>) {
loop {
let fetched_transactions;
{
let blockchain = blockchain.lock().unwrap();
fetched_transactions = fetch_transactions(blockchain.pending_transactions.clone());
}
if !fetched_transactions.is_empty() {
let verified_transactions = verify_transactions(fetched_transactions);
let executed_transactions = execute_transactions(verified_transactions);
{
let mut blockchain = blockchain.lock().unwrap();
store_transactions(&mut blockchain, executed_transactions);
}
}
thread::sleep(std::time::Duration::from_millis(500));
}
}
// メイン関数
fn main() {
// APIの初期化
let mut api = LoveCurrencyApi::init();
// 新しい自治体の登録
api.register_new_municipality("MunicipalityA".to_string());
// トランザクションの作成
let transaction = Transaction::new(
"txn_123".to_string(),
"MunicipalityA".to_string(),
(35.65, 139.7),
8,
100.0,
"Helping others".to_string(),
"SenderPublicKey".to_string(),
"ReceiverPublicKey".to_string(),
);
// データを自治体のチェーンに送信
api.send_data_to_municipality_chain(&transaction, "MunicipalityA");
// Verifiable Credentialのマネージャーの作成
let blockchain = Box::new(DummyBlockchain);
let mut vc_manager = VerifiableCredentialManager::new(blockchain);
// Verifiable Credentialの作成
let mut claim_data = HashMap::new();
claim_data.insert("Name".to_string(), "Alice".to_string());
vc_manager.create_verifiable_credential("user_id_123".to_string(), claim_data);
// 全ブロックの表示
let blockchain = Arc::new(Mutex::new(Blockchain::new()));
blockchain.lock().unwrap().add_pending_transaction(transaction.clone());
// トランザクションパイプラインを別スレッドで実行
let blockchain_clone = Arc::clone(&blockchain);
thread::spawn(move || {
run_pipeline(blockchain_clone);
});
// メインスレッドでの追加トランザクション処理
blockchain.lock().unwrap().add_pending_transaction(transaction.clone());
// 全ブロックの表示
thread::sleep(std::time::Duration::from_secs(2)); // パイプライン処理のため少し待つ
println!("{:?}", blockchain.lock().unwrap().chain);
// Paillier暗号方式のテスト
let (n, g, lam) = generate_key();
let private_key = (n.clone(), g.clone(), lam.clone());
let message = 12345.to_biguint().unwrap();
println!("Original message: {}", message);
let encrypted_message = encrypt(&message, &n, &g);
println!("Encrypted message: {}", encrypted_message);
let decrypted_message = decrypt(&encrypted_message, &private_key);
println!("Decrypted message: {}", decrypted_message);
// ゼロ知識証明のテスト
let secret = 42; // 秘密値
let public_value = secret * 2; // 公開値
let challenge = generate_challenge();
let proof = generate_proof(secret, challenge);
println!("Public value: {}", public_value);
println!("Challenge: {}", challenge);
println!("Proof: {}", proof);
let is_valid = verify_proof(proof, challenge, public_value);
println!("Is proof valid? {}", is_valid);
// LoveCurrency APIのテスト
let mut api = LoveCurrencyApi::init();
let transaction = Transaction::new(
"txn123".to_string(),
"MunicipalityA".to_string(),
(36.2048, 138.2529),
5,
100.0,
"Love Action".to_string(),
"public_key_sender".to_string(),
"public_key_receiver".to_string(),
);
api.send_data_to_municipality_chain(&transaction, "MunicipalityA");
api.register_new_municipality("MunicipalityB".to_string());
// Verifiable Credential Managerのテスト
let mut vcm = VerifiableCredentialManager::new(Box::new(DummyBlockchain));
let mut claim_data = HashMap::new();
claim_data.insert("name".to_string(), "Alice".to_string());
claim_data.insert("age".to_string(), "30".to_string());
vcm.create_verifiable_credential("user123".to_string(), claim_data);
vcm.share_verifiable_credential("user123", "user456");
// Gulf Streamのテスト
let gulf_stream = GulfStream;
gulf_stream.forward_transactions(vec![transaction]);
}
このプログラムは、以下の機能を統合している:
- Paillier暗号方式の鍵生成、暗号化、復号化:メッセージを暗号化し、復号化するための関数を実装している。
- ゼロ知識証明:チャレンジ、証明の生成と検証を行う関数を提供している。
- LoveCurrency API:データの送信、自治体の登録、リクエストの承認を処理するAPIを提供している。
- Verifiable Credential Manager:Verifiable Credentialの作成と共有を管理する機能を提供している。
- ガルフストリーム機能:トランザクションを転送する仮の実装を提供している。
-
トランザクション処理パイプラインの各ステージの関数:fetch_transactions、verify_transactions、execute_transactions、store_transactions は、各ステージごとの処理を担当する。
-
トランザクション処理パイプラインを実行する関数:run_pipeline 関数は、トランザクションをパイプラインで処理する。各ステージの処理を順に実行し、並列処理を実現する。
-
メイン関数:メイン関数では、トランザクションの作成とパイプライン処理のためのスレッドの生成、及びその他のテスト処理を行う。
このプログラムは、メインチェーンと各市町村のブロックチェーンが相互に通信し、動作するように設計されている。
いかがであろうか、これで市町村のブロックチェーンのプログラムも概念設計という意味では完成としたい。ここから基本設計に入っていき、それぞれの動作を矛盾無く行えるよう、細かく設計していく必要がある。次回から、基本設計に入っていきたい。