今日のブロックチェーンについては、怠け者だけで書かれているわけではありません。 さまざまな程度の明快さと有用性を持つ膨大な数の記事があります。 これはもう1つです。 最もシンプルでありながら機能するブロックチェーンを作成し、簡単に、しかし専門家でない人には理解できるように、 この犬 このブロックチェーンは機能します。 そのため、BaumankaCoinプロジェクトが誕生しました。そのソースコードはGitHubからダウンロードできます 。
多くの人は、ブロックチェーンと暗号通貨技術を一種の巨大ロケット科学と考えています。 もちろん、すべての微妙さとニュアンスを理解するには、多くの時間がかかります。 しかし実際には、このテクノロジーを見ると、一般に信じられているよりもはるかに理解しやすいことがわかります。 私たちのコインを実現したので、私たちは人々がこれらの技術のデバイスを「指で」理解するのを助けるつもりでした。
BaumankaCoinは、 PavelMSTUの指導の下で、 almikuとskalniyの 2人の学生によって開発されました 。
基本
取引
最初に扱うセマンティック単位はトランザクションです。つまり、ある口座から別の口座にお金を転送します。 銀行システムの現代の世界では、名前の反対側の金額を減らし、反対側の反対側の金額を増やすことで振替が行われます。 ブロックチェーンでは、トランザクションの配置が異なります。
今のところ、についての質問を残しましょう 神秘的で恐ろしい マイニング、そしてブロックチェーン内のトランザクションについてのみ話しましょう。
まず、トランザクションが次のように見えると仮定します。
- トランザクション1「Vasyaは50個のコインをアーニャに送信しました」
- トランザクション2「グリシャは30枚のコインをアネに送った」
- ...
完了したすべてのトランザクションに関する情報があれば、Ani、Vasya、Grishaの口座の金額を確認できます。
全体的な構造はもう少し複雑です。 各トランザクションにはフィールドがあります:
- 入力 -このトランザクションによって参照されるトランザクション。
- tails- {receiver、sum}の形式の構造のリスト。
この場合、VasyaとGrishaのトランザクションの構成は次のようになります。
ここで、アーニャが70個のバウマンコインをオリヤに移すと仮定します。 上で書かれたように、このために、アーニャはヴァシャとグリシャからの取引を参照する必要があります。 翻訳構造は次のようになります。
個人を転送する場合、以前のトランザクションを参照する必要がありますが、特定のトランザクションを参照できるのは1回だけであることを覚えています。 つまり、残りの10枚のコインを使うために、アーニャはVasyaとGrishaからの送金に言及することはできません。 どうする
この状況から抜け出すには、非常にエレガントな方法があります。アンナは残りの金額を自分自身に振り替えなければなりません。
将来、アーニャは自分で行った送金を参照できるようになります。これにより、彼女は最後の10枚のコインを使うことができます。
その結果、上記のすべての操作は次のように表すことができます。
ユーザー識別
人が自分の電子財布の住所をどのように受け取り、そこにお金が送られるかについて話しましょう。 この手順は、秘密鍵と公開鍵の生成、アドレスの受信の3つの段階で構成されています。
各個人を定義する主なツールは秘密鍵です。 したがって、新しいアカウントを作成するには、特定の範囲から乱数を取得するだけです。 番号が偶然に選択された場合-他の誰かが同じ番号を選択したという事実と一致する確率は非常に小さいです。
次に、 公開 鍵は秘密鍵に基づいて構築されます 。 その後、公開キーが引数としてハッシュ関数に渡されます 。
暗号化ハッシュ関数は、コインの問題およびメッセージ認証プロトコルで使用されます。 この特定のケースでは、ハッシュ関数を使用して擬似乱数を生成します。 ハッシュにはさまざまな関数がありますが、 SHA-256を検討します。 その特徴は、あらゆる量の着信データを256ビットのハッシュに変換することです。 関数の結果、それはハッシュであり、実際、ウォレットのアドレスです。
公開鍵の値を知っているため、どの秘密鍵が構築されたかを計算することは困難であると言わなければなりません。 また、関数の可能な結果の数は2 256です。
検証
次に、振替を行う際に、私たちが実際にウォレットの所有者であることを確認する必要があります。 これを行うには、トランザクション構造にさらに2つのフィールドが表示されます。
- 署名
- 公開鍵。
ステップA:鍵は公開鍵フィールドに記録されます。
ステップB:トランザクションに署名し、署名を適切なフィールドに記録します。
署名とは何ですか? 署名作成スキームは次のとおりです。
すべてのトランザクション情報、 つまり入力 、 テール、および公開キーが収集され ます 。 この情報はハッシュ関数に渡され、ハッシュと秘密鍵は署名アルゴリズムに渡されます。 このアルゴリズムは、公開鍵の助けを借りて、正しい秘密鍵が実際に使用されたかどうかを調べることができますが、秘密鍵自体を見つけることは不可能です。 出力は、512ビットのストリングです。
トランザクションの一般的な構造は次のとおりです。
class Transaction { . . . protected: std::vector<Input> inputs; std::vector<Tail> tails; std::vector<uint8_t> pubKey = std::vector<uint8_t>(279, 0); std::vector<uint8_t> signature = std::vector<uint8_t>(64, 0); . . . };
ブロックする
それではブロックに移りましょう。
ブロックは、複数のトランザクションと前のブロックへのリンクを格納するオブジェクトです。
このブロックは、いわゆる鉱夫によって作成されます(以下について)。 新しいブロックを作成するには、すべてのフィールドに入力し、特定の条件を満たす必要があります。 ブロック作成スキームは次のとおりです。
この図は、最初のブロックが表示されるプロセスを示しています。 もっと詳しく見てみましょう。
- 鉱夫が最初に直面することは、ネットワーク参加者が実行したいトランザクションの正確性をチェックすることです。 署名を検証し、トランザクションが既に使用されているテールを参照していないことを確認する必要があります。 また、1つのブロックが限られた量の情報に対応できるため、ブロックのトランザクション数が制限されることに注意してください。
- その後、検証されたすべてのトランザクションは引数をハッシュ関数に渡します。 出力では、最初のブロックの要素の1つであるMerkle Rootを取得します。
- 2番目のハッシュ関数に提供されるデータ(図を参照):前のブロックのヘッダーのハッシュ。 マークル根; 取引 ノンス (以下のこのフィールドについて)。
- すべてがハッシュされ、「特定のビュー」のハッシュがチェックされます。 たとえば、ハッシュの最後の4バイトがゼロであることを確認します。 そうでない場合は、 ノンスフィールドが変更され、マイナーは再びブロックを取得しようとします。 ハッシュ関数の結果を予測することは不可能です。つまり、マイナーが結果が目的の形式になるまで、 nonce引数を変更するだけで済みます。
したがって、有効なブロックは、前のブロックのハッシュ、ブロック内のすべてのトランザクションのハッシュ、トランザクション自体のリスト、およびナンスフィールドを含むブロックと見なすことができます。このブロックのハッシュは、 ナンスフィールドに変更を加えることで実現されます。
マイナーが目的のナンス値を選択したら、このブロックをすべてのネットワーク参加者に送信し、次の参加者をマイニングできます。 誰かが彼の前にこのブロックを作成した場合、彼は新しいブロックで作業を開始する必要があります。
たとえば、一連の3つのブロックは次のようになります。
データの永続性
情報はネットワークを介して送信されるため、誰でも情報を変更して、偽バージョンをさらに送信できます。
ブロックチェーンデバイスはそのような試みを排除します。 署名が無効になるため、トランザクション内の情報は変更できません。 ブロック自体の情報も変更できません。これは、マークルルートハッシュが現実に対応しないため、および/またはブロック自体のハッシュが条件を満たさないためです。 したがって、情報の不変性が達成されます。
非常に最初のトランザクション
気配りのある読者は、最初のブロックが何を指しているのかと尋ねるかもしれません。 特にこの場合、既知のフィールドと生成アルゴリズムを備えた「ジェネシスブロック」があります。 チェーンは、ジェネシスブロックで始まり、チェーンに含まれるすべてのトランザクションとブロックも正当である場合にのみ、正当と見なされます。
BaumankaCoinには、実装を簡単にするためのジェネシスブロックがありません。 代わりに、最初のブロックのハッシュには0に等しい前のブロックのハッシュがあります。
分岐
すべてのマイナーは、ブロックチェーンにブロックを追加できます(すべてのチェックに合格した場合)。 また、ブロックチェーンはシーケンスであるため、ブロックにはいわゆる「高さ」で番号を付けることができます-ジェネシスブロックのシリアル番号は0ですが、この高さはブロックの一意の識別子ではありません
各ブロックは前のブロックのみを参照できますが、同じブロックを参照する複数のブロックが表示されるとどうなりますか? それらは同じ高さになり(これが高さが識別子として使用されない理由です)、チェーンはより木のようになります。 これは、マイナーがわずか数秒の差でブロックを作成する場合(または、処理能力の高い攻撃者がトランザクションをロールバックしようとした場合)に実際に発生します。 これはチェーンフォークと呼ばれます。
各ノードは、これらのブロックのどれを受け入れるかを個別に選択します。 最初に受け取ったときに選択を停止することに同意しました。 遅かれ早かれ、より高いブロックが現れ、長いチェーンが「メイン」チェーンになり、フォークは徐々に忘れられます(原則として、フォークは1ブロックを超えて成長しません)。
一部のソースのフォークブロックは、他の古いものでは孤児と呼ばれます。 たとえば、 bitcoin.itでは、さまざまな記事で用語が変更されます( 1、2 )。 「古い」という名前に固執するのは、 語源的に近いです。 しかし、孤立ブロックについては言及する価値があります。 これらはそのようなブロックであり、ノードがまだ所有していない(つまり、真正性を検証できない)先行ノードに関する情報です。 最近、孤立ブロックの処理をサポートするクライアントアプリケーションはほとんどありません。通常は拒否されます。
ネットワーク
ブロックチェーンは、各ノードがチェーン全体の完全なコピーを保存するピアツーピアブロードキャストネットワーク上に構築されます。 これは、基本的な機能(ブロックとトランザクションの交換)を維持するのに十分です。 たとえば、ビットコインでは、執筆時点で約130GBです( 現在のサイズはこちらです )。
新しいノードをネットワークに接続するために対処しなければならない主な問題の1つは、他のネットワーク参加者の検索です。 現在、完全に分散化されたソリューションは存在しません。 Bitcoinは、 DNS Seedと呼ばれるBitTorrentトラッカーの類似性を使用します。DNSSeedは、他のピアを見つけるのに役立つサーバーです。 これらのサーバーに関する情報はハードコーディングされています。
BaumankaCoinは、簡単にするために、既知のピアに関する情報をINFOファイルに保存します
すべての既知のピアへのさらなる接続は同じであり、完全に分散されています。 このプロセスをさらに詳しく見てみましょう。明確にするために、新しいノードにA 、そして既知のごちそうBに名前を付けます。 接続されると、 Aは次の内容のB バージョンメッセージを送信します。
バウマンカで
class version { public: . . . net_addr addr_recv; net_addr addr_from; uint32_t nonce; };
Bは空のverackメッセージで応答し、プロトコルバージョンをそれ自体の最小値に設定し、 Aから受信し、その部分のバージョンを送信する必要があります。 同様のアクションがAによって行われます。 このプロセスは「バージョンハンドシェイク」と呼ばれ、完了すると、ノードは両方でサポートされるプロトコルバージョンを使用して通信します。
次に、既知のピアに関する情報の交換があります。 Aは、 Bに、何も含まれていないgetaddr要求を使用して、既知のアクティブなピアのリストを要求します。 ごちそうは、 Bが最近(Bitcoinで-過去3時間)メッセージを受信した場合にアクティブと見なされます。 Bはaddrノード情報メッセージで応答します。
インベントリメッセージ
誰かがトランザクションまたはブロックを作成または受信すると、{オブジェクトタイプ(ブロック/トランザクション)、ハッシュ}という形式のいくつかの構造を含むinvメッセージを、これらのオブジェクトに関する情報とともに送信します。 受信者はinvと同じ構造のgetdataメッセージで応答しますが、それ自体に新しいオブジェクトのみをリストします。 そして、これがブロック( block )とトランザクション( tx )に関する完全な情報を含むメッセージの送信後にのみです。
BaumankaCoinのクエリには、簡単にするために、前述の最後のブロックのハッシュのみが含まれています。 「非教育」暗号通貨では、すべてが少し複雑です。
ハンドシェイク後、 Aは彼のブロックチェーンの関連性についてまだ知られていない。 したがって、この情報を更新する必要があります。 これを行うために、 Aは、知っている最後のブロックのハッシュを含むgetblocksリクエストを送信します。
Bに新しいブロックがある場合、 Bに事前送信invメッセージを送信します。 説明されているプロセス全体は、おおよそ次のとおりです。
おわりに
複雑なプロセスのこれらの簡単な説明が、読者のブロックチェーン技術の理解を形成するのに役立つことを願っています。 私たちの仕事を通して私たちを助けてくれた最も有用な記事の1つは、 Bitcoin in a Nutshellです。 また、bitcoin.orgおよびbitcoin.itを使用したプロトコル。 ソースはここからダウンロードできます 。