読者です 読者をやめる 読者になる 読者になる

25歳海外駐在員のマネー、資格奮闘記

25歳の東南アジア某国に生息する海外駐在員。Bitcoinをメインに、英語や駐在生活に関して情報発信中。

Mastering Bitcoinを読んで分かったこと トランザクション編

仮想通貨(暗号通貨)

遅ればせながらMastering Bitcoinを読んでみました。分かっていた気になっていたけど実は分かっていなかった点があぶり出されて、非常にすっきりした気分です(笑)。

Mastering Bitcoin

Mastering Bitcoin

 

 

備忘を兼ねて、解消された不明点をまとめますが、あまりにもきちんと理解できていなかった箇所が多いので、何回かに分けてまとめます。第1回はトランザクションから。

 

トランザクションのValidateの順番

あるノードから受信したトランザクションは、以下の検証ステップを経て、各ノードに正統なトランザクションとして受け入れられます。念のためですが、これはブロックチェーンへのブロック書き込みとは別の概念です。

  1. 受信したトランザクションに含まれるInputからUTXO(未使用のOutput, Unspend Transaction Output)を特定する
  2. UTXOからscriptPubKeyとよばれるスクリプト(一般的には、送信者のBitcoinアドレスを含む)を取り出す
  3. InputからscriptSigとよばれるスクリプト(一般的には、送信者のデジタル署名とPublic Keyを含む)を取り出して、scriptPubKeyとscriptSigを実行する

 

トランザクションの基礎はこちら。

cryptocoin.hatenablog.com

 

トランザクションスクリプト P2PKHとP2PK

ScriptPubKeyとScriptSigとサラッと書きましたが、どちらもトランザクションスクリプトとよばれるBitcoin専用の簡易言語で作られたプログラムのことを指しています。

 

なぜ専用の言語が使われるかというと、複雑な処理を認めないことでBitcoinネットワークへの攻撃を防止するためです。例えば、このプログラムはチューリング不完全な言語として設計されており、プログラム内でループ処理が認められていません。そのため、無限ループ処理を組み込んだ、DDoS攻撃を防止することができます。

 

トランザクションスクリプトは5種類のスクリプトが認めれています。最も一般的なスクリプトはP2PKH (Pay-to-Public-Key-Hash)と呼ばれるスクリプトになります。

 

P2PKHはその名前の通り、Public KeyのHash、すなわちBitcoinアドレスを支払い先に指定したScriptのことを指します。これとは別にP2PK (Pay-to-Public-Key)というトランザクションスクリプトもあり、この場合はPublic Keyを受取人に指定して送信することになります。P2PKの方がシンプルな構成ですが、セキュリティの観点からP2PKHがメインで使われています(多分。ちょっとここのP2PKHがメジャーな理由は自信なし)。

 

P2PKHを使用した場合のトランザクション検証の動きを簡単にまとめると、以下のような流れになります。

前提 InputとOutputに含まれる情報

Input: 送信者のデジタル署名、送信者のPublic Key

Output: 送信者のBitcoinアドレス

フロー
  1. 送信者のPublic Keyが本物であることを確かめるために、InputのScriptに含まれるPulic KeyがBitcoinアドレス(=Pubilc Keyにハッシュをかけたもの、Outputに含まれる)と一致するかを検証
  2. 一致した場合は本人性の確認のために、デジタル署名(Inputに含まれる)を送信者のPublic Key (Inputに含まれる)で検証

 

ちなみに、P2PK(Pay-to-Public-Key)を使用した場合は、Output (UTXO) に送信者のPublic Keyを含んでいるため、2番のデジタル署名の検証のみで終了です。

 

トランザクションスクリプト Multi-SignatureとP2SH

複数人の承諾がないと、Bitcoinを使用できないようにしたい場面があります。例えば、経理担当者の決済の他に、経理部長の承認を必要とするというような事例が考えられます。この場合、Multi-SignatureまたはP2SHのいずれかのトランザクションスクリプトを利用することで、上記スキームを実現することができます。

 

Multi-Signature

Multi-Signatureはひとりの受取人に対して、複数のPublic Key (N個)を指定する種類のスクリプトです。これに対して、受取人側はこのトランザクションをInputとして送金に利用するタイミングで、このトランザクションで指定されたPublic Key(N個)に対応するデジタル署名(N個以下)を付与することでトランザクションを送金に利用することができるようになります。

 

例えば、P2PKを使用する場合は、経理担当者のPublic Keyだけを送信先に指定していたのに対して、Multi-Signatureを使用する場合は経理担当者と経理部長両方のPublic Keyを指定してもらうことになります。

 

この会社が受け取ったBitcoinを送金手段として使用したい場合は、経理担当者と経理部長両方のデジタル署名をInputに付与することで送金できるというわけです。

 

ただ、この方法の場合は、送信者に複数のPublic Keyを指定してもらう必要があるため、通常のWalletアプリを使用して送金することができません。また、仮に指定できたとしても送信者の手間が増えてしまうのであまり一般に使用されていません。そこで、この問題を解消すべく生まれたのが、P2SHです。

P2SH

P2SH (Pay-to-Script-Hash) は、「Multi-Signatureで送信者が指定していた複数のPublic Key」に対して、Hashをかけたものを受信者のアドレスとして利用するというものです。この方法を利用すると、送信者としては通常のBitcoinの送金同様、アドレスを指定して送るだけの作業になるため、送信者側の負担が軽減されます。

 

逆に受信者は、当該トランザクションを送金に利用する際は、デジタル署名だけでなく、アドレス作成に使用したPublic Keyなどの情報をInputに添付する必要があります。

 

トランザクションスクリプト OP_RETURN

ちなみにもうひとつ、OP_RETURNというトランザクションスクリプトもあります。これは、Payment以外の目的でのBitcoin利用を拡充するために導入されたスクリプトです。Bitcoinの各ノードは、未使用のアウトプット (UTXO) を素早く探すため、UTXOプールとよばれるメモリを保持しています。UTXOが新たに生まれるとUTXOプールに格納され、逆にUTXOがインプットに使用されるとUTXOプールから削除されるという動きをします。

 

しかし、Bitcoin送金以外の目的でトランザクションを使用する際には、送金額が0コインとなっている場合があります。その場合、UTXOは二度とインプットに使われることはないにもかかわらず、UTXOプールに格納されてしまいます。これが繰り返されるとUTXOプールが肥大化して、メモリを使い切ってしまうおそれがあります。

 

そこで、もしOutputにOP_RETURNというコードが含まれている場合は、UTXOをUTXOプールに格納しないという仕様に変更することで、UTXOプールの枯渇を防ぐことができるようになりました。ちなみに、もしOP_RETURNが記載されたUTXOがインプットに入ってきた場合は、検証無効となり送金が拒否されます。

 

まとめ

まとめてみると、なかなかなボリュームの記事になってしまいました。ほぼ、トランザクションスクリプトに関する記事になってしまったので、トランザクションスクリプトの種類を最後にまとめておきます。

 

代表的なトランザクションスクリプト

  • P2PKH
  • P2PK
  • Multi-Signature
  • P2SH
  • OP_RETURN

 

勉強しながらなので間違っている箇所もあるかもしれませんので、ご指摘いただけると非常に助かります。