272ページ中126〜129ページ。
Mastering Bitcoin 日本語訳 PDF
前回まで
取引の支払/受取判定する方法を探す
- MasteringBitcoin日本語訳を読む(Bitcoinトランザクション)
- MasteringBitcoin日本語訳を読む(Bitcoinマイニング)
- MasteringBitcoin日本語訳を読む(トランザクションの使用)
- MasteringBitcoin(トランザクションscriptとScript言語)
- 総支払額を算出する方法の考察1
- 総支払額を算出する方法の考察2
コメントに助けられtrezor APIにtxid
を渡せば支払う側のアドレスを取得できることが判明。結果的に支払/受取を判定することができ、以下のような集計ができるようになった。
今回からの方針
とにかく読む
本当は送金するためのJavaScriptコードを知りたいだけなのだが、そのためには暗号通貨にまつわる基礎知識がなさすぎる気がする。一応トランザクションの概要は理解できたつもりだが、まずはMastering Bitcoin 日本語訳 PDFの読了を目指してみる。
前回の続きから読んでみる。トランザクションの署名だか承認だかで使うScript言語について。transaction情報のvin
, vout
に含まれる。
Script言語
Script と呼ばれているBitcoinトランザクションスクリプト言語は、 Forth言語のような逆ポーランド記法の言語です。もしちんぷんかんぷんに聞こえるとしたら、あなたはおそ らく1960年代のプログラミング言語を勉強したことがないのでしょう。
アセンブリ、フォートラン、ベーシックは名前だけ知ってる。script
なんて名前の言語は聞いたこともない。
scriptはとてもシンプルな言語で、限 られたハードウェアで動くように設計された言語です。おそらく電卓のような組み込みデバイスくらい簡単な ハードウェアです。これは最小の処理のみを必要とし、最近のプログラミング言語でできるようなことの多く はできません。
ふーん。いわゆる低級言語というやつかな?
wikipediaでスクリプト言語のページをみたけど、固有言語としてのScript言語ではないみたい。ウィキにも認知されていないほどマイナーってことかな?
どうでもいいけど、Wikipediaのデザインがいつの間にか変わってる。英語ページへのリンクとか消えてる。英語のほうが詳しかったりする場合もあるから翻訳して見てたりしてたのになぁ。と思ったら見出しの横にあった。英語のほうにもScript言語らしきものは書いてない。
Script言語を勉強するとき、どうすればいいかわからない。実行エンジンは? ドキュメントは? ググラビリティ低すぎて見つけられない。coin
とかのキーワードと一緒に検索すれば記事が出てきたが公式ではない。一応英語でbitcoin用wikiっぽいページをみつけた。
あと、ビットコスクリプト言語を理解してるのは地球上でたった10人。という記事には衝撃的なことが書かれている。
「ビットコインのスクリプト言語を完全に理解できているのは地球上でまだ10数人」
え、1960年代に作られてた言語なのに理解している人が10数人しかいないの?
暗号通貨の利用者はもっと多いはず。仮想通貨トレーダーの人数、月間600万人超で日本が世界2位にによると月間3000万人以上が利用しているようだが。
米国で、月間約2260万人が仮想通貨交換所を利用している。続いて日本(約610万人)、韓国(約570万人)の利用者が多いとされる。
暗号通貨の利用者ですら、そんなマイナー言語について学習しようとする人間はいないってことかな? あるいは完全な理解をしていないだけで、知っている人はそれなりにいるのかな?
PDFに戻ろう。
BitcoinのScript言語はスタックベース言語と呼ばれています。というのは、 スタック と呼ばれるデータ構造を使っているからです。スタックとはとても簡単なデータ構造で、イメージ的にはカー ドを重ねたもののようなものです。スタックは2つの操作を許しています。pushとpopです。pushはアイテム をスタックの一番上に加えます。popは一番上にあるアイテムをスタックから除きます。
スタックはデータ構造で勉強したことある。キューの逆みたいなやつ。先に入れたものほど後にとりだすやつ。
Script言語はそれぞれのアイテムを左から右に処理することでscriptを実行していきます。数値(定数)がスタ ックにpushされます。オペレーターは1つまたは複数の値をスタックに対してpushまたはpopし、またはそ れらに対して何らかの操作をします。場合によっては操作した結果をスタックにpushするかもしれません。
上下なのか左右なのかどっちさ。最後に突っ込んだやつを最初にとりだすんだよね? 最初に突っ込んだやつが最後にとれる。とにかくScriptはスタックベースなのね。
例えば、 OP_ADD はスタックから2つのアイテムをpopして、2 つのアイテムを加え合わせ結果をスタックにpushします。 条件オペレーターは条件を評価して、TRUEかFALSEというブール型の結果を作り出します。例えば、 OP_EQUAL はスタックから2つのアイテムをpopして、もしそれらが等しいならTRUE(TRUEは数値の 1によって表現されます)をpushし、等しくなければFALSE(数値の0で表します)をpushします。
なるほど。イメージできた。OP_ADD
やらOP_EQUAL
やらは、説明されているような動作をするコマンドなのだろう。それをオペレータと呼んでいるみたい。
Bitcoinトラ ンザクションscriptは通常有効なトランザクションを示すTRUEの結果を生成するために条件オペレーターを 含んでいます。 Bitcoinのscript検証を使って簡単な算数をやってみる。図では 2 3 OP_ADD 5 OP_EQUAL という scriptで、加法オペレーター OP_ADD を実行し2つの数値を加え結果をスタックに置き、次に OP_ADD の結果と 5 が等しいかをチェックする条件オペレーター OP_EQUAL を実行しています。簡潔に言えば、 OP_ というプレフィックスは Bitcoinのscript検証を使って簡単な算数をやってみる。 で省略されています。 以下はちょっとだけ複雑なscriptで、 2 + 7 – 3 + 1 を計算しています。
「2 3 OP_ADD 5 OP_EQUAL
」というscriptを書いたときの話。
2
,3
という2つの値がそれぞれスタックに積まれるOP_ADD
コマンドで2つのスタックから値を取り出して加算した結果5
をスタックにぶちこむ- リテラル
5
をスタックにぶちこむ OP_EQUAL
コマンドで2つのスタックから値を取り出して比較した結果TRUE
をスタックにぶちこむ
ということになるのだろう。
以下はちょっとだけ複雑なscriptで、 2 + 7 – 3 + 1 を計算しています。
scriptがいくつかのオペレーターを含んでいるとき、スタックの性質上1つのオペレーターの結果を次のオペ レーターだけが使うことができます。
2 7 OP_ADD 3 OP_SUB 1 OP_ADD 7 OP_EQUAL
鉛筆と紙を使ってこのscriptが有効かあなた自身でやってみましょう。scriptの実行が終わった段階で、スタ ックにTRUEが残っているはずです。
2
で2
をスタックにpushする7
で7
をスタックにpushするOP_ADD
で7
,2
をpopし、加算した結果9
をpushする3
をpushするOP_SUB
で3
,9
をpopし、減算した結果6
をpushする1
をpushするOP_ADD
で1
,6
をpopし、加算した結果7
をpushする7
をpushするOP_EQUAL
で7
,7
をpopし、比較した結果TRUE
をpushする
たしかに最後はTRUE
になった。
ほとんどのlocking scriptは資金の使用にあたっての所有権の証明のため Bitcoinアドレスや公開鍵を参照していますが、locking script は複雑である必要はありません。結果としてTRUEが出力されるlocking scriptとunlocking scriptのどんな組み合わせも有効とみなされます。Script言語の例として使った簡単な算数も、トランザクシ ョンアウトプットをロックするために使うことができるきちんとしたlocking scriptです。
script
言語的には真偽値を返すなら何でもいいってことね。
でも暗号通貨的にはそのコインを誰が所有しているかを証明するために使っていると。
ロックというのは、所有者しか使えないよう暗号化することだろう。それが署名だと思われる。所有者本人にしかScriptの結果をTRUE
にできないようにすることで、そのコインは所有者しか使えないようになる。そういう意味だろう。
locking scriptとしてさきほどの算数のscript例の一部を使ってみましょう。 3 OP_ADD 5 OP_EQUAL これは以下のunlocking scriptを持つインプットがトランザクションにあれば満たすことができます。 2 有効性を確認するソフトウェアはlocking scriptとunlocking scriptをくっつけて以下のscriptを作ります。 2 3 OP_ADD 5 OP_EQUAL Bitcoinのscript検証を使って簡単な算数をやってみる。図で見たように、このscriptが実行されるとこの結果 は OP_TRUE になりトランザクションは有効であると分かります。この場合、有効なトランザクションアウトプットのlock ing scriptだけでなく、算数の計算ができる人であれば誰でも2がこのscript を満たすことがわかるので誰でもUTXOを使うことができることになります。
項目 | 値 |
---|---|
unlocking script (scriptSig ) vin |
2 |
locking script (scriptPubKey ) vout |
3 OP_ADD 5 OP_EQUAL |
つまりunloking
のほうがlocking
の引数になるってことか。
TIP: もしスタックの一番上にTRUE ( {0x01} のように表現されます)、または TRUEではないが0以外の値があればトランザクションは有効と検証されたことになります。ま たは、script実行後にスタックに空値ではなく何も残っていなかった場合もトランザクションは 有効と検証されたことになります。トランザクションが無効になってしまう場合は、スタック の一番上に偽({} のように表現される長さ0の空値)がある場合や、OP_VERIFY やOP_RETURNまたはOP_ENDIFのような条件付き終了オペレータなどによって明示的にscript 実行が終了させられる場合です。詳細については [tx_script_ops] を参照してください。
何もなくても有効なのか。でも「長さ0の空値」は無効なのか。それらは何が違うのかよくわからない。まあいいや。
この話をもとに考えてみる。たぶん支払うときにScriptを使うのだろう。Scriptを実行しその結果がTRUE
ならコイン所有者であると判定し、トランザクションを作成して送信する。その後、マイナーがそのトランザクションを発見し、マイニングしてブロックチェーンに取り込む。という流れかな?
もしそうなら、送金するときの手続きとしてScriptの実行が必要になるということだ。支払いをプログラミングしたい私のような立場の人間は、どこまで理解していればいいのか。mpurse, mpchain, counterParty, counterBlock の各種APIではどこまでやってくれるのか。たぶんサーバ側で実行してくれているのだろうけど。いまだによくわからないが読み進めよう。
チューリング不完全
BitcoinトランザクションScript言語は多くのオペレーターを持っています。しかし、意図的にループやif文な どの分岐処理がないように制限されています。これは言語が チューリング完全 ではないということを言っており、このようになっているのはscriptの簡潔さや実行時間を予測できるように することがあります。Script言語は汎用言語ではないのです。これらの制限によって、無限ループを作ること やBitcoinネットワークを使ったDOS攻撃を起こすようなトランザクションに内在する"論理爆弾(logic bomb)"などを作ることができなくなっています。思い出してみてください、全てのトランザクションはBitco inネットワーク上の全てのフルノードによって有効性が確認されているので、トランザクションの有効性確認 処理に問題があれば簡単に脆弱性が作れてしまいます。言語が制限されているためにトランザクションの有効 性確認メカニズムが脆弱性を生むことを防いでいるのです。
自由度を担保しつつバグらせないような仕様の言語がscript
ということか。
必要条件を満たしつつ不要なリスクを持たぬよう、あえてScript言語のようなチューリング不完全な言語を採用したと。
ステートレスな検証
BitcoinトランザクションScript言語はステートレスです。これは、scriptの実行前の状態を何も保持しない、 またはscriptの実行後の状態を一切保存しないということです。このため、scriptを実行するために必要な全 ての情報はscriptの中に含まれていることになり、scriptはどんなシステム上でも同じプロセスで実行できる ことが予測できるということになります。もしあなたのシステムがscriptを検証できるなら、確実にBitcoinネ ットワーク内の他全てのシステムもまたscriptを検証でき、有効なトランザクションは全ての人に対して有効 なのです。この結果の予測可能性はBitcoinシステムの本質的な利点です。
どこでも再現可能ということか。でも、そのScript実行エンジンはどこにあるやら。たぶんフルノードアプリをインストールしたら一緒に入っているのだろうけど、ブロックチェーンのサイズが数十GBというから試せないんだよなぁ。
今回はここまで。