サトシ ↔ マイク・ハーン — BitcoinJとコントラクト
サトシさん、こんにちは。
お元気でいることを願っている。ようやく Google の弁護士全員を説得した。Apache 2 ライセンスで BitCoinJ を公開する:
http://www.bitcoin.org/smf/index.php?topic=4236.0
まだ不完全で、特にブロックチェーンの分岐を適切に処理できていないが、残りの部分は順次実装していく。ドキュメントとコメントに多くの労力を費やしたので、現在のコードを理解・ビルドできなかった新しい層に BitCoin を開放できればと思う。今後 1〜2ヶ月で、完全なクライアントモード実装に必要な大きな欠落部分を仕上げる予定だ。
忙しいところ申し訳ないが、いくつか質問に答えてもらえないだろうか。
完全な SPV の実装の一環として、プロトコルに getmerklebranch メッセージを追加することを考えている。これはトランザクションハッシュを指定すると{blockhash, branch}のペアのセットを返すもので、フルチェーンを保存せずにブロードキャストされたトランザクションをブロックに組み込まれる前に検証できるようにするものだ。このアプローチについてどう思うか?
また、最近さまざまなトランザクションタイプの探求を考えている。例えば testnet で IsStandard()チェックを削除するなどだ。単純なコインの移動以外のトランザクションについて、あなたが事前に多くの思考を費やしたことは明らかだが、残念ながらそのいずれも論文やコード内に文書化されていない。エスクロー、マルチペイなどはいずれも興味深いが、スクリプト言語で何ができるかのアイデアリストをまとめてもらえないだろうか。
最後に、トランザクション置換を可能にするコードは無効化されているが、コメントにはその理由が書かれていない。これは単に攻撃対象領域・複雑さを減らすためだろうか、それともより深い理由があるのだろうか?シーケンス番号がトランザクション自体ではなくトランザクション入力のプロパティである理由も完全には理解できていない。
コミュニティに戻ってくるつもりはないか?これを見たかどうか分からないが:
http://bitcoin.sipa.be/speed-lin.png
ネットワークにとってエキサイティングな時期だ!
ありがとう!
/mike
お元気でいることを願っている。ようやくGoogleの弁護士全員を説得した。Apache 2ライセンスでBitCoinJを公開する:
まだ不完全で、特にブロックチェーンの分岐を適切に処理できていないが、残りの部分は順次実装していく。ドキュメントとコメントに多くの労力を費やしたので、現在のコードを理解・ビルドできなかった新しい層にBitCoinを開放できればと思う。今後1〜2ヶ月で、完全なクライアントモード実装に必要な大きな欠落部分を仕上げる予定だ。
素晴らしいニュースだ。クライアント要件のみのクリーンな書き直しでは多くの複雑さを省くことができるし、Java の開発者にも門戸を開くことになる。
マイク・ハーンのメール(2011年3月7日 14:13 UTC)忙しいところ申し訳ないが、いくつか質問に答えてもらえないだろうか。
喜んで質問に答える。
マイク・ハーンのメール(2011年3月7日 14:13 UTC)完全なSPVの実装の一環として、プロトコルにgetmerklebranchメッセージを追加することを考えている。これはトランザクションハッシュを指定すると{blockhash, branch}のペアのセットを返すもので、
それは CMerkleTx だ。
マイク・ハーンのメール(2011年3月7日 14:13 UTC)フルチェーンを保存せずにブロードキャストされたトランザクションをブロックに組み込まれる前に検証できるようにするものだ。このアプローチについてどう思うか?
理解できない。マークルブランチはトランザクションをブロックにリンクするが、それはブロックが Proof of Work を示す場合にのみ意味を持つ。まだ解かれていないブロックにリンクしても何も証明しない。
ネットワークノードが 0-conf トランザクションを検証できるのは、完全なトランザクションインデックスを持っているためで、以下のことが可能だ:
- 依存関係に対して署名を検証する。
- 存在するすべてのトランザクションを知っているため、まだ別の支出を見ていないと言える。
トランザクションの依存関係に対する CMerkleTx について話しているのか?それなら 1)は得られるが、2)は得られない。
存在するすべてのトランザクションを知らない場合、2)をどうやって実現するか分からない。他のノードを信頼するしかないだろう。その信頼は複数のノードに分散させることができる。ノードは有効と認めるトランザクションのみをリレーする。接続しているすべてのノードからトランザクションの inv メッセージを受信した場合、それらのノードはそのトランザクションが有効であり、最初に見た支出であることを証明している。
マイク・ハーンのメール(2011年3月7日 14:13 UTC)また、最近さまざまなトランザクションタイプの探求を考えている。例えばtestnetでIsStandard()チェックを削除するなどだ。
非常に良いアイデアだ。-testnet では間違いなく許可すべきだ。
マイク・ハーンのメール(2011年3月7日 14:13 UTC)単純なコインの移動以外のトランザクションについて、あなたが事前に多くの思考を費やしたことは明らかだが、残念ながらそのいずれも論文やコード内に文書化されていない。エスクロー、マルチペイなどはいずれも興味深いが、スクリプト言語で何ができるかのアイデアリストをまとめてもらえないだろうか。
最後に、トランザクション置換を可能にするコードは無効化されているが、コメントにはその理由が書かれていない。これは単に攻撃対象領域・複雑さを減らすためか、それともより深い理由があるのか?
攻撃対象領域を減らすためだけだ。トランザクション手数料の引き上げには役立たない。トランザクションは nLockTime から有効になる。ある時点で有効でなくなるトランザクションは機能しない。一度有効になったトランザクションは、永久に有効でなければならない。
以下のスレッドを参照してほしい:
http://www.bitcoin.org/smf/index.php?topic=1786.msg22119#msg22119
http://www.bitcoin.org/smf/index.php?topic=2181.msg28729#msg28729
シーケンス番号がトランザクション自体ではなくトランザクション入力のプロパティである理由も完全には理解できていない。
コントラクトのためだ。記録されていないオープントランザクションは、nLockTime まで置換し続けることができる。複数の当事者からの支払いを含む場合がある。各入力の所有者が自分の入力に署名する。新しいバージョンを書くには、それぞれがより高いシーケンス番号に署名しなければならない(IsNewerThan を参照)。署名することにより、入力の所有者は「全員が資金を投入し、出力がこうであるなら、私は自分の資金を投入することに同意する」と言っている。SignatureHash には SIGHASH_SINGLE のような他のオプションもあり、これは「この 1 つの出力(つまり自分のもの)が望み通りであれば同意し、他の出力については気にしない」という意味だ。これが高い nSequenceNumber で書かれた場合、当事者はその 1 つの条件を除いて交渉から離脱できる。あるいは SIGHASH_NONE で署名して完全に離脱することもできる。
当事者は OP_CHECKMULTISIG を使用してより高い nSequenceNumber のトランザクションを作成し、署名を完了するために当事者のサブセットの署名を必要とする、事前に合意されたデフォルトオプションを作成できる。当事者はこのトランザクションを保留し、必要に応じて十分な署名が集まるまで回覧する。
nLockTime の 1 つの用途は、一組の当事者間での高頻度取引だ。全員一致の合意によりトランザクションを更新し続けることができる。資金を提供する当事者が次のバージョンに最初に署名する。一方の当事者が変更への合意を停止した場合、最後の状態が nLockTime で記録される。必要であれば、各バージョンの後にデフォルトトランザクションを準備して、n-1 の当事者が応答しない当事者を排除できる。中間トランザクションをブロードキャストする必要はない。最終結果のみがネットワークに記録される。nLockTime の直前に、当事者と数人の証人ノードが見た中で最も高いシーケンスのトランザクションをブロードキャストする。
存在するすべてのトランザクションを知らない場合、2)をどうやって実現するか分からない。他のノードを信頼するしかないだろう。その信頼は複数のノードに分散させることができる。ノードは有効と認めるトランザクションのみをリレーする。接続しているすべてのノードからトランザクションの inv メッセージを受信した場合、それらのノードはそのトランザクションが有効であり、最初に見た支出であることを証明している。
おっしゃる通りだ。入力の検証について話していたのだが、すべてのオープントランザクションを把握しなければ確かに意味がない。したがって、CMerkleTx を取得できることは重要ではない。
サトシ・ナカモトのメール(2011年3月9日 17:15 UTC)攻撃対象領域を減らすためだけだ。トランザクション手数料の引き上げには役立たない。トランザクションはnLockTimeから有効になる。ある時点で有効でなくなるトランザクションは機能しない。一度有効になったトランザクションは、永久に有効でなければならない。
以下のスレッドを参照してほしい:
http://www.bitcoin.org/smf/index.php?topic=1786.msg22119#msg22119http://www.bitcoin.org/smf/index.php?topic=2181.msg28729#msg28729
なるほど。つまり現在、手数料は事前に決めなければならないため厄介で、低すぎた場合にトランザクションを修正する方法がなく、ネットワークはいずれ忘れるものの、ウォレットにはコインを使ったと記録されたままになる。これはすでに起こり始めている。
サトシ・ナカモトのメール(2011年3月9日 17:15 UTC)コントラクトのためだ。
なるほど。システムのまだ探索されていない領域全体が目の前に開けた :-) 仲介者を信頼する必要なしに分散コントラクトやエスクロートランザクションを形成するという概念は、BitCoin 自体とほぼ同じくらい斬新な概念だと思う。
もっと質問がある!
プロトコルには publisher/subscriber チャネルを設定するための未完成の部分があり、ネットワークを介した分散ルーティングを扱っている。これの目的は何だったのか?P2P マーケットのアイデアだったのか、それとも予想されるトランザクション手数料のブロードキャストなど、何かもっと低レベルの機能だったのか?
数ヶ月前に BitCoin を一般化することについて興味深い議論があったが、あなたがそれをどのように達成しようとしていたかを完全に理解するのは難しかった。複数の独立したチェーンの上に別のマークルツリーを配置するという概念は理解できたと思う:
http://www.bitcoin.org/smf/index.php?topic=3414.msg48171#msg48171
しかし、後方互換性のために 200 バイトを持つというあなたのコメントは理解できなかった。また、これは明らかだと思うが、念のため確認する。あなたのアイデアでは、代替チェーンは BitCoin とまったく同じ形式と検証ルールのセット(同じスクリプト言語など)を共有し、すべてのマイナーは非金融的な性質のブロックであっても検証できるということか?そして、別々のブロックチェーンを持つ意味は、単にクライアントモード実装のストレージコストと帯域幅を管理することなのか?
ありがとう!
以下のスレッドを参照してほしい:
http://www.bitcoin.org/smf/index.php?topic=1786.msg22119#msg22119http://www.bitcoin.org/smf/index.php?topic=2181.msg28729#msg28729なるほど。つまり現在、手数料は事前に決めなければならないため厄介で、低すぎた場合にトランザクションを修正する方法がなく、ネットワークはいずれ忘れるものの、ウォレットにはコインを使ったと記録されたままになる。これはすでに起こり始めている。
ネットワークは忘れないし、所有者のクライアントは再ブロードキャストし続ける。オーバーフロートランザクションは、残りの 0.3.8 ノードが減少する中でも数ヶ月間ネットワークに記憶されていた。
優先度には経過時間が含まれるため、トランザクションが待機するにつれて経過時間が増え、最終的には十分な優先度を持つようになる。
上記のリンクの 1 つで、手数料を増やすために正直な二重支払いを送信することを検討している。多くの作業が必要だが、実行は可能だ。現時点ではその価値はないと思う。
現在のシステムでは、ノードが現在の条件に十分な手数料を含めるようにし、ネットワークがすべてのトランザクションを最終的に処理するようにしており、十分に機能している。ギャビンは、ノードが自分のトランザクションを書き込む際に優先度をチェックしていなかった見落としを修正している。
処理速度の不確実性を心配するユーザーは、手数料を含めることへの動機付けと考えるべきだ。
マイク・ハーンのメール(2011年3月9日 17:39 UTC)プロトコルには publisher/subscriber チャネルを設定するための未完成の部分があり、ネットワークを介した分散ルーティングを扱っている。これの目的は何だったのか?P2P マーケットのアイデアだったのか、それとも予想されるトランザクション手数料のブロードキャストなど、何かもっと低レベルの機能だったのか?
クライアントに組み込んだ eBay スタイルのマーケットプレイスを実装しようとしていた。Publish/subscribe は商品オファーや評価・レビューのブロードキャストに使用される予定だった。レビューはあなたが生成したブロックによって重み付けされる。JSON-RPC を優先して正しく放棄した。これにより他の開発者が外部で実装できるようになった。publish/subscribe の「中間で出会う」メカニズムは興味深い概念だったが、それを使用するものは何も残っていない。
これは最も技術的に要求の厳しいユースケースを探索し、ブロックチェーンが開始された後のルールのロックイン性を考慮して、将来必要になる可能性のあるすべてをビットコインがサポートできることを確認するためのコード作成の一部だった。
マイク・ハーンのメール(2011年3月9日 17:39 UTC)数ヶ月前にBitCoinを一般化することについて興味深い議論があったが、あなたがそれをどのように達成しようとしていたかを完全に理解するのは難しかった。複数の独立したチェーンの上に別のマークルツリーを配置するという概念は理解できたと思う:
http://www.bitcoin.org/smf/index.php?topic=3414.msg48171#msg48171しかし、後方互換性のために200バイトを持つというあなたのコメントは理解できなかった。また、これは明らかだと思うが、念のため確認する。あなたのアイデアでは、代替チェーンはBitCoinとまったく同じ形式と検証ルールのセット(同じスクリプト言語など)を共有し、すべてのマイナーは非金融的な性質のブロックであっても検証できるということか?そして、別々のブロックチェーンを持つ意味は、単にクライアントモード実装のストレージコストと帯域幅を管理することなのか?
いいえ、他のチェーンはビットコインのルールには従わない。それらは完全に独立したチェーンだ。マイナー以外は何も共有しない。他のネットワークの Proof of Work の定義は、自分のブロックのハッシュを含むビットコイン形式のブロックを(自分のチェーンの難易度に従って)解くことだ。ビットコインブロックが有効であるか、ビットコインによって使用されているかは気にしないが、マイナーが両方のチェーンを同時に作業できるようにする。
BitDNS ブロックをハッシュする手順:
- BitDNS ブロックをハッシュする
- ビットコインブロックを構築する
- ビットコインブロックの Tx 0 の scriptSig に BitDNS ハッシュを挿入する
- ビットコインブロックをハッシュする
そのハッシュが BitDNS のターゲット以下であれば、BitDNS ブロックは有効だ。
BitDNS ブロックには、ハッシュに使用されたビットコインブロックを再構築するために必要な約 200 バイトのデータが必要だ:
- ビットコインブロックヘッダー
- Tx 0 へのマークルブランチ
- Tx 0(ちなみに、Tx 0 の prev ハッシュは常に 0 なので、省略すると 32 バイト節約できる)
素材となる「ビットコインブロック」がビットコインチェーンで実際に有効であったかどうかは問題ではない。ただし、有効であった可能性はある。BitDNS にとっては、その複雑なハッシュ計算を行うために必要な単なるソルトの集まりだ。マイナーが BitDNS のみをマイニングしていてビットコインに関心がない場合、すべてゼロの空白ビットコインブロック(ナンスを除く)を使用するだろう。
アイデアをさらに拡張性のために発展させるなら、BitDNS ブロックハッシュを Tx 0 に入れる代わりに、BitDNS を含むマークルツリーのルートを入れることを検討してくれ。これが概念的に最上部にあるマークルツリーだ。
改めてありがとう。
ハル・フィニーは、あなたが新しいマークルルートを Tx0 の scriptSig に格納するつもりだと推測していた。少なくとも彼は正しいアイデアを持っていたことが分かった :-)