PBFT(Pratical Byzantine Fault Tolerance)

PoWやPoSと同様Byzantine Faultモデルだが、ファイナリティの不確実性や性能問題を解消している

– PBFTではネットワークのすべての参加者をあらかじめ知っている必要がある
– 参加者の1人がプライマリーとなり、要求を全参加者に送る。要求に対する結果を集計し、多数を占めている値を採用することでブロックを確定。
– 不正なノード数をf個とする場合、ノード数は3f+1個である必要があり、確定にはf+1個以上のノードが必要
– 分岐しない為、性能的に非常に高速

Sieve
IBMで考案されたPBFTを拡張したアルゴリズム
Paxos、Raftなどのコンセンサスアルゴリズムもある

考え方によるが、中央集権型か、合意形成型かで大きく異なる様ですね。しかし、PoWのビットコインがこれだけ仮想通貨の中で支持を集めているというのは、ネットが登場して、現代社会というのは本当に変わりましたな。

Proof of Stake

– 貨幣量を多く所有している承認者が優先的にブロックを作成できる
– 貨幣量によってハッシュ計算の難易度が下がる
– Proof of Workの代替案
– マイニングによる消費電力がない
– コンセンサスに必要な時間が短い
– ASIC等を使ったマイナーによる中央集権化のリスクが少ない

ビットコインの取引処理件数は7件/1秒と言われており、Visaカードの
50,000件/1秒に比べて取引速度が大きく劣る

Coin Age
コインの保有量 x コインの保有期間 が大きければ大きいほどマイニングに成功しやすくなる

Randomized Proof of Stake
コインの保有量に比例して、ランダムに取引承認者を選ぶ

ただし、コインをため込まれると、通貨の流動性が下がる
PoSでは格差が広がり易い

PoSの公式

SHA256(prevhash + address + timestamp) <= 2^256 * balance / diff [/code] GitHubにblock chainのサンプルがありますね。 https://github.com/AvinashNath2/Block-Chain-Example/blob/master/Block_Chain.py

PoWトランザクション

1.walletがトランザクションを発行し、参加者全員にブロードキャスト
2.受け取った承認者がハッシュ計算。先に見つけたブロックがブロックチェーンに追加
3.walletが別のトランザクションを発行し、全員にブロードキャスト
4.受けっとた承認者がハッシュ計算。複数のノードが同時に見つけた場合はブロックチェーンは分岐する
5.次に別のノードがブロックを追記した時、追記されたブロックチェーンが正となる
Byzantine Faultに対応
参加サーバはローカル通信のみでよい
多数決の代わりとなるのはCPU演算力
電気代が安い地域に集中する懸念がある

from random import randint 
from hashlib import sha256 

previous_hash = "****"
cnt = 1
nonce = str(randint(0, 1000000))

header = sha256(f'{previous_hash}{nonce}'.encode()).hexdigest()

while header[:4] != "0000":
	text = 'loop:{}, header:{}, header[:4], nonce:{}\n'
	print(text.format(cnt, header, header[:4], nonce))

	nonce = str(randint(0, 1000000))
	header = sha256(f'{previous_hash}{nonce}'.encode()).hexdigest()
	cnt += 1 

text = 'loop:{}, header:{}, header[:4]:{}, nonce:{}'
print(text.format(cnt, header, header[:4], nonce))

コンセンサスアルゴリズム

ビザンチン将軍問題の解決が重視され、パブリック型では、悪意のある者が紛れ込んでいることを想定した仕組みが構築される
コンソーシアム型はPoWは必要なし
コンセンサスアルゴリズムが整理と真偽判断をする
Proof of Stake はPoWの改良版

問題
– 特定のマイナー(ブロック作成者)が計算能力を占有すると、PoWが正常に機能しなくなる
– チェーンが分岐したときの決済完全性が完璧ではない、不確実性が存在する
– 通信時間のネットワーク性能の限界
– 容量の増加

コンセンサスアルゴリズムの種類
– Proof of Work
– Proof of Stake
– Paxos
– Raft
– PBFT
– Sieve

障害時の想定モデルが異なる

P2Pの連携の動き

Bitcoin core(初回)
1. DNSによる探索
2. クライアントにハードコーディングされている準永久的ノード一覧の参照
3. コマンドラインによるIP指定
※ハードコーディングとは、本来記述すべきでないリソースをソースコードの中に埋め込む事
2回目以降は、ノード一覧を保持したDBを参照して連携
— データの送受信はハッシュをinvメッセージとして相手クライアントに送り、getdataメッセージの送受信から、情報本体をやりとりする

Ethereum
1. あらかじめハードコーディングされているブートストラップノードの一覧を参照して接続
ブートストラップノードは起動時にコマンドラインから指定することもできる
— ハッシュがすべてのノードによって共有されている空間にチェーンとして保存され、ワークプールとして利用される

Hyperledger Fabric
-起動時に指定された起点となるノードに対してディスカバリープロトコルを発行して参加者一覧を入手
-その後、validating peerの場合は、全てのvalidating peerとメッシュ状のネットワークを形成、non-validating peerの場合は、接続許可されている最も近いvalidating peerとのみ接続
— ノード間の通信にgRPCを利用しており、双方向でストリーミングのメッセージングがやりとり可能。シリアライズ化にProtocol buffersを利用

あれ、BitcoinとEthereumって、P2Pも情報の送受信も仕組みが全く違うやんけ。。。
DNS-IPはネット回線のネットワークとしては基本のように思うが、なぜこんなにハードコーディングが使われるんだろうか。。キュリオシティをそそりますね。

P2Pブロックチェーンの動き

Proof of Work(計算量証明)をコンセンサスアルゴリズムに採用

1. P2Pトランザクションのノード(ノードX)が取引データを送信 ※この時点では、取引自体は未成立
2. トランザクションが全参加者宛に伝播
3. トランザクションを受け取った全ノードがマイニングを実施し、条件に合うハッシュ値を発見すると、既存のブロックチェーンに新しいブロックを追加
4. 新しいブロックを追加したノードは、ブロックをP2Pネットワークにブロードキャスト
5. ブロックを受け取った各ノードは、ブロックが正当なものであるかを検証し、正しいものであれば、ブロックチェーンを更新。この時点で取引が成立

なるほど、取引成立までにProof of Workが入っているのね。

疑問点
-> Proof of Workのロジックは、ランダム関数を使っているのか??
-> ブロックチェーンのトランザクションの伝播対象は、取引所までか?それとも、ユーザー単位なのか?例えば、サービスにブロックチェーン決済を取り込んだ場合は、トランザクションはサービス提供者までに留まるのか?
-> マイニング業者の競争は、単純にCPUの性能の勝負なのか?それともマイニングアルゴリズムなども左右されるのか?

ブロックチェーン基盤

1. Bitcoin Core (Bitcoin Foundation)
https://bitcoin.org/ja/download
ビットコインリファレンス実装
Proof of Work

2. Ethereum (Ethereum Foundation)
https://www.ethereum.org/
分散型アプリケーションDapps構築
Proof of Stake

3. Hyperledger Fabric (Hyperledger Project)
https://www.hyperledger.org/projects/fabric
P2P分散レッジャー技術基盤
Practical Byzantine Fault Tolerance

4. Corda (R3 CEV)
https://www.corda.net/
金融向け分散型台帳基盤

5. Chain Open Standard 1 (Chain.inc)
https://www.openchainproject.org/get-started
ブロックチェーン暗号化など

6. mijin (テックビューロ)
https://mijin.io/
プライベート型ブロックチェーン

7. Orb1 (Orb)
https://imagine-orb.com/
定期的に取引を確定させることで、決済完了性を確保

8. Eris (Eris Industries)
https://erisindustries.com/
パーミッション型ブロックチェーン

——–
スマートコントラクト、電子署名・ハッシュ関数、コンセンサスアルゴリズム、P2Pネットワーク

——–
誰でも参加型(パブリック型)、信頼する参加者のみに絞り込むか(コンソーシアム型、プライベート型)
->参加者形態により、マイニング、ブロックチェーン閲覧、ブロック生成、マイニング報酬 などが異なる

——–
ブロックチェーンブロック
-> 前ブロックヘッダのハッシュ値、ナンス、トランザクション群のハッシュ
-> トランザクションの内容

分散型台帳 – Decentralized ledger

– データベースデータが、ブロックチェーン技術によってネットワークを介して共有される
– 分散型台帳では、書き込み要求があった場合、全システムで共有
– 複数のユーザから同じデータに対して書き込み要求があった場合は予めルールを決める。ただし合意形成に時間がかかる
– コンセンサスアルゴリズムは様々
– 結果的に、一つのシステムにアクセスしているように見える

e.x. 貿易業務(ステークホルダーが多い)

– ブロックチェーンは分散型台帳以外にも、海外送金、IoT連携などでも期待されている
– ビットコインは取引記録の承認を行った参加者に手数料が与えられる
— 新しいブロックは、直前のブロックのハッシュ値、プルーフオブワーク、n個の取引記録
– 国際送金には、送金・決済時に一時的に法定通貨から仮想通貨に変換する(1.9%程度でできるところがある)

ビットコインの仕組み

– ビットコインが生み出す「報酬」によってシステムコストを補う
– ブロックチェーンのブロック生成で報酬を得る
– 1ブロックあたり25BTC
– ビットコインでは10分間に1ブロックだけ生成される仕組み
– 報酬は全てのマイニング業者で分けている
– ビットコインの処理性能が決まっている(1秒間に最大7取引?)
– BTCはシステム維持費用をマイニングとういうBTCのエコシステムに取り込んでいる

大手マイニング業者 BitFury
https://bitfury.com/

Blockchain その2

– blockchainでは、ジェネシスブロックを含め、一つ前のハッシュを保持して、新しいトランザクションを作る
– 一つのブロックのハッシュ計算に時間がかかるようにすれば、新しく作られるまでに、それまでのハッシュ計算を書き換えられるリスクが減る、
– ブロックを改良する(適当な数字を加えるなど)

import hashlib
import json
import datetime

class Block:
	def __init__(self, index, timestamp, transaction, previous_hash):
		self.index = index 
		self.timestamp = timestamp 
		self.transaction = transaction 
		self.previous_hash = previous_hash 
		self.difficulty = 4
		self.property_dict = {str(i): j for i, j in self.__dict__.items()}
		self.now_hash = self.calc_hash()
		self.proof = None 
		self.proof_hash = None 

	def check_proof(self, nonce):
		proof_string = self.now_hash + str(nonce)
		calced = hashlib.sha256(proof_string.encode("ascii")).hexdigest()
		if calced[:self.difficulty:].count('0') == self.difficulty:
			self.proof_hash = calced 
			return True
		else:
			return False

	def mining(self):
		proof = 0
		while True:
			if self.check_proof(proof):
				break
			else:
				proof += 1
		return proof  


	def calc_hash(self):
		block_string = json.dumps(self.property_dict, sort_keys=True).encode('ascii')
		return hashlib.sha256(block_string).hexdigest()

# def new_transaction(sender, recipient, amount):
# 	transaction = {
# 		"差出人": sender,
# 		"宛先": recipient,
# 		"金額": amount,
# 	}
# 	return transaction

block_chain = []
block = Block(0, 0, [], "-")
block.proof = block.mining()
block_chain.append(block)

for i in range(5):
 
    block = Block(i+1, str(datetime.datetime.now()), ["適当なトランザクション"], block_chain[i].now_hash)
    block.proof = block.mining()
    block_chain.append(block)
 
for block in block_chain:
    for key, value in block.__dict__.items():
        print(key, ':', value)
    print("")

[vagrant@localhost python]$ python app.py
previous_hash : –
timestamp : 0
index : 0
proof_hash : 0000a63ece63ab6bc14791cf8bb4930b57f3e102c97040c1ac94c01c7a7bcb4c
property_dict : {‘previous_hash’: ‘-‘, ‘timestamp’: 0, ‘index’: 0, ‘difficulty’: 4, ‘transaction’: []}
difficulty : 4
transaction : []
now_hash : d1f0dc2f2526d9873c958cac696cd4f64b230ebcfcc8537a0bf94645cc2760de
proof : 30621

previous_hash : d1f0dc2f2526d9873c958cac696cd4f64b230ebcfcc8537a0bf94645cc2760de
timestamp : 2019-10-19 14:58:19.290332
index : 1
proof_hash : 0000f827f0eb3f6445cfcdad5ad49f70ad1a3a5821664a003dbcc79b89312acf
property_dict : {‘previous_hash’: ‘d1f0dc2f2526d9873c958cac696cd4f64b230ebcfcc8537a0bf94645cc2760de’, ‘timestamp’: ‘2019-10-19 14:58:19.290332’, ‘index’: 1, ‘difficulty’: 4, ‘transaction’: [‘適当なトランザクション’]}
difficulty : 4
transaction : [‘適当なトランザクション’]
now_hash : a325c83c16377f143b2c18f5658dc3e4963e9c48cfc823641160ff02fe2e285a
proof : 59756

previous_hash : a325c83c16377f143b2c18f5658dc3e4963e9c48cfc823641160ff02fe2e285a
timestamp : 2019-10-19 14:58:19.677796
index : 2
proof_hash : 0000e93839e2be3b31a26ede35f120605d32923f870aab38a7a2593d43e76377
property_dict : {‘previous_hash’: ‘a325c83c16377f143b2c18f5658dc3e4963e9c48cfc823641160ff02fe2e285a’, ‘timestamp’: ‘2019-10-19 14:58:19.677796’, ‘index’: 2, ‘difficulty’: 4, ‘transaction’: [‘適当なトランザクション’]}
difficulty : 4
transaction : [‘適当なトランザクション’]
now_hash : 003c134be0ba4b6118ad86e9914c266980546bd6379a7a2bf94c6cbd3acf1285
proof : 54445

previous_hash : 003c134be0ba4b6118ad86e9914c266980546bd6379a7a2bf94c6cbd3acf1285
timestamp : 2019-10-19 14:58:20.040778
index : 3
proof_hash : 0000f10e20ef472e1c37ed8cd666f25f5483f0f5e5b97a7cc93823f4a82b3a56
property_dict : {‘previous_hash’: ‘003c134be0ba4b6118ad86e9914c266980546bd6379a7a2bf94c6cbd3acf1285’, ‘timestamp’: ‘2019-10-19 14:58:20.040778’, ‘index’: 3, ‘difficulty’: 4, ‘transaction’: [‘適当なトランザクション’]}
difficulty : 4
transaction : [‘適当なトランザクション’]
now_hash : 07ed3179113ea8b90f71189df0a5fe14d86640899b50c2682b7cd0a6259e5d1c
proof : 9815

previous_hash : 07ed3179113ea8b90f71189df0a5fe14d86640899b50c2682b7cd0a6259e5d1c
timestamp : 2019-10-19 14:58:20.096824
index : 4
proof_hash : 0000e2f39590f8aca4422e913d174dbb4ffe3ce94ecb75648e6681627d317a4b
property_dict : {‘previous_hash’: ’07ed3179113ea8b90f71189df0a5fe14d86640899b50c2682b7cd0a6259e5d1c’, ‘timestamp’: ‘2019-10-19 14:58:20.096824’, ‘index’: 4, ‘difficulty’: 4, ‘transaction’: [‘適当なトランザクション’]}
difficulty : 4
transaction : [‘適当なトランザクション’]
now_hash : 85bf9eab363c3f0c0e6fec320e19699a64d760a7fd8bea992e07b3bb62348d64
proof : 72875

previous_hash : 85bf9eab363c3f0c0e6fec320e19699a64d760a7fd8bea992e07b3bb62348d64
timestamp : 2019-10-19 14:58:20.540764
index : 5
proof_hash : 0000da7db9dc07627d53e6c4f9eba2e76f3c7f3bb7cdd1bdb32c4f3242918397
property_dict : {‘previous_hash’: ’85bf9eab363c3f0c0e6fec320e19699a64d760a7fd8bea992e07b3bb62348d64′, ‘timestamp’: ‘2019-10-19 14:58:20.540764’, ‘index’: 5, ‘difficulty’: 4, ‘transaction’: [‘適当なトランザクション’]}
difficulty : 4
transaction : [‘適当なトランザクション’]
now_hash : 131259e11a3679e3f06612e06ea80d13f8bc2b82478a9408a0ad142692ab6fe4
proof : 14094