私の意見では、ビットコインは現実世界の『V フォー・ヴェンデッタ』です。もちろん、現実はもっと残酷な世界政府です。このゲームは、人類の文明、政治、社会的属性、経済、人権に関するものです。 IBM HyperLeger はファブリックとも呼ばれます。社会全体で管理されるスーパー台帳として考えることができます。権力を握る中央組織は存在しない。あなたが行うすべての取引はネットワーク全体でオープンかつ安全であり、その信用は社会全体で証明されます。 Bitcoin との関係は、Fabric を使用して Bitcoin と呼ばれるアプリケーションを構築し、世界を変えることができるという点です。 そのビジョンは本当に素晴らしいです。まさに私たちが世界を変えたいと思っていることのようです。しかし、私たちは残酷な現実と世界の前では常に無知です。ブロックチェーンは、段階的に壮大な青写真を構築する必要があります。少なくとも工業生産や国民経済に活用した例はない。 Fabric は IBM から生まれました。当初の目的は工業生産に貢献することでした。 IBM は 44,000 行のコードをオープンソース化しました。これは大きな貢献です。ブロックチェーンの原理を詳しく探求する機会を与えてくれます。しかし、結局のところ、IBM は自社の利益と顧客の利益に基づいて行動しており、目的もなくこの公共の福祉活動を行っているわけではありません。ファブリックを見るとき、私たちは慎重な考え方を持つ必要があります。ブロックチェーンは必ずしもこのようにする必要はありません。それとビットコインの最も重要な非技術的な違いは何ですか?まずは生地のキーワードを見てみましょう(英語の方が正確な言葉もあるので、翻訳はしません)。 1. 用語
2. 建築アーキテクチャには、メンバーシップ、ブロックチェーン、チェーンコードという 3 つのコアロジックがあります。 2.1 会員サービスこのサービスは、ノードの ID、プライバシー、機密性、監査可能性を管理するために使用されます。非許可型ブロックチェーン ネットワークでは、参加者は承認を必要とせず、すべてのノードが同じように扱われ、トランザクションを送信してこれらのトランザクションをブロックに保存できます。メンバーシップ サービスは、公開鍵インフラストラクチャ (PKI)、分散化、一貫性に依存して、非許可型ブロックチェーン ネットワークを許可型ブロックチェーン ネットワークに変換します。 2.2 ブロックチェーンサービスブロックチェーン サービスは、HTTP/2 上に構築された P2P プロトコルを使用して分散型台帳を管理します。ワールド ステートのコピーを維持するための最も効率的なハッシュ アルゴリズムを提供します。 PBFT、Raft、PoW、PoS などの特定のニーズに応じてコンセンサス プロトコルを設定するために、プラグ可能なアプローチが採用されています。 2.3 チェーンコードサービスチェーンコード サービスは、VP ノード上でチェーンコード ロジックを実行するための安全で軽量なサンドボックス操作モードを提供します。ここではコンテナ環境が使用され、その中のベースイメージは、OS レイヤーやチェーンコードを開発するための言語、ランタイム、SDK レイヤーなど、すべて署名検証済みのセキュアなイメージです。現在、Go、Jave、Nodejsの開発言語がサポートされています。 2.4 イベントブロックチェーン ネットワークでは、VP ノードとチェーンコードがイベントを送信して、いくつかの監視アクションをトリガーします。たとえば、チェーンコードはユーザー イベントを生成できるユーザー コードです。 2.5 APIとCLIユーザーの登録、ブロックチェーンのクエリ、トランザクションの送信を可能にする REST API を提供します。一部のチェーンコード固有の API を使用して、トランザクションを実行し、トランザクション結果を照会できます。開発者は、CLI を使用してチェーンコードをすばやくテストしたり、トランザクション ステータスを照会したりできます。 3. トポロジー 分散ネットワークのトポロジー構造は研究する価値があります。この世界には、多くの参加者、さまざまな役割、さまざまな利益団体が存在します。さまざまな状況への対応は、分散ネットワークにおけるルールと法則を象徴しています。ルールがなければ秩序は生まれません。ブロックチェーン ネットワークには、メンバーシップ サービス、VP ノード、NVP ノード、および 1 つ以上のアプリケーションが存在します。それらはチェーンを形成し、それぞれ独自のセキュリティ要件と運用要件を持つ複数のチェーンが存在することになります。 3.1 単一VPノードネットワーク最も単純なネットワークには VP ノードが 1 つだけ含まれるため、コンセンサス部分は省略されます。 3.2 複数のVPノードネットワーク複数の VP と NVP が参加するネットワークは貴重で有意義です。 NVP ノードは VP ノードのワークロードを共有し、API リクエストとイベントの処理を担当します。 VPノードについては、VPノード間でメッシュネットワークを形成して情報を伝送します。 NVP ノードは、許可されている場合、隣接する VP ノードに接続できます。アプリケーションが VP ノードと直接通信できる場合は、NVP ノードを省略できます。 3.3 マルチチェーンネットワーク内に複数のチェーンが存在し、各チェーンの意図が異なる場合もあります。 4. プロトコルFabric は、双方向のストリーム メッセージ伝送である P2P 通信に gRPC を使用します。転送するデータ構造をシリアル化するには、プロトコル バッファーを使用します。 4.1 メッセージメッセージには、検出、トランザクション、同期、コンセンサスの 4 つの種類があります。各情報タイプには、ペイロードによって示されるサブ情報がさらに含まれます。 ペイロードは、トランザクションやレスポンスなどのいくつかのオブジェクトを含む不透明なバイト配列です。たとえば、タイプが CHAIN_TRANSACTION の場合、ペイロードはトランザクション オブジェクトになります。 メッセージ メッセージ { 列挙型 { 未定義 = 0; DISC_HELLO = 1; DISC_DISCONNECT = 2; DISC_GET_PEERS = 3; DISC_PEERS = 4; DISC_NEWMSG = 5; チェーンステータス = 6; CHAIN_TRANSACTION = 7; CHAIN_GET_TRANSACTIONS = 8; チェーンクエリ = 9; SYNC_GET_BLOCKS = 11; SYNC_BLOCKS = 12; SYNC_BLOCK_ADDED = 13; SYNC_STATE_GET_SNAPSHOT = 14; SYNC_STATE_SNAPSHOT = 15; SYNC_STATE_GET_DELTAS = 16; SYNC_STATE_DELTAS = 17; 応答 = 20; コンセンサス = 21; } タイプ type = 1; バイトペイロード = 2; google.protobuf.Timestamp タイムスタンプ = 3; } 4.1.1 検出メッセージ新しく起動されたノードでは、CORE_PEER_DISCOVERY_ROOTNODE (ROOTNODE はネットワーク内の他のノードの IP を参照します) が指定されている場合、検出プロトコルの実行を開始します。 ROOTNODE は最初の検出ノードであり、その後、ネットワーク全体のすべてのノードが ROOTNODE ノードを通じて検出されます。検出プロトコル メッセージは DISC_HELLO であり、そのペイロードは HelloMessage オブジェクトです。これには、メッセージを送信するノードの情報も含まれます。 メッセージ HelloMessage { ピアエンドポイント peerEndpoint = 1; uint64 ブロック番号 = 2; } メッセージ PeerEndpoint { ピアID ID = 1; 文字列アドレス = 2; 列挙型 { 未定義 = 0; バリデーター = 1; 非バリデータ = 2; } タイプ type = 3; バイト pkiID = 4; } メッセージピアID { 文字列名 = 1; } ノードが DISC_HELLO メッセージを受信し、そのブロックの高さが現在のブロックの高さよりも高いことがわかった場合、ノードはすぐに同期プロトコルを送信して、そのステータスをネットワーク全体と同期します (マーク: ただし、この同期ロジックはソース コード レベルでは実装されていないようです)。 新しく参加したノードは、DISC_HELLO メッセージの送信を完了すると、ネットワークに参加している他のノードを検出するために、定期的に DISC_GET_PEERS を送信します。 DISC_GET_PEERS に応答して、ノードは DISC_PEERS を送信します。 4.1.2 同期メッセージ同期プロトコルは、上記の検出プロトコルから始まります。ノードが自分のブロックのステータスが他のノードのステータスと一致しないことを検出すると、同期がトリガーされます。ノードは3種類の情報をブロードキャストします: SYNC_GET_BLOCKS、SYNC_STATE_GET_SNAPSHOT、または 現在ファブリックに組み込まれているコンセンサス アルゴリズムは pbft です。 SYNC_GET_BLOCKS は一連の連続ブロックを要求し、送信されるデータ構造内のペイロードは SyncBlockRange オブジェクトになります。 メッセージ SyncBlockRange { uint64 相関ID = 1; uint64 開始 = 2; uint64 終了 = 3; } 受信ノードは SYNC_BLOCKS で応答します。そのペイロードは SyncBlocks オブジェクトです。 メッセージ SyncBlocks { SyncBlockRange 範囲 = 1; 繰り返されるブロックブロック = 2; } start と end は開始ブロックと終了ブロックを示します。たとえば、start=3、end=5 はブロック 3、4、5 を表します。 start=5、end=3 はブロック 5、4、3 を表します。 SYNC_STATE_GET_SNAPSHOT は、現在のワールド状態のスナップショットを要求します。この情報のペイロードは SyncStateSnapshotRequest オブジェクトです。 メッセージ SyncStateSnapshotRequest { uint64 相関ID = 1; } correlationId は、要求ピアがメッセージに対する対応する応答を追跡するために使用されます。このメッセージを受信したピアは、ペイロードが SyncStateSnapshot オブジェクトである SYNC_STATE_SNAPSHOT で応答します。 メッセージ SyncStateSnapshot { バイトデルタ = 1; uint64 シーケンス = 2; uint64 ブロック番号 = 3; SyncStateSnapshotRequest リクエスト = 4; }SYNC_STATE_GET_DELTAS デフォルトでは、元帳には 500 個の遷移デルタが含まれます。 delta(j)はblock(i)とblock(j)間の状態遷移を表します(i = j -1)。
4.1.3 コンセンサスメッセージコンセンサス フレームワークは、受信した CHAIN_TRANSACTION を CONSENSUS に変換し、それをすべての VP ノードにブロードキャストします。 4.1.4 トランザクションメッセージファブリックには、デプロイ、呼び出し、クエリの 3 種類のトランザクションがあります。 Deploy は指定されたチェーンコードをチェーンにインストールし、Invoke と Query はデプロイされたチェーンコードの関数を呼び出します。 4.2 元帳元帳は主にブロックチェーンとワールドステートの 2 つの部分で構成されます。ブロックチェーンは、過去の取引を記録する一連の接続されたブロックです。ワールドステートはキー値データベースです。トランザクションが実行されると、チェーンコードに状態が保存されます。 4.2.1 ブロックチェーンブロックチェーンとは、各ブロックに前のブロックのハッシュが含まれるブロックのリストを指します。ブロックには、トランザクションのリストと、これらすべてのトランザクションを実行した後の世界の状態のハッシュも含まれます。 メッセージブロック{ バージョン = 1; google.protobuf.Timestamp タイムスタンプ = 2; バイトトランザクションハッシュ = 3; バイトstateHash = 4; バイト previousBlockHash = 5; バイトconsensusMetadata = 6; 非ハッシュデータ 非ハッシュデータ = 7; } メッセージブロックトランザクション { 繰り返しトランザクション トランザクション = 1; } 前のブロックのハッシュはどのように計算されますか?
上記のデータ構造には、トランザクション Merkle ツリー (これらのトランザクションを記述するために Merkle ツリーを使用) のルート ノードである transactionHash があります。 4.2.2 世界の状態ピアのワールド ステートは、デプロイされたすべてのチェーンコードの状態の集合です。チェーンコードの状態は、キーと値のペアのセットによって記述されます。ネットワーク内のノードは一貫したワールド ステートを持つと予想されるため、ワールド ステートの暗号ハッシュを計算して比較しますが、これには高価な計算能力が消費されるため、効率的な計算方法を設計する必要があります。たとえば、世界状態の編成を実装するためにバケットツリーが導入されています。 ワールドステートのキーは {chaincodeID, ckey} として表されます。キーは次のように記述できます: key = chaincodeID+nil+cKey。 ワールド ステートのキーと値のペアは、事前定義された数 (numBuckets) のバケットで構成されるハッシュ テーブルに格納されます。ハッシュ関数は、どのバケットにどのキーが含まれるかを定義します。これらのバケットはマークルツリーのリーフノードとして機能し、最小の番号のバケットはマークルツリーの左端のリーフノードとして機能します。最後から 2 番目のレイヤーは、左から maxGroupingAtEachLevel (定義済みの数値) のリーフ ノードをグループ化して N 個のグループを形成することによって構築されます。各グループでは、そのグループに含まれるリーフ ノードの親ノードとしてノードが挿入され、最後から 2 番目のレイヤーが形成されます。最後のレベルの親ノード (先ほど説明した挿入ノード) には、maxGroupingAtEachLevel より少ない子ノードが存在する可能性があることに注意してください。ルート ノードが構築されるまで、この方法で上位レイヤーの構築を続けます。 たとえば、{numBuckets=10009 かつ maxGroupingAtEachLevel=10} の場合、毎回形成されるツリー内のノードの数は次のようになります。
4.3 コンセンサスフレームワークコンセンサス フレームワークは、コンセンサス、コントローラー、ヘルパーの 3 つのパッケージで構成されています。
現在、pbft と noops の 2 つのコンセンサス プラグインがあります。 5. 実施と貢献SYNC_BLOCK_ADDED ハンドラを実装する 私の同僚の 1 人が SYNC_BLOCK_ADDED メッセージのハンドラーを実装したので、noops コンセンサス モードでブロックが (マイニング/追加された) 元帳に追加されると、NVP ノードがメッセージを処理し、新しく追加されたブロックを独自の元帳に保存できます。 SYNC_BLOCK_ADDED メッセージに対応するコールバックは beforeBlockAdded (core/peer/handler.go) です。公式コードは次のとおりです。 func (d *Handler) beforeBlockAdded(e *fsm.Event) { peerLogger.Debugf("受信メッセージ: %s", e.Event) メッセージ、OK := e.Args[0].(*pb.Message) !okの場合{ e.Cancel(fmt.Errorf("予期しないメッセージ タイプを受信しました")) 戻る } // ブロックとデルタ状態を元帳に追加します _ = メッセージ }ここではブロック情報を取得して処理する方法がないので、以下を追加する必要があります。 + バリデータが有効の場合() { + e.Cancel(fmt.Errorf("VP は SYNC_BLOCK_ADDED を受信すべきではありません")) + 戻る + } // ブロックとデルタ状態を元帳に追加します - _ = メッセージ + ブロック状態 := &pb.BlockState{} + エラー:= proto.Unmarshal(msg.Payload, blockState) + エラー!= nilの場合{ + e.Cancel(fmt.Errorf("BlockState のアンマーシャリング エラー: %s", err)) + 戻る + } + 座標 := d.コーディネータ + ブロックの高さ:= coord.GetBlockchainSize() + ブロック高さ <= 0 の場合 { + e.Cancel(fmt.Errorf("ジェネシスブロックは作成されません")) + 戻る + } + curBlock、エラー:= coord.GetBlockByNumber(blockHeight -1) + エラー!= nilの場合{ + e.Cancel(fmt.Errorf("ブロック #%d、%s の取得エラー", blockHeight -1, err)) + 戻る + } + ハッシュ、エラー:= curBlock.GetHash() + エラー!= nilの場合{ + e.Cancel(fmt.Errorf("最新ブロックのハッシュエラー")) + 戻る + } + バイトの比較(ハッシュ、ブロックステートブロックの前のブロックハッシュ) != 0 の場合 { + e.Cancel(fmt.Errorf("受信したブロックのPreviousBlockHashが現在のブロックのハッシュと一致しません")) + 戻る + } + 座標.PutBlock(ブロックの高さ、ブロックの状態.ブロック) + デルタ := &statemgmt.StateDelta{} + err := delta.Unmarshal(blockState.StateDelta);ゼロ != エラー { + e.Cancel(fmt.Errorf("破損した状態デルタを受信しました")) + 戻る + } + 座標.ApplyStateDelta(メッセージ、デルタ) + coord.CommitStateDelta(msg) != nil の場合 { + e.Cancel(fmt.Errorf("状態を前方に再生し、ハッシュは一致しましたが、コミットに失敗しました。状態は無効になりました")) + 戻る + } + peerLogger.Infof("ブロックチェーンの高さが %d に増加しました", coord.GetBlockchainSize()) HELLOメッセージの状態転送を有効にする また、NVP ノードが最初にネットワークに参加すると、DISC_HELLO メッセージを送信し、その後、他のノードからそのノードのブロックチェーン情報を含む DISC_HELLO メッセージを受信することもわかりました。ただし、公式コードでは、NVP がこれらの戻りメッセージに基づいて自身のステータスを同期するための実装は提供されていません。 NVP がネットワーク内で独自の状態同期を実装している場合、新しいブロックがマイニングされますが、NVP はこの新しいブロックを独自のチェーンに追加することはできません。そのため、ここで厄介な状況が発生します。新しい NVP ノードがネットワークに参加すると、HELLO メッセージを通じて他のノードのブロックチェーン情報を取得し、自身のステータスの同期を開始します。完了するまでには確かに時間がかかりますが、同時に、ネットワーク内のトランザクションは継続され、新しいブロックが継続的にマイニングされます。 NVP は SYNC_BLOCK_ADDED を受信し、それを処理するハンドラーを持っていますが、ハッシュが一致しないため、この時点では新しいブロック情報を自身のチェーンに追加することはできません。結局、NVP ノードは初期同期を完了していません。 |
<<: ブロックチェーンクレジット: トランザクションの熱力学の第二法則
>>: フィンテックスタートアップのRevolutが海外取引手数料ゼロを実現するために775万ユーロを調達
通貨価格の変動は徐々に減少しており、市場は慎重に前進している1. 市場動向<br/>今日...
ここ数日、奇妙なことが起こりました。 日曜日、トランプ大統領は、アメリカ合衆国がビットコイン、イーサ...
最近、一部のメディア、ソーシャル プラットフォーム、研究グループは、「金融イノベーション」を仕掛けと...
シカゴ・マーカンタイル取引所(CME)が12月10日にビットコイン先物を正式に開始する予定であるとい...
Business Insiderは、英国のHSBC銀行が、取引の透明性の高さを生かし、透明性の高い国...
10月17日のマイニングウェブサイトによると、昨日、ビットコインチャイナは、引き出しを迅速化するた...
テンセントテクノロジー(深セン)有限公司と深センテンセントコンピュータシステム有限公司は、inCha...
もうすぐ年末ですね。家族から結婚を強制されていますか?アント・ファイナンシャルの若手エンジニアである...
出典:ウォールストリートジャーナル欧州委員会は現地時間7月20日、欧州連合(EU)全域でのマネーロン...
存在証明 (PoE) は、ビットコイン ブロックチェーンに組み込まれた機能で、誰でも変更不可能な方法...
クレイジーな解説:オーストラリアの政治情勢は混沌としており、選挙結果は衝撃的です。 2014年にはオ...
編集者注: この記事の著者であるブライアン・アームストロングは、Coinbase の共同創設者兼 C...
8月18日、テスラ(TSLA.O)のCEOマスク氏のファミリーオフィス責任者であるバーチャル氏が、ド...
著者 |ハシピ分析チーム...
クレイジーレビュー:日本のビットコイン取引所2社が、取引失敗による損失を防ぐための損害保険商品を立ち...