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なんかも使えるようなので、そっちを見に行った方が良いのかもしれんね。