Help us understand the problem. What is going on with this article?

LINE Beacon+Bitcoinで君と僕がそばに居たことが永久に記録されるLINE BOTを作った

More than 3 years have passed since last update.

概要

『都市の幽霊』をコンセプトにしたアイドルグループの・・・・・・・・・と共同で、LINE BeaconとBitcoinを使った「君と僕がそばに居たことが永久に記録される」LINE BOT、ѺをLINE BOT AWARDに出品しました。

Ѻ紹介動画

LINE@IDの@hxf7252xで検索するか、または以下のURLやQRコードから友達登録ができます。
注:Developer Trialプランなので、先着50人しか友達になれません(2017.02.28現在)。
https://line.me/R/ti/p/%40hxf7252x
broad_on_qr_code

2月25日と26日、・・・・・・・・・のライブと物販でѺをお披露目しました。今後も定期公演などで常用していくので、友達登録の上で・・・・・・・・・のイベントに行くと「アイドルのそばに居たことが永久に記録される」体験ができます。

Ѻ?

<君>と<僕>という二つの点が、LINEという線を介し、面となって地球を包む。このBOTの名前「Ѻ」はそんな様を表しています。

broad_on

仕組み

1.LINE Beaconを<君>が持つ。Ѻを友達登録したスマホを<僕>が持つ。
2.二人がそばに近づくと、メッセージ「<君の名>と<僕の名>がそばにいる」を載せたBitcoinが瞬時に送金される。そのメッセージは、変更・消去不可能な形で、永久に記録される。
3.毎日22時に、その日のすれ違い情報がLINEで通知される。

LINE Beacon

LINE Beaconとは、周囲10mに信号を発信する機械です。その信号をスマホが受信することで、「LINE Beaconとスマホが10m以内にある」ことが分かります。

詳しくは、過去の記事をご覧ください。

LINE Beaconを持ったアイドルを探し回るイベント

Bitcoin

Bitcoinとは、お金のやり取りが永久に記録されるデジタル通貨です。具体的には、「AがBにいくら送った」という送金情報が、世界中に散らばった約6000のコンピューターに拡散されます。

それらコンピューターの所有者は、自らの儲けのために送金情報を保持し続けます。
なぜ儲かるのか。それは、新規に発行されるBitcoinを手に入れるには、過去の送金情報を持っていなければならないからです。

Bitcoinは、送金する際にメッセージを上乗せすることができます。そのメッセージは、誰にも書き換えることができず、誰にも消すことができません。

詳しくは、過去の記事をご覧ください。

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

この二つを組み合わせることで、「君と僕がそばに居たことが永久に記録される」機能が実現しました。絶対的に二人の交流を記録し、誰にも改変・削除を許さず、永遠に覚えていてくれる、「世界そのものへの刻み込み」です。

これは2017年2月26日のライブで、実際に刻まれた記録です。
https://chainflyer.bitflyer.jp/Transaction/265ddcb1dc6d28cf91ef992b2137b81ab3cd1c6b45e328b0845ba7a41b335f0e
transaction

時差通知

瞬時に送金されるBitcoinと違い、すれ違い通知は、22時に一日分がまとめて送られます。
なぜ即座に通知せず、時差を持たせたのでしょうか。

一つ目の理由は、安全上の問題です。10mという超至近距離かつリアルタイムにアイドルの居場所が知られてしまうと、犯罪に巻き込まれるのではないか……という危惧がありました。

二つ目の理由は、時差で幸せを届けたいから。例えば、もし街中で憧れのアイドルに出会っても、気付かずに通り過ぎてしまうかもしれません。でもѺがあれば、「あの時、あの子がそばに居たんだ」と事後的に知るができます。「あの時、僕は幸せだったんだ」という気づき。即時でないからこそ、既にに今日すれ違っているかもしれないという「可能性としての過去」に包まれながら今日を少し幸せに生きられるのではないでしょうか。

時差通知

応用例

Ѻはアイドル以外にも応用できます。

例えば、江の島にはたくさんの猫がいます。その中の数匹にBeaconを付け『幸福の猫』という設定付けをします。観光案内でその事実を知らせ、Bluetoothをonにして観光をしてもらう。このように店舗ではなく動く存在に取り付けたBeacon、ローカリティや観光とѺは親和的です。言葉を交わせないもの(動物・モノ・建物・乗り物…)とのコミュニケーションを撮影以外のやり方で保存し、そもそも出会ったとすら認識していないものとの『出会い』を記録する。ここにはコミュニケーションの定義自体の拡張があります。

幸せの猫

Ѻと・・・・・・・・・が描く未来

先日、LINEがLINE Simple Beaconを公開しました。
これにより、公式のLINE BeaconデバイスではないBLE機器を、LINE Beacon対応デバイスとして使えるようになります。
それは、公式デバイスの約10mという制限がなくなり、Bluetoothが届く範囲ならば50mでも、100mでもすれ違い通信が可能になることを意味します。
このことは、『都市の幽霊』というコンセプトを持つ・・・・・・・・・と、そのコンセプトを実現するためのツールであるѺにとって重要な意味を持ちます。

『いまここ』からの脱却

・・・・・・・・・がこれまで試みてきたテクノロジーは、いずれも、『いまここ』からの脱却、すなわち、時間と空間の超越を目指してきました。

例えば、アイドルのリアルタイムの心拍数に合わせて、スマホが振動するHeartSyncは、現場におらずとも、彼女たちの鼓動を直に感じ取ることができます。これは空間を超えることを志向したのでしょう。

会話を録音できる交流会。何年後、何十年後に、ふと彼女のことを思い出して、あの時しゃべった事を再生することができます。こちらは時間を飛び越えるギミックです。

交流会ではまた、アイドルの担当の『匂い』を持ち替えることができます。家に帰っても、彼女の気配が残っている――場に依存しない、『纏えるアイドル』を標榜する・・・・・・・・・ならではの仕掛けといえます。

Ѻは「・・・・・・・・・最初期テクノロジーの集大成」と言えます。それは、10mという超至近距離の『いま、ここ』での出会いが、Bitcoinの送金情報の連鎖――ブロックチェーン――に編み込まれ、世代を超えて語り継がれる物語となり、同時に、世界中に散らばったコンピューターに飛散し、薄い膜となって地球を覆うことで、『君と僕の話』から『世界の話』にすり替わるからです。

都市の幽霊

もし日本中のアイドルが、Beaconを持ってѺを使ったら、どんな世の中になるでしょうか。
一日の間に、あの子とも、あの人ともすれ違っていた。知らず知らずのうちに、色んなアイドルに囲まれて生活していることを、実感するのではないでしょうか。

昔のひとは、よく「お天道様が見ているよ」と言いました。

都市の幽霊とは、お天道様のように、普遍的に、都市のどこにでもいて、いつも我々を見守っている、そんな存在です。

アイドルとは、そのようなものではないでしょうか。

実装

Beaconイベントが発生したら、Bitcoinを送金するAPIサーバー(node.js。Bitcoreというライブラリを使用)に、hwidに紐付けられた<君の名>とユーザーのLINE表示名<僕の名>いりのメッセージをPOST。
送金に成功したらトランザクションIDが返ってくるので、それをデータベースに保存しておき、22時にPush APIで各ユーザーに通知する。

イベントの度にBitcoinを送金すると費用がかさみすぎるので、前回から3時間以上経っていればPOSTするという条件をつけました(現在は・・・・・・・・・でしかѺを利用していないので、すべてのhwidを一緒くたに扱っています)

callback.rb
    when Line::Bot::Event::Beacon
      hwid = JSON.parse(body)["events"][0]["beacon"]["hwid"] #Beaconの識別ID
      your_name = Beacon.where(hwid:hwid).map { |obj| obj.your_name }[0] #Beaconに紐付けられた<君>の名前
      now_time = JSON.parse(body)["events"][0]["timestamp"]/1000.0

      my_name = contact['displayName']
      while my_name.bytesize > 26 #ユーザーのLINEの表示名が26Byteより大きい場合は、それより小さくなるまで、末尾から削る。
       my_name = my_name.chop!
      end

      #3時間制限。初めてのbeaconイベントか、前回から3時間以上経っているか、前回のtxidがempty string=タイミングが被っててbroadcast失敗だったならばPOST。
      if Event.where(user_id:user_id).where(event_type:"beacon").count > 0 then
        last_beacon_event_time_plus_three_hours = Time.parse(Event.where(user_id:user_id).where(event_type:"beacon").order(id: :desc).map { |obj| obj.timestamp }[0]).to_i + 10800
        if now_time > last_beacon_event_time_plus_three_hours then
          bitcoin_message_post user_id,your_name,my_name,timestamp,event_type,hwid
        elsif Event.where(user_id:user_id).where(event_type:"beacon").order(id: :desc).map { |obj| obj.txid }[0].empty? == true then
          bitcoin_message_post user_id,your_name,my_name,timestamp,event_type,hwid
        else p "in 3hours"
        end
      elsif Event.where(user_id:user_id).where(event_type:"beacon").count == 0 then
        bitcoin_message_post user_id,your_name,my_name,timestamp,event_type,hwid
      end
    end
  }
callback.rb
def bitcoin_message_post(user_id,your_name,my_name,timestamp,event_type,hwid)
  url = URI.parse("Bitcoinを送金するAPIサーバーのURL")
  res = Net::HTTP.new(url.host, url.port)
  res.use_ssl = true
  res.verify_mode = OpenSSL::SSL::VERIFY_NONE
  req = Net::HTTP::Post.new(url.path)
  req.basic_auth ENV["BASIC_AUTH_USER"],ENV["BASIC_AUTH_PASS"]
  req.set_form_data({"bitcoinmessage" => "#{your_name}#{my_name}が10m以内にいる"}, ';') #Beaconに紐付けられた<君>の名前と、ユーザー<僕>のLINEの表示名をPOSTする。
  res.start { |http|
    response = http.request(req)
    txid = response.body
    Event.create(user_id:user_id,timestamp:timestamp,event_type:event_type,your_name:your_name,my_name:my_name,hwid:hwid,txid:txid)
  }
end
broadcast.js
app.post('/bitcoinmessage', function(req, res) {
  getUTXO(a_address, function(utxos){

    utxos.forEach(function(utxo){console.log(utxo.toJSON());});
    console.log(req.body.bitcoinmessage);

    //トランザクション生成
    var transaction = new bitcore.Transaction().fee(100000)//送金手数料は0.001BTC
      .from(utxos)
      .addData(req.body.bitcoinmessage)
      .change(a_address)//お釣り用アドレス
      .sign(privateKey)

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

    broadcast(transaction, function(id){
      console.log(id);
      res.send(id);
    });
  });
});
push_message.rb
two_hours_ago = Time.now-7200
Event.where(event_type:"beacon").where(timestamp: (two_hours_ago-86400)..(two_hours_ago)).each {|obj|
  message = {type:'text',text:"#{obj.timestamp.in_time_zone('Tokyo')}#{obj.your_name}が10m以内にいたよ!\n\n君と#{obj.your_name}がそばに居たことは、Bitcoinのブロックチェーンに刻まれ、永久に消すことができない。\nブロックチェーンは下のサイトから見れるよ。\n\nhttps://chainflyer.bitflyer.jp/Transaction/#{obj.txid}"}
  line_client.push_message(obj.user_id,message)
}
a-r-i
「アイドル×テクノロジー」をテーマに、アイドルグループと共同でイベント・作品づくりをしています。 「アイドルの睡眠データを3Dプリンタでオブジェ化」 「アイドルとオタクがBitcoinで永久に消えないメッセージを刻む」 「過去にアイドルが居た場所に近づくとスマホが震えるアプリ」 お気軽に連絡ください。
https://github.com/a-r-i
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした