サトシ ↔ マイク・ハーン — さらなる質問

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

メリークリスマス、サトシ。君が世界のどこにいるのかも、祝う習慣があるのかも分からないけど :-)

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

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

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

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

マイク・ハーンのメール(2010年12月27日 20:21 UTC)

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

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

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

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

以下に詳細を述べる:

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

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

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

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

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

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

マイク・ハーンのメール(2010年12月27日 20:21 UTC)

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

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

マイク・ハーンのメール(2010年12月27日 20:21 UTC)

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

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

マイク・ハーンのメール(2010年12月27日 20:21 UTC)

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

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

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

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

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

情報をありがとう。

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

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

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

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

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

サトシ・ナカモトのメール(2010年12月29日 22:42 UTC)

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

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

サトシ・ナカモトのメール(2010年12月29日 22:42 UTC)

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

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

サトシ・ナカモトのメール(2010年12月29日 22:42 UTC)

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

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

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

マイク・ハーンのメール(2010年12月30日 00:27 UTC)

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

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

サトシ・ナカモトのメール(2011年1月7日 13:00 UTC)

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

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

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

マイク・ハーンのメール(2011年1月7日 13:24 UTC)

オープンソースだ。

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

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

マイク・ハーンのメール(2011年1月7日 13:24 UTC)

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

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

マイク・ハーンのメール(2010年12月30日 00:27 UTC)

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

この計算過程を見てみたいものだ。ある意味、コインの数は任意だ。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

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

マイク・ハーンのメール(2011年1月10日 16:48 UTC)

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

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

ハル(ハル・フィニーだと思うが)

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

マイク・ハーンのメール(2011年1月10日 16:48 UTC)

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

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

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

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

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