Electrumでコールドウォレットを試してみた
まだBitcoin Coreが比較的軽かった頃、いくつかウォレットを作っていましたが、もう最近ではリソースを食いすぎて、全く使わなくなってしまいました。
しかし、ちゃんと取り出せるようにしておきたいので、紙に書き出しておいたプライベートキーからElectrumのコールドウォレットに取り込んで、送信トランザクションの作成と署名ができるかどうか試してみました。
ただ、完全にネットから切り離されたPCを準備するのは大変なので、Dockerでネットアクセスできないコンテナを作成して実験することにしました。
まずはDockerでElectrumをビルドして、イメージを作成。次に実行するのですが、このときに --net=none を付けてネットワークが使えないようにしたいところですが、どうもElectrumはネットワークへの接続を前提にしているようですのでこのオプションは付けないで実行します。
(追記: restoreのときに-o(オフライン)オプションを付けるとよいみたいです。ただし、この場合はその後のpaytoでエラーとなるため、公式ドキュメントに書かれているようにウォッチオンリーなホットウォレットから署名なしのtxを作成し、それをオフラインウォレット側で署名するという手順が必要となるようです。)
$ docker build -t electrum . $ docker run -it --rm electrum
Electrumの最新をビルドするようになっていますが、本当はちゃんとタグの付いたやつをビルドすべきです。 今はテストなのでこのまま進みます。
最初はネットワークにつないでヘッダを取っておきます。
root@xxx:~/electrum# electrum daemon start
同期するまで少し時間がかかります。 ~/blockchain_headers のサイズでも監視しながら待ちましょう。
root@xxx:~/electrum# ls -l ~/.electrum/ total 2284 -rw-r--r-- 1 root root 2326528 Jun 4 13:37 blockchain_headers
2016/06/04の時点で32MBぐらいでした。結構でかいです。
同期が完了したら、daemonを停止しておきます。
(追記: 停止してもrestore時に開始してしまうので意味がないようです。)
root@xxx:~/electrum# electrum daemon status { "auto_connect": true, "blockchain_height": 400043, "connected": true, ... "server_height": 414752,
ここで5で始まるプライベートキーを取り込みます。
root@xxx:~/electrum# ./electrum restore -w coldwallet : Enter argument (will not echo): Password (hit return if you do not wish to encrypt your wallet): Recovering wallet... Recovery successful Wallet saved in '/root/electrum/coldwallet'
プライベートキーはタイピングかコピペになると思いますが、キーロガーやクリップボードを盗むようなソフトが入っているとまずいので多少フェイクを入れながら入力するとよいかもしれません。まあ、そもそもそういうコンピュータを使っている時点でやばそうですが。
マルウェアじゃなくてもクリップボードをいろいろと監視するソフトなどが入っているとそこからセキュリティホールができちゃうかもしれませんので、切っておいた方がよいです。Ubuntuの場合はfcitxのデフォルトでそういうのが入っているので注意しましょう。
完了したら、パブリックアドレスと残高を確認してみましょう。
root@xxx:~/electrum# electrum listaddresses -w coldwallet -b [ "1xxxx, 1.2345..." ]
送信リクエストの発行と署名を行います。
root@xxx:~/electrum# electrum payto -w coldwallet -f 0.00002 1xxxx... 0.0001 { "complete": true, "final": false, "hex": "010...
最後にhexの右のクォートの中をオンラインウォレットでbroadcastすればよいようです。
送信は過去にLitecoinで試したので、これでいけるはずですが、まだ試していません。
まあ、なんにせよプライベートキーからパブリックキーと残高がちゃんと確認できたら一安心ですね。
a-ads.comの成果
最近、なかなかやる気が出なくて全然記事を書いてませんでした。
3箇所に貼り付けているa-ads.comの成果ですが、トータルで0.00083950Ƀの入金がありました。
50円ぐらいですね。まあ、ないよりはましですね。
JACKで自動的に接続するツールをGo言語で作ってみた
JACKは色々なことができて便利なのですが、PulseAudioと比べると準備に色々と手間がかかって面倒なことがあります。
面倒なことをできるだけ減らしたいので、まずは新たなポートが見つかるとjack_mixerへ自動的に接続してくれるツールを作ってみました。
audio-tools/main.go at master · ohac/audio-tools · GitHub
まだ、マッチングの処理が賢くないので、改善していく必要がありますが、とりあえずはメトロノームのjack_metro --bpm 90を立ち上げると自動でjack_mixer:metro(モノラルチャンネル)につながるところまではできました。
WindowsでJACKを使っている人はあまりいないと思いますが、これはLinuxでしか動作確認していません。
ハマったところはコールバック内でconnectはできないことと、chanがうまく使えなかったところです。 とりあえず1秒間隔のポーリングにしていますが、シングルタスク用のキューみたいなやつに置き換えたいです。
guvcviewが動かなくなったのでffmpegでキャプチャする方法を調べてみた
先日、guvcviewで動画が取れることが分かったので、定期的にギターの練習動画を取ってみて、モチベーションを上げようと思っていた。
これがそのときの動画。
PCに付属しているWebcamでは角度の調節が難しかったので、LogicoolのC270というやつを購入した。 また、Ubuntuが15.04のままでセキュリティ的にまずい状態だったので、15.10に上げてみた。
その後、気がつくとguvcviewでキャプチャできなくなってしまった。
cheeseではちゃんとキャプチャできたので、guvcview側の問題っぽいけど、よく分からなかった。
cheeseはJACKに対応していないので、PulseAudioかALSAを使わなければならず、あまりカスタマイズもできなさそうだったので、他の方法を模索していたところ、ffmpegコマンドでキャプチャできるということが分かった。
ここからffmpegのオプションと格闘することになるのだが、結果から言うと以下のオプションでうまくキャプチャすることができた。
ffmpeg -f video4linux2 -s 640x480 -i /dev/video1 -f jack -i ffmpeg -acodec pcm_f32le -vcodec yuv4 -y test.avi
JACK側から見るとffmpegというデバイスが見えるので、そこに向かって録音したい音をつなげてやればよい。 acodecとvcodecで圧縮させるとCPUパワーを使うため、このPCでは処理落ちなどが発生し、あまり使いものにならなかった。
acodecはJACK側がf32leだったため、それに合わせてみた。コンテナは.aviにしたが、他にもよいものがあるのかもしれない。
acodecがlibvorbis、vcodecがmjpegまたはmpeg1videoならほとんど処理落ちしなかったが、どうせ後で変換するのだし、ストレージは割と余っているので、上記オプションとなった。
最後に ffmpeg -i test.avi test.webm とかで小さくして、保存するなりアップロードするなりすればよさそう。
ALSA/PulseAudio/JACKのメモ
しばらく触っていないとすっかり忘れてしまうのがオーディオ周りのALSA, PulseAudio, JACKの設定など。
まず最初に ~/.config/pulse/client.conf に autospawn = no を書き、PulseAudioの自動起動を無効にする。 (この設定はログインしなおす必要があったと思う。killでもいけたかも。)
追記: pulseaudio -k で kill できる。
次にALSAのデフォルトを無音のループバックにして、デバイスをALSAに占有されないようにする。
デバイス一覧は aplay -l で表示できる。 alsamixergui -c 1 のようにカード番号を指定してミキサーを表示する。
/usr/share/sounds あたりに .ogg ファイルがあるので、これでいろいろテストできる。 特にCD品質な desktop-login.ogg が扱いやすい。これを sox で.wav に変換する。
$ sox /usr/share/sounds/ubuntu/stereo/desktop-login.ogg /tmp/desktop-login.wav
なお、CD品質に変換するには -b 16 -c 2 と rate 44100 を指定すればよい。
$ sox bell.ogg -b 16 -c 2 /tmp/bell.wav rate 44100
まずは hw を直接指定して aplay で音を確認する。事前にでかい音が出ないように alsamixergui で調整しておく。
$ aplay -D hw:1,0 /tmp/desktop-login.wav
次にこのデバイスに ~/.asoundrc で名前を付ける。とりあえず内蔵カードなので pc という名前にしておく。
pcm.pc {
type hw
card 1
}
動作確認。ログインしなおしたりする必要はない。
$ aplay -D pc /tmp/desktop-login.wav
あとは !default をループバックデバイスにする。rateやipc_keyは状況に応じて変更する。 詳しくは覚えていないが、今は以下のようになっている。
pcm.!default { type plug slave { pcm "ploop" #rate 44100 #rate 8000 } } pcm.cloop { type dsnoop ipc_key 18485 slave.pcm "hw:Loopback,1,0" } pcm.ploop { type dmix ipc_key 18486 slave.pcm "hw:Loopback,0,0" }
JACKとの連携用の設定もしておく。これもあまり覚えていないが、以下のようになっていた。
pcm.jdefault { type plug slave { pcm "jack" #rate 44100 #rate 8000 } } pcm.alsajack { type jack playback_ports { #0 system:playback_1 #1 system:playback_2 0 "jack_mixer:alsa L" 1 "jack_mixer:alsa R" } #capture_ports { #0 system:capture_1 #1 system:capture_2 #} } pcm.jack { type plug slave { pcm "alsajack" } }
JACKからこのループバックデバイスが見えたら、JACKに対応していないアプリ、例えばChromeなどからの入力を扱うことが可能となる。
参考にしたサイト
Go言語でBitcoinの署名を検証してみた(その1)
最近はGo言語のトレーニングをしていますが、慣れていないので結構大変です。 早くいろいろと記憶して楽になりたいです。
ところでgocoinというソフトがあり、その中にsecp256k1というライブラリがあったので、これを使ってBitcoinの署名を検証してみました。
GitHub - piotrnar/gocoin: Full bitcoin solution written in Go (golang)
gocoin自体は非商用利用可のライセンスのようですが、secp256k1はMITライセンスとなっておりました。 gocoinのbtcというのを使えば簡単ではあるのですが、MITライセンスの方がよいので、とりあえずsecp256k1だけを使ってみました。
今のところ、このコードでは公開鍵のhex列がないと検証できませんが、一応動いております。 署名の形式もチェックしていないので、古いクライアントで署名したものだとうまくいかないかもしれません。 ちなみにこのテスト署名はElectrumを使って署名したものです。
Bitcoinアドレスは公開鍵そのものではなく、公開鍵のハッシュ値なんですね。 だからこんなに短くできるのかと納得しました。
Bitcoinアドレスで検証するためにはどうやら署名から公開鍵に戻して、そのハッシュと比較するようです。 今回は疲れたので、このへんでやめときます。
暗号通貨を使ったプロトコルを考えてみる
ここ何日か暗号通貨を使ったサービスを考えていたが、結局のところどのようなサービスでも共通している部分はプロトコルにしてしまった方がよいのではないかと考えるようになった。
なんとなく考えているイメージは以下のようなもの。
- 基軸となる暗号通貨を決める(Bitcoin, Altcoinなど)
- メッセージングのプラットフォームを決める(メール、Web、専用アプリなど)
- 複数サポートもあり
- メッセージングのデータフォーマットを決める(JSON, MessagePackなど)
- 受付用のウォレットアドレスを決める
- 公共・分散的なものの場合はスパム防止の意味でProof of Burnを選択
これらのパラメータは各々のサービス提供者が決めればよい。
あとはサービス提供者が受け取ったメッセージをどのように扱うかというところ。
サービス利用者は専用のウォレットアドレスを1つ決め、メッセージに対して署名し、サービス提供者に渡す。通信経路が暗号化されていない場合はオプションで暗号化してもよい。
場合によっては利用者に対して返信する必要があるので、そのようなメッセージングプラットフォームを選択するか、もしくはウォレットアドレスで暗号化してWebなどでブロードキャストしてもよい。
サービス提供者は受け取ったメッセージを検証し、問題なければメッセージに書かれている要求内容を確認し、入金などの条件を満たしておればそれを実行するといった感じ。
例えば以下のようなサービスが考えられる。
- ストレージの提供
- 計算資源の提供
- 翻訳
- 広告
現状ではこれらをまとめて簡単に構築できるようなフレームワークがないと思うので、いつか作ってみたいと考えている。