導入:「CSW」&チューリップ信託
2016年5月2日、去年の末から何かと話題だったオーストラリア人(CSW)が、いよいよ本当に自分が中本哲史である証拠を示した、とか近日中に示すらしい、という話が報道されました。つまりそれは、Bitcoinブロックチェーンの奥底に大陸氷河のように凍結されていた中本哲史資産を移動させるという意味だと思われたため、いろいろな意味で世界中に大きな衝撃が走りました。
しかしその数日後には突然、あれはやっぱナシね、ごめん、という話になり、やっぱりあいつはニセモノだったんだ、とみんなが一安心しましたが、しかし VaughnPerling を含む斯界の大物数名が、なぜか依然としてCSW=中本哲史説を強く支持し続けており、さらにはTulip Trading Trustなる信託財産および信託契約がどうとかいう、現時点では証拠もない胡散臭すぎる話までもが飛び出してきて、もうこの件については考えてもムダで経過を見るしかないかな、というのが、この記事を書いている時点の状況だと思います。
私はもともと、Bitcoinを発明したほどの人類史上に残る大天才が、あんなその辺のオッサンみたいな顔をしているわけはないだろ? こんなのに騙されるヤツは、Ethereum 創始者の Buterin Vitalik 先生のお顔などをよく見て、人を見る目を養っとけよ、という意見でした。ただ、故 Dave Kleiman と CSW が二人合わせて中本哲史だというなら、それはそれであり得るのかも……
私の希望としては、中本哲史はあくまでも「市民による通貨選択の自由を実現するために敢然と立ち上がった、孤高の天才プログラマーにして革命の闘士」であってもらいたいですが。
需給懸念によるBitcoin相場の乱高下
まあCSWやTulip Trustの話は置いとくとしても、本物の中本哲史のものとされる鍵ペア(≒アドレス)には今でも、これまでの発行済み全BTCの5%程度に当たる莫大なUTXOが残存している(≒残高がある)という事実は、Bitcoinのブロックチェーンを調べれば(原理的には)誰でもわかることであり、またそのことは広く知られています。そのため、万一オーストラリアのあいつが本物だった場合、今回の騒動をきっかけにして、この数百億円相当のBTCが市場で売りに出されるようなことにでもなったらたまらん、というわけで、5月2日にはBTCの相場が大きく下落しました。(今にして思えば、4月末の急激な調整も、例の報道の内容を事前に知ったインサイダーの影響によるものだったのかも。)そして、その後速やかに、どうやらあいつはニセモノ臭いという見解が支持を集めるにつれ、需給懸念は解消されてBTCは値を戻すことになりました。
ゴールデンウィークも相場に張り付いてカチカチカチッと忙しくデイトレーディングをやっていらっしゃった勤勉な皆さんは、きっと底値付近でしなくても良い損切りをなさって、4月後半の含み益を綺麗さっぱり吐き出されたのではないでしょうか。どうもお疲れさまです。今後もその調子でがんばってくださいね。
「Proof of Burning」や「出金凍結」という機能
そういうことをやりたくなる場合も(稀にだが)ある
さて、今回の騒動で改めて顕在化したのは、「莫大なBTCを個人として所有し、いつ恣意的に処分するかもわからない中本哲史」などという存在は、BTC市場にとっては迷惑な需給懸念の発生源以外のなにものでもなく、本音を言うと存在していてもらいたくないんだ、ということではないでしょうか。
まったくひどい話ではありますが、仮に中本哲史とはすでに3年前に逝去したDave Kleiman氏のことであり、彼が研究に使っていたコンピュータを含む家財道具一切はすべて焼けて灰になったか何かして消えてしまった、ということが明らかになってくれれば、BTC市場にとっては一安心、というわけです。
こういう構図は、本物の中本哲史氏が生存していたとしたら、彼にとってはかなり困ったことです。ヘタに名乗り出たりしたら、その行為自体によって多くの人に迷惑をかけることになるし、さらには自分の身に物理的な危害でも加えられかねない。実際、この記事の冒頭でふれたVaughnPerlingは、非常にわかりにくく韜晦した言い方ではありますが、あのオーストラリア人(CSW)はやむを得ない理由から、本物でありながらわざとニセモノだと思われるために信用を失う振る舞いをしてみせたのだ、と主張しているように読めます。
このように、自分の存在自体がBTC市場にとっての台風の目のようなものになってしまうことを避けようとするならば、中本哲史氏が自分の所有するBTCの大部分について、自らの意思でその流動性をなくすことができれば良いわけです。
たとえば、仮に中本哲史氏が時価400億円分のBTCを持っているとして(現実にはもっと多額だったはず)、そのうち360億円分のBTCについては、永久に誰も使えないようにしてしまう(札束を燃やしてしまうようなもの)。そして、残り40億円分のうち、20億円分のBTCについては、今後10年間は絶対に使えないようにして、残りの20億円分のみ、いつでも使えるようにしておく。とまあ、こんな感じで、BTCの「廃棄証明(Proof of Burning)」や「一定期間の出金凍結」を、自分の意思で実現し、それを世界に対して証明することができれば、中本哲史氏は、BTC市場に迷惑をかけることなく、自分のBTC資産のうちの一部について流動性を実現することができるわけです。
もしこういうことができたなら、360億円分については、永久に誰も使えなくなったわけだから、通貨の発行自体が取り消されたに等しく(株式で言えば自社株買い&消却)、20億円分については、今後10年間は市場に出回ることがないわけだから、当面の売り圧力にはならないことを確信できる、というわけで、BTC市場も納得することでしょう。
さて、仮に本物の中本哲史氏がこういうことをやりたいとしたら、それをBitcoinやEthereumで実現できるのか? できるのならば、やり方はどうするのか? そのやり方はイケてるのか? というのが、この記事のテーマです。
ダメなやり方
まず、暗号技術を使わない、素朴なやり方ではこれを実現することはできない、ということを示します。
たとえば俺が中本哲史だったとして、まず何かのアドレスに宛てて廃棄したい360億円分を移動したあと、そのトランザクション出力を消費するための秘密鍵を捨てて忘れてしまえばいいじゃんか、というようなことを思いつくかもしれませんが、これはまあ、全然ダメです。
「秘密鍵を忘れた以上、自分はそのトランザクション出力を消費することはできない。そして、事実としてそれが消費されていないことは、Bitcoinのブロックチェーンを調べれば、いつでも誰でも確認できる」と言いたいのでしょうが、そういう考えは、「当事者にとっての実体的真実の存否」と「主張内容の第三者への証明」との区別を理解していないことに由来する初歩的な誤謬です。
あなたが消費に必要な秘密鍵を失ってしまい、それを消費できない、ということは、あなた自身にとっては何よりも確実な真実なのでしょうが、しかしあなたはそのことを、第三者に証明することはできないのです。「あなたが嘘をついていて、秘密鍵のメモを残している可能性」、「あなた自身も覚えていない秘密鍵の記録がどこかに残存していて、あなたの死後に遺族がそれを利用する可能性」等々のあらゆる可能性が存在しないことを、あなたが世界に対して証明することは、端的に不可能です。
「いや、だから、UTXOが現実に消費されていないということを、(Bitcoinのブロックチェーンを調べれば)いつでも誰でも確認できるじゃないか!」と言いたいでしょうか? しかし、現実に出金されたらそれが即座にバレる、ということは、BTC市場にとってあなたを信頼すべき根拠にはまったくならないことに気づいてください。
市場としては、あなたが嘘をついて秘密鍵を隠し持っているんじゃないかと疑っているわけです。仮にあなたが隠し持った秘密鍵を利用して資金を引き出したら、確かにそれはバレます。でも、バレたからといって、あなたの引き出した資金が消えてなくなるわけではないのですから、あなたにとって、それがバレるということは何のデメリットにもならず、だから、あなたがその資金を引き出さないだろう、と市場が信じる理由は何もないのです。(あなたがそれによって刑事罰を受けるとか、賠償金の支払義務を負うということなら、また話は違ってきますが。)
Bitcoinでの自己資金凍結の実現方法
Bitcoinを使った廃棄証明(Proof of Burning)
まず、Bitcoinシステム上で自分の意思により360億円分のBTCを永久に誰も使えなくして、それを世界に対して証明することができるのか? と言えば、これはできます。中本哲史さん良かったですね、札束は燃やせますよ。
どうやるのかと言うと、任意のアドレスを宛先として360億円相当のBTCを送金するトランザクションを作り、そのTX_OUTのscriptPubKeyの内容を
scriptPubKey: OP_RETURN
こうしておけば良いのです。これで、どんな署名もこのトランザクション出力を入力として消費することはできなくなりますから、現在のBitcoinノードの実装では、このようなトランザクションはUTXOデータベースに登録すらされません。
普通にBitcoinを決済(送金)の手段として使っている限りは、
scriptPubKey: OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
scriptSig: <sig> <pubKey>
以外のパターンのスクリプトを使うことはあまりなく、チューリング完全でもないくせに、独自のスタックマシンのモデルと多数のop codeの把握を要求してくるBitcoinのスクリプト機能は、かの悪名高いトランザクション展性(トランザクション変形性)の元凶でもあり、Bitcoinの設計における失敗の中でもまず最強の横綱級だ、というのが衆目の一致するところなわけですが、ともかく、この中途半端に高機能なスクリプト機能のおかげで、貨幣の廃棄証明(Proof of Burning)はいちおう暗号学的に実現できるようになっているわけです。
ただしBitcoinのモデル上、この廃棄証明はアドレス単位ではなく、トランザクション出力単位になってしまうということに注意してください。つまり、このアドレスに送金されたBTCは永久に使えなくなる、というようなことはできず、このトランザクションでこの宛先に送ったBTCは永久に使えない、ということができるに過ぎません。
普通に商売をやっていると誰しも、「カネに色は付いていないから」というようなことを、人に言われたり、自分が言ってみたり、言いたくなったりすることはあるものですが、**Bitcoinのコアで扱われるのはあくまでも「取引の記録」であって、「残高」のような抽象化された量ではない**ので、常にその取引の起源に関するしがらみを引きずることになっていて、「カネに色は付いていない」というような常識は通用しないのです。「この1万円札には落書きがしてある」とか、「この十円玉にはギザギザが付いている」とか、そういう世界。
こういうのは面白いといえば面白いのですが、正直、今となってはBitcoinって面倒くせえヤツだなあ、という感を拭えない面があります。
Bitcoinを使った時限凍結
Bitcoinシステム上で20億円分のBTCを今後10年間だけ利用できないようにして、それを世界に対して証明することができるか? といえば、これは端的にできません。中本哲史さん残念でした。
なぜできないか、といえば、中途半端に高機能なBitcoinのスクリプト機能には、IFとELSEによる条件分岐の制御構造はあっても、肝心の現在時刻を取得するためのop codeがないからです。つまり、Bitcoinの機能不足のためこのシナリオは実現できないのです。以上、終了。
Ethereumでの自己資金凍結の実現方法
Ethereumを使った廃棄証明(Proof of Burning)
Ethereumシステム上で自分の意思により360億円分のETHを永久に誰も使えなくして、それを世界に対して証明することができるのか? と言えば、これはできます。Ethereumでも、札束は燃やせる。
具体的にどうやるかといえば、送金(出金)機能のないコントラクトを作成して、そのコントラクトのアドレスに好きなだけETHを送金すれば良い、のだと思います。
Ethereum VMのバイトコードでETHを送信するには、
0xf1 CALL op code
を利用しますから、このバイトコードを含まないコントラクトは、そのアドレスからETHを出金することができないはずです。ゆえに、そのコントラクトのアドレスに送金されたETHは決して引き出されることはなく、永久に使えない、ということになるでしょう。
このやり方は、Bitcoinの「入力として利用できないトランザクション出力」よりもわかりやすいモデルに基いていると言うことができます。「この口座は /dev/null
のようなもので、そこに送金した資金は使えなくなるんだ」というのはそれ自体わかりやすい話ですし、凍結された資金の金額を確認する方法もBitcoinよりも容易です。
このようなわかりやすいモデルによる管理が実現できるのは、EthereumがBitcoinと異なって、アドレスごとの「残高」を、量として管理しているからにほかなりません。Ethereumでは、「カネに色は付いていない」のです。
Ethereumを使った時限凍結
それでは、Ethereumシステム上で20億円分のETHを今後10年間だけ利用できないようにして、それを世界に対して証明することができるか? といえば、できます。
Bitcoinのスクリプティング機能と違って、Ethereum VMのバイトコードには、現在のブロックのタイムスタンプを取得する
0x42 TIMESTAMP op code
というのがありますから、これと任意の日時との大小比較
0x11 GT op code
を行い、その結果を見て
0x57 JUMPI opcode
で条件分岐すれば良いわけです。
もちろん、「現在のブロックのタイムスタンプ」というのは、現在時刻を取得するための手段として決して精度の高いものではなく、リアルタイムに実世界とからむようなシステムを構築しようとしたらまったく実用的ではありませんが、しかし今回のように、資産を何年間凍結する、というような用途のためには十分実用に耐えるでしょう。
このようにEthereum VMには、Bitcoinのスクリプティング機能には存在しなかった「現在時刻の取得」相当の機能が用意されていたので助かったわけですが、このことは決して偶然ではありません。
もともとEthereumの基本的な設計コンセプトとして、チューリング完全なプログラム実行環境(Ethereum VM)から、ブロックチェーンの情報を読めるようにする、ということがあって、その結果として、ブロックやチェーンに関する情報が網羅的にEthereum VMから参照できるように op code が定義されているのです。(例えば、「現在のブロックのハッシュ値」を参照することによって擬似乱数を取得できるので、ギャンブルのプログラムもスマートコントラクトとして作れる、とかいう面白いんだか何だかよくわからない話も、かなり初期からあります。)
そういうわけで、この 0x42 TIMESTAMP op code
も、Ethereumの本質的な設計方針からの直接的な帰結として実装されているわけなので、これはまあ、コンセプトの勝利なわけだ。
もっと良いやり方はあったはず
ここまでの話の流れからは、資金の凍結を実行しそれを世界に対して証明しようとする場合、Ethereumの方がBitcoinよりも機能的に優れている、という結論になるでしょう。この結論が間違っているわけではありませんが、しかし本当のところ、今になって考えてみれば、Ethereumよりももっと良いやり方はあったはずなのです。
汎用機能は扱いにくい
そもそも、Bitcoinのスクリプティング機能にしてもEthereumのコントラクトにしても、単純な出金凍結や時限凍結を実現するための手段としては、あまりにも大げさであって、「牛刀をもって鶏を割く」というような印象を受けないでしょうか。
これは、いわゆるMultisig(複数人の署名がそろって初めて資金移動を可能にする、というポリシー)をEthereumで実現するための実装方法についても、まったく同じことが言えます。スクリプティング機能やコントラクト機能が高度に汎用的なのは良いのですが、利用頻度が圧倒的に高いごく単純なパターンについても、難解な汎用機能による擬似プログラミングが必須になる、というのは良いソフトウェアの設計ではないと言いたくなります。
Bitcoinの(従来型のアドレスを使う)場合、「1個の公開鍵に対応するアドレスに対して、そのアドレスの署名によって消費できるBTCを送金する」というだけの、最も単純でよくあるタイプのトランザクションすら、スクリプティングによって実現しなければならず、そのスクリプティング部分がトランザクション展性(トランザクション変形性)の原因になっていた、といういうのだからひどかった。(segregated witnessの導入に伴って、この問題は解消されますが。)
おまけに、スクリプティングのop codeは機能が十分ではなく、時限凍結すら実現できないというのだから、もう踏んだり蹴ったりと言って良いでしょう。
これに比べればEthereumは、最も単純な1個の公開鍵に対する送金トランザクションはもともとコントラクトなしで実現することができ、より複雑なケースについては、かなり豊富な機能を備え、しかもチューリング完全なEthereum VMでコントラクトを動かせば良い、というわけなのだから、Bitcoinに比べればずいぶん進歩している。
しかし、チューリング完全である、ということには当然ながら暗黒面もあり、提示された任意のコントラクトが、意図された動作をするかどうかを証明することは、一般的には不可能である、と言わざるを得ません。これは、「単純な資金凍結やMultisig程度のことまで、汎用のコントラクトで実現させるのが妥当なのか?」という先ほどの素朴な疑問にも直結します。
「出金条件」のフィンガープリントとしての「アドレス」
「出金凍結」や「Multisig」程度の単純な出金制御をすっきりと実現するための最も妥当な方法は、Bitcoinの比較的新しい機能であるMultisigアドレスのようなものだと思われます。
すなわち、Bitcoinのアドレス(従来型)やEthereumのアドレスのように、単純に1個の公開鍵のダイジェスト値をアドレスにするのではなく、何らかの構造を持った「出金条件」オブジェクトを、決まったやり方でシリアライズしたバイト列のダイジェスト値を「アドレス」にしておけば良いのです。
こうしておけば、そのアドレスから出金しようとするトランザクションのwitness部分において、そのアドレスの生成元である「出金条件」オブジェクトとそれに対応する署名を合わせて提示することで、正しい署名者による正真な出金許可があることを証明することができます。
そのような「出金条件」のデータ構造としては、
- 誰の署名によって出金を許可するのかを表す「権限」要素
- いつからいつまで出金を許可するのかを表す「期間」要素
- どの宛先への出金を許可するのかを表す「宛先」要素
ぐらいを含めておけば、「出金条件」の定義時も検証時も面倒なプログラミング作業を必要とすることなく、自己資金の凍結を含む多くの有用なシナリオに対応できるようになるでしょう。アドレスとは、「誰の許可によって、いつからいつまで、どの宛先に対して出金できるのか?」という条件のフィンガープリントに他ならない、というわけです。
具体的なシナリオの例としては、
- 「9人の理事の過半数」および「3人の監事の過半数」の両方の許可が得られたら、このアドレスから出金できるようにしたい。→「権限」要素によって実現可能。
- 受益者が30歳になったら初めて、受益者の署名によってこのアドレスから出金できるようにしたい。→「期間」要素によって実現可能。
- 大学または下宿先に宛てた支払いのみが可能な受益者のアドレスを作って、そこに仕送りしたい。→「宛先」要素によって実現可能。
こんな感じですかね。
「出金条件」という考え方自体が、規律に反する恣意的な出金を抑止しようという方向のものなので、子を思う親みたいなシナリオとか、法人内部の不正防止みたいなシナリオが自然と思いつきます。
まとめ
何か実現したいシナリオがあった場合、それを汎用的なスクリプティング機能で実現するのか、あるいは開発者があらかじめ想定したパターンに沿ったデータ構造(フラグや区分値の組み合わせ)で実現するのかは、常に悩みの種です。
汎用的なスクリプティング機能には、単一の機能で多くのシナリオをカバーできるというメリットがありますが、しかしほとんどのユーザーはそんなものを学びたくないし、デバッグやテストのツールが揃っていない言語でプログラムを書くのは、高い力量を持つプログラマーでも難しい。だから、スクリプティング機能は、特に複雑なシナリオをカバーするためのセーフティネットと考えて、一般的なシナリオについては、それを使わなくて済むような機能を搭載すべきである、というのは、まあつまらない一般論です。
暗号通貨について言えば、たとえば「Tulip Trust の信託契約それ自体をブロックチェーン上で実現する」というような野心的なことをやりたいのならば、Ethereum VMをターゲット環境としたスマートコントラクトをプログラミングしなければいけないことも、やむを得ないでしょう。
しかし、単純な「権限者」と「期間」と「宛先」との組み合わせによって出金条件を制御できるような機能は、スマートコントラクトの実装をするまでもなく簡単に実現できれば、その有用性は大きいだろうと思われます。その具体的な実装手段として、「出金条件オブジェクト」のダイジェスト値を暗号通貨のアドレスとして、トランザクションのwitness部においてその種明かしをする、というやり方は、かなり洗練されたうまいやり方だと思います。