Develop with pleasure!

福岡でCloudとかBlockchainとか。

MWEBチェーン上での送金と非対話型のトランザクションの構築

前回、MWEBチェーンへのペグインまで行ったので↓

techmedia-think.hatenablog.com

今回は、MWEBチェーン上でMWトランザクションを使った送金をしてみる。

MWEB上での送金

新しいmwebタイプのアドレスを作成し、そこに送金する↓

$  ./litecoin-cli sendtoaddress tmweb1qqfhtsgcqxz0ez0je526ay5v8uerrtjsu33q7may3v43kwe4n0paz7qlwzsag2dschehz7qm4p4f8gfpu3cngpwsthjckhlah9txn24ukxulxx2yf 0.0001
2c83e8f14fed5bb6c8d4630c0d833f860dc48262b31af05f3d3acab8a362ca9e

このトランザクションの内容は↓

$ ./litecoin-cli getrawtransaction 2c83e8f14fed5bb6c8d4630c0d833f860dc48262b31af05f3d3acab8a362ca9e 1
{
  "txid": "2c83e8f14fed5bb6c8d4630c0d833f860dc48262b31af05f3d3acab8a362ca9e",
  "hash": "2c83e8f14fed5bb6c8d4630c0d833f860dc48262b31af05f3d3acab8a362ca9e",
  "version": 2,
  "size": 2203,
  "vsize": 0,
  "weight": 0,
  "locktime": 2352363,
  "vin": [
    {
      "ismweb": true,
      "output_id": "147785fb93659118be70445d947496dbedd7983086446f73d5f803eec2ff7691"
    }
  ],
  "vout": [
    {
      "ismweb": true,
      "output_id": "fc93c77ff288e5e2a0247662ffaf5470878b99a2805a76b8e4715d1b5ebfbf1c"
    },
    {
      "ismweb": true,
      "output_id": "fda598167f8f0973b711427c21673a90093b9ca2b8cd6ef285c7879d6ecb2f22"
    }
  ],
  "vkern": [
    {
      "kernel_id": "9eca62a3b8ca3a3d5ff01ab36282c40d863f830d0c63d4c8b65bed4ff1e8832c",
      "fee": 0.00003900,
      "pegin": 0.00000000,
      "pegout": [
      ]
    }
  ],
...

※ ちなみにトランザクションがブロックに格納されるとgetrawtransactionはデータを返さなくなる。これはトランザクション・カットスルーによりチェーン上から消えるためだと思われる。ただ、ウォレットRPCであるgettransactionを使えば確認は可能。

↑のレスポンスを見ると、アウトプットにはoutput_idしか表示されていないが、MWEBのアウトプットは以下の要素で構成されており、output_idはこれらのデータから生成したハッシュ値になる。

  • commitment:コインの量を秘匿したPedersen commitment
  • sender_pubkey:送信者がトランザクション作成時に作成する一時鍵
  • receiver_pubkey:受信者の公開鍵。ステルスアドレスの使用鍵の公開鍵に共有シークレットから導出した値を乗算して導出される公開鍵であるため、チェーン上でステルスアドレスの公開鍵と直接リンクすることはない。
  • message:アウトプットに関する以下のメタデータ
    • 機能ビット
    • 鍵交換に使用する公開鍵:送信者が生成したシークレットを受信者のステルスアドレスの使用鍵の公開鍵に乗算して導出した公開鍵。
    • View Tag:受信者が自分宛の送金であることの判断に使用するタグ。送信者が生成したシークレットを受信者のステルスアドレスのスキャン鍵の公開鍵に乗算して導出した公開鍵のハッシュ値の先頭1バイト。
    • 暗号化されたブラインドファクター
    • 暗号化されたコインの量
  • rangeproof:コミットしたコインの量がある範囲内にあることを証明する範囲証明のデータ
  • signature:送信者がsender_pubkeyに対応する秘密鍵messageに署名した署名データ

トランザクションは送信者が作成するので、受信者にだけ送信したアウトプットのコインの量とブラインドファクターを伝えるため、それぞれ暗号化した上でmessageにセットしている。暗号鍵は送信者と受信者間のECDHで導出。

↑のデータもgettransaction RPCで返してくれればいいんだけど現状output_idしか返ってこない。一応、ブロックに格納されればgetblock RPCをverbosityを2で呼べば、上記のデータも確認できる。

$ ./litecoin-cli getblock 28a45a7be6451ee0ea3711f98a5ccd873a924527ab57b2770c7f566d381d1edf 2
{
...
  "mweb": {
  ...
    "outputs": [
      {
        "output_id": "fc93c77ff288e5e2a0247662ffaf5470878b99a2805a76b8e4715d1b5ebfbf1c",
        "commit": "09ae2d9b5e4165866b243f0f9904c1cad209fd1555ac73f082ffd54da84f104779",
        "sender_pubkey": "03142b67a14b6a5b25c5ad6dcc27e9460df313e2471fa27423afdba16fb1cd687b",
        "receiver_pubkey": "03de1719eed6d102124709c1ea77f9dd1685a55f65a9528d8f95e9c3266baed22a",
        "range_proof": "45ba23016fe6bd67061a31b075e92368cbcc0866bca5676eafc3e92b2da2d56ef35dc23ef3013667c1fb5247757fbf65b13d2b83b519182b18574cc6939b11d4065cbaa033847a9c5807f1b20cdc6dcae6218c4b0aae437ddb34c64ba45b3878a8bef89605e3bf7616f40197b4e8874d4c3a23cc1e6ac742158dc85c030d832c2cd960f105ceffca0aacfe83d653d34c844592b0cb8cc4ea917b44893e09d340367724ec419de1a5cbd8f5a6b578061496ce2aec1887a1cfa39feb246c4f99b3c8a094501ab5e1d39021415fcb7a215d450218a45404dd5b9432a7b9072bb6a37ca8cbaba7e4d92be693a6b7bd36b2f131840db69a0467aa454b3158af0558cdf690f65dd0b41407cca1a1c6c43e4de0c60383148d9fb115a3194cdab9bfc3abaef46484dd3ff0ce8fde4e23da3c999688c54e71fd7c9a195f535c4e98ce16f887026bc97b4e37bbf65391dbc974d5c376b54b6601e513def1b57f9ed984bb1edba9002e7902990c915c0d0e5eeed1663c8d369965b7ed7352d7389ee0cca3ed62de420439c3598b77ec9093c34913e550bebf63429536b3a8e9571e9b9d8fef5a19ecc784009e0f52c653a81d6ce3bcf9eb1768965ce4724cadc65c6dd198837a57367c7b12913d0bb7c03c28f23101a31cdf41a63087395d413bca5ccfc6c7ac16450d93591ef0bd8ab31315cf46feb42755615c7ba8c3a1572eeab0a78b419e5d5b27dfffdd45cdf252243dad23b3a3341fc2539da2ff2d8aae55799ee6bbcbfba956a4adef7f7a2d45156be7e335357935ace521158a28921bad3192ba5d59b2b7c998399daa1527c7ff71d3291ee87610ab50ee9328efc548d403f573c8ae14e1be5aad1099276c1b2b60c2be22c5e7ec2a86585cce87407027c5dbbeadb76bff361890e9bc92b6d769f09c5c26b8d7a5963696ef8d8d38a6cae2f8a45440a2a2",
        "message": "0102abb3c11c7f9ad6ccdca7cbe4cc77c31ea5c1947fdc3ec4673dd199a0c90fd17f1b1aa7b9a2e319c7a0bfda7fa299099e47879f793cf4b31b45"
      },
...

何故かsignatureは出力されない(ソースコード変更すれば出力は可能)。

アウトプットに受信者ではなく送信者の公開鍵や署名があるのは、LitecoinがMimblewimbleを導入するにあたって非対話的にトランザクションを構築できるようにしているため↓

非対話型のトランザクション構築

Mimblewimbleプロトコルでは、インプットのコミットメントの合計とアウトプットのコミットメントの合計の差分、つまりPedersen commitmentのブラインドファクターの差分値である公開鍵に対して有効なデジタル署名を提供する必要がある。

インプットとアウトプットのブラインドファクターの差分値であるため、それに対してデジタル署名を作成するには、送信者と受信者の協力が必要になる。つまり、トランザクションの作成は対話型になる。

ただ、MWEBではトランザクションを非対話型で構築できるように拡張している。

Mimblewimbleプロトコルトランザクションの構築を対話的に行う必要があるのは、ブラインドファクターがそのコインの所有権を制御する秘密鍵に役割をしているため。送信者がアウトプットのブラインドファクターを知ってしまうと、送信者と受信者両方がコインの所有権を持つことになってしまうのでまずい。そのため、インプットのブラインドファクターは送信者のみが、アウトプットのブラインドファクターは受信者のみが知っているという状況になり、その状態で両者が部分的なSchnorr署名を作成し、それを集約することでデジタル署名を完成させる仕組みになっている。

MWEBでは、この対話型のプロセスを非対話型にするために、コインの所有権の仕組みに手を加えている。

インプットとアウトプットの差分のKernel Excessに対するデジタル署名は、そのままコインのインフレーションが行われていないことの証明に使用するが、コインの所有者であることの証明はこれとは別に行われる。

具体的には、↑でアウトプットにsender_pubkeyreceiver_pubkeyという2つの公開鍵が追加されているが、インプットが参照するアウトプットのreceiver_pubkeyと、アウトプット内のsender_pubkeyの差分であるOwner Offsetの提供を求めるというもの。コインを使用する際のインプットのreceiver_pubkeyは受信者しか知らないため、ブラインドファクターを送信者が知っていたとしても、そのアウトプットのreceiver_pubkeyの所有権の証明はできないため、送信者にブラインドファクターが知られていても、コインが盗まれることはない。

内容が少し古いけど詳細は↓(もともとLIP-0004として提案されていたけど、どうも現在のLIP-0004はまったく別の仕様の提案になってる)

techmedia-think.hatenablog.com