BitCoinに関する追加の質問

8 件のメッセージ サトシ・ナカモト, マイク・ハーン 2010年12月27日 — 2011年1月10日

Satoshi、メリークリスマス。世界のどこにいるにせよ、お祝いしていると仮定して :-)

私はAndroid携帯で動作するクライアントの構築を視野に入れて、簡易支払い検証のJava実装に取り組んでいる。そのため、ストレージ要件とBitCoinのスケーラビリティについて多く考えてきたが、論文では答えられていないいくつかの疑問が生じた(論文の新版を出してもいいかもしれない。現在では内容の一部が古くなっていると思う)。

具体的には、BitCoinにはさまざまなマジックナンバーがあり、コードにも論文にもその由来が説明されていない。例えば、2100万枚のコインが発行されるとインフレーションが停止するという事実。この数字は何らかの方法で導き出されたはずだが、どのようにして決められたのか分からない。

もう一つは10分間のブロック目標だ。これはトランザクションがネットワーク全体に伝播できるように選ばれたと理解している。しかし、BGPのような既存の大規模P2Pネットワークは、新しいデータを1分未満で世界中に伝播できる。

最後に気になる数字は、ブロックサイズの500kb制限だ。Wikipediaによると、Visaだけで2009年に620億件の取引を処理した。割り算すると平均で毎秒2000トランザクション、ピーク時はおそらくその倍の毎秒4000トランザクションになる。10分間のブロック目標では、ピーク時にブロックは240万トランザクションを含む必要があるが、これは500kbには収まらない。この500kbは公式クライアントから徐々に撤廃される一時的な制限なのか、それともより根本的なものなのか?

私はAndroid携帯で動作するクライアントの構築を視野に入れて、簡易支払い検証のJava実装に取り組んでいます。そのため、ストレージ要件とBitCoinのスケーラビリティについて多く考えてきましたが、論文では答えられていないいくつかの疑問が生じました(論文の新版を出してもいいかもしれません。現在では内容の一部が古くなっていると思います)。

論文における簡易支払い検証は、IPアドレスへの送信のようにトランザクションを直接受信することを想定していたが、誰もそれを使っていない。あるいは、ノードがすべてのトランザクションを公開鍵でインデックス化し、メールサーバーからメールをダウンロードするようにダウンロードできることを想定していた。

代わりに、クライアント専用ノードはフルブロックを受信して、自分のトランザクションをスキャンすべきだと考えている。それらを保存したりインデックス化したりする必要はない。初期ダウンロードでは、プログラムが初めて実行される前には支払いが存在し得ないため、ヘッダーのみをダウンロードすれば十分だ(ヘッダーダウンロードコマンドは0.3.18で追加された)。それ以降は、フルブロックをダウンロードする(ただしヘッダーのみ保存する)。

クライアント専用モードのコードはほぼ実装済みだ。GitHubにフィーチャーブランチがあり、このメッセージにパッチも添付している。

以下に詳細を述べる:

「これまでのクライアントモード実装だ。クライアント専用モードはブロックヘッダーのみを記録し、txインデックスを使用しない。生成はできないが、トランザクションの送受信は可能だ。エンドユーザー向けには完全に仕上がっていないが、fClientが有効でなければ完全に何もしないので問題ない。現時点では、主にクライアント専用の再実装者向けのカットラインを示すドキュメントだ。

fClient=trueでは、ヘッダーのみの初期ダウンロードのみテストした。

少し背景を説明する。CBlockIndexにはブロックヘッダーのすべての情報が含まれているため、ヘッダーのみで動作するには、通常通りCBlockIndex構造を維持するだけだ。フルブロックがディスクに記録されないため、nFile/nBlockPosはnullだ。

途中でblk*.datを削除せずにクライアントモードのオン/オフを切り替えるコードはまだ実装されていない。主に、非クライアントのLoadBlockIndexがブロック位置がnullのブロックインデックスエントリを無視するようにすれば済む。そうすれば、それらをフルブロックとして再ダウンロードする。クライアントモードへの切り替えは問題ない。フルブロックがあっても気にしない。

初期ブロックダウンロードが長くなりすぎる場合、新しいユーザーがすぐに使い始められるように、クライアントモードをオプションとして用意したい。クライアントモードの適切なオフ切り替えにより、後でクライアントモードをオフにして、生成を始めたい場合はフルブロックをダウンロードできる。むしろgetworkマイナーを使ってプールに参加すべきだ。

クライアント専用の再実装はEvalScriptを全く実装する必要がないか、せいぜい標準トランザクションテンプレートで使用される5つのオペコードだけを実装すれば十分だ。」

具体的には、BitCoinにはさまざまなマジックナンバーがあり、コードにも論文にもその由来が説明されていません。例えば、2100万枚のコインが発行されるとインフレーションが停止するという事実。この数字は何らかの方法で導き出されたはずですが、どのようにして決められたのか分かりません。

経験に基づく推測で、計算するときりのいい数字になる。非常に普及した場合に低すぎず、そうでない場合に高すぎないものが欲しかったのだ。

もう一つは10分間のブロック目標です。これはトランザクションがネットワーク全体に伝播できるように選ばれたと理解しています。しかし、BGPのような既存の大規模P2Pネットワークは、新しいデータを1分未満で世界中に伝播できます。

伝播に1分かかるなら、10分は良い推測だった。ノードは作業の10%しか失わない(1分/10分)。レイテンシによって無駄になるCPU時間の割合がもっと大きければ、私が考えていない弱点があるかもしれない。攻撃者は自分のブロックを連鎖させているためレイテンシの影響を受けず、有利になる。レイテンシにより、チェーンは一時的により頻繁にフォークするだろう。

最後に気になる数字は、ブロックサイズの500kb制限です。Wikipediaによると、Visaだけで2009年に620億件の取引を処理しました。割り算すると平均で毎秒2000トランザクション、ピーク時はおそらくその倍の毎秒4000トランザクションになります。10分間のブロック目標では、ピーク時にブロックは240万トランザクションを含む必要がありますが、これは500kbには収まりません。この500kbは公式クライアントから徐々に撤廃される一時的な制限ですか、それともより根本的なものですか?

実際の使用量が制限に近づき、正常に動作していることを確認してから、より高い制限を段階的に導入できる。

最終的にクライアント専用の実装が実現すれば、ブロックチェーンのサイズはあまり問題にならなくなる。それまでは、すべてのユーザーが開始するためにブロックチェーン全体をダウンロードする必要がある間は、合理的なサイズに抑えられるのは良いことだ。

非常に高いトランザクション量では、ネットワークノードは統合され、プールマイニングやGPUファームが増え、ユーザーはクライアント専用で動作するようになる。最適化と並列化の開発作業により、スケールアップを続けることができる。

ソフトウェアの現在の処理能力がどうであれ、ムーアの法則の速度、年間約60%で自動的に成長する。

情報をありがとう。

クライアント専用ノードについて同じ結論に達し、それを実装してきた。もうすぐ完成だ……ブロックチェーンのダウンロード、ブロック/トランザクションの解析と検証が完了し、支払いトランザクションの作成もほぼ完了している。

v1は基本的にあなたの提案通りに行い、ブロックロケーターを構成するために必要なブロックのみを保存するという最適化の可能性がある(指数的な間引きで)。Androidはアプリ専用のローカルストレージを提供しているため、新しいブロックを受け入れるためにブロックチェーン全体を保存する必要はない……常に最長チェーンに追従できるだけの量があれば十分だ。

ところで、あなたのコードは読みやすく、非常に貴重な参考になった。ありがとう。

v2では、安全でロックダウンされたリレーノードを実行して、トランザクションがメモリプールに受け入れられたときに携帯電話にメッセージを送信することで、ブロックチェーンに統合される前のトランザクションを表示することを考えている。Androidはすべての携帯電話に安全で低消費電力のバックチャネルを提供している。デバイスがオフラインの場合、メッセージはサーバー側に保存され、着信メッセージを処理するためにアプリが自動的に起動される。

リレーノードがハッキングされていない限り、このシステムは低額取引をUIで即座に表示するのに十分な信頼性を提供するはずだ。ある程度の中央集権化/単一障害点を導入するが、リレーメカニズムが停止またはハッキングされても、被害は新しいブロックがダウンロードされるまでの10分間だけだ。

クライアント専用の再実装はEvalScriptを全く実装する必要がないか、せいぜい標準トランザクションテンプレートで使用される5つのオペコードだけを実装すれば十分です。」

確かに、クライアント専用の実装がEvalScriptを実装する意味はない。ブロックチェーン全体を保存しインデックス化しなければ、トランザクションが二重支払いされていないことを検証できないからだ。私のコードはスクリプトを解析し、標準的な構造であることに依存しているが、実際には実行しない。

経験に基づく推測で、計算するときりのいい数字になります。非常に普及した場合に低すぎず、そうでない場合に高すぎないものが欲しかったのです。

この計算過程を見てみたいものだ。ある意味、コインの数は任意だ。nanocoinの表現により、発行量は事実上無限と言えるほど膨大だからだ。

実際の使用量が制限に近づき、正常に動作していることを確認してから、より高い制限を段階的に導入できます。

何らかのより堅牢な自動アップデートメカニズム、またはこの段階的導入のスケジュールを実装する価値があるだろう。人々が「BitCoinに自分の時間と労力を費やす価値があるか」を評価する際に、スケールアップの確固たる計画が文書化されていることは良いことだからだ。

ハードウェアの物理的な能力については心配していないが、アプリが再実装され、自動アップデートしないノードの数が増えるにつれてのプロトコルの硬直化が気になる。クライアント専用の再実装はもちろん問題ないが、SMTPのような他のシステムは、拡張メカニズムが組み込まれているにもかかわらず、グローバルなアップグレードが不可能であることが証明されている……実装が多すぎ、インストールが多すぎるのだ。

クライアント専用ノードについて同じ結論に達し、それを実装してきました。もうすぐ完成です……ブロックチェーンのダウンロード、ブロック/トランザクションの解析と検証が完了し、支払いトランザクションの作成もほぼ完了しています。

素晴らしい!初のクライアント専用実装は、本当に次のステップへの前進になるだろう。オープンソースになるのか、それともGoogleの独自技術か?

素晴らしいですね!初のクライアント専用実装は、本当に次のステップへの前進になるでしょう。オープンソースになりますか、それともGoogleの独自技術ですか?

オープンソースだ。そうせざるを得ない——余暇の個人プロジェクトとして開発しており、Googleのポリシーでは成果物をオープンソースにすることが条件だ。でも、いずれにせよそうするつもりだった。

数日前にアプリでtestnet上の初めてのコイン送金に成功した。今週末にもう少し進められることを期待している。順調にいけば、2月頃には公開できるものがあるだろう。

オープンソースです。

完璧だ。あなたのコードが簡素化の方法を示せば、他の開発者もそれに続くだろう。クライアントはフル実装よりもハードルが低い挑戦だ。より多くの開発者の手の届く範囲にあれば、私が思いつかなかったような、より洗練されたUIやその他のものを考え出すだろう。元のソフトウェアはGPUファームやプールサーバーで使われる産業用の古いものになると予想している。

ところで、将来的にクライアント版の良い機能として、秘密鍵を暗号化して保持し、送金のたびにパスワードを入力するようにすることがある。

数日前にアプリでtestnet上の初めてのコイン送金に成功しました。今週末にもう少し進められることを期待しています。順調にいけば、2月頃には公開できるものがあるでしょう。

素晴らしい、進捗を教えてほしい。

非常に普及した場合に低すぎず、そうでない場合に高すぎないものが欲しかったのです。

この計算過程を見てみたいですね。ある意味、コインの数は任意です。nanocoinの表現により、発行量は事実上無限と言えるほど膨大だからです。

計算すると、ちょうど10分ごとに1ブロックになる: 21000000 / (50 BTC * 24時間 * 365日 * 4年 * 2) = 5.99 ブロック/時間

364.58333日/年に調整した。50 BTCから25 BTCへの半減は210000ブロック後、約3.9954年後であり、リターゲティングメカニズムのベストエフォートに基づくおおよその値だ。

100 BTCと4200万枚も考えたが、4200万は多すぎるように思えた。

典型的な金額が馴染みのある範囲になるようにしたかったのだ。100000単位をやり取りしていると、希少に感じない。脳は0.01から1000の範囲の数字をより扱いやすいのだ。

非常に大きくなれば、小数点を2桁移動させて、セントが新しいコインになる。

ああ、なるほど、それは納得がいく。

ところで、もしまだ見ていなければ、フォーラムでsecp256k1のセキュリティに関する議論がある:

http://www.bitcoin.org/smf/index.php?topic=2699.0

Hal(Hal Finneyだと思うが)は、この曲線はランダムな曲線よりも攻撃のリスクが高いと考えているようだ。パフォーマンスの改善のためにsecp256k1を選んだのか?

ところで、もしまだ見ていなければ、フォーラムでsecp256k1のセキュリティに関する議論があります:

http://www.bitcoin.org/smf/index.php?topic=2699.0

Hal(Hal Finneyだと思いますが)

はい、彼だ。Cryptographyメーリングリストで支持的で、最初のノードの一つを運用していた。

この曲線はランダムな曲線よりも攻撃のリスクが高いと考えているようです。パフォーマンスの改善のためにsecp256k1を選んだのですか?

正直に言うと、このプロジェクトはリリース前に2年間の開発を要し、多くの課題のそれぞれにかけられる時間は限られていた。SHAとRSAの推奨サイズに関するガイダンスは見つかったが、比較的新しかったECDSAについては何も見つからなかった。RSAの推奨鍵サイズを取り、ECDSAの同等の鍵サイズに変換したが、アプリ全体が256ビットセキュリティと言えるように増やした。曲線の種類を推奨するものは見つからなかったので、ただ……一つ選んだ。鍵サイズが十分に大きければ、欠点を補えることを願っている。

当時は、ECDSAを使っても帯域幅とストレージのサイズが実用的かどうか懸念していた。RSAの巨大な鍵は論外だった。当時はストレージと帯域幅がより厳しかったように感じた。サイズがようやく実用的になりつつあるか、もうすぐそうなるだろうと感じていた。発表したとき、サイズについて他の誰も懸念しなかったことに驚いたが、彼らがいかに多くの問題を議論したかにも驚き、さらにそのすべてが私がすでに考えて解決していたことだったのにも驚いた。

結果的に、ECDSAの検証時間がより大きなボトルネックかもしれない。(私のテストでは、OpenSSLはECDSA検証に3.5msかかり、毎秒約285回の検証が可能だった)クライアント版はこの問題を回避する。

状況が進化するにつれて、フルノードを実行する必要がある人の数は、当初想像していたよりも少なくなった。処理負荷が重くなっても、少数のノードでネットワークは問題なく機能するだろう。