ビットコイン・インスティテュート

民主主義のためのハッシュ/秒スロットリング

InterArmaEnimSil 2010年7月13日18:23 UTC

古いマシンではコイン生成が実用的ではないと不満を述べる投稿を多く見てきた(正確には不可能だと書いているが、それは正しくない)。他にも、FLOPS×運=コインという考えを支持する投稿がいくつかあり、それはおおむね正しいと思う。さらにOpenCL/CUDAのサポートを提唱する投稿もあったが、それはOpenCL対応カードを持つ人にFLOPSの面で信じられないほどの優位性を与えるように思える。

「運がなければコインは得られない……」という人もいるが、ちょっと待ってほしい……コンピューターを扱っているのだ。乱数生成器は運とは無関係だ。統計的平均に基づいて動作する。(もしBTCがマシンの大気ノイズに基づく真の乱数生成器を使っているなら間違っているかもしれないが、そのような生成器は遅すぎて実用的ではないと思う。)

では、毎秒のハッシュ数に上限を設けたらどうだろうか? 例えば250khash/秒でシステムクロックに基づいて(利用可能なサイクル数ではなく)上限を設ければ、「最低要件」を満たす誰もが、CUDAを実行するTESLAクラスターを持つ人に対して不利にならずに生成に参加できる(いや……人々がTESLAクラスターをこれに使うわけはないが……言いたいことは分かるだろう)。もちろん、ブロック生成のペースを維持するために難易度を調整する必要があり、上限に違反しているクライアントが生成したブロック(つまり不正行為で他のクライアントを上回っている)のチェックも必要だが、これらはコードで比較的容易に解決できる問題だ。

InterArmaEnimSil 2010年7月14日19:07 UTC

なるほど、全員のマシンがそれぞれ異なる問題のハッシュに取り組んでいるなら、運が要素になるのは理解できる。しかし、自分のマシンが取り組んでいる問題と他の人の問題との間の変動の源は何なのだろう? 先の返信の一つでは、そのユーザーが最近参加したトランザクションに関係しているようだったが…最近のトランザクションに参加していない私たちはどうなるのだろう? (最後のトランザクションは少なくとも2日前だ)

knightmb 2010年7月14日19:17 UTC
InterArmaEnimSilの投稿(2010年7月14日19:07 UTC)

なるほど、全員のマシンがそれぞれ異なる問題のハッシュに取り組んでいるなら、運が要素になるのは理解できる。しかし、自分のマシンが取り組んでいる問題と他の人の問題との間の変動の源は何なのだろう? 先の返信の一つでは、そのユーザーが最近参加したトランザクションに関係しているようだったが…最近のトランザクションに参加していない私たちはどうなるのだろう? (最後のトランザクションは少なくとも2日前だ)

コイン生成に関しては、ネットワークに接続さえしていればいい。それだけで、あなたのコンピューターが「見つけた!」というメッセージをブロードキャストし、他のコンピューターがそれが有効かどうかチェックできる。ブロックは常に生成されているので、オフラインでのコイン生成は現実的ではない。なぜなら、2日前にあなたのコンピューターがブロックを見つけたが、私のPCもそうで、私のPCはずっとオンラインだった場合、ネットワーク全体が私のPCを勝者/所有者と認定するからだ。あなたのPCが2日後にやってきて同じ解を見つけたとブロードキャストしても、他のコンピューターは「遅すぎる、XYZがすでに解いた、次は頑張れ」と返すだけだ。

問題のバリエーションに関して言えば、ブロックが見つかると、全員が次のブロックに取りかかる。だから、あなたのコンピューターがブロック68000の解決に向けて1%しか進んでいない時に「XYZが数分前にブロック68000を解いた」というメッセージを受け取ると、あなたのPCは「じゃあ次に行こう」と思う。すでに誰かが解いたブロックにCPUを浪費しない。そこが検証の部分だ。そうでなければ、誰かがクライアントを改ざんして「ブロック68000、68001、68002などを解いた」とブロードキャストして全範囲の所有権を主張することになる。クライアントがブロックを解いたと言うと、他のすべてのコンピューターが「わかった、じゃあ証明しろ、結果を送れ」と言う。十分な数が互いにそれについて話し合うと、「はい、あなたのPCがブロック68000を解いた、新しい所有者だ、おめでとう」と合意する。

重要なポイントは、我々のPCがブロックを解くのに数時間/数日かかるが、他の全員がそれが本当かどうかチェックするのはミリ秒しかかからないということだ。これにより、ネットワーク上での「偽ブロック発見」攻撃が防止される。

別の例を挙げよう。何百人もいる部屋がある。全員にランダムに混ぜられたルービックキューブが渡される。最初に解いた人が50コインもらえる。

誰かが「解いた!」と叫んだら、周りの人が一目見るだけで本当かどうかわかる(全面に単色)。誰かが「解いた!」と叫んでもまだグチャグチャなら、全員その人を無視して続ける。「本当に」解いた最初の人が賞を獲得し、全員が現在のルービックキューブを捨て、天井からさらにランダムに混ぜられたルービックキューブが落ちてきて、プロセスが再開される。

データの意味を理解するためのハウスキーピングフィールドを除けば、ハッシュされるデータの残りはランダムだ。全員のものが異なり、解に近づくことは決してない。調整して再ハッシュするたびに、解を見つける確率は同じだ。これはくじ引きを買うのと同じだ。全員の番号が異なり、すべてが当たりの可能性がある。しかし、より多くのくじ引きを手に入れた人は、このプロセスが繰り返されればより頻繁に当たるかもしれない。より速くハッシュできるコンピューターはより多くのくじ引きを持つが、各ハッシュ計算が当たりである確率は同じだ。

Strofcon 2010年7月14日19:50 UTC

確認が取れるまで軽く受け止めてほしいが、以下が自分の理解だ……

問題自体にバリエーションはない――すべてのノードが同時に同じブロックに取り組むことが意図されている(レイテンシーなどを考慮して)。運の要素は、各ノードが新しいブロックの解決を開始する際に生成するランダムな数値(ナンス)にある。新しいブロックを解く必要がある時、各ノードはランダムな値(ナンス)を生成し、それを使ってブロックをハッシュする。そのハッシュが正しくなければ、ナンスがインクリメントされ、新しいインクリメントされた値でブロックが再ハッシュされる。

例えば自分のボロPCが1,000 khash/s(実際そうだ…… 😞)を出し、あなたが100,000 khash/sのクラスターを持っているとしても、自分のボロPCが非常に少ないハッシュ数でブロックを解く値にランダムに(そして非常に幸運に)たどり着く合理的な可能性がある……例えばわずか10ハッシュでナンスが当たりだとする。1秒あたり1,000,000ハッシュを処理しているので、ブロックを解くのに1/100,000秒しかかからなかった。あなたのクラスターが自分の幸運な推測に勝つには、0.00001秒以内に正しいナンスを生成しなければならない……つまりクラスターは100,000,000 (hash/s) / 100,000 (s) = 1,000ハッシュ以内に正解しなければならない。可能なハッシュの巨大な数を考えると、1,000以内に当たる確率は極めて低い……

確かに、10ハッシュ以内に当たる自分の確率はもっと天文学的に低かったが、言いたいことは伝わったと思う。そう、クラスターは全体として自分のボロPCよりも多くのブロックを解くが、毎回勝つわけではない。

さて、ここまで説明したが……きっと誰かが自分の推論の欠陥を指摘するだろう! 😊 でもそれで構わない。すべてを正しく理解したいんだ!

編集 - ラズロの方がはるかに簡潔に言ったが、同じポイントを言っている……と思う? だといいが!

ランダムなナンスに加えて、各ブロックにはBitCoinアドレス(新規生成され、この目的のみに使用される)も含まれており、ブロックを解いた場合に50 BCの報酬がそのアドレスに記録される。2つのノードが同じランダムなナンスから始めたとしても(可能性は低い)、異なるBitCoinアドレスを持つことはほぼ確実だ。

knightmbの投稿(2010年7月14日19:17 UTC)

もしあなたのコンピューターがブロック68000の解決に向けて1%しか進んでいなかったらこれはよくある混乱のポイントだ。ブロック解決に向けて1%進んでいるというようなことはない。解決に向けて進捗することはないのだ。24時間作業した後でも、解決できる確率は開始時やどの瞬間と同じだ。

37枚のコインを同時に投げて全部表を出そうとするようなものだ。試すたびに、成功する確率は同じだ。

RNGはOpenSSLのセキュアな乱数生成器だ。Windowsではコンピューターが起動してからのすべてのハードウェアパフォーマンスカウンターの完全なセットでシードされ、Linuxではdev/randomだ。

Insti 2010年7月14日20:39 UTC
Strofconの投稿(2010年7月14日19:50 UTC)

確認が取れるまで軽く受け止めてほしいが、以下が自分の理解だ……

問題自体にバリエーションはない――すべてのノードが同時に同じブロックに取り組むことが意図されている(レイテンシーなどを考慮して)。運の要素は、各ノードが新しいブロックの解決を開始する際に生成するランダムな数値(ナンス)にある。新しいブロックを解く必要がある時、各ノードはランダムな値(ナンス)を生成し、それを使ってブロックをハッシュする。そのハッシュが正しくなければ、ナンスがインクリメントされ、新しいインクリメントされた値でブロックが再ハッシュされる。

ナンスとhashについて言っていることは正しい。だが……

みんな別々のブロックに取り組んでいるんだ。

ブロック作成者に50BTCを支払うには、その送り先となるBitcoin Addressを知っている必要がある。 ブロック作成者が自分の作り出した50BTCを使えるようにするには、その50が支払われたbitcoin addressに紐づく秘密鍵を持っている必要がある。

誰もがそれぞれ別の秘密鍵を持っているので(ランダムに生成される)、誰もがそれぞれ別のBitcoin Address(紐づく公開鍵をhashしたもの)を持っている。

ブロックの構成要素のひとつが、その50BTCをブロック作成者のBitcoin Addressに支払うトランザクションのhashだ。

つまり、みんな別々のブロックを持っているということだ。

最初に自分のブロックを解いた者が「勝ち」となり、そのブロックは全員から「次」のブロックとして認められる。

InterArmaEnimSil 2010年7月14日20:45 UTC

ナンス + your_address + ガベージデータ = クライアントごとに変わるランダム性、というわけだ。

了解した。みんなありがとう。システムへの信頼が回復した。

knightmb 2010年7月14日21:10 UTC
Instiの投稿(2010年7月14日20:39 UTC)

ナンスとhashについて言っていることは正しい。だが……

みんな別々のブロックに取り組んでいるんだ。

ブロック作成者に50BTCを支払うには、その送り先となるBitcoin Addressを知っている必要がある。 ブロック作成者が自分の作り出した50BTCを使えるようにするには、その50が支払われたbitcoin addressに紐づく秘密鍵を持っている必要がある。

誰もがそれぞれ別の秘密鍵を持っているので(ランダムに生成される)、誰もがそれぞれ別のBitcoin Address(紐づく公開鍵をhashしたもの)を持っている。

ブロックの構成要素のひとつが、その50BTCをブロック作成者のBitcoin Addressに支払うトランザクションのhashだ。

つまり、みんな別々のブロックを持っているということだ。

最初に自分のブロックを解いた者が「勝ち」となり、そのブロックは全員から「次」のブロックとして認められる。

なるほど、つまりくじ引きの運でもあり、順番でもあるってこと? つまり、私のコンピューターは自分のブロックを解こうとしている。1時間で解けるかもしれないし、100時間かかるかもしれない。解けたら、次の別のランダムなブロックに進むの?

ということは、古いPCがBit Coinネットワークに参加して、4日間ブロックに取り組んで解いて、それからネットワークにブロードキャストして、検証されてからチェーンに追加される、というわけ? ということは、その4日の間、他の誰かが別の場所で同じブロックを解いて所有権を主張する可能性はないってこと?