2017/12/27

ECDSAの署名+αで公開鍵が算出できるらしい

年末なので、調整モードです(?)。


Bitcoinに関係してるような、してないような実装をやっている。
残念ながら、私は自分で理論を構築できるタイプではないので、誰かが考えた仕様を読んで実装している。
困るのは、そういう人は「当然知ってるよね?」といわんばかりの態度で、何だかわからないことを書いてくるのだ。


今回出てきたのは「ECDSAの署名に、リカバリー用のIDを載せたデータを作る」という文章。
なんか説明が出てくるだろうと読み進めていったが、特にない。
テストデータを見ていくと、どうやら、これらから公開鍵が計算できるらしい。
ナンダッテー!


elliptic curves - How does recovering the public key from an ECDSA signature work? - Cryptography Stack Exchange
たぶん、これなのだと思うが・・・読んでもさっぱりわからん、というか、読めない。
一番上の回答は項目が3つだけしかないのだが、息苦しい。。。

誰か実装してないか探しているのだが、OpenSSLにはあるようだし、Pythonにもあるようだったが、私が使っているライブラリにはAPIがないのだ。
じゃあ、これ読んで実装するしかないのか、私は・・・?

2017/12/26

期待したアプリがポートで待ち受けているかどうか

前回の続きみたいなものだ。

netcatを使って、ファイアウォールではポートを閉じていないことはわかった。
しかし、そのときにやりたかったことは相手のアプリと通信することで、それはうまくいっていなかったのだ。
結果としては、アプリの設定が足りず、開いていたポートは別の用途で使うためのものだった、というだけであった。

もしそのとき、アプリがどのポートを開けているのかわかっていれば、設定が足りていなかったということがわかったので、その方法を知っておきたい。


$ netstat -nap

Ubuntuだと、これでプロセス名付きで出してくれる。
WSLではダメだったから、なんかあるのかもしれん。


たとえば、

tcp        0      0 127.0.0.1:18332         0.0.0.0:*               LISTEN      1196/bitcoind

だと、bitcoindというプロセスがlocalhostの18332というポートで待ち受けていることが分かる。

tcp        0      0 0.0.0.0:18333           0.0.0.0:*               LISTEN      1196/bitcoind

これは、localhost以外からも待ち受けている場合だろう。
外部から接続したいときは、このポート番号を使えばよいということがわかる。

たしかtestnetのbitcoindは、18333がP2P用で、18332がJSON-RPC用だったはずだ。
通常、JSON-RPCはlocalhostにしか公開していないのでこうなる(bitcoin.confで公開するIPアドレスを指定可能)。


こんな感じで、待ち受けている様子だけは見ることができるが、何のために開けているのかはわからないので、そこからは自分で調べることになるのだ。

2017/12/22

ファイアウォールの設定ではじかれているのかどうか

まったくの個人メモだ。


いま、MicrosoftのAzureにUbuntu VMを立てて、手元のUbuntu PCと通信するテストをしている。
プロトコルの仕様があって、それを実装している相手と、自分で実装したアプリを通信させようとしているのだ。

相手はクラウド上なので、Azureの設定でファイアウォールがきっちり設定されているから、穴を開けなくてはいかん。
自アプリは手元のPCなので、192.168.x.xみたいなローカルアドレスだから、クラウドから自アプリに接続させることはできず、自アプリから接続させなくてはならない。


で、ここからが本題だ。
つまり、うまくいっていない。

  • 自アプリからクラウド側にsocketを張りにいって、その接続はできている
  • 一応、telnetで確認したが、指定したIPアドレスとポート番号は空いているようだ
  • しかし、自アプリからデータを送信して、それが正しければ相手から返ってくるはずなのだが、それが返ってこない
  • 困ったことに、相手のアプリがどうログを出すのかがわかっていない

というところだ。

まあ、これから悩むのは私の仕事なのだが、socketが張れたのに、送受信がファイアウォールなどで止められることがあるのだろうか?という、すごく初歩的なところで悩んでいた。
悩むというか、わからんので失敗する理由から除外して良いかどうか判断できなかったのだ。


そういえば、JSON-RPCを使ったアプリの動作確認をするときにコマンドを使ったことを思い出した。
netcatだ。

catコマンドみたいに、といってよいかどうかわからんが、標準入力で受け取ったデータを指定したIPアドレス:ポート番号に流してくれるようだ。
今回は、こちらを読んでやった。

netcatってなんじゃらほい - マイペースマイライフ

今回、クラウド側が受ける方なので、そちらは -l オプションでポート指定した待ち状態にしておき、手元のPCから-l無しで実行すると入力待ちになるので、標準入力から打ち込んでリターンを押すと相手に転送される(標準入力は、デフォルトではトリガが何かないとキャッシュされるため)。

以前であれば、socketでbindやらconnectやら使っていたかもしれないが、コマンドを知ってしまえば楽ちんというか、手間が省略されるし、確実だ。


そして・・・困っている環境でやってみたのだが、うん、普通に送信できてるし、受信できてるね。
ってことは、ファイアウォールとかの問題ではなく、少なくともアプリより下では問題ないのだろう。
はあ、問題がよくわからなくなっただけではあるが・・・わからないということがわかっただけでもよしとしよう。

2017/12/13

[lmdb]putに成功してもgetに失敗したのはcommitエラーだった

lmdbで、mdb_get()してキーが無かったらmdb_put()する、という処理にしていた。
それは動いていたのだが、ずっと動かしていると急に、mdb_get()→失敗してmdb_put()→成功→同じキーでmdb_get()→失敗、という動作をするようになってしまった。
今まで動いていたので、APIの使い方を間違っているとか、lmdbの仕様を確認してなかったとかだろうと思ったのだが、どうにもわからない。。。


あれこれ考えていると、mdb_txn_commit()も戻り値があることに気付いた。
いや、commitで失敗してもやれることがないだろうと思って、チェックしていなかったのだ。

そうすると、一覧にないエラーが起きていた。

MDB_MAP_FULL

見ていくと、mdb_env_set_mapsize()にたどり着いた。
えー、これってmdb_put()で返すように書いてあるけど、mdb_txn_commit()のタイミングで返すの。。。
まあ、commitするまで反映しないということからすると、その方が自然なのか。。。


どうやら、mapsizeがDBに保存できるサイズの上限らしい。
たしかに今回は、初めて実動作させて大量のデータを保存させていたのだ。

DBって、ディスク容量に制限されるだけかと思っていたのだが、処理の都合でいろいろあるということがわかった。
SQLとか使うほどじゃないから軽いやつにしよう、くらいで選択してはよくないのかもしれんな。

2017/12/11

[lmdb]トランザクションのネスト

lmdbのトランザクションはmdb_txn_begin()で始まるが、ネストはできるのだろうか?

LMDB: Getting Started

Transactions may be read-write or read-only, and read-write transactions may be nested. A transaction must only be used by one thread at a time. Transactions are always required, even for read-only access.

R/Wであればネストでき... may beって?
Google翻訳だと「入れ子になっている可能性があります」と訳されたんだけど、「入れ子にすることもできる」の方が正しいのかな。


では、とmdb_txn_begin()をR/Wで2回呼んだのだが、2回目で止まってしまった。
話が違うでは無いか!
2回目のオプションでMDB_RDONLYを付けるといけるのだが、そういう意味でネストできると書いているのだろうか?
いや、今作っているプログラムで2回呼び出して書込んでいるルートがあったので、こうやって心配になって確認しているのだ。
心配だったので回避させたのだが、もしかしたら別スレッドからだったのでロックしなかっただけかもしれない。

スレッドごとに別トランザクションが発生するのは、使い方はよろしくないかもしれない。

A transaction must only be used by one thread at a time.

これは・・・一度作ったトランザクションをスレッド間で使い回すな、という意味だろうか。
「be used」なので、使い回すのはダメだけどbegin()すること自体は問題ない、と捉えてよいのか。。。


ちなみに、straceでロックするところを見てみると、futex(FUTEX_WAIT)を最後に実行していた。
lmdbはPOSIXのlock fileを使うと書いてあったので、ファイルロックしていたからfutexで変化するのを待っているのか?


結果として、何も分からんかった、ということになる。
最初のbegin()がR/Wで、2回目がReadOnlyであればいけることはわかった、というくらいだ。

データ保存はDBにお任せ、と気楽に考えて作っていたのだが、高速性を売りにしているということは管理をアプリ側である程度はやるのが前提なのだろう。
まあ、考えてみれば、そうなるな。

2017/12/04

[vscode]WSLのターミナルが赤くなった(解決)

Visual Studio CodeをWindowsで使っている。
統合ターミナルというものでWSL(うちはUbuntu)が使えるので、そうやって設定していた。

今まで普通に使っていたつもりだが、今朝起動させるとこんな感じだった。

image

名前やフォルダ名が入っているのでぼやかしたが、ホスト名部分は普通の配色なのだが、パス名のところから急に背景色が赤くなってしまった。
しかも、これがずっと引き継がれてしまい、何をやっても背景が赤。
さすがに見づらい。
PowerShellの方は問題なさそうだし、オリジナルのターミナルやwsl-temirnalは問題ないので、vscodeのWSLだけだ。


vscode settings - Color theme for VS Code integrated terminal - Stack Overflow
これを試したが、背景色は変わるものの、文字の背景色には反映されなかった。


この部分だと$PS1かと思ったのだが、変更した記憶が無いし、オリジナルのコンソールを開いて$PS1を見ても値が同じだ。
では、とPS1を.bashrcで"$ "だけにしてみたのだが、これでもダメ。
"$ "までは色が付かず、次に入力した文字も大丈夫だったのだが、実行した結果の背景色が赤くなり、それ以降は赤だ。


再起動したら直る、というパターンか?


2017/12/05

再起動してもダメだった。

どうも、この現象のようだ。
TERMINAL background color issue · Issue #39222 · Microsoft/vscode

あー、こんな感じこんな感じ。
最近追加されたissueみたいだから、これからか。。。


2017/12/16

なんか、上記のissueはcloseされていたけど、思っていたのと違うみたいだ。
VScodeがアップデートされたので期待したけど、やっぱり赤い。
また新しく同じようなissueが出ているから、

VSCode Integrated terminal text color goes crazy after npm or gulp commands · Issue #40327 · Microsoft/vscode

設定が変わったのかもしれんと思ったが、最新版ドキュメントでも同じだった。

https://code.visualstudio.com/docs/editor/integrated-terminal#_windows

Extensionも無効にしたが、変わらず。

うーん、使わなければよいだけなのだが、他のPCではうまく表示できているだけに悔しい。
Ubuntuをアンインストールして、またインストールし直したが、やはりダメか。

問題ないPCもあるから、何かの環境だとは思うんだけどねぇ。


2017/12/29

v1.19.1になったが、変わらんな。
来年になると忘れそうだから、現在のスクリーンショットを残しておこう。

image

「こんなxxxはいやだ」みたいな画面だ。

背景色じゃなくて、テキストの背景色というところがどうしようもないのだな・・・。


2018/02/24

まだ、赤い。
今回は、統合コンソールを立ち上げたときに、どこから赤くなるのかを載せてみよう。

image

このタイミングだ。

.bashrcでPS1をシンプルにすると、初っぱなは赤くならないのだが、次の段階ではもう赤くなる。

export PS1='$ '

image



Microsoft Storeからubuntuをインストールした場合、UsersのAppData/Localにあるubuntu.exeを動かすようなので、system32のbash.exeから変更してみたのだが、同じだった。


2018/03/14

まだ赤い。


不思議なことが分かった。
bashコマンドだと、大丈夫なのだ。
echoやcdだと現象が起きないみたい。

image

だから?といわれそうだし、私も何か分かるわけではないのだが。。。

この現象、起きないPCは起きないし、起きるPCはWSLを再インストールしようがvscodeを再インストールしようが元に戻らないから、時間がかかりそうな気がする。


2018/04/08

まだ赤い。


今回は、Ubuntuではなく、Debianをインストールしてみた。
"terminal.integrated.shell.windows"には、"AppData\\Local\\Microsoft\\WindowsApps\\debian.exe"のようなパスで指定してやらんといかんかった。
デフォルトがどれになるのかは、インストールした順番によるのだろうか?
試しにUbuntuをアンインストールすると、System32のbash.exeで起動した。


そして結果は・・・・

image

少し期待したのだが、やはりダメか。


GitHubを見てみよう。
https://github.com/Microsoft/vscode/issues/40327

Openのままだ。


vscodeをアンインストールしてやり直しても、RoamingにあるCodeを削除してやり直してもダメだったから、どこかにある設定を呼んでいそうな気がする。
テーマを変更すると色も変わるから、vscode自身が表示させていると思うのだが、うーむ。。。


2018/04/14

まだ赤い・・・赤かった!
しかし、とうとう解決したのだ!!


何をしたかというと、ColorToolというツールを動かした。
https://news.mynavi.jp/article/bashonwindows-58/

正直なところ、何がどう効いたのかはよくわからない。
元々、コンソールの配色を変更するツールなのだ。

試しに solarized_darkにしてみると、なぜか真っ赤になってしまった。
そう、vscodeでWSLのターミナルを開いたような、あんな真っ赤さだ。
PowerShellで実行したのが悪かったのかもしれんが、どれを指定しても色があり得ないだろう配色になっている。
cmdで実行し直したり、プロパティ見たり、vscodeのWSLから実行したりしていると、いつの間にか直っていた、というわけだ。


気にはなるが、直ればよかろうなのだ。

2017/12/01

[vscode]WSL用の設定

今まで、Linux環境にVisual Studio Codeをインストールして、VNC経由で使っていたのだが、Windows10のFall Creator UpdateからWSLが正式になったので、けっこうな部分がWSL環境でも動くようになっていた。

じゃあ、WindowsにVisual Studio Codeをインストールして、ビルドだけWSLに任せればいいんじゃないの?と思ってしまうだろう。
思ってしまうものなのだ。
ただ、includeパスの設定は何とかできたとしても、通常のLinuxにあるようなものは無理なんだろうな・・・
と思っていたら、ちゃんと資料があった。

https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/Debugger/gdb/Windows%20Subsystem%20for%20Linux.md

これを追加すると、設定として「WSL」が増える。
もし切り替わっていなければ、画面右下にあるOS種別っぽいところをクリックして選択するとよかろう。


vscodeは毎月進化しているので、追っていくのが難しいな。

2017/11/27

[bow]WindowsのUbuntuでダブルクリックによる単語選択をしたい

もう、Bash on Ubuntu on Windowsという名前では無くなってしまい、呼び名が難しくなってしまった。
ともあれ、2017年秋からは正式にLinux環境もStoreからインストールできるようになったので、今Ubuntuで作っているアプリくらいだったら動くんじゃ無かろうか。


インストールはいいとして、コンソールが標準のものでは心許ない。
TeraTermみたいなやつが使いたい。

こちらを見ながら、ConEmuというアプリを使ってみよう。
黒い窓使うよりConEmu使うのが便利だよ、PuTTYも超絶いいよ - Qiita

おおむねよかったのだが、ダブルクリックによる単語の選択が、なんか遅い。
設定を変更していると多少早くなった気はするが、致命的なのが次の行に回り込んだ単語を選択してくれないことだ。

image

希望としては"know"と次の行の文字まで拾ってほしかったのだ。
これは設定を変更しても変わらんかった(やり方がわからんだけかも)。


これは、オリジナルのコンソールでも同じだ。
PowerShellでもそうみたい。

白黒でわかりにくいが、TeraTermはいけるのだ。

image


こちらのwsl-terminalは、なかなかよい。
Bash on Ubuntu on Windows用ターミナルとしてwsl-terminalを試してみる » sa-sa-ki.jpのblog

image


テーマは、私の目に読みやすかったbase16-seti-ui.minttyrcにした。

2017/11/21

[btc]トランザクションを下りたい

Bitcoinのトランザクションを展開したとしよう。
「展開」というのは、Bitcoinのブロックチェーンに投げる、くらいの意味だ。
txメッセージの送信、でもよいかもしれん。


よくあるBitcoinトランザクションだと、vinが1つで、voutが送金先とお釣りの2つだ。
そのvoutのお釣りから、さらに別の送金を行ったとしよう。

いや、もうちょっと今困っている問題に近づけた方がよいな。
私以外の誰か(ここではAさん)が、Aさんが秘密鍵を所有するトランザクションのお釣りから、別のアドレスに送金を行ったとしよう。
そして、私はお釣りを含んでいるトランザクションのTXIDだけは知っているとする。

さて、ここで送金先のTXIDを簡単に知ることはできるだろうか?
ただし、Block Explorerのようなものは使わず、bitcoindのJSON-RPCのみ使用可能とする。


TXIDの特定のvoutが使用されているかどうかは、gettxoutを使うとわかる。
これは、outpoint、すなわちTXIDとindexを指定して、unspentであれば何も返さない(エラーが返るのかも?)。
結果を返すかどうかだけで、とりあえずunspent/spentのチェックだけはできよう。


もし上流に遡りたいのであれば、vinのTXIDをgetrawtransactionなどすればよかろう。
そう、その方向に上っていくのは簡単なのだ。
なのに、もっと簡単そうな下へ下る方となると、途端にやり方が分からなくなる。


以前作ったときはBitcoinプロトコルしか使えなかったので、getheadersなどを使って古いブロック番号からひたすら順番にとり続けた気がする。
セキュリティ的なものなのか、やればできるような機能を持たせていないだけなのか、とにかくbitcoindではそういうことはできないんだ、と結論づけたのだった。


あれから数年が経ち、私もなにもわからずBitcoinを触っていたときよりは知識が増えたはずだ。
もしかしたら、今だと解決できるのかもしれん。
・・・というよりも、下に下りたいという状況が出てきてしまったのだ。

segwitのトランザクションだとwitnessがわからなくてもTXIDが計算できたはずなので、もしかしたら下らずにTXIDがわかるかもしれん、という期待をしながら計算を続けたのだが、無理そうな気配がしている。

送金元のトランザクションはわかるので、vinはわかる。
versionも、決められる。
ただ、voutとlocktimeが自由にできてしまうので、TXIDを事前に計算できないのだ。


あとは、仕様を確認して、実はそこはたどらなくてよいんだ、となることを期待するばかりだ。

2017/11/19

[googlehome]英語でしゃべってもらう

hiro99ma blog: [googlehome]IFTTTのThatをslackbotで受けとる

これで、IFTTTとslackbotを使って、しゃべった言葉をGoogle Homeがしゃべり返すところまで行った。
あとは、翻訳するサービスで無料のところがあれば、それを挟むだけでよさそうだ、とは思っていたところ、こういう記事があった。

Python – googletransを試してみました。 | Developers.IO

制限があったり、いつまで使えるか分からなかったりするようだが、お遊びでやる分には十分だ。


slackbot側のpython

from slackbot.bot import respond_to from googletrans import Translator
import os.path import subprocess def _bcc_exec(cmd): try: print cmd subprocess.check_output(cmd).strip() except subprocess.CalledProcessError as e: print '!!! error happen(errcode=%d) !!!' % e.returncode @respond_to('(.*)') def talk_to(message, params): print params translator = Translator() j2e = translator.translate(params.replace(' ', '')).text print j2e cmd = ['node', os.path.expanduser('~/NodeJs/google-home-notifier-test/slacktalke.js'), '\"' + j2e + '\"'] _bcc_exec(cmd)


google-home-notifier-testのjs側(slacktalke.jsという名前で呼び出している)

var googlehome = require('./google-home-notifier');
var speech;

if (process.argv.length >= 2) {
    speech = process.argv[2];
} else {
    speech = 'I asm slackbot.';
}

googlehome.device('something', 'en');
googlehome.ip('xx.xx.xx.xx');
googlehome.speed(1.0);
googlehome.notify(speech, function(res) {
  console.log(res);
});


IFTTTは、Google AssistantとSlackをつないで、SlackはDirect Messageで作ったslackbotの名前を指定し、MessageでTextFieldを渡すだけだ。

Google Cast APIを使っているので、nodejsはローカルPCで動くようにせんといかんし、nodejsの実行をパス指定で行っているからslackbotもローカルPCで動かさんといかん。
まあそこら辺は素人なので、詳しい人はうまいことやるだろう。
slackbotをnodejsで動かせるか、google-home-notifierのpython版があれば分けなくてもよいのだが、まあいいや。

2017/11/18

[lmdb]mdb_dbi_close()は通常使わない

久しぶりにGoogle HomeやWindows10以外の話だ。
Cのlmdbで、mdb_drop()してエラーが発生したので悩んでいたのだ。


いま、C言語のlmdbを使っている。
「C言語の」とわざわざ書いたのは、どうもpythonなど他の言語にもAPIがあるようだったからだ。
今回はC言語版しか使っていないので、他については分からない。


困っていたのはmdb_drop()だったのだが、そもそもそれ以前にDB保存されているかどうかも危うかった。
ちょっと、まとめておこう。


lmdbの保存から見ていく。

https://gist.github.com/hirokuma/98b5010f4770267ab730efd3422be982

$ sudo apt install liblmdb-dev
$ gcc -o tst lmdb_drop.c -llmdb
$ rm -rf testdb
$ ./tst
$ mdb_dump -a testdb
VERSION=3
format=bytevalue
database=aaa
type=btree
mapsize=1048576
maxreaders=126
db_pagesize=4096
HEADER=END
  6161616161
  313233
DATA=END

databaseが"aaa"、keyが"aaaaa"で、dataが"123"だから、だいたいこんな感じの出力になるのではなかろうか(これはUbuntu 16.04で実行)。


ただ、77行目の「mdb_dbi_close()」のコメントアウトを外すと、DB保存自体されなくなった。
えー、そうなのー!!
順番が、txnの開始→dbi取得だったので、txnのcommitより前にdbiをcloseしてもよいのだろうと思っていたのだ。

確かに、mdb_dbi_close()の説明にも「Normally unnecessary」と書かれているのだ。
通常は不要=やっといても悪いことはない、という判断だったのだが、そうではないのだろう。


では、ここにもう1つdatabaseを追加する。
コメントアウトしている79~92行のコメントを外すのだ。
mdb_dbi_close()は、さっきの話があるので、生かせないのだ。

そうするとですな、dbiが2つ開くことになってしまい、このまま実行するとL82でassertしてしまうのだ。
どうするかというと、L28の引数を1から2に変更するのだ。
つまり、トランザクションを閉じるまでの間は開いていることになるので、その分のmaxdbsは確保しておきなさい、ということだ。


mdb_drop()がうまくいかなかったのも、同じ理由だ。
commit前にL124でmdb_dbi_close()していたので、削除できていなかったのだ。


分かってしまえば大したことはないのだけど、なかなか気付きにくかった。
「Normally unnecessary」というのは本当にそうだったのだけど、Normalって難しいですな。

2017/11/14

[win10]Cortanaが無効になっていると、Cortanaが出てこない

何を当たり前のことを言っているんだ!と思われるだろう。
私もそう思う。

Windowss Fall Creator Update後の設定画面で、Windows10 Professional版とHome版で違いがあったので、版の違いだろうと思っていたのだ。
しかし、それはCortanaを無効にしているかどうかの差だったのだ!

全然記憶になかったのだが、レジストリエディタで無効にしていたことが分かった。
グループポリシーエディタではそのままだったため、すっかり気を抜いていた。

レジストリを元に戻して再起動すると、「Cortana」が出てきた。

image


これが.Net Framework 3.5インストール失敗事件と関係があるのでは!?と思ったが、そこは関係ないようだった。
ちっ。

2017/11/12

[googlehome]dialogflowを少しだけ使った

意外と私の中で長持ちしているGoogle Home mini。
しゃべるのめんどくさいだろう、と思っていたのだけど、思ったより使っている。
音楽流すのと、タイマーと、目覚ましくらいしか使っていない気もするが・・・。


IFTTTとつないで、しゃべった言葉をslack投稿し、slackbotがそれを読んでTTSに投げ、その結果をcastするしくみだけ作った。
そうすると、作業場にslackbotを立ち上げておくと、家でしゃべったら、それを向こう側でしゃべる、ということが、一応できている。
まあ、同じ場所にいないので、本当にしゃべってるかどうかは確認したことがないのだが・・・。


しかし、どうにもまだるっこしいので、別のやり方も知っておきたい。
Actions on Googleでdialog flowというやつをつかうと、似たようなことができるらしい。
以前はapi.aiと呼んでいたものが、今はdialog flowと呼ぶようになったそうだ。

Actions on Googleでapi.aiを使ってGoogle Homeに何か言わせてみる - Qiita

だいたい、この通りにやると動いてくれた。
最初に試したときは別のサイトを見ていたのだが、どこかわからなくなってしまった。。。



  • App informationの「Pronunciation」に書いた文字が、「xxxと話す」みたいにして始まったときに読み上げられる名前。
  • 「xxxと話す」のxxxは、デフォルトはAssistant app nameになる。デフォルトと書いたけど、変更できるかどうかは知らん。
  • 一度動くようにした後、SAVEで設定を変更しただけではテスト動作に反映されない?
    • Simulatorに行って、「CHANGE VERSION」をすると確実に反映してくれそうだった。


この「xxx」だが、何を指定するかが難しい。
たとえば「じゃくそん」だと反応してくれないが「ジャクソン」だと反応してくれた。
日本語だと、解釈して変換した後の文字列が一致しないとダメな気がする。
英語で試してみたいところだが、あいにく私の英語は日本語レベルでしかしゃべれない。。。


IFTTTのキーワードと同じにしたら、IFTTTの方が先に動作した。
これが必ずなのか、何か設定があるのかはわからん。


あと、これは個人の感想だが、声がいつものGoogle Homeの人ではなく、アプリの人の声になるのだが、ちょっと聞き取りづらい。
会話用の音声というのは難しいのだろうねぇ。


Dialogflowのintegrationにnode.jsがあった。
これを使うと、IFTTT経由でSlackのSlackBot用チャネルに書込み、それによってSlackBotが立ち上がってnode.jsを起動し、そこでgoogle-home-notifierが動く、という中間の部分がいらなくなるんじゃなかろうか、と期待した。

が、書いてあるとおりにやると、node.jsのアプリからDialogflowに問い合わせて結果が返ってくるだけだった。
待つ方のサンプルはあるのだろうか。。。


Dialogflowだけでなく、SDKなんかも使えるようなので、そっちを見に行った方が良いのかもしれんね。

2017/11/05

[win10]Fall Creator Updateの設定画面(Home版)

数日前、Windows10 Fall Creator Update後の、Professional版の設定画面を載せた。
「違いは『検索』くらいですねー」などと書いていたのだが、よく見ると様子が違う。

image

Cortana ... ?

Cortanaで検索できるから、文字だけの違いかもしれんと思ったけれども、中身が違う。
うーむ。

Home版のPCはメーカー製で、Professional版のPCは自作という違いがある。
また、Professional版はOEMのDVDでインストールしている。
もう1台、Windows7からのアップデートを行ったWin10Proがあるので、そっちでもアップデートするとさらに違いが分かるかもしれん。

ふっ、謎多きOSよ。

[zybo]Z7シリーズが出ている

何気なくFPGAマガジンNo.19を見ていると、Zyboの広告が出ていた。
「今さらねぇ」と思ったが、よく見ると「Zybo-Z7」と書いてある。
新しいんだ!


ZYBO Zynq-7000 評価ボード: 目的別 秋月電子通商 電子部品 ネット通販
ZYBO Zynq-7010評価ボード Z7-10 開発環境ソフトライセンス付: 目的別 秋月電子通商 電子部品 ネット通販
ZYBO Zynq-7020評価ボード Z7-20 開発環境ソフトライセンス付: 目的別 秋月電子通商 電子部品 ネット通販

7020が増えたのはわかるが、ぱっと見た目の違いが分からん。。。

Zybo Z7 Migration Guide [Reference.Digilentinc]

VGAがなくなってHDMIが2つ(InputとOutput)に分かれ、RAMが増えて、メモリ速度も上がって、カメラ用のポートが増えた、というところか。
LEDも、RGBになったようだ。

7010と7020の違いもあるし、細かい違いはあるようだが、大ざっぱにはそういうところかな。


Digilentのgithubも更新されている。
https://github.com/Digilent

以前、新しいVivadoに持っていこうとして苦労したが、もしかしたら今だと楽にできるのかもしれん。
いつか試したいところだが、それは今日じゃないのだ。。。
作業が落ち着いたら、落ち着いたらきっと。。。

2017/11/04

[win10]OSのロールバックは、あれこれやる前にやろう

困ったことは続くもので・・・。

Fall Creator UpdateしたWindows10 Professionalであったが、.NET Framework 3.5がインストールできない(Home版はできている)。
それでは困るので、OSを前に戻した。

が、戻す前にいろいろ作業していて、Visual Studio2015 Communityをアンインストールして2017 Communityをインストールしたりしていたのだ。
元に戻したとき、この辺も中途半端に戻されたようで、インストールされたアプリに2017が出てこず、2015が出てきてしまう。

もちろん、実体はないので実行はできないし、アンインストールも失敗する。
アンインストールツールを使って削除させたのだが、今度は2017のインストールが失敗する。。。


どうやら、VC++ 2015のruntimeがインストール済みに見えるようで、それをアンインストールしようとして、でも実体がなくて「ProgramData\Package cache」に入っているmsiファイルを探したが見つからず「パスを教えろ」とダイアログが出てきてしまう。


最終的には、このツールを使った。
プログラムのインストールまたは削除をブロックしている問題を解決する

これを使うと、インストールされていないものもリストに出てくるので、それをアンインストールできるようだ。
アンインストールしているのか、レジストリを調整し直しているだけなのかは、よくわからん。

1回の起動で1つしかアンインストールできないので、ひたすら実行。
そもそもどういう項目名なのかもわからんのだが、Package cacheのフォルダ名に相当するIDが項目にマウスを当てていると表示されるようだったので、それで当たりを付けていった。


まあ、Visual StudioなんかはOSとの関係が深いので、こういう目にあったのかもしれない。
とにかく、フルバックアップを取るのが一番安全だと感じた。
以前は、バックアップなんて余裕がある人がやるものと思っていたのだけど、そんなことはいっていられませんな。。

[win10]Fall Creatorアップデート前のものが別物と扱われる?

image

むう、困った・・・。

2017年10月末にWindows UpdateでFall Creator Updateがインストールされた。
うちには、Windows10 HomeとProfessionalがそれぞれあり、どちらにもインストールされた。


Professionalの方には、.NET Framework 3.5がインストールできないという現象が発生している。
アップデート前はインストールされていて、アップデート後に外して、もう一度インストールしようとしたのだ。
ダメだったのでOSのアップデートを戻して試したのだが、それでもダメだったので、Fall Creatorが原因かどうかははっきりしない。
ダウンロードはしているようだし、けっこう処理はしているように見えるのだが、最後の最後でエラーになるのよねぇ。


最初に載せた画像は、Home版で発生している。
うちはATOK Passportを使っているのだが、Faill Creatorみたいな大きめのアップデートが行われる際はMS-IMEに戻されると同時に、登録情報もいくつか消えてしまうのか、シリアルナンバーの入力を求められてしまう。
それは別によいのだが、オンラインアップデートに項目が出てきて、それをインストールしようとすると画像のようなエラーが発生するのだ。


はっきりしないのだけど、今のFall Creator Updateにはアップデート前にインストールされたものの管理がうまくいっていないような感じがする。
.NET Framework 3.5の方は、アンインストールがうまくいっていないとかか?
Home版ではインストールされているのだが、Cleanup Utilityでも候補に出てこないのだ(出てくるものかどうかはわからんが)。

image


Windows Updateはしたいのだが、Fall Creatorだけ外す、みたいなことはできるんだろうか?
起きてしまったものは仕方ないのだが、次の春にもアップデートが行われるだろうから、そのときに同じ過ちを繰り返したくないのだ。

2017/11/03

[nfc]確定申告でのマイナンバーカード

マイナンバーカードという、個人番号カードをNFC化したものがあるが、そっちで確定申告できるということらしい。

スマホで確定申告可能に 国税庁、iPhone非対応  :日本経済新聞

日経新聞って、技術的なニュースが弱いと思う・・・。
技術系のニュースは的外れな気がするのだが、しょうがないのだろうか。

まあ、私に生活とか法律とかの記事を書けといわれたら、同じようなことを書いてしまうかもしれんので、あしざまに言うことは避けておこう。


いや、タイトルに間違いがあるわけではないのだ。
読んだ範囲では、内容も間違っているわけではない。

ただ「○○自動車が新発売する車では空を飛ぶことができません」みたいな感じで、そもそもそんな機能がないのに「飛べるはずなのに飛べる機能を付けなかった」みたいな感じで読めてしまうのが、よろしくないんじゃなかろうかと思ったのだ。


マイナンバーカードは日本で発行するカードなのだが、その内容は国内規格ではなく、どちらかといえば海外で標準となっているType-Bという形式だ。
パスポートなんかもType-Bだったと思う。

iPhoneが対応していないのは、そういう国際規格のフォーマットは読めなくしているからだ。
読めるのは、NDEFという、NFC Forumが作っている規格のものだけだと思う(持ってないので、よくわからん)。
まあ、iOSはそういうところは攻めないので、Androidで数年かやって問題なさそうだったら採用する、とかじゃなかろうか。
ここら辺は、戦略の違いだろう。


ともかく、今回については、iOSがそういう機能を提供していないから、どうしようもない。
国際規格にすれば大丈夫だろうという目論見だったのかもしれんが、iOSの非公開制に阻まれたのかな。
できるとすれば、日本に限ってそういうiOSにしてしまうとか?


また、読めるだけではダメだろう。
JPKIがあるので、正当性の確認は行うに違いない。
正当性というのは、マイナンバーカードを「うちが発行したものです」と認める作業になろう。

まあ、それくらいやってもらわないと使う方も怖いしね。
普及だけでなく、使い勝手が上がるにもまだまだ時間が必要そうだ。

[win10]Fall Creator Updateの設定画面

アップデートされると項目が変わっているので、メモとして残しておく。


image

Home版は、一番最後の「検索」がなかったような気がする(これはProfessional版)。


大きめのアップデートが行われると、設定自体がいくつか元に戻されるのが困る。

  • 高速スタートアップが有効に戻る
  • Alt+TABがスクリーンショットタイプに戻る(アイコンにする
  • MS-IMEが復活して、ATOKを初回使う際にシリアルナンバーが必要になる
  • システムフォントがYuゴシックに戻る

他にもあるかもしれんが、数が多くて気付かんね。

[win10]Fall Creatorになったあと.Net Framework 3.5が入らん→直った

(注意:うちでの解決は、一番下に書いています)

image

これを書いているのが2017/11/03だから、Fall Creator Updateになったのは10月末だったと思う。
最初は安定しなさそうだから、安定連絡を待ってからインストールしようと思っていたのだが、Windows Updateで普通にインストールされてしまった・・・。


アップデートして気付いたのだが、Atok Padが起動しなくなった。
Twitterで「.NET Framework 3.5をインストールし直すとよくなった」という人がいたので、一度削除して、もう一度インストールしようとしたところ、出てきたのが上の画面だ。


下のリンク先はWSLのものだが似た現象だし、この人も.NET 3.5で起きているようだ。
https://github.com/Microsoft/WSL/issues/2582#issuecomment-339568847


ダイアログからWindows Updateの修復ツールっぽいものに連れられていったのでやってみたが、症状が変わらん。
.NET Frameworkの修復ツールらしきものもあったが、変わらん。

あとは、こちらにあるアンインストールとインストールを試すべきか。。。
.NET Framework のアンインストール方法 – Visual Studio サポート チーム blog


いろいろ考えたが、元のバージョンに戻すことにした。
今なら、手痛くないだろう。

・・・戻したが、.NET Framework 3.5はインストールできなかった。
バージョンを上げる前からダメだったのか?
あるいは、上げてから削除するところがダメだったのか?
もはや、理由は分からん。


あきらめて、バックアップから戻すことにした。
今回はEase Backupでだいたい毎週バックアップしているのだ。ふふん。
まあ、そういうバックアップがあるから、バージョンが上がっても戻せばよかろうと思っていたのだよ。


・・・あっ、システムドライブだけバックアップ対象に入れるの忘れてる!!!
そんなばかな・・・。
今まではデータのバックアップしか取っていなかったということなのか。。。


こうなると、もうできるのはバージョンを上げて.NET Framework 3.5がインストールできるようになるのを待つだけだ。
まさか、こんな終わり方になろうとは思わんかったよ。

「やよいの青色申告」がFramework 3.5がないと動かないので、今回の月末処理はあきらめるとしても、確定申告までには動いてくれないと困るのだよなぁ。


2017/11/08

0x80070781は、まだダメ。
dismコマンドでインストールしたときのログにCBS.logにエラーを吐いているようだった。

Overlap: Duplicate ownership for directory

こういうのがずらずら出ている。

しかし、sfcでスキャンしても何も出てこないのだ。
同じような作業をしていたから、どこかで修復されて、PCの再起動で治ったりするんだろうか?


2017/11/18

あれから毎日0x80070781を直すために試しているが、どれもダメだ。

ショートカットが切れたのが残っているせいかもしれんと思って、そういうツールで消してもみた。
Microsoftのfixitにあるインストール・アンインストール不具合用ツールで.NET系のものをアンインストールもしてみた。
Visual Studio2017をインストーラで.NET3.5開発をインストールしてみようともしてみた。
どれも効果が無いか、インストールができないかで終わった。


当時を思い出すと、Fall Creator Update前は.NET3.5をインストールしていて、そこからアンインストールまではできたのよね。
ただ、ATOK Padというツールが動かないので、一度アンインストールしてインストールし直そうとしたところ、今回の現象になったのだ。
同じ並びにある.NET4.7は大丈夫だったし、Media Playerも大丈夫だった。
今のところ、.NET3.5だけ失敗するのだ。。。


もう考えても仕方ないので、システムのフルバックアップを取って、Fall Creator UpdateのISOファイルから再インストールを行っている(これは別のPCから書いている)。
「回復」の方も考えたのだが、今インストールされているアプリは全部削除されます、と言われると、さすがに悩んでしまったのだ。
今回も「再インストール」と書いたが、特にそういう項目があるわけではなく、マウントすると入っているsetup.exeを実行しただけだ。
今、インストールが行われている。

心配しているのは、このインストールによって別の場所に新しくWindowsがインストールされやしないだろうか、ということだ。
ハードディスクが複数台あるので、そっち側にインストールされたりとか。


終わった。
そんなに時間はかからなかった。
うちはWindows Firewall Controlというアプリを使っているのだが、ネットワークは切断したままにしていて、それが有効なまま起動した。
だから、そういう設定も残ったままらしい。

デスクトップなんかも、前と同じように見える。
ATOKのシリアルナンバーを求められたから、何かしら設定は変わっているようだ。
ではさっそく、.NET3.5のインストールを行う。
Windows Updateに接続するかどうか確認されたので、OK。
ダウンロードが始まり・・・終わった。
そして変更を適用して・・・プログレスバーが進んでいって・・・・

ダメだった。
0x80070781で終わった。


こういうエラー番号でネット検索すると、Microsoftではないページで修復ツールっぽいのが見つかることがあるけど、ああいうのは試していない。
さすがに危険だろう。

このエラーは発生する人が少ないのか、あまり引っかからないのだ。
なんとなく、英語圏ではない人の記事が多いように思う。
まあ、Microsoftの検索でも番号は出てこないし、仕方ないのかもしれん。

image


Visual Stucio 2017 communityもインストールに警告が出る。

リターン コード: 1603
リターン コードの詳細: インストール中に致命的なエラーが発生しました。
メッセージ ID: 1714
メッセージの詳細: The older version of Microsoft Portable Library Multi-Targeting Pack Language Pack - enu cannot be removed.  Contact your technical support group. 

これかな?
https://developercommunity.visualstudio.com/content/problem/32202/vs2017-installation-error.html

解決していないようだ。
私のところでは、.NET3.5を含めなくてもこの警告が出るので、関係は無いのかもしれん。
インストール・アンインストール修復ツールでMulti-Targetingのものを修復しようとしたが、4.5.1 Multi-Targeting Packと4.5.2 Multi-Targeting Packは失敗してしまう。
ネットでこれが出てきたので使ったら消えたけど、大丈夫だろうか。。。
https://github.com/tsasioglu/Total-Uninstaller
かといって、このツールを使って失敗するものがインストール・アンインストール修復ツールでうまくいくこともあるし、なんだかわからんな。
しかし、VS2017の警告に関係したのは4.5.1でも4.5.2でもなく、さらにリストの下にあったPortableのMulti-Targetingであった。
それをアンインストールすると、警告が出なくなった。
.NET3.5開発もインストールできたのだが、プロジェクトを作成しても.Net Frameworkの選択に3.5は出てこない・・・。


うーん、クリーンインストールまで行かずに、アプリは残す方向で、もうちょっと危険な修正方法はないだろうか。
ネットにあまり出てこないということは、通常であればうまく行っていると思うので、クリーンインストールすれば解決できるだろうけれども、そこから元と同じ環境に戻すまでの時間がかかりすぎる。


2017/11/23

まだまだ解決していない。

今日は、イベントビューアを見てみた。

image

むう、なんか出てる。。。

この件はたくさん検索に引っかかった。
どうも、バックアップするときに権限がないとかなんとかで出てくるようだが、見た感じはユーザの操作で起きたというよりもアップデートか何かで生じたりしたのかなぁ。

イベント 513, CAPI2 のエラーログが記録される

たくさん引っかかるのだが、うちのは試してもダメだった。
コマンドの出力は変化しているから、処理自体はできていると思うのだが、インストールすると必ず出てくる。
まあ、バックアップをやろうとしているわけじゃないし、Detailが違うから、原因が違うということか。
いくつか同じ件で見つかり、それぞれsdsetに与える引数が違い、どれもダメだった。。。


では、DetailがFindFirstFileのエラーを探してみよう。
Access Deniedだからちょっと違うけど、まだましかも。
Windows Server Backup - Cannot find System Writer SERVER 2012

最初の人は、解決したらしい。
レジストリの方は、NT SERVICEにパーミッションをフルで与えるとなってたけど、うちではNT SERVICEが見つからなかった。。。
そこはスルーして、次がC:\Windows\Microsoft.NETを触っているので、期待できそうだ。
その中にあるFrameworkやFramework64にあるテンポラリっぽいファイルを削除するらしい。
Frameworkの方にはフォルダがバージョンごとにあったが、そもそもv3.5はインストールできていないので無いし、Framework64の方はそもそもフォルダがほとんど無い。
1041、とかいうフォルダへのショートカットがあったのでたどろうとしたが、自分自身へのショートカットになっていてどこにも行けない。。。
こんなショートカットは削除だ。

この状態でインストールさせたところ・・・・できた!
やよいの青色申告も起動したぞ!!
Home版では起動しないAtokPadも動く!


はああああ、誰だよ、こんなところにショートカット作ったの・・・。
作成日時が2017/10/29だから、Fall Creator Updateされた日が怪しいのだが、確証はないな。

2017/11/02

[googlehome]IFTTTのThatをslackbotで受けとる

何をしたいのかだんだんわからなくなってきた・・・。

前回、IFTTTで、「This: Google Assitant」「That: Slack」にして、しゃべった内容をSlackに投稿するところまでは動いた。
しかし、slackbotはそれを読み込めず、例外が発生していた。


ログを出しながら見ていくと、msg['attachments'][0]['pretext']というところに文言が入っているようだった。

あまり深く考えず、pythonのslackbotを変更して、pretextを読むようにした。
https://github.com/hirokuma/slackbot/commit/c04aa038fb0c60d855adb5c4b8aefb6a777feba3


うん、これで@respond_toのparamsに文字列が入るようになって、slackbotも起動し、google-home-notifierを使ってしゃべってくれるようになった。

意味があるのかどうかはわからんが、

    1. 手元にあるGoogle Homeに話しかける
    2. Google Assistantが受け取る
    3. IFTTT経由でSlackが受け取って投稿
    4. それを相手側のサーバにあるslackbotが@respond_toで読込む
    5. nodejsでgoogle-home-notifierを使って文字列を送る
    6. 相手側のGoogle Homeがキャストしてしゃべる

という動作ができるようになった。

あとは、ここに翻訳APIを上手に挟めば、機械翻訳した言葉を相手に伝えることができそうな気がする。
ちょっと調べたけど、翻訳APIは有料サービスのところが多いのですな。

[googlehome]初めてのIFTTT

どうやら、IFTTTというサービスを使えば、Google Homeに音声コマンドを割り当てられるらしいということで、やってみた。


やり方は、いろいろなサイトに書かれているので、ここに書くまでもあるまい。
INPUTとOUTPUTは、ThisとThatという呼び方らしく、Google AssistantをThisに割り当てるそうだ。
まあ、Google Homeに話しかけても「はい、Google Assitantです」としゃべることがあるので、そうなのだろう。


今回は、ThatをSlackにした。
Slackの方には、Slackbotを立てていて、そこからnodejsのgoogle-home-notifierを呼び出せるようにしている。
そうすることで、

Google Home → Google Assistant → (IFTTT) → Slack → Slackbot → google-home-notifier → Google Home

という流れができる。

あー、回りくどい。。。


一番簡単そうな、しゃべった内容をslackbotに書込み、そのテキストをGoogle Homeに読み上げてもらうことにした。
たぶん、動いていると思う。
「たぶん」なのは、動いている先が職場に置いてある方のGoogle Homeなので、家で確認出来るのはSlackbotに通知されるところまでだからだ。
すまん、作業場にいる人々よ・・・。


難しいのは、Google Assitantに読み取ってもらうコマンドを作る部分。
「これなら聞き取れるだろう」と思う言葉を使っているのだけど、なかなかうまく読み取ってくれない。

AndroidアプリのAlloをインストールして、私がしゃべった内容をどう解釈しているのかを確認しながら進めた。
IFTTTの設定を「Japanese」にしているけど、キーワードのところはAlloで漢字変換している文字を書くべきなんだろうか?


いろいろ疑問はあるが、まあまあ認識してくれるようになったからよしとしよう。
なんとなくだが、Google HomeにGoogle Homeが理解できる指示を出すときの方が、Alloで認識させた場合よりも物わかりがよいように思う。
ちょっとしくみが違うのだろうか。


後日談


実際に、作業場に行って、動作状況を確認した。
・・・ダメだった。

Slackには投稿されているのだけど、slackbotがexceptionを起こしてしまうのだ。
slackbotの中の方で、なんだかよくわからない。
KeyErrorで'text'などと出ているのだけど、なんだろう?

2017/10/30

[nodejs][raspi]Raspberry Piにnodejsなどを入れる(2017/10)

Google HomeのためにVirtual Boxで動かしているUbuntuにgoogle-home-notifierをインストールしたのだが、ずっとVMを動かしているわけでもないので、単独で動いてくれる環境もほしくなった。

ああ、だからRaspberry Piでやっている人が多いのか・・・と気付く。
よし、インストールだ。


Raspberry Pi 1を使う。

OSは、2017-09-07-raspbian-stretch-lite。
適当にSDカードに焼いて、起動して、raspi-configでディスク領域を調整したり、SSHを有効にしたり。
aptのupdate/upgradeもやっておく。



noelportugal/google-home-notifier: Send notifications to Google Home
ここにRaspberry Pi用のやり方が書いてあるので、真似する。

真似したのだが・・・ちょっと足りなかった。

$ curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -
$ sudo apt install nodejs git-core libnss-mdns libavahi-compat-libdnssd-dev npm build-essential
$ sudo ln -s /usr/bin/nodejs /usr/bin/node

nodeコマンドはそのままではシンボリックリンクされてなかったし、npmも入ってなかった。
build-essentialは、いるのかどうかわからんが、どうせビルドするだろうからやっておいた。

$ git clone https://github.com/hirokuma/google-home-notifier-test.git
$ cd google-home-notifier-test
$ npm install

ここでかなり時間がかかっている。
・・・そして、404エラーが出てしまった。

npm ERR! 404 Not Found
npm ERR! 404
npm ERR! 404 'types/node' is not in the npm registry.
npm ERR! 404 You should bug the author to publish it
npm ERR! 404 It was specified as a dependency of 'ngrok'
npm ERR! 404
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, or http url, or git url.
npm ERR! System Linux 4.9.41+
npm ERR! command "/usr/bin/nodejs" "/usr/bin/npm" "install"
npm ERR! cwd /home/pi/Nodejs/google-home-notifier-test
npm ERR! node -v v4.8.2
npm ERR! npm -v 1.4.21
npm ERR! code E404
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR!     /home/pi/Nodejs/google-home-notifier-test/npm-debug.log
npm ERR! not ok code 0

/home/pi/Nodejsは、こっちで作ったディレクトリだ。

Ubuntuだとv8だったので「setup_8.x」にしてみたが、4.8.2しかインストールされん。
curlでnodesourceから取ってくるときに警告が出ているのだが、Raspberry PiのCPUだとソース提供されていないのかもしれん。


うーん、よくわからんが、デフォルトパラメーターでエラーが出ているようだから、削った。
ついでにexample.jsを削除し、package.jsonからも使わなくなったrequireを減らしていった。
正しいやり方なのかどうかはわからんが、これなら動いた。

https://github.com/hirokuma/google-home-notifier-test/tree/8a4f07c7f6193d129b20132381a5ebf9fba638aa

cloneしたままのexample2.jsだとIPアドレスが入っていないので、そこは自分のGoogle Homeのやつを入れておくれ。

端末の遅さのせいか、実行してから8秒くらいかかって、ようやくしゃべり始める。
そこそこ、端末側にもパワーがいるのだねぇ。

2017/10/29

[googlehome]avahiで名前解決させたい

Google Home miniだが、Androidアプリは自動で探すことができている。
何か名前解決するしくみがあるに違いない。

avahi-discoverというツールで接続されているかどうかは確認出来るらしい。

Discovery Troubleshooting  |  Cast  |  Google Developers

apt installしただけではavahi-daemonの立ち上げができなかった。
何も考えずに、こちらのssh.serviceをそのまま設定ファイルにすると、うまくいった。
avahi-daemonを設定してDNSサーバ運用をやめた - Qiita


image

おお、見えている。
AvahiはAppleのBonjourと同じようなプロトコルなのか、ツール名なのかわからんが、そんな感じのものらしい。
googleのものが2つ出てくるが、_googlecast._tcpの方がそれなのかな。


avahi-resolveでIPアドレスから名前を引けるらしい。
どーでもいい日々: mDNS、Avahi、Bonjour

やってみたのだが、これはavahi-resolveが失敗した。


困ったことに、ごにょごにょやっているうちに、pingが通るようになってしまった・・・。

$ ping xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.local

このxxx...のところは、UUIDっぽい。
Avahi Discoveryで見えるところの、_googlezone._tcpの下に出てくる名前の方でもあるし、_googlecast._tcpの項目にある"Address"でもある。

だから、jsファイルのip()も、その名前を書けばよいことになる。


ただ、デバイス名からアドレスを引っ張ってくる方はダメなようだ。
これはmdns.createBrowser()したインスタンスの中で起きているようだから、うちがnodejsをv8とかにしたせいかもしれん。
まあ、深くは考えまい。


AvahiというかmDNSというか、とにかく機器名からIPアドレスを探すという処理を使わないのであれば、google-home-notifier.jsからmdnsとbrowserは削除することができる。
それ以外で使っているのは、castv2-clientというやつと、google-tts-apiというやつか。

ttsは、Text to Speechの略らしく、文字をしゃべるということになるか。
うーん、これはわからん。。。
ただ、引数でしゃべる速度を変えるくらいだったらできそうだ。

speed()を追加してみた。example2.jsにサンプルを追加した。
デフォルトは1で、0に近づくとゆっくりになるようだ。
引数の説明で"0.24"という数字が出てきたので、それがゆっくりの下限なのかな?
https://github.com/hirokuma/google-home-notifier-test/tree/d75f4f314aa5bdcbd6da2e78d6be776d5d6e6acf

2017/10/28

[nodejs]google-home-notifierのインストール

ミーハーなことに、Google Home miniを買ってしまった。
職場にGoogle Homeを買ったのだけど、案外ものわかりがいいやつだということに気付いてしまったのだ。
それだけだったらまだしも、IFTTTとかでしゃべらせることができるらしい。
ならば、買わねばならぬのぅ。


Google Home、IFTTT、Googleスプレッドシートを使って独自音声コマンドでログをとる(ついでにNode.jsやngrokやらも使ってLINEやGoogle Homeに通知する) - Qiita
こちらを読むと、google-home-notifierというやつをインストールするらしい。

https://github.com/noelportugal/google-home-notifier

npmでインストールするらしい。
確か、node.jsとかの関係だよな。

$ npm install google-home-notifier

いろいろ出た後、ERRになった。。。
installだからsudoがいりそうな気もしたのだが、そういうエラーではないように見える。

sudo apt install npm node.js libnss-mdns libavahi-compat-libdnssd-dev

よくわからんが、そのページに書いてあって関係ありそうなものをインストールしたら、google-home-notifierもインストール出来たようだ。
WARNがいくつも出ているが、大丈夫よ・・・ね?


書いてあるサンプルをファイルに保存して実行してみたが、requireが見つからんと言われる。
心配になって、もう一度npm installしてみると、エラーではないもののnodeのバージョンが期待よりも古いといわれているようだ。
aptでは最新なのだけど、世の中の最新は別のところにあるらしい。

Ubuntuに最新のNode.jsを難なくインストールする - Qiita

aptではnodeはv4.2.6が最新だったのだけど、これをやるとv8.8.1になった。
全然違うやん・・・。


フォルダの中のファイルを消して、もう一度npm installしなおした。

npm WARN saveError ENOENT: no such file or directory, open '/home/xxx/package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open '/home/xxx/package.json'

なんかダメそうだ・・・。


npm installはあきらめて、こっちの方法でやることにした。
https://github.com/noelportugal/google-home-notifier#listener

手順の最後でexample.jsを動かすようだが、こちらを見ながらやっても改造がうまくいかん。。。
GoogleHomeスピーカーに外部からプッシュして自発的に話してもらいます - Qiita

もしかしたらRaspberry Pi用の説明なのかもしれんと思い、githubに書いてあった方のサンプルを簡単に改造した。

var googlehome = require('./google-home-notifier');

googlehome.device('地下室');
googlehome.accent('ja');
googlehome.notify('冷たいビールが飲みたい', function(res) {
  console.log(res);
});

このファイルをtest.jsという名前で保存し、

~/xxx/google-home-notifier$ node test.js
*** WARNING *** The program 'node' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node>
*** WARNING *** The program 'node' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node&f=DNSServiceRegister>
Device notified

こんなログは出るものの、ちゃんと日本語でしゃべってくれた。
あ、「地下室」というのは、うちにあるGoogle Home miniにつけた名前だ。
別に地下室じゃないんだけどね。。。


このサンプルは、google-home-notifier.jsを書き換えないと動かないやつになっていた。

var googlehome = require('./google-home-notifier');

googlehome.device('地下室', 'ja');
googlehome.ip('xx.xx.xx.xx');
googlehome.notify('朝ごはんは食べましたか?', function(res) {
  console.log(res);
});

デバイス名で検索出来ていたのかと思ったが、IPアドレスを指定している方が効いているみたいだ。
あるいは、デバイス名が英語だったらいけるのかもしれんと思ったが、ダメだった(abortする)。

device()で'ja'にしないと、notify()で日本語をしゃべってくれない。
つまり、しゃべってほしい言語はここで指定することになるようだ。

2017/10/27

[uml]シーケンス図の方向に悩む

データの流れや処理の流れを考えるために、UMLのシーケンス図を描くことがある。

そのときに悩むのが、方向をどっちにするか、だ。
対等な関係のライフラインが並ぶならそこまで気にしないのだが、だいたいはデータの提供元(input)が出てくるので、片方向の矢印を引くことになる。
それを、右側を提供元にするか、左側を提供元にするか、ということで悩んでしまうのだ。


いや、どっちでもよいのだよ。
全体として、その方向が統一して描かれてさえいれば、右だろうと左だろうと困りはしない。
単に、感覚としてどっちを提供元にした方がわかりやすいか、というだけのことだ。


一応検索して見たところ、左側に提供元を置く場合が多そうだ。
電気回路で電源を左側に置くとか、そんな理由なんだろうか?


では、割込の発生は左側に描くかというと・・・上記ルールにあわせるならば、私だと右側になるだろうな。
データの提供元=外面に近い、ではあるものの、アプリ層・ミドル層・ドライバ層、みたいな分け方になると、外面はアプリ層かな、と感じるからだ。
そういう意味では、アプリの階層でいう上位側が左、下位側が右、というところか。


じゃあ左がユーザに近い側かというと、そうでもなかろう。
ソフトウェアとしては、何らかの接点に一番近いのは階層だからだ。
ボタンなりディスプレイなりは、最後はそこで制御するしね。

image

ただ、そこまで細かいことをシーケンス図だけで表現してしまうと、とてもわかりづらくなりそうだ。
本末転倒になりかねないので、そこら辺は割り切ってしまう必要もあるだろう。
機能ブロックに分けて、ブロック単位で描くとか、細かいところは別の図にするとか、工夫がいりそうだ。

image


設計を図で描いていくと、変に細かいところまで同じ表現方法を使おうとして失敗してしまいがちなので、気をつけたい。
というか、今、気をつけねばならんのだ・・・。

[android][nfc]JPKIのASN.1を読む

OpenSCに入っていた、JPKを読込む部分を参考にして、例のカードの総合認証証明書プロファイルのASN.1ダンプを表示させるアプリをCSharpで作っていたものを、Androidでも動くようにした。

https://github.com/hirokuma/AndroidReadJpk/tree/8b68a801b254368f6a6a884ad843cd965aa5441f


起動させると、アプリのタイトルが「Read JPK PubKey」になっているが、あまり気にしないでおくれ。。。
それと、何が出力されているのかは聞かないでおくれ。。。

内容についてはよく知らんのだ。
暗証番号などを入力せずに読めるから、きっと公開鍵かなんかだろうと思ったんだけど、これはたぶん証明書にあたるものだ。
この中のどこかに、公開鍵が入っているんじゃなかろうかね?


元ネタは、こちらだ。
マイナンバーカードでSSHする - AAA Blog

元ネタの方では、2番目にSELECT FILEするのが0x0018になっているが、暗証番号を打ち込まないと読めないやつは怖いので、認証証明書というやつを読込むことにしたのだった。
データ構造はこれになるのかな?
https://www.jpki.go.jp/ca/pdf/cross_certificate_profile.pdf

このアプリではAPIを使ってダンプさせているため、文字列以外は中身が出てきていないようだ。
応用する方法が思いつけば何か作ろうかと思ったが・・・まあ、そういうのは今回は無しだな。

2017/10/26

[java]ASN.1をデコードするライブラリを探す

急に、AndroidでASN.1をデコードしたくなった。
人生は唐突だ。


OpenSSLのコマンドでダンプ出来た気がするのだが、どうもOpenSSLではASN.1の一部しかサポートしていないらしい。
今回読みたいデータがどうなのかわからないけど、二度手間は避けたいところだ。
https://stackoverflow.com/questions/5964269/asn-1-encoding-decoding

Androidの標準にはないような気がするので、Javaで検索した。
Parsing ASN.1 binary data with Java - Stack Overflow

ASN1InputStreamというclassがあるらしい。
親切にサンプルソースへのリンクも載っていて、org.bouncycastle.asn1たちをimportしている。


ここまでは分かったのだが、Android StudioにASN1InputStreamと書いても、いつものようにAlt+Enterで自動的に対処してくれなかった。
ということは、外部JARなどを追加しないといけないのだろう。

それはわかるのだが、これからどうしたらよいのだろう?


こちらが本家だと思われる。
The Legion of the Bouncy Castle Java Cryptography APIs

latest releasesページにJARファイルがあるので、それを使えばよいのか。


それはそれでよさそうだが、StackOverflowに貼ってあったサンプルソースのリンク先を見てみると、ディレクトリ構造?の先頭が「Maven-Central」になっている。
そういえば、pyCharmなんかでは、ライブラリを検索して追加する機能があったけれども、AndroidStudioにも同じようなものがあるかもしれない。

これか。

image

「bouncycastle」で検索すると、大量に出てきた・・・。
たぶん、mavenのこんなページと同じ感じで出てきているんではなかろうか。
https://mvnrepository.com/artifact/org.bouncycastle

bouncycastleのドキュメントページのこちらにasn.1があったから、今回は「provider」というやつを使えばよいのだろう。
latest releasesでいえばこれか。


ただ、ここまでわかっても、まだDependencyのところで絞り込み方がわからん。。。
「org.bouncycastle:bcprov-jdk15on:1.58」でよい気がするのだが、自信はない。
とりあえず追加してやると、ASN1InputStreamをAlt+Enterでimportしてくれたが、それでも自信が持てない。。。

2017/10/24

[nrf]Embedded Studio用も提供される

Nordicからのメールが来た。

最近、BLE開発から遠のいているのでスルーしようとしたのだが、気になる内容だった。

Nordic SemiconductorのnRF51とnRF52 SoC開発に Embedded Studio IDEのサポートが加わる / Product Related News / ニュース / ニュース / Home - Ultra Low Power Wireless Solutions from NORDIC SEMICONDUCTOR


Embedded Studioは、SEGGER社が提供している統合開発環境だ。
以前、評価用に使ってみたことがある。
hiro99ma blog: [nrf]nRF5 SDK for Eddystoneは動くのか? (9) - SES

これが1年半前のことだ。
このときは、無償で使えるのが評価用というか非商用だったので、評価だけで終わった。
当時は仕事としてもやっていたし、そこにお金を掛けるほどでもなさそうだったのだ。


で、今回の紹介を見ると「商用IDEを無償で利用可能」と書かれている。

NordicがEmbedded Studioのライセンス供与を受けたことにより、nRF5 SDKを使うデベロッパーは、nRF51とnRF52をフルにサポートする商用IDEを無償で利用できるようになりました

KeilでSTM32F1であれば制限なくて使えるように、Embedded Studioもそういう方式が使えるのかもしれない。


EclipseでもSEGGERのプラグインがあるので、無償の環境を作ることはできる。
ただ、やはり環境を一から作るのは面倒だ。
私も一度作った環境は、SDKのバージョンが上がっても使い回している。
Eclipseのバージョンが上がるといろいろやり直しになるので、もうEclipseは困らない限り固定バージョンだったりする。

次回、Nordicのチップを使うことがあれば、最有力候補になるな。


しかしまあ、私もここ1年くらい、あまり組込みっぽいことをやっていない。
FPGAもちょっと触っただけだし、今までやっていたNFCやBLEに至ってはほとんど触っていない。

まずい!
非常にまずい。。。

2017/10/21

[c/c++]URIスキームはラベル扱いになってしまう

お仕事でプログラムを作っている。
まだテスト段階なので仮実装が多く、忘れないように#warningなどで目印にしている。


だから、ビルドするとwarningはたくさん出てしまうのだが、エラーは出ないようにしている。
しかし、ソースを見直しているとこんな行が出てきた。

xxx {
   ...
   for (...) {
      ...
  }http://www.yahoo.co.jp/
}

参照したURLをコメントに書こうとしたのだろうが、間違えてソース中にそのまま貼り付けてしまったようなのだ。

にもかかわらず、エラーになっていない。
なんでだ?


単純なソースファイルにしてみる。

int main(void)
{
    http://www.yahoo.co.jp/
    printf("Hello, World!\n");
    return 0;
}

エラーにならないし、ちゃんと動く。


-Wallをつけてようやく分かったのだが、これは「http」というラベル扱いになったのだ。
こう書くと、printfは実行されずに終了する。

int main(void)
{
    goto http;
    printf("Hello, World!\n");

http://www.yahoo.co.jp/
    return 0;
}


何か使い道はないかと考えたが・・・ないな。
「なんか間違ってるよ」と思われるのがオチなので、やめておこう。

2017/10/19

[git]forkして作業するか、forkせずに作業するか (1)

githubでソース管理することを考えている。
まだ一人なので何とでもなっているのだが、そのせいでチーム開発向けのルールが考えついていないのを、なんとかしようとしているのだ。


いつもは、なるべく作業前にブランチを作って、そこで作業して、終わったらpull requestしてマージしてもらう、というやり方にしている(一人しかいないので、自作自演なんだけどね)。


まず、各作業をする人が同じリポジトリを使った方が良いのか、リポジトリを各人で作ってforkした方が良いのか、というので悩んでいる。

最初は同じリポジトリで試して、今は別アカウントでforkしている。
前者が使えるのは、リポジトリへのアクセス権をもらった場合(organizationに追加してもらうなど)だけのようだから、混ぜてやるなら後者しかないか。

前者の利点は、forkしていないから、git pullなどとすれば最新版がmergeできるというところか。
後者だと、相手のリポジトリにmergeしてもらったあと、fork先からのmergeという手段になってしまうと思うのだ。
GitHubでFork/cloneしたリポジトリを本家リポジトリに追従する - Qiita

今はそれでやっているのだが、けっこうfork先からのmergeを忘れてしまう。。
私が悪いと言えばそれまでなのだが、なまじどちらにも同じ権限を持っているだけに、どっちのリポジトリにマージしたのか忘れてしまうこともあった。

そのちょっと前までは、forkしたリポジトリでブランチを作って、fork先にpull requestしてmergeして、fork先からfork元にpull requestする、という2段階でやっていたのだが、さすがに面倒だったのでやめた。
githubでも、pull requestすると、最初にfork元が候補に出てくるから、直接やる方を推奨しているんじゃないかと思っている。


書いていて気付いたが、組織内であればforkさせる理由はあまりないか。
間違ってmainlineを直接編集してしまうという心配はあるのだが、それを避けたければREAD権限にして...forkしてpull request出すのが安全なのか?
branchにprotectをかけるということができるようだから、mainlineだけ保護してしまえばよいのかな?


しばらく、protectして使ってみて、また考えよう。

2017/10/18

[win]SysinternalsのStrings.exeと他のstringsで結果が違うがわからん

WindowsでSlackアプリを使っている。
未読があると、タスクトレイアイコンに赤か青のドットが表示されるのだが、見逃さないように通知領域に出している。

image

Slackアプリは更新が多く、困ったことに更新されると通知領域に表示させる設定がOFFに戻ってしまうのだ。
デスクトップ版もUWP版も変わらないので、OS側なのかな?


私の心が狭いのか、このOFFに戻ったときがどうにも腹立たしい。
「設定アプリ>個人用設定>タスクバー>タスクバーに表示するアイコンを選択してください」と、たどるのが深いのが、また腹立たしさをいや増す。

タスクバーの設定画面までは通知領域のコンテキストメニュー表示から飛べるのだが、最後の画面にたどりつくには、そこからリンクをクリックせんといかん。
設定画面への直接のURIはいくつかあるのだが、この画面に対しては存在しないようだった。


というのが、前置き。

調べていると、この記事が見つかった。

山市良のうぃんどうず日記(102):Windows 10 Fall Creators Updateで増える「設定」は「ms-settings:URI」で狙い撃ち (2/2) - @IT

この人は、DLLからURIを探し出して、Microsoftのページに書いていない画面も探すことに成功している。
私も同じことをしてみようと、フォルダまで飛んで、cygwinを立ち上げてstringsで文字列を出し、grepでフィルタ挿せた。
が、"ms-settings"が1つも出てこない・・・。

記事の時期のせいかもしれんと思ったが、2017年7月なので、それはなさそうだ。
念のため、Bash on Windows on Ubuntuでもやってみたが、結果は同じ。
むう。

最後に、書いてあるとおりにSysinternalsのStrings.exeでもやってみることにした。
こっちは、出てくる。
結果が全然違うのだ。
なんでー!


あり得るとしたら、Windowsだから2byteのUnicodeを使っていて、Sysinternalsはそれに対応しているから・・・か?
理由はよくわからんものの、Windowsアプリの文字列を取ってくるときにはSysinternalsの方を使うのが無難だということはわかった。

2017/10/17

トラックボールを使ってみる

技術ネタではないのだが、今回はトラックボールに持ち替えて1日目になるので、感想を書いておく。


歳を取ってきて、マウスによる腱鞘炎に悩むことも多くなった。。。
私の場合は、右人差し指の第2関節か、右親指の第2関節がよくやられる。

親指の方はよく理由が分からないのだが、人差し指はホイールを動かす量が多い場合だということがわかっている。
デバッグしていて、ひたすらログを上下に眺める状況が数日続くと、もう危ない。

ロジクールの、ホイールがするする回転するマウスを使うようになって軽減したのだが、限界はある。
中指で代用することもあるのだが、使い勝手が悪い。


マウス以外の選択肢となると、トラックボールかペンタブか。
ペンタブは用途に合わないので、トラックボールか・・・と思ったが、踏ん切りが付かない。

そういうとき、飲み会でトラックボールに変えた人がいたので、思い切ってやってみたというわけだ。


買ったのは、ケンジントンのトラックボール。
ネットで買うともっと安いのだが、ヨドバシでは5,100円だった。

image

前方後円墳みたいな見栄えになっているが、下の方は付属品のパームレストだ。
付けた方がよいのかどうかは、まだ悩んでいるところである。

ボタンは2つしかないが、アプリによって同時押しもカスタマイズできる。
私は中央ボタンに割り当てた。
ブラウザでは「戻る」が使えると便利なのだが・・・と思ったら、アプリ単位での割り当てもできた。

ホイールは、ボタンの周りをくるくる回すことになる。
私は親指と薬指で回している。
これのおかげで、スクロールはかなり楽になった。

ホイールのチルトによる水平スクロールはないし、カスタマイズするアプリにもないのだが、他のアプリでShiftキーを押したままホイール回転させることで代用できるものがあるらしい。
今のところ必要に駆られていないので、そういうときはマウスを使うことにしよう。


肝心の使い勝手だが、まだ思った位置にカーソルを動かすことはできないものの、素早い移動はしやすい。
一番難しいのは、ドラッグだ。
まあ、これもやっていれば慣れるんじゃなかろうか。

期待した方向に動かすことができないというのが、慣れの問題なのか、そうでないのか。。。
上下に動かしているつもりでも、ボールを動かす量が多いとぶれてしまうのだ。
ブラウザのマウスゼスチャーなんかは、あんまりうまくできていない。


このままトラックボールでいくか、マウスに戻るのかはわからないけど、もうしばらく使っていてもよいと思った。
とにかくよいのは、指の関節をあまり使わなくて済むところだ。
うまくいけば腱鞘炎対策になりそうだし、そうでなくても腱鞘炎になったらマウスからトラックボールにする、という選択肢が増える。

2017/10/14

[c/c++]16bit→32bitへの拡張は行われるが、32bit→64bitへの拡張は自動で行われない

ミスった・・・。

Windows 10 64bit(Bash on Ubuntu on Windows)
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.5)

#include <stdio.h>
#include <stdint.h>

int main(void)
{
    int32_t  a = -1;
    uint32_t b =  1;
    if (a < b) {
        printf("OK\n");
    } else {
        printf("NG\n");
    }
}


私は、符号違いのために64bitまで自動で拡張されてOKルートを通ると考えていたのだ。
たぶん、過去にも同じような記事を書いていたと思うが、そうではなくNGルートを通った。
変数が32bitではなく、16bitであればOKルートを通る。


『Cクイックリファレンス』のp.48に、同じような例が書かれていた。
まず、-1の方がuint32_tに変換されるのだ。
もちろん、明示的にint64_tに変換すればOKルートを通るのだ。


符号の有無が異なるところは、明示的にキャストした方が無難だな。
昔はコンパイラでwarningが出ていたような気がするけど、-Wallしても出ないんだよなぁ。
-Wだけの方がよいかもしれん。

2017/10/13

[git]間違ってcommitしてpushまでしてしまっても怒らない

ぼーっとしていると、gitの操作を間違うことがある。

昨日は、branchを作るのを忘れたまま作業してしまい、そのままcommitし、pushまでしてしまったのだ。
自分しか使っていないのでなんとでもなるのだが、あまり気持ちがよいものではない。


pushする前であればresetでもやるとよかろうが、pushしてしまうと、できないことはないらしいが、取り消さない方が良いそうだ。
まあ、そういう気はするな。

しかし、それをやってしまうことはあるだろうから、グループ内で運用する場合であっても怒らないような文化にした方がよいだろう。
やってしまいがちな操作を禁止して、やらかしたら怒る、というやり方は萎縮させてしまうだけだと思うので、手順を決めておきたい。


結局、こうやった。

  1. やってしまったcommitをrevertで戻す
  2. その状態でpush
  3. ブランチを新しく作って移動
  4. 1のrevertをrevert
  5. その状態でpush

どうせpushするつもりだったんだから、もうそれでいいや、という運用だ。

commit履歴のコメントが「最初のコメント」「Revert 最初のコメント」「Revert Revert 最初のコメント」と並んでしまうのだが、やらかしたんだな、くらいでスルーしてしまえばよい。


しかし、コメントに「Revert」と入るだけだったら、本当にRevertしたのか、コメントの文字列に書いただけなのか区別できん気がするのだけど、そこまで管理してるのかな?

[btc]bitFlyerのP2WSHアドレス

さっき、bitFlyerからメールが来た。
私はbitFlyerにアカウントを作っているので、アナウンスがあるとメールが送られてくるのだ。


いつも bitFlyer をご利用いただきありがとうございます。 P2WSH 方式の Segwit に対応いたしましたのでお知らせいたします。
 
【P2WSH 方式の Segwit に対応】
お客様が bitFlyer アカウントからビットコインを外部のビットコイン・アドレスへ送付する際のトランザクションを P2WSH(Pay to Witness Script Hash)方式の Segwit に対応しました。当社が世界初*で採用した P2WSH は数ある Segwit の実装方式で安全性及び技術的難易度が高いもので、アドレスが「bc1」で始まることが特徴です。


ほー。


この話は、BIP141と、BIP173に関連したものだ。


まず、「P2WSH方式のSegwit」から。

今のところ、Segwitの表現方法は4つある。
https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#examples

  • P2WPKH
  • P2WPKH nested in BIP16 P2SH
  • P2WSH
  • P2WSH nested in BIP16 P2SH

P2PKHのSegwit版がP2WPKH、P2SHのSegwit版がP2WSHと、名前に「W」が入る。
それに「nested in BIP16 P2SH」が付くかどうかだ。

P2SHというのは、「マルチシグ」が代表格で、複数の人が署名するようなタイプのアドレスだったり、個人じゃなくてスクリプトに署名したり、するタイプのアドレスだ。
個人向けの非SegwitアドレスがP2PKHで、そうじゃなく非SegwitアドレスがP2SHと思っておけばよいかな。


Segwitは、アドレスの方式ではなく、トランザクションの構成などを表すもの。
トランザクションの構成が違うから、アドレスも区別できるようにした、というところかな。

しかし、いきなり「明日からSegwitのアドレスだけにします」と言われても、他のアプリは急に対応できない。
だから、まずは純粋なSegwitのトランザクションではなく、P2SHの皮をかぶせたSegwitトランザクションを作ろう、ということになったんじゃなかろうか。
経緯は知らないが、構成としてはそうなっている。
それが「nested in BIP16 P2SH」とついているタイプのアドレスだ。

アドレスを見ただけでは、それがP2SHなのか、Segwitのnested in BIP16 P2SHなのかは区別が付かない。
区別が付かないから、従来のアプリもP2SHとして処理できる、というわけだ。


ただ、皮をかぶせている分、トランザクションのサイズは大きくなっている。
トランザクションのサイズが大きくなると、手数料に反映されてしまう(基本的に、トランザクションのバイト数で手数料が決まるので)。
だから、どこかでnested inじゃないアドレスを作って普及させねば、という課題があったのだろう。
そこで出てきたのが、BIP173だ。


今までのP2PKHやP2SHのアドレスは、秘密鍵にハッシュ計算を何回か行って作り出すものだ。
BIP173で使うBech32という方式?はそれとは異なる。
どう異なるかは、ここで書くにはとても足りないので、BIPを読んでほしい。
けっして、けっして私が理解できなかったわけではないぞ。。。。

BIPに、アドレスの例が載っている。
https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#examples

価値がある方のblockchainであるmainnetで使えるアドレスは「bc1」で始まっているのが分かるだろう。
bitFlyerのメールだけでは詳細が書かれていなかったのだが、たぶん、これを指しているのだと思う。

BitcoinのMainnetは「bc」、Testnetは「tb」で始まる。
これが「Human Readable Part」と呼ばれる部分だ。
まあ、直訳すれば、人間が読める部分、だな。

その次の「1」は単なるセパレータで、それから後ろが実際のデータ部になる。


Bech32になると、QRコードなんかで表現しやすいらしい。
だからというわけでもないけど、そのうちアドレスはBech32がメインになっていくのかもしれんね。

私ももうちょっと勉強しよう。
リファレンス実装があったので、仕様をよく読まずにC言語でmainnetとtestnetに限定したバージョンを作ったのだけど、regtestのことは考慮になくてね・・・。

2017/10/12

[btc]systemctlでbitcoindを起動させておく

当たり前だが、bitcoindは起動していない間はblockchainの同期を行ってくれない。
testnetしか使わない私だが、作業するたびに同期時間がかかるのは嫌なので、VMを立ち上げたときは起動したままにしているし、クラウド上のものもそうしている。

ただ、Linux自体を再起動したときに起動し忘れることが多々ある。
うちではUbuntuを使っていて、serviceよりもsystemctlを使うような感じがしたので、メモを残しておく。


Sample init scripts and service configuration for bitcoind

bitcoindのgithubに、簡単な説明が書かれているので、基本的にはこれに従う。


説明では、データを/var/lib/bitcoindに置くようだが、既に運用しているデータフォルダがあるし、ユーザも1人しかいないので、そっちを使い回すことにする。

systemdの場合はここに書いてあったが、Ubuntu16.02には /usr/lib/systemd/system というディレクトリが無かった。
作るほどでもないと思うので、 /etc/systemd/system に bitcoind.serviceというファイルを置いた。
個人のものをsystemd/systemに置くのもどうかと思うが、一人だと迷惑はかからんだろう。


ファイルの中身も、githubにサンプルが上がっている。
bitcoin/bitcoind.service at master · bitcoin/bitcoin

PIDは何番でもいいし、wallet機能はいるし、さっき書いたようにユーザも固定したいのでそこら辺だけ変更している。
UserとGroupが個人のもので、今運用しているのだったら、ExecStartは「/usr/bin/bitcoind -daemon」くらいで済んでしまう。

他の設定は、変更してもよいのだろうけど、このままでも困りそうにないので残した。


あとは、これだけやれば起動した。

$ sudo systemctl enable bitcoind.service
$ sudo systemctl start bitcoind.service

reloadするようなコマンドを打たないとダメだったような気がするのだけど、動いてるな・・・。
まあ、reloadせんといかんときはメッセージが出てきた気がするので、それに従えばいいんじゃなかろうかね。

2017/10/11

[c/c++]gccの-Dオプションで文字列を指定する

以前、INIファイル形式を読込みたいので、ライブラリを使った記事を書いた。

コメントとして「#」を許容させるためにあれこれやっていたのだが、ソースを見ると行頭の「;」と「#」はコメント扱いのようだ。。。
https://github.com/benhoyt/inih/blob/master/ini.c#L125

マクロの「INI_INLINE_COMMENT_PREFIXES」は、インラインだから、行の途中で見つかった場合にコメントとする文字のようだ。


前回はMakefile自体を変更したが、よそのgithubに入っているMakefileを変更するのは避けたい。
そういうときは変数が使えるようになっていると、なんとかできる。
inihでは「EXTRACCFLAGS」が外部用に用意されているようだった。

$ EXTRACCFLAGS="-g -O2 -D'INI_INLINE_COMMENT_PREFIXES=\"#\"' -DINI_STOP_ON_FIRST_ERROR=1" make -f Makefile.static

文字列は、シングルクオーテーションで囲むのがよさそうだった。
Makefile中ではないので、#をエスケープしなくても大丈夫だ。


シングルクオーテーションで囲むのは、-Dで関数マクロ形式を指定する場合の説明に載っていたやり方を真似しただけなので、もしかしたら文字列はもっと簡単なやり方があるのかもしれん。

2017/10/09

[zybo]これまでの復習

久しぶりにZyboを触ろうとしたが、どういうものだったか、何を調べてきたのかすら記憶に残っていないので、復習しておこう。



まず、CPU?として、XilinxのZYNQ-7000シリーズである、Z-7010が搭載されている。
PS部としてARM Cortex-A9(650MHz)が2つ。
PL部として7-series Artix FPGA相当のものが搭載されている。

PS部とPL部は、EMIO, AMBAなどのバスでつながっているようだ。


ARMのA9が載るだけあって、周辺も充実している。
RJ45もあるし、HDMI(I/O)、Dsub9のVGA、MIC IN, LINE, INもあるし、タクトスイッチやスライドスイッチ、GPIOのポート(Pmod)もある。
USBは、Type-Aもあるし、microBを使えばFTDIが載っているのでUSBシリアル変換でコンソールとして使うこともできる。

microSDカードもささり、そこから起動させるようなこともできるのだ。


なかなかよいのだが、発売がもう3年くらい前になるためか、情報があまり更新されていない。
FPGAの勉強用であれば、もうちょっと最近発売されているボードの方がおすすめだと思う。

Xilinxが発売しているボードであれば、Vivadoなどの開発環境で最初から設定が入っていそうだから、本筋にすぐ入っていけるのではなかろうか。
私なんか、おかげで、新しいPetaLinux(Xilinxが提供しているLinux環境)をZyboで動かすために数ヶ月かかってしまったぞ。

まあ、それはそれで勉強になってよいのだけどね。


おかげで、まだVHDLとかVerilogとかにはほとんど手を出していない。


FPGAというと、なんとなく組込みジャンルで考えていたのだが、ZyboみたいにOSが載る環境で使えてしまうと、もっと違う使い方をした方がよいような気がしてくる。

もちろん機器の制御もできるけれども、ハードウェアに近い部分でロジックを作ることもできるのだ。
そうなると、柔軟な並列演算処理装置、という見方もできよう。
GPUで仮想通貨のマイニングしたり、ディープラーニングの演算をさせたりするような、そんなイメージだ。

私はCortex-M系のマイコンを使うことが多かったのだが、A系だと電池で動かすこともないだろうし、動作クロックもそうとう高い。
Linuxを載せたとしたら、デバイスの制御にはデバイスドライバを介することになるだろう。
割り込み処理ですれスケジューリングされてしまうはずだ。


そうなると、少々のことであればPL部を使う必要がないはず。
PS部からGPIOで制御した方が、自由がききやすいと思う。
そうなっていないということは、A9とOSが載った環境ですら難しいことをPL部にやってもらうのがよいのではなかろうか。

ということで、結果的に「FPGAのFPGAっぽい部分をがんばるべし」という結論になった。
何をがんばればよいのかわからんけど、GPIOみたいなものの制御ではなく、並列でロジックを書けるようになるとか、そういう方向がよいのかな?

[xilinx]SDx 2017.2が出ていた

3連休なので、FPGAのことをやることにした。

最後にFPGA関連で更新したのがは、PetaLinuxをPC-Linuxでビルドする話の最終回で、ちょうど1ヶ月前(2017/09/09)だった。
あれからVivadoなども起動せずにいたのだが、今日Xilinx Information Centerを起動すると、SDx 2017.2が出ていた。
リリース日が09/05になっているから、単に私が見逃していただけのようだ。

image

Xilinxのすごいところは、リリースノート(pdf)なんかも日本語版を用意するところだ。
過去の分から作りやすいだけなのかもしれないが、いやいや、すごいもんですよ。


さて、いまSDxをインストールしているのだが、これにはVivado 2017.2も含んでいる。
使ったこと無いけど、Vivado HLSも含んでいる。
リリースノートからすると、XSDKに入っているのと同じARMのToolchainを含んでいるそうだ。
だから、XSDKでできることがSDxでもできるのであれば、SDxだけあればよいはずだ。


SDxがインストールできるのは、Zybo購入時にSDSoCのライセンスを購入しているからだ。
つまり、WebPACKではないので、WebTalkをオフにすることができる。
まあ、仕事で使っているわけでも無いし、変な動作をしないなら気にしないのだけどね。


あとは、私がこれらを使いこなせるかどうかなのだが・・・まだ全然ダメだ。
まずは、LED以外のチュートリアルを動かして遊んでみよう。


SDxでインストールされたVivadoを起動すると、ウィンドウの名前は「Vivado 2017.2_sdx」という名前になっていた。
微妙に違いがあるのかもしれん。

Vivado 2017.2で使ったことのあるプロジェクトがRecentとして出てきたので、そこら辺は共通なのか。
ただ、IPのリビジョンが微妙に上がっていたようで、そこはUpgradeした(プロジェクトをVivado 2017.1で作ったままだったかもしれない)。


Upgradeしたあとは、Bitstreamを作り直す。
プログレスを示すくるくるが出てくるようになった。
できれば、右下に出てくるか、最小化しないようにできるとありがたいのだが、まあぜいたくは言うまい。

いまRunning synth_designが実行されているようなのだが、とても長い。。。
そんなにPCの性能は悪くないと思うのだが、うたた寝しても良いくらいの時間はかかっているだろう。

ようやく終わって、Exportしなおして、Launch SDKすると、SDxが起動した。
以前、XSDKで作っていたプロジェクトが表示されている。


ということは、SDxがインストールされていれば、VivadoとXSDKは個別にインストールしなくてよいということになるな。


ついでに、SDxのチュートリアルをやっておこう。
SDxのリリースノートから、ug1028-sdsoc-intro-tutorial.pdfというSDSoC環境チュートリアルがたどれたのだ。

チュートリアルをやりたいというよりは、SDxでZyboを使ったデバッグができるのかを試したかったので「6.デバッグ」だけにする。


説明はZC702ボードになっているが、Zynq-7000デバイスであればよいらしい。
Zyboはそうなので、動くのだろう。
スタンドアロンアプリケーションをダウンロードして実行するところまで行えるそうだ。

ボードの設定は、SDカードがどうのこうの書かれているが、microUSBで電源とUARTを確保し、起動モードはJTAGにした。
以前System Debugをした感じからすると、他のモードでも動くんじゃないかと思うが、演習に関係するところだけ確認させたいのでそうしているようだ。


次は、スタンドアロンプロジェクトの作成。
書いてあるとおりにやっていくだけだ。
最後に「Build Project」するのだが、これが重くて長い。。。
15分以上やっているが、まだ25%だ。

結局、26分くらいかかりました。

image

すごいスペックというわけではないけど、けっこうよいスペックじゃないかと思うのだが、どうだろうか。
ウイルス対策ソフトがDefenderなので、そこで時間かかったりするのかもしれん。


デバッグは、Eclipseでデバッグするときの要領でよいが、選択するのは「Launch on Hardware(SDSoC Debugger)」だ。
似たような項目がたくさんあるので、赤文字のところを気にしておこう。
選択すると、パースペクティブを変更するか聞いてくるので、Debugに切り替える。
そうすると、mainで止まった状態が表示される。

ZyboのUARTというかシリアルポートというか、それをターミナルにつないでおく。
私はTeraTermにした。


ブレークポイントで止まった状態なので、再開アイコンをクリックする。
そうすると、ターミナルに何か出てきて、SDxの方は_exitで停止した。
ブレークポイント一覧を見ると、mainと_exitに設定されていたので、これでよいようだ。

Testing 1024 iterations of 32x32 inting point mmultadd...
Average number of CPU cycles running mmultadd in software: 1145442
Average number of CPU cycles running mmultadd in hardware: 19192
Speed up: 59.6833
TEST PASSED


何をやったのかはわからんが、行列演算で使いそうな計算をPL側に持っていったことで高速化したとか、そんな感じではなかろうか。
まったくVivadoに触ってないし、FPGA Programなんかもやっていないから、うまいこと使いこなせると私のようなソフト屋さんには便利そうだ。

2017/10/07

jqコマンド

最近、JSON-RPCで指示を出して、その結果を取得するようなプログラムを作った。
ネットでよくある、JSON整形してくれるページで結果を確認したので、まあ間違ってはいないようだ。


JSON形式は、あまりお好きではない。
理由は、コンマだ・・・。

最後のデータにコンマを許可しないというルール故に、出力するときはひどく面倒なのだ。
まず、1行目の先頭にコンマがあってはならないので、1行目は普通に出力する。
2行目があるなら、コンマを出力してから2行目を出力することになる。
そして、それを繰り返していき、最後のデータの場合はコンマ無しで終わらせる。


順番にデータを掃き出すときはそこまで困らないのだが、嫌なのはforなどでぐるぐると掃き出したい場合だ。
コンマを出力する処理を、行の出力を行う前に置くか、後に置くか。。。
前に置くと、1行目だけコンマ出力をスキップする、という処理がいるし、後に置くと「次のデータがあるか」をチェックする処理がいる。
それが嫌だったら、1行目の出力と2行目以降の出力を分け、forですぐにコンマ出力するようにしておけばよいが、コンマのためだけに処理を分けるのも腹立たしい。

最後のデータにコンマを許可するか、あるいはコンマを無くしてしまう構造だったら悩まなくて済むと思うのだ。
まあ、データ構造に文句を言っても仕方ないのだが・・・。


JSON形式で出力するのが面倒であることを書きたいだけの記事なのだが、それだけでは何なのでjqコマンドのことを書こう。

Ubuntuではapt-getでinstallすることになるが、jqというJSON形式のデータを整形したり加工したりできるコマンドがある。
非常に多機能なのだが、自作で掃き出したJSON形式の改行やスペースが見づらかったとしても、引数無しでjqコマンドを通すだけで見やすくなる。

$ ./cli/lightning-cli getinfo
{ "id" : "02d030cf51591116155597cee2cbf8bb432fa01b691c055d329b51c838fd754130", "port" : 9735, "network" : "testnet", "version" : "v0.5.2-2016-11-21-964-geedbd1d", "blockheight" : 1209621 }


$ ./cli/lightning-cli getinfo | jq
{
   "id": "02d030cf51591116155597cee2cbf8bb432fa01b691c055d329b51c838fd754130",
   "port": 9735,
   "network": "testnet",
   "version": "v0.5.2-2016-11-21-964-geedbd1d",
   "blockheight": 1209621
}

ほら、この通り!
カラーが使えるコンソールであれば、パラメータとデータで色分けもしてくれるし、データも数値か文字列かで色が変わってくれるので、見やすい。


いま見ているgithubのサイトで、よくわからない使い方をしているので、なにやっているのか見ておきたい。

https://github.com/ElementsProject/lightning#receiving-and-receiving-payments

route=$(cli/lightning-cli getroute <recipient_id> <amount> 1 | jq --raw-output .route -)

cli/lightning-cliコマンドが何を出力するのかはあまり関係ないのだが、例がないと分かりづらいので載せておこう。

{ "route" :
         [
                 { "id" : "aaa", "channel" : "1207790:27:0", "msatoshi" : 101023561, "delay" : 92 },
                 { "id" : "bbb", "channel" : "1207703:21:0", "msatoshi" : 100511006, "delay" : 56 },
                 { "id" : "ccc", "channel" : "1207785:11:0", "msatoshi" : 100001001, "delay" : 46 },
                 { "id" : "ddd", "channel" : "1207779:2:0", "msatoshi" : 100000000, "delay" : 36 } ] }

コマンドの1行としては、「route=$(中身)」が外側で、その中身がjqの結果になるのだと思う。
では、cli/lightning-cliコマンドが出力した内容をjj.txtというファイルに保存したとすると、こうなるはず。
青文字が結果だ。

$ cat jj.txt | jq --raw-output .route-
[
   {
     "id": "aaa",
     "channel": "1207790:27:0",
     "msatoshi": 101023561,
     "delay": 92
   },
   {
     "id": "bbb",
     "channel": "1207703:21:0",
     "msatoshi": 100511006,
     "delay": 56
   },
   {
     "id": "ccc",
     "channel": "1207785:11:0",
     "msatoshi": 100001001,
     "delay": 46
   },
   {
     "id": "ddd",
     "channel": "1207779:2:0",
     "msatoshi": 100000000,
     "delay": 36
   }
]

「route」要素だけを出力したことになるのかな?
ただ、これを環境変数?に代入して、echoなどで掃き出しても、改行が残らないのだ。

$ route=$(cat jj.txt | jq --raw-output .route -)
$ echo $route
[ { "id": "aaa", "channel": "1207790:27:0", "msatoshi": 101023561, "delay": 92 }, { "id": "bbb", "channel": "1207703:21:0", "msatoshi": 100511006, "delay": 56 }, { "id": "ccc", "channel": "1207785:11:0", "msatoshi": 100001001, "delay": 46 }, { "id": "ddd", "channel": "1207779:2:0", "msatoshi": 100000000, "delay": 36 } ]

最後のハイフンがそういう意味なのかと思ったけど、ハイフンを外しても結果が変わらんかった。
tarコマンドで、標準出力とか標準入力とかを使うときにハイフンを付けるのと同じ意味のように思う。
じゃあ、パイプじゃなくてもいいやん、というか、パイプで書いているからハイフンがなくても動いているのかもしれん。


とにかく、何が言いたかったかというと、バイナリデータ最高!、ということでした。。。

2017/10/06

AzureでVM作った後にNSGを変更する

まったくの個人メモです。

Azureの使い方がよくわかってないけど、がんばってVMをたくさん作った後で、設定するネットワークセキュリティグループを間違えていたのに気付いたときの変更方法。



  1. 変更したいVMをクリック
  2. 左から「ネットワーク」をクリック
  3. 上に出ているネットワークインターフェイスをクリック
  4. 左から「ネットワークセキュリティグループ」をクリック
  5. 上の「編集」をクリック
  6. 現在のネットワークセキュリティグループが表示されるので、クリックし、気に入ったものをクリック
  7. 上の「保存」をクリック


ネットワークインターフェイス名が分かっているなら、リソース一覧から選択した方が早いな。

2017/10/05

[md]markdownで改行しようとスペース2つ付けたらMD009

Visual Studio Codeをしばしば使っている。

markdownに便利なExtensionsもあるので、適当にインストールしているのだが、それからLINTのようなものが働いて動的に指摘が入るようになった。
あまり慣れていないので助かる。

指摘と言っても、エラーになるわけではないから、無視してもよい。
pyCharmでpythonを書いたときに指摘されるような、あんな感じだ。


指摘を見ていると、改行しようとして行末にスペースを2つ入れているところに何か出ていた。

image

スペースをつなげるなって?
でも、markdownの改行は、行末にスペース2つじゃなかったっけ。。。


https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md#md009
https://github.com/markdownlint/markdownlint/blob/master/docs/RULES.md#md009---trailing-spaces

改行についてはbr_spacesというオプションで指定することで回避できそうだが、デフォルトは0だし、vscodeのオプションにはそれっぽいものが出てこなかった。
今回は、MD009はfalse設定にすることで、見過ごすことにしよう。。。


デフォルトが0ということは、markdownの改行はあまりやらないのか、他の手段を使っているということなのか。
英語だと、段落になるまでずらずらつなげて書くのかもしれないけど、日本語だと「ここで別の行にしたいが、段落を変えたいわけではない」ということがあると思うので、そういう違いなのかもしれん。

2017/10/02

[c++]boost::tie ?

前にboostを使って最短経路を求める(1,2,3,4,5)というのをやった。
そのときは目的を達成できてよかったのだが、今になってよくわかっていないところがあることに気付いた。

サンプルソースのここで並び替えを行っているのだが、本業ではこの箇所で辺(edge)に載っているデータを使って計算するようにしていた。

bool found;
graph_t::edge_descriptor e; boost::tie(e, found) = edge(v, p[v], g);

これで、foundがtrueになれば、該当するedgeの番号がeに入ったことになるらしい。

しかし、別の箇所では

boost::tie(e1, inserted) = boost::add_edge(v1, v2, graph);

などとしている。

単に戻り値をeやe1に入れるだけなら、boost::tieなどいらないはずだ。
そもそも、boost::tieってなんだ??


http://www.boost.org/doc/libs/1_65_1/libs/tuple/doc/tuple_users_guide.html

tupleは要素数固定のデータ集、でよいのかな?
そして、tieはtupleだけど要素が固定値ではないもの・・・?


std::pairは2つ限定だし、std::tupleはC++11からのようだから、boostにあったtupleがC++11に入ったのかな?
よく見ると、std::tieもC++11にあるそうだ。
boostのtieとstdのtieは同じものだろうか?

いろいろ疑問はあるが、今回はboost::tieの使い方を知りたいだけだ。
消極的だが、やむを得ん。


int i; char c; double d; 
tie(i, c, d) = make_tuple(1,'a', 5.5);

左辺にtieを置いても、ちゃんと使えるようだ。

ということは、最初に挙げた例のfoundやinsertedも、単に変数として使っているだけか。

いや、この引数がboost::tie::inserted、みたいな役割を持っていて、それによって何か結果が変わってくるんじゃないかと心配していたのだ。
自分でbool変数を作っているのだし、それはないか。


これで終わらせようとしたが、さすがにサンプルコードくらいは書かねばなるまい。

/*
 * $ g++ -o tst tietie.cpp
 */
#include <iostream>
#include "boost/tuple/tuple.hpp"

int main(void)
{
    int a;
    std::string b;
    boost::tie(a, b) = boost::make_tuple(123, "yoshio");
    std::cout << a << ", " << b << std::endl;
    return 0;
}

123, yoshio


まあ、そのまんまですな。。。

なんというか、局所的な構造体っぽい使い方ができるのかな?
ただ、戻り値を構造体にするとなると、構造体を定義して、実装側と使う人がincludeなどで共通の構造体を使わないといかんけど、tieだと型と順番が揃っていればよい。

けど、だったら構造体でもいいんじゃないの、という気がするが、構造体が増えていくのも面倒な気がする。
型は同じだけど用途が異なるので、中身が同じ構造体を別に用意する、みたいなことはしなくてよいか。


なんとなく、gcc -Sでアセンブラ展開すると、700行近くなった。
試しに、2行追加してみる。

/*
 * $ g++ -o tst tietie.cpp
 */
#include <iostream>
#include "boost/tuple/tuple.hpp"

int main(void)
{
    int a;
    std::string b;
    boost::tie(a, b) = boost::make_tuple(123, "yoshio");
    std::cout << a << ", " << b << std::endl;

    boost::tie(b, a) = boost::make_tuple("yoshio", 123);
    std::cout << a << ", " << b << std::endl;

    return 0;
}

これをアセンブラ展開すると、1200行ちょっとになる。
順番が違うから、それに応じたコードを生成するしかないのか。


では、同じtieの並びで変数が違ったらどうなる?

/*
 * $ g++ -o tst tietie.cpp
 */
#include <iostream>
#include "boost/tuple/tuple.hpp"

int main(void)
{
    int a;
    std::string b;
    boost::tie(a, b) = boost::make_tuple(123, "yoshio");
    std::cout << a << ", " << b << std::endl;

    int m;
    std::string n;
    boost::tie(m, n) = boost::make_tuple(123, "yoshio");
    std::cout << a << ", " << b << std::endl;

    return 0;
}

これは、750行程度だった。

変数mを、int型からuint8_t型に変更すると、972行。
uint64_tにしても同じだった。

C++のテンプレートは、基本的にマクロの拡張のようなものだったと思うので、uint8_tはint内に収まるから、途中は全部int型で処理して最後にキャストしてやろう、みたいなことはできないのだろう。

まあ、今回は最適化したわけでもないし、アセンブラにして眺めただけなので、違いは出てくるかもしれんが、コードサイズが大きくなることを心配するのであれば、そこら辺は実装側で気をつけねばならんだろうな。

2017/09/29

[btc]bitcoinはあやしいのか、という話はあまり意味が無いと思う

正直なところ、どうでもよい話なのだが、ネタが無いので。

Googleニュースで、キーワードを設定しておくと適当に拾ってきてくれる。
「bitcoin」「blockchain」などのキーワードを設定していると、それなりにニュース記事を拾ってきてくれるようだ。
比較的新しいけど、最新というわけでもないから、閲覧されている順番とか、そんな順かもしれない。

ニュースの内容は、だいたいこういう感じだろうか。

  • どこかが実証実験した
  • どこかがブロックチェーンで何かすることにした
  • 仮想通貨に関する誰かの意見

意見の記事は、かなりの確率で仮想通貨に否定的な内容だ。
あやしいとか、バブルだとか、信用ならないとか、バブルだとか・・・。


まあ、気持ちはよくわかる。

その方面の技術の人じゃなかったら内容を判断することができないので、投資・投機だけやっている人は困るだろう。
今までの知識が役に立たないとき、だいたいは拒否する方を選ぶものだ。

銀行みたいにお金を取り扱うところは、また訳のわからんものが出て・・・と思うかもしれない。
あまり日本の銀行には技術者が多くないという話を聞くので、技術的に分からなければ遮断する方向に行ってしまうだろう。

逆に、技術の人からすると、価値が上がったり下がったりするのは技術のせいじゃないので、知ったことではないと思う。
私はbitcoinしか見てないので、最近はやりのICOなんかは詳しくないのだが、見る人が見るとあやしいものはわかるんじゃないかと思う。
ソースが公開されていれば内容を調べればよいし、公開していないなら調べようがない、というだけだ。


そういう感じだと思うので、全部に通じているような人じゃなければ、あまり相手にしない方がよいかもしれん、とは思う。
私も技術だけしかわからないので、もうちょっと視野を広げないとなー、という気持ちだけは見せている。


仮想通貨は、株式よりも外貨取引に近いと思う。
ただ、どこかが発行しているものではない、というのが「仮想」なのか。

この部分が「発行しているところがないお金なんて信用できない」と「発行しているところがないので安心」のどちらかになるんじゃなかろうか。
そこに価値を見いだす人は買うだろうし、見いださない人は買わないだろう。
買う人が多いと、需要が増えるから、価値が上がる。


ただ、価値が上がった下がったといっても、技術自体がなくなるわけじゃない。
もし、あれこれあって、bitcoinが使えない状態になってしまったら、面倒だろうけど、別の安定した仮想通貨で技術を延ばすだけだ。
bitcoinはわかりやすくて気に入っているのだが、まだまだ私もこの分野では新米なので、あれこれ学んだ方が良いのかもしれんしね。


ごにょごにょ書いていったが、

  • 全体的に見て、よいと思うのであれば、認めてよいのではないか
  • よくわからないなら、そのまま触らなくても問題ないと思う
  • 金儲けの手段としてしか見ない人がぐいぐい言ってきたら、仮想通貨よりも人格を判断した方がよい

というのが今のところの感想だ。

2017/09/27

[c/c++]メモリリークしていると思うが、どうしたものか

アプリのバージョンアップで変更履歴を見ると、ときどき「メモリリーク修正」みたいなものがある。
メモリリークなんて、最初からがんばればよかろうに・・・と若い頃は思っていた。

というよりも、組込みソフトの場合、動的にメモリを取らず、静的にメモリを確保することが多いので、気にしていなかったのかもしれない。
静的に取ることが多いのは、

  • そもそも動的メモリがない(mallocがないなど)
  • 同時に動的メモリを確保して足りなくなることがあってはいけないので、最初から確保しておく

などという理由なんじゃないかと思う。

私の場合は、mallocが無いので、そもそも動的メモリという選択肢がない、という場合が多かった。
まあ、OSが載ることもほとんど無いしね。


ここ半年くらい、PCのLinuxでソフトを書いている。
もちろん、mallocなんか普通に使える。
同時にメモリを確保して足りなくなるなんてことが、ほぼない。
そもそも、PC Linuxで作ることを前提にしているので、リソースは十分にあるものという仕様になっている。
であれば、動的メモリを使わない必然性がなくなってしまう。


なんとなく気付いたかもしれないが、私は動的メモリが苦手なのだ・・・。
なるべくがんばったので、やったことを書いておこう。


前提として、C言語のみ、だ。


malloc系のAPIとfree()をマクロにした

出落ち感があるが、これに尽きる。

マクロにしておくと、例えばmallocしたところを__FILE__と__LINE__で出すことができる。
inlineにしていても、これはできないと思うのだ。

static変数を使って、通過したカウンタなんかを付けるのもやる。
malloc系でインクリメントして、free()でデクリメント。
全部解放していると思っているところでカウント値を見れば、簡易的なチェックには使える。



valgrindする

してたんだけどねぇ。。。
とにかく、終了するアプリじゃないので、valgrind結果を見るタイミングがない。
unit testのときには使えるのだけど、mallocするタイミングとfreeするタイミングが別々になることが多くなると、unit testでは漏れが確認できない。

というよりも、アプリが終了しないので、動的にチェックできたとしても、今が解放されているべきなのか、そうでなかったらいくつ確保されているべきなのか、というのは状態によって異なるので、結局ログを全部追わないとわからんかったりする。

デストラクタとかガベッジコレクションのある言語が憎たらしくなるのは、こういうときだ。


しかし、もう2017年も後半になってきた。

実は、私が知っている手段以外によいものがあるかもしれない。
それに、オライリーの「Debug Hacks」から読み直すべきかもしれん。
組込みで使えそうなところ以外は読んでいないからだ。

2017/09/20

JavaScriptの整数範囲はJSONに影響するのか?

以前、JSON-RPCをやるのにuint64_t対応したライブラリが見つからない、という話を書いた。

結局、内部でしか使わないからいいや、ということで、jsonrpc-cをforkして、uint64_tにだけ対応させることにした。


それはそれでよいのだけど、世の中にはあるんじゃなかろうかと探していた。
同じ疑問を持つ人がいた。
c++ - Does libjson support 64 bit int types? - Stack Overflow

libjsonは知らんのだが、回答からすると、JavaScriptは内部的に53bitまでの制限があるよ、ということらしい。
ECMAScript仕様のページにリンクが貼られていて、確かにごにょごにょ書かれている。


こちらは、ECMAのJSON仕様(pdf)だ。
ただ、JSONのtext format仕様なので、値の範囲がどうのこうのということは書かれていない。


だから、やはり安全にいくなら、uint64_tは文字列にする方がよいのだろう。
32bitずつにして、上下で表してもよいかもしれんが、とにかく表せないかもしれない書式を使うのは危ないかもしれん。
まあ、そんなことをいえばint64_tだって53bit以上あるのだから同じことか。


それだったら、いっそのこと全部の数字を文字列で表せばいいやん、みたいな気持ちになってしまうので、深追いは止めよう。
大人の対応というのは、最終的に自分への負担が減る対応にするべきなのだ。。。

2017/09/18

[vscode]gdbを使ってみよう(2017/09/18)

コンパイラとしてgcc系のものを使うことが多いので、デバッグもgdb系になる。
が、何十年もやっていながら、未だにgdbに慣れていない。。。

だが、世の中にはGUIで隠してくれるデバッガもある。
dddやinsight、eclipseもプラグインで対応できる。
nRF51をデバッグしていた頃はeclipseを使っていたのだが、起動が重たいので、動かすかどうかをためらうこともあった。

最近、Visual Studio Code(以下、vscode)を使うことが多くなったので、そっちでも同じようなことができそうな気配がする。
まずは、vscodeでgdbを使ったデバッグをしてみよう。


vscodeは更新が多く、また機能をextensionsで実現することも多いため、最新版ではここに書いていることが使えなくなっているかもしれない。

こちらは、2017/08/18に更新されているので、これを眺めながらやっていく。
C++ Programming | Visual Studio Code Docs


ビルドはコマンドラインでやってもよいのだが、せっかくなのでvscodeからやってみよう。
昔やった、lmdbのサンプルコードがあったので、それで試していく。
コード自体はどうでもよいのだが、Hello Worldみたいなサンプルではわかりづらいので、多少込みいったものを選んだだけだ。


サンプルは、こうやってビルドできた。

$ gcc -o tst ex1.c -llmdb -pthread

そのフォルダでvscodeを起動。

$ code .

ファイルで開くとダメそうな気がするので、ディレクトリ指定で開くとよいかもしれん。
その状態で Ctrl+Shift+B を押すと、タスクがないよ、というメッセージが出てくる。
「Configure Build Task」の方をクリックすると、4択になるので「Others」を選択。
すると、.vscode/tasks.jsonというディレクトリとファイルを作ってくれる。

tasks.jsonは、こんな感じで書く。

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "taskName": "gcc",
            "type": "shell",
            "command": "gcc -Wall -ggdb -o tst ${relativeFile} -llmdb -pthread",
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "problemMatcher": {
                "owner": "c",
                "pattern":[
                    {
                        "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
                        "file": 1,
                        "line": 2,
                        "column": 3,
                        "severity": 4,
                        "message": 5
                    }
                ]
            }
        }
    ]
}

リンク先よりもversionが上がっているので、変わりやすいのかもしれん。


"group"を書いて、"kind"を"build"にしないと、Ctrl+Shift+Bでビルドしてくれなかった。
"problemMatcher"を書いておくと、それに引っかかった出力がタブ「PROBLEMS」に出てくれる。
${file}だとフルパスになるためか、PROBLEMSをクリックしてもファイルがないと言われてしまった。
${relativeFile}だとvscodeを開いたディレクトリからの相対パスになるようで、そっちだとOKだった。


makeしたい場合は、こんな感じで書いた。

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "taskName": "make",
            "type": "shell",
            "command": "make",
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "problemMatcher": {
                "owner": "c",
                "pattern":[
                    {
                        "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
                        "file": 1,
                        "line": 2,
                        "column": 3,
                        "severity": 4,
                        "message": 5
                    }
                ]
            }
        }
    ]
}

ただ、これは統合開発環境じゃないから仕方ないのだが、problemMatcherは出力をなぞるだけのため、Makefile内でディレクトリ移動してMakefileを呼び出す、みたいなことをやっていると、ファイルを見つけられないようだ。

make用のExtensionsがあるのかもしれんが、まあ今回はよかろう。


次はgdb。

https://vscode-doc-jp.github.io/docs/languages/cpp.html#%E3%83%87%E3%83%90%E3%83%83%E3%82%B0
https://code.visualstudio.com/docs/languages/cpp#_debugging-your-code

どっちを見ても、launch.jsonというファイルを作れ、と書いてある。
仕方ないので、.vscodeディレクトリで右クリックし、「New File」でlaunch.jsonを作った。
そうするとlaunch.jsonファイルがタブで開き、右下辺りに「Add Configuration...」というボタンが出てきた。

ボタンを押すと、versionなどのテンプレートが出てきたので、Enterを押して確定。
まだボタンが出ているので押してみると、追加する中身のテンプレートが選べるようだった。
せっかくなので、C++のLaunchするやつを選択。
これはありがたい。


と、ここまでやってリンク先を見たら、Debug Viewにしてやればファイル作成などは勝手にやってくれたみたいだ。。。
悔しいので、.vscode/launch.jsonを消してやり直す。

まず、左側のデバッグっぽいアイコンをクリックし、Debug Viewにする。
設定してくれそうなアイコンが出てくるので、クリック。
そうすると、さっきのような選択が出てくるので、C++のgdbできそうなものを選択。
まあ、できるファイルは同じっぽいな。


"program"は書き換えないといかんだろう。
"${workspaceRoot}/tst"にする。
ファイル保存して、Viewにあるデバッグ開始しそうなアイコンをクリック!

・・・開始エラー?
よくわからんのでもう一度押すと、今度は動いて、設定していたブレークポイントで止まったようだ。
たぶん、launch.jsonの"stopAtEntry"を設定しておくと、その関数で止まるようになってるんじゃなかろうか。


変数名にマウスを当てると中身が見えるし、構造体も出てくれる。
整数型は10進数で、ポインタは16進数で表示するようだ。
16進数で見たい場合は、WATCHとして追加するしかなさそうだ。
例えば、env->me_flagsという値を16進数で見たかったら、「env->me_flags,h」のように指定するそうだ。
https://github.com/Microsoft/vscode-cpptools/issues/379

2016年12月のことだから、今は別の手段があるかもしれん。。。が、それっぽいのは見つからなかった。
まあ、こういうのは、だいたい解決されていくものだし、方法がないわけではないからよかろう。


こんな感じで、gdbを使うだけであればlaunch.jsonを作るだけでよさそうだ。

2017/09/17

[btc]confオプションはフルパスで書くべし

testnetでなかなかマイニングされないので、regtestに切り替えようとしている。
まあ、testnetは有志によるものっぽいから、何が起きても文句は言えない。。。


まず、testnetとregtestを同時に動かしておけるかどうか。
これは、ダメそうだ。
bitcoindがHTTP serverになるようで、2つめを起動したらエラーになった。

Error: Unable to start HTTP server. See debug log for details.

引数で何か設定すればよいのかもしれんが、まあそこまで切実ではないので、よかろう(実はできるのだが、後述)。


次は、confファイル。
bitcoindはデフォルトで~/.bitcoin/bitcoin.confを見に行くが、regtestのために書き換えるのが面倒だから、regtest用のconfファイルを読み込ませたい。

regtest=1
server=1
txindex=1
rpcuser=xxx
rpcpassword=xxxxx
rpcport=18443

こんな感じか。
rpcportを設定したのは、まあ、確認みたいなものだ。

$ bitcoind -conf=./regtest.conf

そして別のコンソールから確認。

$ bitcoin-cli -conf=./regtest.conf getblockcount
74242

ん??
regtestなのにブロックがあるし、やるたびに増えていってるからどこかからダウンロードしているようだぞ。
networkinfoで見ると、やはりピアが見えているし、ポート番号も8333だ。
ということは、mainnetを見に行ってるらしい。


こうやるのがよさそうだ。

$ bitcoind -conf=./regtest.conf -regtest

納得がいかないのだが、仕方ない。

regtest.confから「regtest=1」を削ってもよいかも。
ただ、bitcoin-cliの方は-confで設定したregtestを見ているようで、-regtestオプションを付けなくてもよいようだ。
まあ、bitcoindが付けているのだから、両方付けた方が統一されていてよいかもしれん。


では、最後にJSON-RPC。

$ curl --user xxx:xxxx --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getblockcount", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18443/

ダメだ、接続できない。
wiresharkでbitcoin-cliしたときのポートを見ると、18332になってる。
全然confファイルの言うことを聞いてくれんやつだ。。。

そして、ポート番号を18332にしてもダメ。
認証に失敗しているようだから、rpcuserなんかも見てないということか??
しかし、getnetworkinfoで見ると、なんか18444を監視している。
いっちょんいうことばきいてくれんっちゃけんねぇ。。。


このregtest.confを、カレントディレクトリではなく~/.bitcoinの中に置き、-conf=regtest.confとディレクトリ無しにすると、すんなり動く。
-regtestもいらないし、JSON-RPCも書いてある通りの設定になる。
よくわからんが、その方がいろいろやるよりも安全な気がする。


自動実行するときは、systemdに登録しているのだが、そのときはたぶんUserで指定した人の~/.bitcoin/bitcoin.confを使っているのだろう。
ここを見ると、/etc/bitcoin/bitcoin.confを例にしているので、そういうのはありなんだ。。。
https://github.com/bitcoin/bitcoin/blob/master/doc/init.md

systemdのservice設定を見ると、conf指定だが、フルパスで書いているな。
https://github.com/bitcoin/bitcoin/blob/master/contrib/init/bitcoind.service

まさか・・・。

$ bitcoind -conf=`pwd`/regtest.conf

はい、そういうことでした。
confはフルパスで書くべし、でした。

最初に試した、testnetとregtestを同時に動かす、もconfファイルを相対パスで指定していたのでうまく動いていないだけだった。
datadirを別にすれば、regtestを複数立てることもできるんじゃなかろうか。意味はなさそうだがね。

2017/09/16

[bow]lmdbのmdb_env_open()でエラーになる

msg queueを使うプログラムを作っていたのでUbuntu16.04で作業していたのだが、socketに変更したので今のbash on Ubuntu on Windowsでも動かせるようになったんじゃなかろうか、ということでやってみた。

・・・そこに行き着く前に、lmdbのmdb_env_open()でエラーが返ってきた。。。


エラーの内容は、exec format error。
ENOEXECというやつだ。

ずーっとたどると、mmap()でエラーを返しているようだった。
gdbを使わず、printfデバッグで探していたので、たどるのが大変だった・・・。
GUI環境じゃないところで、まだgdbを使えないのだよ、私は。


この辺りかな?
mmap's problem · Issue #658 · Microsoft/BashOnWindows

いろいろ書いてあってよくわからんが、まあ、たぶんbowのバグなんだろう。
2017年秋バージョンに期待だ。

[btc]testnet3

bitcoindでは、ほとんどtestnetを使っている。
bitcoin.confにも「testnet=3」と書いている。

が、btcdなんかは1と書く(3だとエラー)。
つまり、testnetは実質、testnet3しかないというになるだろう。

そもそも、testnet3ってなんだ??


Testnet - Bitcoin Wiki

このページの最終更新日は2017年2月8日なので、新しいといってよいだろう。

testnetには3つあります。

testnet2は、testnetと異なるgenesis blockを持つ最初のtestnet resetだ。
testnet3は、現在のtest networkだ。

2行目の訳が怪しいので、原文を読んでおくれ。
とにかく、初代testnet、testnet2、testnet3があり、今はtestnet3ということだ。

引数だって「-testnet」だし、bitcoin.confが「=1」でも「=3」でも特に動作は変わらないようだ。
bitcoindでも、bool扱いしているように見えるから、0でなければtestnetになるんじゃなかろうかね。

2017/09/14

[tech]IPFS

世の中にはいろいろと技術があり、「これどうやってるんだろう??」というものも多い。
IPFSも、私にとっては「ど、どうやってるんだ??」という技術の一つだ。

なんというか、ブロックチェーンと非常に似たものを感じる。


ブロックチェーンでの開発を行っていると、何かに依存した状況を極力作りたくない。
「ああ、この情報をサーバに置きさえすれば解決するのに・・・」と思ったとしても、それをやってしまうと依存が生じてしまう。
まあ、多少はよいか、という考え方もあるのかもしれないが、やっぱりここまできたらねー、という意地みたいなものも出てくる。


そこで、IPFSだ。
全然技術的に理解はできていないのだが、ファイルをアップロードすると、適当にファイルを分割されて、適当に冗長性を持たせつつ、適当に分散させて、ノードを提供している人たちに持たせている。
たぶん、ブロックチェーンのフルノードみたいに、全員が同じものを持つ、というものではないように思う。
また、単に分割してばらまくわけでもなさそうだ。

それを取得するには、アップロードしたときに渡されるハッシュ値を使う。
ファイル名に相当するのかな。
それを使うと、そのハッシュ値に相当するものがファイルとして取得できるようだ。


サイトにある「Try it」を試しただけで、それ以上は入り込んでいない。
私がやったときは、子猫の画像が取得できた。


まあ、Bitcoinのブロックチェーンだって、こんだけ人々がアクセスしてもハッシュ値でトランザクションが一意に表せているので、IPFSの参加者くらいであれば十分にまかなえているのかもしれないし、ハッシュ値のサイズだって違うかもしれない。

だから、ハッシュ値でファイル名の代わりにする、という考え方はまだわかるのだが、残りの重要な部分はさっぱりわからん。
RAIDみたいな感じを持ってしまうけど、たぶんどこかのIPFSノードが動いていないくらいだったら問題ないんじゃなかろうか。


これは、なんというか、ぞくぞくする怖さを感じましたな。
こういう技術が生まれてくることに、まだまだ視野が狭かったなー、と感じざるを得ない。
いや、自分で生み出せたかも、とかじゃなくて(無理無理...)、世の中で未発見のものは、発見されたとしても私には理解ができないものなんじゃなかろうか、などと考えていたことに対してだ。

一般技術者としては、その発明/発見に敬意を表しつつ、理解し、より使いやすい形にしたり、安全にしたり、応用したりするのがまっとうなやり方かな、と思う。