Ethereumのコントラクトで学ぶ、ポンジースキームの仕組みについて

お久しぶりです。@tanaproです。この記事はドワンゴアドベントカレンダー2日目の記事です。

Ethereumとは

Ethereumというプロジェクトがあります。世界で一番有名なスマートコントラクトを実行できるプラットフォームです。スマートコントラクトを日本語で表すと「自動執行される契約」となるのですが、ここではエンジニア的な説明をしてみます。

オブジェクト指向言語を想像してみてください。ここにあるクラスがあるとします。このクラスには内部変数と外部から実行できるメソッドが定義されており、メソッドを実行するとコードに記述されたとおりの処理が走り、内部の変数が変化します。

このクラスが誰にでも見える形で公開され、誰にでも自由に実行でき、そしてコードに書かれているとおりに処理されることが保証されている。それを実現しているのがスマートコントラクトです。予め決められた契約(コード)がスマートに自動執行されます。

スマートコントラクトはその新しさゆえ、実際に有効活用されている事例は世界を見渡してもほとんど存在しません。これが本当に使えるものなのか、その検証もできていない段階です。しかし、一部の分野ではこのスマートコントラクトが確実に役に立つという見方があります。それがお金を掛けるゼロサムゲームの分野です。運営者の存在なしに賭博が実現できれば、権力者によって運営を停止に追い込まれることもありません。例えばaugurというプロジェクトは未来に起こる出来事を予想してお金を賭けるプラットフォームを目指しています。まだプロダクト自体はローンチされていませんが、Ethereum上に乗るアプリケーションとしては一番期待されているものの一つです。

また、Ethereumには内部で使えるETHという通貨が存在します。ビットコインのように他のアドレス宛に送金する用途の他、コントラクトを実行するための燃料としても必要になるものです。自動執行されるコントラクト、内部で使えるお金・・・だんだん賭け事に使えそうな雰囲気が見えてきました。今回の記事では参加者どうしてお金の奪い合いをするポンジースキームという仕組みをコントラクトにしたものを例に、Ethereumで使うプログラム言語Solidityのコードを見ていきます。実際のコントラクトを見る前に、まずはポンジースキームについて説明します。

ポンジースキームとは

あるところに悪いおじさんがいました。このおじさんは「数ヶ月で資産が2倍になる投資案件」を顧客に販売しています。

まず、あるお客さんから1万円を出資してもらいました。そしてさらに他のお客さんからも2万円を出資してもらいした。ここで、今受け取った2万円をそのまま最初に出資してくれたお客さんに渡します。最初のお客さんは資金が2倍になり大喜びです。

そこから営業を重ね、ある三人組のお客さんから計4万円を出資してもらうことに成功しました。ここで、今受け取った4万円をそのまま2番目に出資してくれたお客さんに渡します。2番目のお客さんは資金が2倍になり大喜びです。

またまた営業を重ね、あるお客さんのグループから計8万円を出資してもらうことに成功しました、・・・・(以降繰り返し)

そしてついに、新規のお客さんが現れなくなったので、おじさんは闇に消えることを決意しました。

初期にお金を入れた人は資金が2倍になっています。そして、新しいお金が入ってくる限り、このポンジースキームは続きます。しかし、ある時点で必ず破綻します。後からお金を入れてくれる人が現れなくなったとき、最後に資金を入れていた顧客は大損をするのです。

今回は"Doubler"と呼ばれるコントラクトを例にEthereumのコードを見ていきたいと思います。

ポンジースキームのコントラクト

https://etherchain.org/account/0xfe9c69945687539fabbf531133838d9cce522a76#code

自分がお金を入れた後にさらにお金を入れてくれるカモが現れたとき、自分の資金が2倍になるコントラクトです。

まずこのコントラクトがEthereumブロックチェーン上に載ると、コンストラクタが呼ばれowner変数に作成者のアドレスがセットされます。作成者のみが実行できるcollectFees()関数にある通り、集められた手数料はこのownerアドレス宛に送金されます。

参加者が現れてこのコントラクト宛に送金が行われるとenter()が実行されます。この関数の中身が上記で説明したポンジースキームの肝の部分です。送金した人のアドレスと送金額を管理するparticipants変数、送金した人のインデックス管理をするidx変数の処理を見ていけば雰囲気でわかってくるかと思います。

while (balance > participants[payoutIdx].amount / 100 * 188){
  uint transactionAmount = participants[payoutIdx].amount / 50 * 95;
  participants[payoutIdx].etherAddress.send(transactionAmount);
  balance -= participants[payoutIdx].amount / 100 * 188;
  payoutIdx += 1;
} 

まだ支払いが行われてなく、かつ、一番早く送金した人の投入金額の2倍の資金がコントラクト内にあれば支払いが行われる様子です。participants[payoutIdx].etherAddress.send(transactionAmount);の部分でETHの送金が行われます。(正確には2倍ではなく手数料が引かれています)

このようにコントラクトが実行されるとコードで記述されたとおりの処理が実行されます。

Ethereumを使うことのメリット

ビットコインを使ってもこのポンジースキームのようなプロダクトを作ることはできます。しかし、それは必ず誰かが管理しているサーバ上のプログラムを使ってでしか実現できません。つまり、管理者を信用しなければ成り立たないのです。管理者が途中で逃げればお金は返ってこないでしょう。Ethereumを使うと特定の誰かを信用せずともこのような仕組みを実現できるのです。

(今回はポンジースキームが法的にどうなのかという問題には一切触れていません。技術的にこういうことが可能だという点を理解して頂きたいのが目的です。)

まとめ

最近のEthereumは脆弱性があったりスパム攻撃を受けたりDapp上の資金が盗まれてハードフォークしたりと混乱状態にあります。安定してアプリケーションを動かせるようになるのにはまだ数年くらいかかるかもしれません。それ以前に、本当にEthereumを使った有用なアプリケーションが登場するのかどうかも分かりません。しかし、今回挙げたポンジースキームのコントラクトを見て、可能性や将来性を多少なりとも感じた方は少なくないのではないでしょうか。

Ethereumの今後に期待するのであれば、内部通貨であるETHを購入すると将来値上がり益を享受できるかもしれません。ナイストレード目指して頑張ってください!

f:id:dsaki:20161130171252p:plain