トランザクションとスクリプト:DUP HASH160 ... EQUALVERIFY CHECKSIG
ビットコインの wallet.dat を解析する小さなツールを書いているところだ。主にビットコインが正確にどのように動作するのかをよりよく理解したいからだ。
トランザクションの出力には値(ビットコインの数量)と、ビットコインに組み込まれた Forth 風の小さなスクリプト言語を通して実行されるバイト列があることがわかった。例えば: [‘TxOut: value: 100.00 Script: DUP HASH160 6fad…ab90 EQUALVERIFY CHECKSIG’]
まず、ビットコインにスクリプト言語が組み込まれていることに少し不安を感じる。非常にシンプルなスクリプト言語(ループなし、ポインタなし、数学と暗号だけ)であるにもかかわらずだ。不安なのは、より複雑であり、複雑さはセキュリティの敵だからだ。また、2番目の互換性のある実装を作ることも難しくなる。しかし、これは乗り越えられると思う。
コードを見ると、新しいトランザクションは署名をプッシュし、次に公開鍵をインタプリタのスタックにプッシュし、その後 TxOut スクリプトを実行することで検証されている(この理解で合っているだろうか?)。
TxOut に任意の有効なスクリプトを持つトランザクションを作成するコードを書くことは可能だろうか? 例えば、以下のスクリプトで TxOut を作成できるか:OP_2DROP OP_TRUE …誰でも使えるコインを作成するために?
そして、作成できるコインの種類における柔軟性こそが、このように設計された理由なのだろうか?
ビットコインの性質上、 バージョン 0.1 がリリースされた時点で、 核となる設計はその後の生涯にわたって固定されたものとなる。 そのため、 私は考えうるすべてのトランザクション種別をサポートするように設計したかった。 問題は、 一つ一つの種別が使われるかどうかに関係なく専用のサポートコードとデータフィールドを必要とし、 しかも一度に一つの特殊ケースしかカバーできなかったことだ。 そうしていれば特殊ケースの爆発になっていただろう。 解決策は スクリプト であり、 これは問題を一般化して、 取引当事者が自分たちのトランザクションをノードネットワークが評価する述語として記述できるようにする。 ノードは、 送信者の条件が満たされているかどうかを評価する範囲でトランザクションを理解できればよい。
スクリプトは実体としては述語である。 真または偽に評価される単なる等式だ。 述語 (predicate) は長くて馴染みのない言葉なので、 私はスクリプトと呼ぶことにした。
支払いの受取人はスクリプトに対してテンプレートマッチを行う。 現状、 受取人は 2 つのテンプレートのみを受け入れる: 直接支払いとビットコインアドレスだ。 将来のバージョンはトランザクション種別を増やすテンプレートを追加でき、 そのバージョン以降を実行するノードはそれらを受け取れるようになる。 ネットワーク内のあらゆるバージョンのノードは、 新しいトランザクションの中身を読めなくても、 ブロックへの検証と取り込みは行える。
この設計は、 私が何年も前に設計した非常に多様なトランザクション種別をサポートする。 エスクロー取引、 担保付き契約、 第三者仲裁、 複数当事者署名などだ。 ビットコインが大きく普及した場合、 これらは将来探求したくなるものだが、 すべて後で可能にするために最初から設計しておく必要があった。
ビットコインの第 2 の互換実装が良いアイデアになるとは私は思わない。 設計の多くの部分は、 すべてのノードがロックステップで完全に同一の結果を得ることに依存しており、 第 2 の実装はネットワークにとって脅威になる。 MIT ライセンスは他のすべてのライセンスおよび商用利用と互換性があるので、 ライセンスの観点から書き直す必要はない。
サトシ、この設計にはどれくらいの期間取り組んできたんだ? よく考え抜かれていて、事前にたくさんのブレインストーミングや議論なしに、ただ座ってコードを書くようなものじゃない。みんな穴を探そうと当たり前の質問を投げかけているが、しっかり持ちこたえている 😊
Bitcoinの第二の互換実装は決して良いアイデアにはならないと思う。設計の多くが、すべてのノードがロックステップで完全に同一の結果を得ることに依存しているため、第二の実装はネットワークにとって脅威となる。MITライセンスは他のすべてのライセンスや商用利用と互換性があるので、ライセンスの観点から書き直す必要はない。
良いアイデアかどうかにかかわらず、いずれ誰かがネットワークを攪乱しようとする (あるいは自分の用途のために乗っ取ろうとする) 。既存コードを改変するか、自前の版を書くかのどちらかで、いずれにしてもネットワークの脅威となる。
トランザクション内スクリプトという仕組みの柔軟性には感服するが、自分の中の意地悪な部分が、すぐにそれを悪用する方法を考え始めてしまう。TxOut スクリプトには様々な興味深い情報を仕込めるし、改変されていないクライアントがそうしたトランザクションを検証して無視するだけなら、隠れた一斉配信の通信路として使える。
これは、流行るまでは便利な機能だ。だが、誰かが「最新のレディー・ガガのビデオを友人全員に配ろう」 と思いつき、何百万ものトランザクションで決済ネットワークを溢れさせ始めたらどうなるか…
スクリプトは実際には述語だ。真または偽に評価される単なる方程式だ。述語(predicate)は長くて馴染みのない言葉なので、スクリプトと呼んだ。
Bitcoin の性質上、バージョン 0.1 がリリースされた時点で、コアの設計はその生涯にわたって不変となった。そのため、考えられるすべてのトランザクションタイプをサポートするように設計したいと思った。問題は、各機能には使用されるかどうかに関わらず特別なサポートコードとデータフィールドが必要で、一度に一つの特殊ケースしかカバーできないことだった。特殊ケースの爆発的増加になっていただろう。解決策はスクリプトで、問題を一般化して、取引当事者がトランザクションをノードネットワークが評価する述語として記述できるようにした。
ノードは、送信者の条件が満たされているかどうかを評価する範囲でのみトランザクションを理解する必要がある。
第 2 のバージョンは、私にとって大規模な開発とメンテナンスの負担になるだろう。第 2 のバージョンが物事を固定してしまう中で、ネットワークをアップグレードしながら後方互換性を維持するのは十分に大変だ。もし第 2 のバージョンに問題が発生すれば、ユーザー体験は両方に悪い印象を与えるが、少なくとも公式バージョンを使い続けることの重要性をユーザーに再認識させることにはなるだろう。もし誰かが第 2 のバージョンをフォークしようとしていたら、少数派バージョンを使うリスクについて多くの免責事項を公表しなければならないだろう。これは意見の不一致がある場合に多数派バージョンが勝つ設計であり、少数派バージョンにとってはかなり厳しいことになるし、できれば詳しく触れたくない。バージョンが 1 つしかない限り、その必要はない。
そうだ、ほとんどの開発者はソフトウェアのフォークを好まないが、今回は本当の技術的な理由がある。
ギャビン・アンドレセンの投稿(2010年6月17日 10:58 UTC)トランザクション内スクリプトという仕組みの柔軟性には感服するが、自分の中の意地悪な部分が、すぐにそれを悪用する方法を考え始めてしまう。TxOut スクリプトには様々な興味深い情報を仕込めるし、改変されていないクライアントがそうしたトランザクションを検証して無視するだけなら、隠れた一斉配信の通信路として使える。
それは人気が出て、誰かが支払いネットワークに何百万ものトランザクションを送り込んで最新の Lady Gaga の動画を友達全員に転送するのが楽しいと思うまでは素敵な機能だな…… それがトランザクション手数料の理由の 1 つだ。必要であれば他にもできることがある。
ラズロ・ハニエツの投稿(2010年6月17日 09:50 UTC)サトシ、この設計にはどれくらいの期間取り組んできたんだ? よく考え抜かれていて、事前にたくさんのブレインストーミングや議論なしに、ただ座ってコードを書くようなものじゃない。みんな穴を探そうと当たり前の質問を投げかけているが、しっかり持ちこたえている 😊
2007年からだ。ある時点で、信頼をまったく必要とせずにこれを行う方法があると確信し、考え続けることを止められなかった。コーディングよりも設計の作業の方がはるかに多かった。
幸いなことに、これまでに提起されたすべての問題は、以前に検討し計画していたものだ。
なるほどな、俺やギャビンみたいな連中があれこれ穴を探そうとしても悪く取らないでくれよ。みんなここに集まってるのは、これがどんどん発展して大きなものになるのを見たいからだと思うんだ。でも同時に、壊し方を見つけるのにも興味があるんだよ(そうすれば直せるからな)。これまでのところ、互換性を壊さずに機能を追加できているし、よくカバーできてると思うぜ。
これは興味深い。トランザクション手数料を支払う代わりに、匿名の支払いの中にメッセージを埋め込む方法になり得る。
つまり、支払いの中に「公開鍵 [xxx] 宛に暗号化されたメッセージ: [yyyyy]」という No-op 文字列が含まれていたら、それが宛先に渡されるということか? あるいは「受信者への平文メッセージ: [zzzzz]」でもいい。
もちろんこれらのメッセージの内容、つまり [xxx] や [yyyyy] は Bitcoin 自体とは無関係だが、Bitcoin の上に構築されるレイヤーの一部として使えるだろう。
メッセージの埋め込みにこれほど興味があるのは、Tor や I2P のような「ライブ」な匿名ネットワークではなく、Freenet のような「静的」な匿名ネットワークが使えるようになるからだ。ライブなネットワークには exit node があり、その一部は侵害され得る。政府が全 exit node の 1%を侵害すれば、特定のサイトがどこにホストされているかを突き止められる可能性が少しはある。先ほどの Heroin Store の例で言えば、その店宛に N バイトのメッセージを送り、侵害したすべての exit node で N バイトのメッセージを監視する。それを数時間続けて、N バイトのメッセージがどこに送られているかを見れば、最終的にその店の IP アドレスが分かる。
Freenet のようなネットワークでは、データはただ漂っているだけで、たとえば web サイトが特定の 1 台のマシンにあるわけではない。データをクラウドに公開すれば、人々が定期的にアクセスしている限りそこに残り続ける。
色々調べた結果、script は拡張性を提供することを意図しているのだと理解できた。
bitcoin が、生成によって分配される 23,000,000個の「株式」に分割された一種の資産を表すものだとする。
ユーザーが別のカスタム資産を作れるようにしたい。その資産はグローバルにユニークな hash を持ち、アドレス間で送受信できる。たとえば企業が「株式」を発行し、それを bitcoin で交換・検証できるようにする。ゲームエンジンが独自の通貨を発行して追跡することもできる。
script で何か近いことでも実現できるのか、それとも互換性を壊す変更が必要なのか? そもそも現時点でこういったオプションをサポートするためにネットワークを「アップグレード」することは可能なのだろうか?