表題の件、みなさまもお困りのことが多いと思います。
日本語のフォントもなんだかダサくなってしまうし。わかりやすい例だと以下のように、スライドの編集時には見えていた絵文字がプレゼンテーションモードでは豆腐になってしまうわけですね。
今回紹介したいワークアラウンドはとても簡単です。
Google スライド拡張をインストールした Chrome でネットワークを切断する。これだけ。
本当にネットワーク切断しなくても、開発者ツールから切断状態にできるので便利ですね。ご査収ください。
表題の件、みなさまもお困りのことが多いと思います。
日本語のフォントもなんだかダサくなってしまうし。わかりやすい例だと以下のように、スライドの編集時には見えていた絵文字がプレゼンテーションモードでは豆腐になってしまうわけですね。
今回紹介したいワークアラウンドはとても簡単です。
Google スライド拡張をインストールした Chrome でネットワークを切断する。これだけ。
本当にネットワーク切断しなくても、開発者ツールから切断状態にできるので便利ですね。ご査収ください。
ちょっとしたコマンドラインツールを作ってるときはよく go run main.go
するんだけど、作業ディレクトリが main.go から離れてしまうと go run $GOPATH/src/...
みたいなことをする羽目になり、ちょっとありがたくない。ファイルが増えてくると go run *.go
することになるが、テストコード(*_test.go
)が入ってくると go run
できないので、そいつを除いてやる必要もあり面倒。
そこで go list
を使ってパッケージ名からソースコードを一覧し、それを go run
に渡してやる簡単なシェルスクリプトを書いた。
GitHub - motemen/gorun: Run Go programs by their package path
使い方はこんな感じ。
usage: gorun [-l] [-tags tags] packages [arguments...]
gorun github.com/motemen/ghq
みたいに、main パッケージへのパスを指定すると go run
的なことをしてくれます。手元のソースコードを動かしたいなら、go run main.go
の代わりに gorun .
すればよい。
-l
フラグをつけると go run
する代わりにソースコードをリストアップしてくれるので、entr みたいなのに渡すのに便利。
実際に go run
するところは
go run "${flags[@]}" -exec "bash -c 'shift; exec \"\$0\" \"\$@\"'" "${files[@]}" -- "$@"
となっているんだけど、この -exec
がミソで、go run
するプログラムの引数に *.go
なファイルを渡したいようなときに、プログラムのソースコードとプログラムへの引数を --
によって分割する、というようなことをおこなっている。
Ethereum はブロックチェーン上でアプリケーションを動かせる(スマートコントラクト)ってので興味を惹かれて、どんなことができるのか調べてたんだけど、感じを掴むために一つ書いてみた。
やりたいことは、ウェブページに送金ボタンがあって、そこから特定のアドレスに Ether を送金し、送金が確認されたら秘密のコンテンツをページ上に表示する、てなもの。送金の確認はスマートコントラクトで行えるが、秘密の情報をブロックチェーン上に記録するわけにはいかないのでこれはウェブサーバに秘匿することになる。とすると、ウェブサーバに私はこの Ethereum アドレスです、とセキュアに伝えてやる必要がある。後で書くけど、あまりいい解法ではない。
知識ゼロの状態から分からないことを潰しつつなんとか動くところまでこれたので、ウェブアプリケーション開発者がつまづいたところをメモっとく。
まずはデモ。MetaMask で、Ropsten テストネットワークで 0.001 ETH 送金できるアカウントにログインしている必要がある。下のボタンで Heroku のサイトが開くので、そこで(一度も送金していない場合は)Pay する。トランザクションが確定すると Paid になるので、Reveal するとサーバから秘密のコンテンツが送信され、表示されるはず。
**********
ソースコードは https://github.com/motemen/sketch-eth-pay-for-content 。
で、いきなり MetaMask って何なん、ってなるわけだけど、ウェブと Ethererum ネットワークを仲介するブラウザ拡張なのらしい。Ethereum アカウントの管理や、トランザクションに署名する UI なんかを提供する。ウェブページは JavaScript 経由で MetaMask の API を呼び出して、送金やコントラクトの呼び出しといった、Ethereum 界における処理をおこなうことができる。
Mist という、同じような機能をもつ専用ブラウザみたいなやつもあるんだけど、下に書く認証のための RPC コールが制限されていて、今回は対象としなかった。このようにまだまだインタフェースは整備されておらず、発展途上感がある。
その JavaScript の API というのが Web3 というライブラリにまとめられている(MetaMask はこの web3 を訪問したページに埋め込む!)。Web3 の API は Ethererum ノードへの RPC 呼び出しとなっている。go-ethereum(geth)のコンソールも Web3 が使える JS の REPL として提供されている。
名前は「Web 3.0」に由来しているっぽい。
ここで構成の話。今回登場するのはひとつのウェブアプリケーションとひとつのスマートコントラクト。
スマートコントラクトのほうのコードはほとんど明らかで、ただ mapping に送信アドレスとその額を保存するだけ。問題はウェブ側となる。
ウェブアプリケーションは訪問者の Ethereum アカウントのアドレスを正しく知る必要がある。訪問者のアドレスは web3 経由で取得することができるが、それを詐称不可能な形で送受信できなくてはいけない。
そこで考えられるのが、クライアントサイドでメッセージへの署名をおこない、サーバサイドでそれを検証する方法。web3 のレイヤではまだ整備されていないが、MetaMask の RPC としてそんなメソッドが用意されている。
The New Secure Way To Sign Data In Your Browser – MetaMask – Medium
ここで説明されているメソッドを呼び出すと以下のような(MetaMask の)ダイアログが表示され、ユーザが「Sign」を選択すると Ethereum アカウントによるメッセージへの署名が生成される。これをサーバが受け取って検証すれば、どのアドレスのアカウントがメッセージに署名したかを知ることができる。
というわけで、全体のフローはこういう感じ。
……のだけれど、署名するメッセージにはウェブサイトに特有の情報が暗黙には含まれないので、悪意あるサイトがユーザに署名させたメッセージを再利用して、アカウントを詐称することができてしまう。そのため上記のようにユーザにアクセスしているサイトを確認するよう促している。ここがけっこう辛いところで、サイトオリジンの情報が署名に付与されるようになると、ウェブからはだいぶ使いやすくなりそう。サービスの利用規約に署名させるなど、メッセージの内容そのものに意味がある場合は問題にならないのだと思う。この話は以下のスレッドでも議論されていた。
書いてたときには思いつかなかったけど、サイトの訪問者に紐付けられたセッション情報を含んだトランザクションを送信してもらい、それをサーバサイドで検証する、という方法もありそう。セッションごとにトランザクションが必要だけど、そっちのほうが有望かもしれない。そうしたほうがいい気がするな……。
Truffle Suite - Your Ethereum Swiss Army Knife
開発の方法は色々あるみたいだけど、Truffle を使った。使ってみた感想としては、これがあれば十分じゃないかな。Solidity によるスマートコントラクトの開発、JavaScript によるテスト、それからデプロイまで Truffle が提供していて、この枠からはみ出したいと思ったことはなかった。作ってるものが小さいからかもしれないけど。
使い方は公式サイトのチュートリアルに詳しく書いてあるので、あまり迷うことはないんじゃないかと思う。マイグレーションやコンソールにおいてコントラクトを表すオブジェクトがどういうインタフェースなのかはよくわからなかったので勘で書いてるけど……。
JavaScript で Ethereum 上のスマートコントラクトとやり取りするのは web3 経由でもできるんだけど、truffle-contract ってモジュールをつかうとより楽になる。
web3 でスマートコントラクトの API を呼び出すには、abi と呼ばれるインタフェース情報とかネットワーク上のアドレスとかが必要なのだけど、truffle migrate
でデプロイすると生成される build/contracts/*.json
がその情報をすべて保持している。これを truffle-contract に渡せば、スマートコントラクトの API が JavaScript から非常に簡単に叩けるようになる。現在の truffle-contract 3.0.4 では、web3 の 1.0.0-beta とは相容れないので注意。
テストは JavaScript で書ける。テスト用のネットワークにデプロイしたスマートコントラクトと JavaScript 経由でやり取りするイメージ。mocha 的な書き方ができて、describe
の代わりに contract
を書くことになっている。テストを書くことで web3 世界観も学べる。
テスト用のプライベートネットワークを GUI で提供するアプリケーション。truffle.json で development ネットワークをこれ(127.0.0.1:7545
)に指定すれば、テストやコンソールの実行時に、アカウントやトランザクションの様子をわかりやすく確認できる。デフォルトでは自動マイニングが有効になっていて、発行されたトランザクションがすぐにブロックチェーンに取り込まれるが、マイニングの間隔を指定することもでき、非同期にトランザクションが解決されていく世界でのテストにも便利。
Infura - Scalable Blockchain Infrastructure
Ethereum ノード(の RPC)を提供するサーバ。普通に Ethereum ネットワークとやりとりすることを考えると、ブロックチェーンのすべてのブロックをダウンロードしないといけないわけだが、Infura が提供する RPC を使えばその手間が省ける。トランザクションへの署名などは手元で行うので、安全(なはず)。サーバサイドでも、コントラクトのデプロイ時にも使っている。MetaMask もこれを使っているらしい。
truffle
を実行しようとしたときに truffle.js
が呼び出される挙動の回避策で、どちらかだけ残しておけばよい。truffle migrate --reset
する必要がある。これまで中央集権的なアプリケーションしか作ったことがなかったので、簡易なものとはいえ原理的に内部状態がつつぬけのスマートコントラクトを書くのは発想を変えなきゃいけないところがあって頭を使う。スマートコントラクトを使えば権限の表現や操作が適切におこなえそうな感触があった。面白い。
web3 は現在 1.0.0-beta の段階。MetaMask や Mist の足並みも揃っているようには思えないので、Web との自然な連携にはもうちょっと時間がかかりそうだ。だけど Truffle による開発は思った以上に快適だった。
ブロックチェーンの歴史から、スマートコントラクトのセキュリティまで広くカバーしていて、とりあえずこの一冊を読んでおけばだいぶ分かる。流れが早い分野だと思うけど、内容も十分新しい。
Ethereum Pet Shop -- Your First Dapp | Truffle Suite
Truffle のチュートリアル。Truffle によるスマートコントラクトの開発全体のオーバービューを知るのによいと思う。
geth でコントラクトの生成をおこなう低レイヤなチュートリアルがある。開発を始めるには Truffle だけでもいいと思うけど、中で何が起きてるか知りたかったらこれを見るとよさそう。