Alternative chain
代替チェーン (代替チェーンから転送)
ブロック連鎖アルゴリズムを使用して特定のトピックについて分散したコンセンサスを達成するシステムです。 代替チェーンは、Bitcoinなどの親ネットワークとマイナーを共有することができます。 これはマージドマイニングと呼ばれます。 代替チェーンは、DNS、P2P通貨交換、SSL証明機関、タイムスタンプ、ファイル保管および投票システムを実装する方法として提案されています。
目的編集
Bitcoinはブロックチェーンアルゴリズムを使用して、誰がコインを所有しているかについての分散したコンセンサスを達成します。
ブロックチェーンは、Bitcoinプロジェクト専用に開発されました。しかし、悪意のある人や信頼できない人がいる場合には、分散したコンセンサスを確立する必要があるあらゆる場所に適用できます。
Bitcoinブロックチェーンを他の目的で悪用する可能性はありますが、同じマイナーを共有する代替ネットワークとチェーンを設定する方が良い。これを行う理由は、以下の3つあります。
- 一点目は、多くの人が共有する大規模で複雑なデータ構造です。その完全性を検証するには、ECDSAの検証やディスクシークのような多くの遅い(したがって高価な)操作が必要です。今日、Bitcoinに参加するすべての人はノードを実行し、したがってすべてを維持します。将来のエンドユーザはおそらくより効率的だが多少安全性の低いモード(SPV)を使用するだろうが、加盟店やマイナーはおそらくこの共有データ構造の維持のための全コストを支払うことになると考えられる。これらの人々は今日、新しい支払い形態に共通の関心をもって団結している。
Bitcoinチェーンを財務的に維持する理由の1つは、無関係なスキームのコストを支払いにのみ関心を持つ人々(商人である正式な例)に外部化することは不公平だということです。 Bitcoinsを商品やサービスの受け入れに費やすコストを増加させることは、商人の数を減らしたり、コストを増やしたりして、システムを使用するすべての人に害を及ぼす。
- 二点目、すべての可能な分散クォーラムをBitcoinの設計制約に詰め込むのは悪い工学である。 Bitcoinが使用する取引フォーマットは柔軟性がある。しかし、最終的には財務のために設計されています。 「値」フィールドを省略することはできません。特定の用途には意味をなさないが、常にそこにある。金融以外のアプリケーションを金融システムの上に構築すると、わかりにくい奇妙なプロトコルやコードが作成され、保守性の問題が発生する。
- 3点目、中本哲志がBitcoin以外の関連データを主鎖に入れることに反対したことです。システムの作成者として、彼の意見は、それを拡張することについて真剣に誰でも重視する必要がある。
新しいネットワークの設計編集
Nakamotoブロックチェーンを使用する新しいネットワークを作成するには、新しいネットワークの意味を定義することから始める必要があります。 Bitcoinトランザクションはスクリプトを使用して値を分割して結合する。しかし、それを行う必要はない。 Googleプロトコルバッファの構文を使用して記述された単純なDNSスタイルの「トランザクション」の例を次に示します。
message NameTx { required string name = 1; repeated bytes ip_addresses = 2; required bytes pubkey = 3; enum ClaimType { NEW_NAME, TRANSFER } required ClaimType type = 4; // Only used if type == TRANSFER. The new owner of the name and signature proving current ownership. optional bytes dest_pubkey = 5; optional bytes signature = 6; }
これは、Bitcoinスタイルのトランザクションとは非常に異なります。入力、出力、アドレス、値またはスクリプトの概念はありません。非常にシンプルなDNSスタイルのスキーム(濫用のコントロールなどがない)には必要なものがあります。また、「コインベース」取引の概念もありません。
ブロック定義もあなた次第です。それは、Satoshiが選んだのと同じ方法でフォーマットする必要はありませんが、ほとんどの同じ概念的な部分が必要です。 Bitcoinのデータもいくつか保存する必要があります。必要なものの最小限の例は次のとおりです。
message MyBlock { required bytes prev_block_hash = 1; required uint32 difficulty = 2; required uint32 time = 3; repeated MyTx transactions = 4; } message SuperBlock { required MyBlock my_data = 1; required BitcoinData bitcoin_data = 2; }
私たちが何をしているのかだけでなく、何がないのかを観察することが重要です。 Satoshis形式の次のフィールドはありません。
- version:protobufsはバイナリデータフォーマットのバージョン管理を担当しています
- merkle root:必要であれば、Merkleのルートにあなたのトランザクションを並べ替えることを選ぶことができます。それで、Satoshiと同じディスクスペースの再生トリックを使うことができます。しかし、厳密にはオプションです。単純化したい場合、スキップすることもできます。
- ノンス
共有作業編集
bitcoin_dataフィールドは、マイナーと仕事を共有する方法です(ビットコインノードの横にソフトウェアをインストールすることでオプトインすると仮定します)。これは次のように定義されています:
message BitcoinData { // A Bitcoin format block header. Because it's in Satoshis custom format we represent this as a byte array. required bytes header = 1; // The first transaction from the block. required bytes coinbase_tx = 2; // The merkle branch linking the coinbase transaction to the header. required bytes coinbase_merkle_branch = 3; // The coinbase scriptSig contains bits of data in order. Which one is our hash? required int coinbase_tx_index = 4; }
仕事を分かち合うために必要なことは、上記の4つのことだけです。
merkle treeは、ツリー内の各ノードがハッシュであるデータ構造です。葉ノードは、ツリーに含めるもののハッシュです。内部ノードは、子ノードの連結のハッシュです。 MerkleブランチはMerkleツリーの一部です。ツリー内にあるすべてのものを必要とせずに、与えられたものがツリー内にあることを暗号で証明することができます。 BitcoinコードのCBlock :: GetMerkleBranch()関数によって計算されます。
効率のためにMerkleブランチをここに格納します。現在のBitcoinブロックの大きさに関係なく、代替ネットワークでは少量のデータしか処理できません。あなたはBitcoinブロック全体を格納することができます - それは単純ですが非効率です。
Merkleブランチはコインベーストランザクションをブロックヘッダーにリンクするので、ブロック内にあることを証明できます。コインベースTXは、通常のBitcoinコインベース(新しいコインとクレームを作る)ですが、scriptSigの入力には、今日のscriptSigでないエントリが含まれています。その余分なエントリはブロック構造のハッシュです。今日のcoinbase scriptSigは次のように書式設定されています:
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce, int64& nPrevTime) { ..... pblock->vtx[0].vin[0].scriptSig = CScript() << pblock->nBits << CBigNum(nExtraNonce); ..... }
ちょうど難易度のビットと "余分なノンス"。しかし、それはあまりにも大きくない限り、実際に何かを含むことが許されています。
<MyBlock hash> <nBits> <nExtraNonce>
BitcoinにMyBlockハッシュを取得するには、現在実装されていないRPCコマンド "setextrahashes"が必要です。それは、グローバルリストを更新し、IncrementExtraNonce関数は、scriptSigが構築されたときに余分なハッシュを含めるでしょう。これはBitcoinにとって非常に簡単な変更です。
上記のscriptSigでは、coinbase_tx_indexはゼロになります。任意の数の代替チェーンを同時に処理することが可能です:
<MyBlock hash> <SomeOtherChainBlock hash> <nBits> <nExtraNonce>
この場合、SomeOtherChainのBitcoinDataメッセージは0ではなく1になります。
より複雑な変更は、もう1つの新しいRPCです。あなた自身の鎖を持っているので、それは独自の困難があります。ほとんどの場合、Bitcoins自身とは異なるでしょう。だから、Bitcoinに "外に出す必要があるブロックが合った場合知らせてください"と言う方法が必要です。一度に複数の困難を掘り起こすために、ノードは最も簡単な困難に合わせて仕事を(ネットワーク経由で)提供します。マイナーが解決策を発見したことを報告すると、難しいチェーンを確認するのが難しくなります。
重要事項:チェーンには独自の難易度があり、ブロック作成率は採掘の程度に左右されません。
独立したノードソフトウェア編集
新しいネットワークには独自のコードベースがあります。あなたが気に入っているような言語で書かれていて、好きなP2Pプロトコルを使って、好きなようにデータを保存することができます。
ネットワーク上のノードは、新しいトランザクションについて通知するメッセージを受信すると、そのトランザクションがネットワークのルールに従っていることを確認します。シンプルなDNSの例を使用するには、新しい名前を主張している場合、それが既に存在していないことと、署名が正しい名前を転送していることを確認します。
トランザクションが有効な場合は、現在のMyBlockメッセージに追加されます。このメッセージはバイナリにシリアル化され(protobufsがこれを行います)、ハッシュして、あなたのノードは現在の余分なハッシュが何であるかをBitcoinに知らせるRPCを行います。 Bitcoinは、ネットワークに適したBitcoin形式のブロックを見つけたら、ソフトウェアに通知し、ブロックヘッダー、coinbaseトランザクション、およびMerkle分岐を渡します。あなたのノードは、それらをまとめてBitcoinDataメッセージにします。これは、代替チェーンブロックと一緒に接着されます。この「スーパーブロック」は、独立したP2Pネットワーク経由でブロードキャストされます。
新しいネットワーク上のノードがスーパーブロックを受信すると、次のことが行われます。
- MyBlockの内容が正しいこと、つまりトランザクションがルールに従っていることを確認します。
- MyBlockのprevハッシュがチェーンのどこかに適合し、難しかったことを確認します。
- MyBlock構造体をハッシュし、このハッシュがBitcoinDataコインベースscriptSigの正しい場所に表示されることを確認します。
- BitcoinフォーマットブロックのMerkleルートをヘッダーから抽出し、提供されたコインベースtxが実際にそのブロックに存在することを確認します(ブランチ、ルート、tx、およびヘッダーを一緒に使用します)。
- Bitcoin形式のブロックヘッダーのハッシュがMyBlock構造の難易度以下であることを確認します。
あなたは、MyBlock構造の内容に対して十分に堅実な作業が行われたことを確認しました。そのため、あなたのノードは新しく発見されたブロックを中継することができます(または、P2Pネットワークを使用しないと、 )。
一方、BitcoinがBitcoinネットワークとチェーンに適したブロックを見つけたら、それをブロードキャストし、明らかにMyBlockのハッシュが含まれています。幸いにもこれは33バイトのオーバーヘッドに過ぎないため、誰も気にすることはありません - 金融チェーンの公害は簡単で一定です。通常のBitcoinノードはこの余分なハッシュを無視するだけで、何も意味しないことに注意してください。
新しいブロックチェーンの扱い編集
あなたは再組織を扱わなければなりません。これはブロックチェーンアルゴリズムの標準的な部分です。 re-orgが発生すると、あなたの世界の状態がまだ理にかなっているかどうかを確認する必要があります。たとえば、新しいチェーンでは、他の誰かがあなたが所有していると思ったリソースを所有している可能性があります。これらのイベントをユーザーに通知する方法と、ここでアプリケーションの特定のロジックが適切であるかどうかは、ユーザーの責任です。
新しいチェーンに独自のパラメータを選択できます。一例として、Satoshiは、待ち時間と無駄な作業との間のトレードオフとして、10分ごとに1つの新しいブロックを対象とすることを選択しました。ブロックが同時に見つかったために、より多くの分割を許容したい場合は、はるかに大きなもの(時間、日)を選択することもできます。 Bitcoinは、およそ2週間ごとに難易度を再測定します。他の時間を選択することもできます。
Satoshiは、ブロックチェーンを格納するために、Berkeley DBをトランザクションから(それらの中で登場した)ブロックにインデックスを付ける方法として使用することを選択しました。あなたは好きなデータベースを使うことができます。
== Bitcoins ==を使って代替チェーンでリソースを支払う
DNS関連のデータを財務チェーンに入れる理由としてよく言われるのは、Bitcoinsで名前を払うという希望です。独立したチェーンでもこれを行うことができます。ルールを作成し、2つのチェーンを適切にリンクすることができるからです。
まず、支払いの目的と、コインを受け取る人を決定します。 DNSシステムの場合、名前を払う理由は2つあります。
- 辞書攻撃を介して興味深い名前を主張する人々による悪用を防ぐため。
- 人々にあなたのソフトウェアを実行し、あなたの代替チェーンを奨励する。
最初のケースでは本当に誰も支払いを受け取るべきではありません。お金は担保として置かれており、他の用途はありませんので、それが不足していれば十分です。 2番目のケースでは、支払いはDNSチェーンで働くマイナーに行くべきです。
これを実装するために、仮想DNSトランザクションメッセージを次のように拡張します。
message NameTx { required string name = 1; repeated bytes ip_addresses = 2; required bytes pubkey = 3; enum ClaimType { NEW_NAME, TRANSFER } required ClaimType type = 4; // Only used if type == TRANSFER. The new owner of the name and signature proving current ownership. optional bytes dest_pubkey = 5; optional bytes signature = 6; // Only used if type == NEW_NAME. optional bytes collateral_signature = 7; optional string miner_address = 8; optional uint64 miner_fee = 9; }
collateral_signatureフィールドは、いくつかのBitcoinsを保持する公開鍵から生成されたECDSA署名を含む。購入者の名前がトランザクションを作成し、マイナーがそれを受け取った後に記入されたときに、作業を開始する前に、マイナーアドレスは空白になります。
2 BTCのマイナー料金で10のBTCを要する名前を購入するには、ユーザはDNSソフトウェアの「名前を購入」ボタンを押す。 RPC経由でローカルのBitcoinノードと通信し、以下を実行します。
- 新しいBitcoinアドレス(キー)を作成します。
- 10新しいアドレスにBTCを送信します(自己送りトランザクション)。
- Bitcoinからキーを抽出します。これは、あなたのウォレットに費やすことができなくなったことを意味します。
- どこかのローカルDNSデータファイル(「財布」)に鍵を格納します。
- miner_feeフィールドに2 BTCの事前に合意された値を設定します。
- 公開鍵部分をとり、collateral_signature(署名はそれ自身を署名できません)とminer_addressがないNameTxのバージョンに署名するために使用します。
- 署名はcollateral_signatureフィールドに置かれます。
- トランザクションは、2 BTCを請求するマイナーに送られます。
マイナーは取引を受け取ると、10 BTCが使われていないことを確認します。
- ECDSA公開鍵回復アルゴリズムは、collateral_signatureで実行されます。いくつかの可能なキーが得られます。
- 回復された公開鍵は、署名が正しいことを検証するために使用されます。このステップでは、可能なキーのどれが正しいキーであるかもわかります。
- 正しい公開鍵がBitcoinアドレスに変換されます(ハッシュします)
- DNSノードソフトウェアは、Bitcoinに照会して、そのアドレスに10のBTCが関連付けられているかどうか、またはそのアドレスのバランスが低いかどうかを検出します。今日のソフトウェアは、システム内のすべてのアドレスのバランスを索引付けしませんが、追加することができます(ブロックエクスプローラでこれを実行します)。
- アドレスに実際に10個の未使用Bitcoinsがある場合、担保が存在し、その名前を提供することはOKです
次に、Minerは自分自身のために新しいBitcoinアドレスを作成し、miner_addressにそれを含むように設定し、それを現在作業中のブロックに組み込みます。 DNSチェーンの難易度に一致するブロックが見つかった後、ブロードキャストされます。他のノードでは、次の操作を行います。
- 取引ごとに、担保が使用されていないことを確認するために確認手順を繰り返します。
- マイナーの住所の残高を確認します。
- 残高がまだminer_feeに等しくない場合、その名前は所有されているがDNSクエリに応答して提供されていない「保留中」の状態になります。
ユーザーはその放送を観察し、その名前が支払いを保留中であることを確認するので、取引で見つけたアドレスに2 BTCを送信します。ノードが支払いを確認したことをノードが認識すると、その名前のDNSクエリに応答し始めます(つまり、所有プロセスが完了しています)。
ユーザーが名前の所有に疲れたら、担保キーを財布に再インポートしてコインを使います。 DNSネットワークは、コインが費やされたことをすぐに観察し、誰かが購入するために名前を利用できるようにします。
非リソースベースのチェーンをインセンティブにする編集
たとえチェーンに所有権の概念がない場合でも、つまりブロック自体を見つける行為が支払われているものであっても、altチェーン上のマイニングをインセンティブにすることは可能です。これの一例は、ブロック内の存在がユーザを満足させるのに十分であるタイムスタンプ連鎖である。
これを実装するには、通常どおりに新しいチェーンを設定します。この新しいチェーンのブロックは、Bitcoinと同じ方法でトランザクションをMerkleツリーに配置します。ブロックに何かを組み込むことを望むクライアントは、一部のマイナーに直接接続し、取引を提出します。マイナーは通常どおり取引に住所を追加します。あるブロックを見つけたマイナーは、そのブロックをトランザクションが作成された接続クライアントにただちに送信しますが、新しいブロックを他のマイナーにブロードキャストしません。クライアントは、ブロックの埋め込みのために支払う有効なBitcoinトランザクションで応答します。すべてのクライアントが支払いを終えると、トランザクションがブロードキャストされます。
クライアントの接続が切断されたり、十分に早急に支払いが行われなかったりすると、ブロック内のトランザクションをそのハッシュに置き換えることができます。このようにして、ブロックの有効性は保存される。なぜなら、メルクルツリーは依然として有効であるからである。新しく発見されたaltブロックは、延滞していない顧客のトランザクションを除いてブロードキャストされます。クライアントがまだ接続されている限り、見つかったすべてのトランザクションの支払い処理は迅速に完了することができます。支払いを集めてBitcoinネットワーク上でそれらをブロードキャストするだけで、信頼を必要とする競争の可能性を最小限に抑えるのに数秒かかります既に支払い済みであるにもかかわらず、次のブロックで取引を取り戻すことができます。
alt-chainではマイニングするがBitcoinではできない編集
これまでは、すべてのaltチェーンのマイナーがBitcoinで同時に掘り起こす計画を検討しました。 Bitcoinの取引レートに追いつくためのコストが非常に高くなっているため、おそらくBitcoinではなく、あなたのチェーンで掘り下げたい人もいます。
Bitcoinノードが接続されていない状態で掘り起こすには、Bitcoin自身が行うのと同じネットワークプロトコルを実装するだけです。 マイニングツールが作業を要求すると、プログラムは正しくフォーマットされたものの最終的には偽のBitcoinブロックを生成します。 このブロックの内容は、Bitcoinネットワーク上で決してブロードキャストされないため、正確である必要はありません。たとえば、prevBlockHashフィールドはすべて0にすることができます。 純粋に下位互換性のために存在します。 ブロックには有効なMerkleルートとコインベーストランザクションが必要ですが、他のトランザクションは必要ありません。重要なコインベースtxの唯一の部分はハッシュを保持している部分です。
スケールアップ編集
シンプルなスキームでは、作業中の各altチェーンは、Bitcoinコインベーストランザクションで33バイト必要です(長さは1、ハッシュは32)。 2つの独立したaltチェーンで2人の独立したマイナーが働いている場合、hashinがBitcoinネットワーク上の他の誰にとっても意味をなさないので、coinbaseのscriptSigには1つのハッシュしか必要ではないことに注意してください。マイナーがほんの一握りのチェーンで作業したい場合、このオーバヘッドはBitcoinブロック内の残りのデータによって矮小化されます。
しかし、数百、数千、または数百万の代替チェーンで作業したい場合、コインベーススクリプトSigのサイズは大きくなり、実行不能になります。これを解決するために、scriptSigに格納されているハッシュは、別のMerkleツリーのルートになります。今回は、すべてのブロックのハッシュを処理するツリーです。 BitcoinDataメッセージは次のように拡張されます:
message MyBlock { required bytes prev_block_hash = 1; required uint32 difficulty = 2; required uint32 time = 3; repeated MyTx transactions = 4; } message SuperBlock { required MyBlock my_data = 1; required BitcoinData bitcoin_data = 2; } message BitcoinData { // A Bitcoin format block header. Because it's in Satoshis custom format we represent this as a byte array. required bytes header = 1; // The first transaction from the block. required bytes coinbase_tx = 2; // The merkle branch linking the coinbase transaction to the header. required bytes coinbase_merkle_branch = 3; // The merkle branch linking MyBlock to the merkle root in the coinbase_tx. required bytes altblock_merkle_branch = 4; }
検証のステップはもう少し複雑になります。
- ヘッダーがaltチェーンのために十分な難易度であることを確認する
- coinbase_txがそのブロックの一部であることを確認するには、coinbase_merkle_branchがヘッダーのmerkleルートにリンクされていることを確認します。
- coinbase_txから2番目のmerkleツリーのルートを抽出する(2MRと呼ぶ)。
- alt-chainブロック(my_data)をハッシュし、altblock_merkle_branchがmy_dataハッシュを2MRにリンクすることを確認します。
これで、MyBlockインスタンスが処理されていることが証明されました。他にも数千ものチェーンについて知っておく必要はありません。
これは高度な技術であり、追加のスケーラビリティが必要でない限り、おそらく実装する価値はありません。旧式のネットワークに影響を与えることなく、新しいチェーンに対して後方互換性のある方法で導入することができます。
二重証明からの保護編集
Merkle Treeのスケーラビリティへのアプローチには注意が必要です。単なる実装であれば、複数のaltチェーンブロックヘッダを1つのBitcoinブロックに入れることで、作業者のシステムを不正行為させることができます。 alt-chainブロックがすべて同じ前ブロックハッシュを持っていれば、この「不正行為」は問題にはなりません。競合するブロックがネットワークに入ったときに起こるように、競合に勝つでしょう。この問題は、1つのBitcoinブロックの補助的なMerkleツリーにリンクされた一連のaltチェーンブロックがすべて存在する場合に発生します。鉱山労働者は一度にすべての作業を行うことができ、難解なものよりも彼のハッシュから多くを得ることができます。
Namecoinのsolutionは、altチェーンブロックがBitcoinブロックに埋め込まれるパスを制約することです。これは機能しますが、将来、多くの代替チェーンを持つマイナーやチェーンデザイナーのための画像が複雑になります。
新しいチェーンのより良い解決策は、複数のブロックが同じ作業証明書ハッシュを持つのを禁止することです。難易度ターゲットに対して測定されたハッシュは、すべてのブロックにわたって一意である必要があります。つまり、一連のブロックを同じMerkleツリーに埋め込むことはできず、ネットワークが1つのみを受け入れるので、それらを同時にすべて獲得することはできません。 しかし、この「より良い解決法」は、同じ作業証明のために競合する複数のブロックを保護するものではなく、あなたのブロックチェーンを何もない状態の攻撃にさらす可能性があります。 これが不可能であることを最初に確認しない限り、使用しないでください。
一般化証明:編集
トランザクションとヘッダー、merkleブランチ、 noncesに埋め込まれたハッシュはすべて、ブロックヘッダーの作業の証明の目標に貢献します。これらの基本操作のシーケンスとしてすべてを表現することができます。
- 現在のデータにバイト文字列を付加する
- 現在のデータにバイト文字列を追加する
- 現在のデータをハッシュする
柔軟性を最大にするために、ワークシェアリングチェーンのブロック受け入れアルゴリズムは、これらの操作だけを使用してスクリプト形式でプルーフを受け入れることができます。スクリプトは、代わりにチェーンブロックヘッダを入力として受け取り、その出力のハッシュはチェーンの難しさを満たす必要があります。
この設計では、ノンス以外のすべてのBitcoin block header fieldsで構成されているプレーンBitcoinの動作証明をサポートしています。また、作業証明スクリプトはnonceを単に追加します。したがって、作業共有ルールは元のBitcoinルールの拡張として考えることができます。
このアイデアを単純に実装すると、Blockcoinトランザクションにデータを含めることで、ブロックに受け入れられるようにして仕事の証明を作成できるようになることに注意してください。