localhost_workspaces_monacharat_tool_parts_tester_index.html.jpg

そろそろモナキャラットの生成&配信が始まります!モナキャラットが何か知らない人はとりあえずこちらをご確認ください。

モナキャラット:ご紹介

モナキャラットではMONACHARATトークンを保有しているアドレスの中から、保有枚数に(ほぼ)比例する当選確率で派遣先の抽選を行います。

しかし抽選というのはなかなか難しいもので、Twitter上の抽選企画はほとんどが詐欺ですし、つい先日も日本の仮想通貨交換所が満を持したIEOの抽選でヘマをやっていましたし、ヘマがなくとも運の悪いユーザというの疑心暗鬼に陥りがちです。つまり何がいけないのかというと、正しく抽選が行われているかどうかを外側から検証・監査できないのが致命的によくない。

モナキャラットではこの問題を解消すべく、ブロックチェーン上のオープンな疑似乱数を抽選(および、詳細は別記事にしますがイラストの生成)に使います。

この記事の記載に沿って計算すれば誰でも同じ派遣先を導き出せるので、モナキャラット運営の抽選にヘマや不正がないかどうかぜひ検証・監査してみてください。

擬似乱数の取得

モナキャラットの派遣先の抽選などに使う擬似乱数には、当該モナキャラットの発行トランザクションを含むブロックのブロックハッシュの値をPBKDF2-SHA512で2048回ストレッチ(ソルトなし, 32バイト出力)した値を使います。

例としてテスト用のモナキャラット A4822736159505387458 の場合

  1. A4822736159505387458の発行トランザクションはブロック2392384に入っている
  2. ブロック2392384のブロックハッシュは 6cde9d0c01dcb4a1871cf063f22616e044801a0f2abb1a10865924178bad4cc6
  3. 6cde9d0c01dcb4a1871cf063f22616e044801a0f2abb1a10865924178bad4cc6 をPBKDF2-SHA512で2048回ストレッチ(ソルトなし, 32バイト出力)するとc9f2efbee2cede7e543927fc3c4ce8f3c191b7e2ef4aea974913a27d9a2493e3

という手順で疑似乱数 c9f2efbee2cede7e543927fc3c4ce8f3c191b7e2ef4aea974913a27d9a2493e3 が取得できるので、これを使います。

モナキャラット毎にこうして取得した擬似乱数はあらすじにも記載されます。

備考: PBKDF2-SHA512を挟む必要性

モナコインのブロックハッシュは、マイニングアルゴリズムLyra2REv2を通す前の値(ブロックのデータを反映した値にnonceを足したやつ、ここでは「元の値」とします)をSHA256dしたものです。つまりモナコインのブロックハッシュの値はビットコインのように直接厳選されたものではないので、ブロックハッシュをそのまま乱数として使っても通常は問題ありません。

ところが計算コストが SHA256d << Lyra2REv2 なので、モナキャラットのように手法まで公開した上でブロックハッシュを直接乱数として使ってしまうと、先に元の値をSHA25dして自分のアドレスにモナキャラットがくる場合だけLyra2REv2するようにすることでマイニング効率をほとんど落とすことなくマイナーが不正できる可能性があります。

PBKDF2-SHA512で2048回ストレッチすれば「自分のアドレスにモナキャラットがくるかどうか」を事前計算するコストをかなりかさ増しでき、マイナーによる不正が難しくなるというわけです。

派遣先アドレスの決定

取得した疑似乱数を使って、以下の手順で派遣先アドレスの抽選を行います。

  1. モナキャラットを発行する直前(日本時間の正午)に get_holders でMONACHARATトークンの保有アドレスのリストを取得しておく
  2. リストをアドレスの辞書順に並べ替えて、モナキャラットの母星(mona1qgfpak2j68dxg7pcf6ldqflm43at7qusnm2vnft)は除く
  3. 擬似乱数HEXの末尾12桁をリストのMONACHARAT総額で割った余りAを求める
  4. リスト順にA+1番目のMONACHARATトークンを保有しているアドレスが派遣先

例えば手順2まで済んだリストが

  • アドレス1 100枚
  • アドレス2 50枚

となっている場合は、次のようになります。

  1. 疑似乱数 c9f2efbee2cede7e543927fc3c4ce8f3c191b7e2ef4aea974913a27d9a2493e3 の末尾12桁は10進数で 178660340700131 なので余りAは 178660340700131 % (100+50) = 131
  2. 132番目のMONACHARATトークンはアドレス2にあるので、派遣先はアドレス2

備考: get_holdersのタイミング

モナキャラット側では発行の直前にAPIを叩いて返ってきた値を使うだけなので、ブロック承認のタイミングによっては後から検証するにはちょっとばかし曖昧なことになります。大抵はモナキャラット発行直前のブロックの状態が反映されるでしょうが、場合によってはもうちょっと前の状態が使われるかも。

ただその1,2ブロックで派遣先が変わることはかなり稀と考えられるのに加えて、いちおうモナキャラット側で取得した最新のリストはこちらで確認できるので、問題はないでしょう。

ちなみに原理的には後からも確認可能とはいえ、過去の特定時点でのget_holdersの結果を取得できるAPIはないので、検証したい場合はあらかじめ正午にget_holdersを叩いておくことをオススメします。

モナキャラット発行(正午)から派遣(午後6時)までは時間がありますが、派遣先は発行トランザクションがブロックに取り込まれた時点で確定しています。計算すれば自分のところにくるかどうか先にわかるので、約5時間58分はじらし期間とお考えください。

備考: DEXやDispenserに乗せてる残高

get_holdersはDEXやDispenser向けに確保された残高も含むリストを返してくれるので、MONACHARATトークンをDEXやDispenserに出品していてもちゃんと抽選に参加できます。

おわり

モナコインのチェーンを使って暗号学的に抽選の公平性を担保する試み。

第三者が検証・監査できるようにするためにわざわざ頑張った設計&実装をやって、こういう面倒な説明書まで書いたので、単発でもいいから誰か試してみてくれると嬉しいです。実装のヘマがあるかもしれないし。あともし設計上の問題があったら教えてください。よろしくー