アイドルとオタクがBitcoinで永久に消えないメッセージを刻む

#概要
原宿を拠点とするアイドルグループの・・・・・・・・・が大阪で◯→●→🌏というイベントを実施しました。
その内容は、アイドルとオタクがBitcoinを使って世界にメッセージを刻むというもの。
刻まれたメッセージは消すことができず、永久に残り続けます。

本記事ではイベントの体験レポートから始めて、いったい何でこんな催しを開いたのか、Bitcoinとは何なのか、そしてなぜ永久にメッセージが残るのかを説明し、最後にそれを実装する方法を紹介します。

・・・・・・・・・については、[前回の記事](http://qiita.com/a-r-i/items/8987a808f60a294e894b#とは)を参照してください。

#イベントのレポート
・・・・・・・・・が東京を飛びだし、大阪に初めての遠征をしました。初日は大学での講義と、ライブ。二日目はライブと、ファンとの交流イベントというスケジュール。
講義とライブについては、あらかじめ詳しい情報が告知されていましたが、最後の交流イベントで何をするのかは、オタクにも、・ちゃんにも伝えられていませんでした。
事前に知らされていたのは、タイトルが◯→●→🌏ということだけ。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">【大阪 交流イベント<br> 「◯→●→🌏」詳細】<br><br>①なにかする🍚<br>②なにかする🏃<br>③なにかする📨<br><br>🕒2/5(日) 15:00～16:30予定<br>🗾心斎橋FanJから徒歩10分圏内<br>(集合場所は当日このアカウントで告知！)<br>💴2000円、予約不要<br>(前日夜ライブの半券持参で無料！) <a href="https://t.co/sZszL3PgmL">pic.twitter.com/sZszL3PgmL</a></p>&mdash; ・・・・・・・・・運営 (@tokyo_tsukurou) <a href="https://twitter.com/tokyo_tsukurou/status/824555480596967425">2017年1月26日</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">大阪遠征、イベントすべて出揃いました💗<br><br>・①③④は無料イベントです(④は条件付き)。<br>・①では東京でもやったことのないような「コンセプト・ライブ」をやる予定。<br>・②③では「文学少女」を初披露。<br>・④は・ちゃん達も何をやるか分からないよ…😨❗️<br><br>ワクワクドキドキ…応援来てね❗️ <a href="https://t.co/5aVXW0Ov7t">pic.twitter.com/5aVXW0Ov7t</a></p>&mdash; ・・・・・・・・・ (@dotstokyo) <a href="https://twitter.com/dotstokyo/status/826308832318017536">January 31, 2017</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

2017年2月5日、お昼の三時。◯→●→🌏は、道頓堀にある某たこ焼き屋さんにて行われました。イベントは前後半に別れ、前半では・ちゃんとたこ焼きを食べます。

![たこ焼きを食べる・ちゃんの写真](http://i.imgur.com/BXD5k1w.jpg "たこ焼きを食べる・ちゃんの写真")
![たこ焼きを食べる・ちゃんの写真](http://i.imgur.com/IQdVGOz.jpg "たこ焼きを食べる・ちゃんの写真")
![たこ焼きを食べる・ちゃんの写真](http://i.imgur.com/TpnC8Xe.jpg "たこ焼きを食べる・ちゃんの写真")

たらふく食べたところで、前半が終わり後半に。
まず、下の資料が配られました。ご覧のとおり簡単な説明のみで、メッセージが世界に公開されるとは書かれていますが、「永久に刻まれる・消すことができない」というBitcoinのキモは伝えられていません。
![説明資料のスクショ](http://i.imgur.com/bfZsDvp.png)

これは**自分が何をしているの分からない内に世界にメッセージが刻まれてしまっている**という体験をつくりたかったためで、ユーザーが向き合うインターフェイスも、Bitcoinを意識させない、そっけないフォームにしました。

![index.html](http://i.imgur.com/BfooEUN.png "index.html")

送信ボタン(●→🌏)をクリックすると、戻るリンクだけのページに遷移し、フォームの内容が刻まれます。
![broadcast.html](http://i.imgur.com/ngRYN6K.png "broadcast.html")

資料が配られるやいなや、疑心暗鬼の声が会場を包みます。「Bitcoinって何？」「なんか怖い！」「Bitcoinって昔ニュースでやってたよね」

ここで、プロデューサーから追加の説明。「書く内容は自由ですが、一つだけルールを決めたいと思います」
「メッセージに・を含めてください」

ざわめきの中ノートパソコンが回され、いよいよ作業がはじまります。手順としてはオタクが6人いる・ちゃんの中から一人を選んで、二人で一緒に内容を考え、刻む。

・ちゃんの帰りのフライト時刻が近づいてるということもあり、相談時間は3分ほど。くわえてTwitterどころじゃない強い文字数制限。さらに・を含めるルール。そんな縛りの下で刻まれたメッセージが以下となりなす。

![刻まれたメッセージの一覧](http://i.imgur.com/GG45Y2i.png)
https://chainflyer.bitflyer.jp/Address/18975CmAnNGXLnSw8XfPnN1ENV5wkSnT72

これにて、その場はお開きとなりました。

#いったい、このイベントは何だったのか

##Bitcoinとは何か
本題に入る前に、まずはBitcoinについて説明します。

Bitcoin。それは、中心のないデジタル通貨です。これまでの電子マネーやポイント、アプリ内通貨は発行会社のコンピューターにのみ存在しました。もしも、その会社がデータを消してしまえば、あなたのお金は失われてしまいます。

Bitcoinでは、そのような絶対的な力を持った中央機関が存在しません。特定の会社や組織が運営しているのではなく、誰でも参加でき、誰にもコントロールができないオープンソース・プロジェクトです。
誰もあなたのお金を取り上げることができず、誰も取引を取り消せません。

Bitcoinにはメッセージを上乗せする機能があり、今回はそれを利用しました。そのメッセージは誰も書き換えられず、誰も消すことができません。

##このイベントの真の意味
それでは、なぜBitcoinを用いたのか。このイベントの目的は何だったのか。イベントから六日後の2月11日、・・・・・・・・・運営がその意図を明らかにしました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">遅ればせながら大阪交流イベント「◯→●→🌏」のネタばらしです！◯→●は◯(たこやき)を・ちゃんに食べさせるイベント、●→🌏は・ちゃんとの思い出を「地球」に刻むイベントでした。後者はとても長くなるので(！)画像にして添付しました。ご覧ください☺<a href="https://twitter.com/hashtag/%E3%83%89%E3%83%83%E3%83%84%E5%A4%A7%E9%98%AA?src=hash">#ドッツ大阪</a> <a href="https://twitter.com/hashtag/%E3%83%89%E3%83%83%E3%83%84%E3%83%89%E3%83%83%E3%83%84%E3%83%89%E3%83%83%E3%83%84?src=hash">#ドッツドッツドッツ</a> <a href="https://t.co/9YlE86itwF">pic.twitter.com/9YlE86itwF</a></p>&mdash; ・・・・・・・・・運営 (@tokyo_tsukurou) <a href="https://twitter.com/tokyo_tsukurou/status/830401238034296832">2017年2月11日</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

![このイベントの真の意味](http://i.imgur.com/GXE6muN.jpg)
![このイベントの真の意味](http://i.imgur.com/0Rogqkg.jpg)

##なぜ永久にメッセージが残るのか
ここまで当たり前の前提として受け入れてきましたが、そもそも、なぜ永久にメッセージが残るのでしょうか。
さしあたり、二つの根拠を示します。

　一つ目は、地理的な理由です。ビットコインの取引履歴は全世界に散らばった約6000台のコンピューターに発信され、保管されます(下図参照)。たとえ政府の取り締まりやハッキング、自然災害に見舞われても、すべての情報が消えることはありません。

　二つ目は、それらのコンピューターには取引履歴をずっと保ち続けるインセンティブがあるからです。ビットコインは10分に1度、新規のコインを一人だけに発行します。[^1]このコインを手に入れる競争に加わるには、過去すべての取引履歴を持っていなければなりません。ビットコインの価値が保たれている限りは、誰かがレースに参加する(=取引履歴が残る)ことが期待できるのです。

![Bitcoinのノード](http://i.imgur.com/OKq22WD.png)
*Bitcoinの取引履歴を保管しているコンピューターの数と分布。2017年2月8日、https://bitnodes.21.co より*

#実装
Bitcoinでメッセージを刻むにはいくつかの方法[^2][^3][^4]がありますが、今回は[Bitcore](https://bitcore.io)というJavaScriptライブラリを使いました。

Bitcoreを使ったメッセージの記録については、こちらの記事に依っています。
[ビットコインのブロックチェーンにデータを記録する（OP_RETURNの利用）](http://noumenon-th.net/webstrategy/2015/04/30/bitcoin/)

文字数カウントの部分は、こちらのコードを借用。Bitcoinに添付できるメッセージは80byteまでで、半角なら40文字、全角なら26文字、絵文字なら20文字。今回は全角を基準として半角52、全角26、絵文字13字にフォームの文字数を制限しました。
[jQueryで入力フォームに文字カウント（カウントダウン）を設置する方法](http://black-flag.net/jquery/20120229-3696.html)

【注意】二重投稿対策をしていないため、broadcast.htmlをリロードすると連投する仕様になっています。不特定多数に公開する場合は、必ず対策をしてください。

```html:index.hmtl
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  <script type="text/javascript">

  //制限文字数の設定
  var stopCount = 26;

  function strLength(strSrc){
    len = 0;
    strSrc = escape(strSrc);
    for(i = 0; i < strSrc.length; i++, len++){
      if(strSrc.charAt(i) == "%"){
        if(strSrc.charAt(++i) == "u"){
          i += 3;
          len++;
        }
        i++;
      }
    }
    return len;
  }

//文字数カウント
  function showLength( str,name ) {
    var strCount = Math.ceil(strLength(str).toString() / 2);
    if(strCount > stopCount){
      document.getElementById('submit').style.display = "none"; //全角換算で26文字を超えたら送信ボタンを消す。
      document.getElementById(name + "Inner").innerHTML = '<em style="color:#ff0000;">' + strCount + ' / 26 Over!</em>';
    }else if(strCount == stopCount){
      document.getElementById('submit').style.display = "";
      document.getElementById(name + "Inner").innerHTML = '<em style="color:#ff0000;">' + strCount + ' / 26</em>';
    }else{
      document.getElementById('submit').style.display = "";
      document.getElementById(name + "Inner").innerHTML = strCount + " / 26";
    }
  }
  </script>
</head>
<body>
  <form id="textForm" name="textForm" action="broadcast.html"> //フォームを送信したらbroadcast.htmlに遷移
    <input name="text" type="text" id="text" size="70" value="" onkeyup="showLength(value,id);"/>
    <span id="textInner">0 / 26</span>
    <input type="submit" id="submit" value="●→🌏" onclick="funcBtn();"> //submitボタンを押すと、funcBtnメソッドを実行
  </form>

  <script>
  function funcBtn() {
    localStorage.text = document.textForm.text.value; //フォームのメッセージをローカルストレージに保存
  }
  </script>
</body>
</html>

```

```html:broadcast.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<script src="bower_components/bitcore/bitcore-lib.min.js"></script>
<script src="bower_components/bitcore-explorers/bitcore-explorers.min.js"></script>

</head>
<body>
  <script>
  var bitcore = require('bitcore-lib');
  var explorers = require('bitcore-explorers');
  var insight = new explorers.Insight();

  var a_address = ""; //Bitcoinアドレス
  var privateKey = ""; //秘密鍵

  getUTXO(a_address, function(utxos){

        utxos.forEach(function(utxo){console.log(utxo.toJSON());});
        console.log(localStorage.text);

        //トランザクション生成
        var transaction = new bitcore.Transaction().fee(100000) //送金手数料。今回は0.001BTC=117円
          .from(utxos)
          .addData(localStorage.text) //ローカルストレージに保存したメッセージを添付
          .change("") //お釣り用アドレス
          .sign(privateKey)

        console.log("transaction",transaction.toJSON());

        broadcast(transaction, function(id){
          console.log(id);
  　　});

  });

  function getUTXO(address, done)
  {
    //utxosの取得
    insight.getUnspentUtxos(address, function(err, utxos) {
      if (err) {
        console.log(err);
      }
      done(utxos);
    });
  }

  function broadcast(tx, done)
  {
    //ブロードキャスト
    insight.broadcast(tx, function(err, id) {
      if (err) {
        console.log(err);
      }
       done(id);
    });
  }
  </script>
</body>
  <a href="index.html">戻る</a>
</html>
```

#まとめ
メディア環境の変化に応じてアイドルも変化してきた歴史がある。
・・・・・・・・・運営はインタビュー[^5]でそう語りました。
Bitcoinも一つの表現媒体と言えます。このコインが世のありかたを一変させるとき、アイドルもまた、それに適応するように変わっていくのかもしれません。
彼女への好意が、いつのまにか世界への好意にすり替わっているような、薄い膜のように世界を覆うアイドルへと。

#追記
2018年6月9日、仙台市天文台にて、◯→●→🌏と同内容の企画🌕→⚫→🌏を実施。40人がメッセージを刻む。

<blockquote class="twitter-tweet" data-cards="hidden" data-lang="ja"><p lang="ja" dir="ltr">🆕【仙台遠征】<br>【天文台イベント！】<br>6/9 1845＠仙台市天文台<br>第3回定期公演番外編<br>「Tokyo in Micro and Macro」<br>第1部「Macro」<br><br>①天体観測&amp;チェキ会<br>②Bitcoinでメッセージを刻む「🌕→●→🌏」<br>③6月公開予定新アプリβ版体験会<br><br>入場料込で予約2000円（〜6/9 0930まで）<a href="https://t.co/TP1KScWhd0">https://t.co/TP1KScWhd0</a> <a href="https://t.co/z20l7yPZED">pic.twitter.com/z20l7yPZED</a></p>&mdash; ・・・・・・・・・運営 (@tokyo_tsukurou) <a href="https://twitter.com/tokyo_tsukurou/status/1003478331663134720?ref_src=twsrc%5Etfw">2018年6月4日</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

刻まれたメッセージはこちらから確認できます。
https://chainflyer.bitflyer.jp/Address/1MLhbtWXrH8Y7FrHs3FnXnaCvbJw2USwQe

![Dfd1FkBU0AA2gwp.jpg-large.jpeg](https://qiita-image-store.s3.amazonaws.com/0/133133/cb455e6e-2e9a-37d1-583f-e5b3136989c1.jpeg)

#注
[^1]: 正確には新規コイン+送金手数料。新規コインが与えられるのは2140年(予想)まで。以後は送金手数料のみ。
[^2]: [OP_RETURN でUTF-8のメッセージをブロックチェーンに記録する](http://yamalabo.joho.fuk.kindai.ac.jp/wordpress/2016/09/07/op_return-でutf-8のメッセージをブロックチェーンに記録す/)
[^3]: [Bitcoinのブロックチェーンに任意の80byteデータを刻みこむ](http://qiita.com/yyu/items/8650563126380d813e8e)
[^4]: [coinb.inでメッセージをBitcoinブロックチェーンに書き込む](http://qiita.com/a-r-i/items/6c61880a0f4668c885a6)
[^5]: [“ポスト・ポケモンGO!”時代のアイドル・グループ!? 「・・・・・・・・・」デビュー直前初インタヴュー](http://ototoy.jp/feature/index56.php/2016082303/3)