Ethereum のスマートコントラクトを使用したスマートロックのプロトタイプをつくってみました。
このスマートロックでは、ユーザが鍵を解錠する権利を取得するために、あらかじめスマートコントラクト上に公開鍵を書き込んでおき(このとき Ether で支払いも済ませる)、鍵を解錠する際は公開鍵認証を行ってユーザの確認を行います。
今回のプロトタイピングの主目的は、「Ethereum Wallet の公開鍵を使って、ユーザのデバイスと鍵デバイスの間で公開鍵認証を行う」ということがちゃんとできるかどうかの検証です。結果としてはうまくできたのでうれしい。
この方法を使うと、受益者(サービスを受けるべきユーザ)の確認・認証を Ethereum の Wallet だけでできるので、鍵以外にも何か使えるかなあと思っています。
実際に動いているところ
VIDEO youtu.be
この動画だけだと全く意味不明ですね。
Web Bluetooth API を使用したウェブサイト(HTML+JSで実装)と Raspberry Pi (上のプログラムは Node.js で実装) が BLE で繋がっていて、ウェブサイト上の解錠ボタンをクリックしたら、アヒルちゃんが動いています。
アヒルちゃんが乗っているのはサーボモータで、実際にはこのサーボモータを使って、アヒルちゃんではなく鍵を動かすことになります。
Web Bluetooth API を使用したウェブサイトがユーザ所有のデバイス、Raspberry Pi + サーボモータが鍵デバイスになります。ユーザ所有のデバイスについては実装が楽なのでウェブサイトにしましたが、BLE が使えるのであれば iPhone でも Android でもなんでも ok です。
全体の概要図みたいなもの
ざっくり解錠の流れ
鍵を解錠する権利の取得
Ethereum スマートコントラクトに公開鍵を書き込みます。
ここで Ether 建てによる支払いも完了できます。ただし、エスクロー等の手段を使用しないのであれば、鍵の持ち主を信用できる場合に限ります。
鍵を解錠
[ユーザのデバイス] 鍵デバイスに鍵の解錠要求を出します。
[鍵デバイス] 解錠要求を受け取ったら、Ethererum スマートコントラクト上の公開鍵を取得します。(値を読むだけなので、手数料のGasはかかりません。)
[鍵デバイス] 乱数を生成します。
[鍵デバイス] 乱数を公開鍵で暗号化し、暗号化した乱数をユーザのデバイスに返します。
[ユーザのデバイス] 秘密鍵で暗号化された乱数を復号します。
[ユーザのデバイス] 得られた乱数のハッシュ値を鍵デバイスに返します。
[鍵デバイス] 自身が生成した乱数のハッシュ値と、ユーザのデバイスから受け取ったハッシュ値を比較して、一致していれば鍵を解錠します。
ここでは、ユーザのデバイスはインターネットに接続できる必要がないため、BLE 以外にもスマートカードとかでも同じようなことができる気がします。
鍵自身が Ethereum のノードになっているときはいいけど、外部のノードを使用するときは、ノードが嘘をついている可能性もあるので、複数のノード上のスマートコントラクトの値を読んだほうがいいのかな?
プロトタイピングで使用したもの
Raspberry Pi + サーボ - 鍵デバイス
Chrome - ユーザデバイス
Node.js - 鍵側のコード
HTML/JS + Web Bluetooth API - ユーザデバイス側のコード
使用した node modules - web3, eth-crypto, bleno, crypto, cylon
Solidity - スマートコントラクトのコード
最初は、BLE を使うユーザのデバイスを iOS にしようと思ったけど、ちょっと楽をするために、ブラウザから Bluetooth を使用することのできる Web Bluetooth API を使ったのでかなり楽にプロトタイプをつくることができました。
おわりに
書いてる途中で、「鍵」がゲシュタルト崩壊してきました。「鍵デバイス」という名前だと秘密鍵やら公開鍵やらと混同してしまうので、「スマートロック」という名前を使用して説明すればよかったです。でもめんどくさいからこのままでいいや。
あと、スマートロックといいながら、まったく鍵の機構を作っていないのでタイトル詐欺かもしれない。ごめんなさい。
あとあと、公開鍵認証のやり方がこれでいいのか不安。ちゃんとコンピュータサイエンスを勉強したいなあ。やっぱり大学に行きなおすべきか。学費稼がないと。
今日も現実逃避できて楽しかったけど、そろそろ本格的に確定申告やばい。
参考
blog.playground.io
blog.playground.io