Monacoinのブロックチェインに含まれるOP_RETURNのデータを一覧表示

前回、MonacoinのブロックチェインにOP_RETURNのデータを保存する方法を説明しました。

OP_RETURNで80バイトまでのデータをMonacoinのブロックチェインに保存 - ohacのブログ

今回はこれを取り出して一覧表示する方法について説明します。

前回と同様に以下のpython-OP_RETURNの改造版をcloneします。

GitHub - ohac/python-OP_RETURN: Simple Python commands and library for using bitcoin OP_RETURNs

以下のようなスクリプトをlist-OP_RETURN.pyという名前で保存します。

import sys, string
from OP_RETURN import *

def OP_RETURN_list_sub(height, testnet=False):
    txns=OP_RETURN_get_block_txns(height, testnet)
    txids=txns.keys()
    for txid in txids:
        txn_unpacked=txns[txid]
        found=OP_RETURN_find_txn_data(txn_unpacked)
        if not found:
            continue
        vintxid = txn_unpacked['vin'][0]['txid']
        if vintxid == '0000000000000000000000000000000000000000000000000000000000000000':
            continue
        data = found['op_return']
        try:
            data = data.decode('utf-8')
            print(data)
        except:
            print OP_RETURN_bin_to_hex(data)

def OP_RETURN_list(testnet=False):
    max_height=int(OP_RETURN_bitcoin_cmd('getblockcount', testnet))
    heights = [655049, 660399, 660413, 684062, 684069, 859463, 860016, 873025,
               874951, 875066, 875582, 875615, 876901, 904773, 904868, 965884,
               965927]
    for height in heights:
        OP_RETURN_list_sub(height, testnet)
    for height in range(1005000,max_height):
        OP_RETURN_list_sub(height, testnet)

OP_RETURN_list()

heightsには既知のブロック高が入っており、range(1005000,max_height)で1005000から最新までを調べるようにしています。

以下、実行結果です。

$ python list-OP_RETURN.py 
Hello!
Hello world!
Hello! txout0!
0468507040118fd428901db808a1ff347ff9b2a68137403f79deed98cbb5e568
happy monacoin 80 byte op_return thank you for mr.watanabe 2016/06/09      
hello!
hello!
4d4e53540100000013c10000000000001343304e56426b36555141456f7a446d2e6a7067
4d4e5354ffffffff13c1000005af00001343304e56426b36555141456f7a446d2e6a7067
4d4e5354ffffffff7b0e0200730c0200e38188e38188e38198e38283e381aae38184e3818b2e6a7067
4d4e5354ffffffff1b700000706f0000e69982e99ba82e6a7067
4d4e5354ffffffff1b700000706f0000e69982e99ba82e6a7067
4d4e5354ffffffff1b700000606f0000e69982e99ba82e6a7067
4d4e5354ffffffff98fb000071f6000043746d58397a6356494141644a785f2e6a7067
4d4e5354ffffffff1b7000004c6f0000e69982e99ba82e6a7067
awduiefnpiuerhagnvaeuip;wiensaio;dwsdfviuvsndi uvsdn cubvsovdaduisnduipvndfb
vvm@wer0mv@0
Hello, Monacoin!
こんにちは世界

ここまでできたら、ポーリングで定期的に最新情報を取り出して、ある条件で絞り込んだ上位プロトコルを作ることもできそうですね。

今回の件は以下のAsk Monaの内容が大変参考になりました。ありがとうございます。

askmona.org

なお、今回結構苦労したのがSegwitのtx部分をスキップするところでした。

オリジナルのOP_RETURN.pyはSegwitに対応しておらず、ドキュメントをあちこち探しましたが、分かりやすく説明されたものがなくて、バイナリデータと英文を見比べながらようやく完成させることができました。

OP_RETURNで80バイトまでのデータをMonacoinのブロックチェインに保存

ブロックチェインを使ったアプリを作りたくなったので、まずは基本的なところから試してみた。

OP_RETURNを使えば80バイトまでのデータをBitcoinのブロックチェインに保存できますが、ご存知のようにBitcoinの価格が高騰しており、ちょっとした実験にも手数料がかかってしまいます。 これが原因でCounterpartyも同様に手数料がかかってしまい、とてもお気軽に使える状態ではないかと思います。

testnetを使えば実験はできますが、これは本当にテスト用なのでアプリを作るには適していません。

ということでMonacoinを使って実験してみました。

python-OP_RETURNというソフトがあったので、これをMonacoin用に調整してみました。

GitHub - ohac/python-OP_RETURN: Simple Python commands and library for using bitcoin OP_RETURNs

monacoindがlocalhostで動作しており、~/.monacoin/monacoin.confがあれば自動でRPCのパラメータを読んでくれます。

以下のコマンドでHello, Monacoin!という16バイトの文字列を送ってみました。 なおMR5DV..は私のウォレットアドレスの1つです。

$ python send-OP_RETURN.py MR5DVFxd6YxrYQSUoby6Q9DrVGDX5RFvVB 0.02 'Hello, Monacoin!'
TxID: 5090920aba9c64a1dca6c68553e6f45d65745cb88b5fe40f99e55ce083f2c00f
Wait a few seconds then check on: https://mona.chainsight.info/tx/5090920aba9c64a1dca6c68553e6f45d65745cb88b5fe40f99e55ce083f2c00f
monacoin-cli gettransaction 5090920aba9c64a1dca6c68553e6f45d65745cb88b5fe40f99e55ce083f2c00f
monacoin-cli getrawtransaction 5090920aba9c64a1dca6c68553e6f45d65745cb88b5fe40f99e55ce083f2c00f

monacoin-cliのgettransactionコマンドを使ってtxを確認します。

$ monacoin-cli gettransaction 5090920aba9c64a1dca6c68553e6f45d65745cb88b5fe40f99e55ce083f2c00f
{
  "amount": 0.00000000,
  "fee": -0.00200000,
  "confirmations": 25,
  "blockhash": "2d1f49b4a476c35d7435150e87d7a36674f12645c6eed7c373a225931d11ae69",
  "blockindex": 1,
  "blocktime": 1495857840,
  "txid": "5090920aba9c64a1dca6c68553e6f45d65745cb88b5fe40f99e55ce083f2c00f",
  "walletconflicts": [
  ],
  "time": 1495857057,
  "timereceived": 1495857057,
  "bip125-replaceable": "no",
  "details": [
    {
      "account": "",
      "category": "send",
      "amount": 0.00000000,
      "vout": 2,
      "fee": -0.00200000,
      "abandoned": false
    }
  ],
  "hex": "010000000128fb81d1cc4ac49dc853605223d9763f19c3aa3fd31cec1e1777574c936d9bb4000000006a47304402207ce1ca33838afc218667dddbacfa4f8a429f51613ccd845ca9b8b055b51527d1022032693910718bcafd3cc4885c8a9112dfd9abbcecac8d704423743b4372f9b2210121031a57e2277899a85fdbd999b94896b9815883187b4cb9349ef09c1ea60c3b990effffffff0380841e00000000001976a914bc61040096f2c4422d9470f6ffd70fd919fe397588acf7084fd3050000001976a91494f9592a5d3704d5e0e5f092bbb2e8ee73c0bb0388ac0000000000000000126a1048656c6c6f2c204d6f6e61636f696e2100000000"
}

hexのところの最後の方にある 48646c6c.. の部分が Hello, Monacoin! です。

$ echo -n 'Hello, Monacoin!'|xxd
00000000: 4865 6c6c 6f2c 204d 6f6e 6163 6f69 6e21  Hello, Monacoin!

Webブラウザからは以下のサイトで確認できます。

https://mona.chainsight.info/tx/5090920aba9c64a1dca6c68553e6f45d65745cb88b5fe40f99e55ce083f2c00f

詳細の + ボタンを押すと OP_RETURN 48656c6c6f2c204d6f6e61636f696e21 となっていることが確認できます。

ちなみにやってみたいことはBitTorrentでのデータホスティング冗長化サービスです。

BitTorrentSHA1ハッシュ(20バイト)をOP_RETURNで受け付け、サービス提供者のアドレスにMonacoinを送れば金額とデータサイズから提供期間を決めてホスティングするといったことが可能だと思います。 違法データをホスティングしてしまわないようにするためにある程度検閲する必要があるかもしれません。あるいは暗号化データしかホスティングしないことにしてデータのエントロピーを見て判断するといった対策ができるかもしれません。

Monacoin用のElectrum試作版

ElectrumをMonacoinで使えるようにしてみました。 ただし、PoWとかのチェックは全く行っていませんので、あくまでもテスト用です。 また、Mで始まるアドレスの対応やBTCをMONAに変更する対応などもできていないところがあります。 サーバはCoinomiさんのものをお借りしております。

Commits · ohac/electrum · GitHub

以下のようなDockerfileを準備します。

FROM ubuntu:16.04
RUN apt-get update && \
    apt-get upgrade -y && \
    apt-get install -y vim python-pip git python-qt4 pyqt4-dev-tools && \
    apt-get clean
RUN pip install --upgrade pip && \
    pip install dnspython pyaes ecdsa qrcode pbkdf2 protobuf pip requests \
                pysocks jsonrpclib ltc_scrypt
WORKDIR /root
RUN git clone https://github.com/ohac/electrum.git
WORKDIR /root/electrum
RUN git checkout monacoin-20170514
RUN pyrcc4 icons.qrc -o gui/qt/icons_rc.py

ビルドします。

$ docker build -t elemona .

以下のようなスクリプトを準備。

#!/bin/bash
XSOCK=/tmp/.X11-unix
XAUTH=/tmp/.docker.xauth
USENET=
#USENET="--net=none"
if ! [ -a $XAUTH ]; then
  touch $XAUTH
  xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
fi
docker run -it --rm \
  -v $XSOCK:$XSOCK:rw -v $XAUTH:$XAUTH:rw \
  -e DISPLAY -e XAUTHORITY=${XAUTH} --ipc=host $USENET \
  elemona

立ち上げ。

# ./electrum

試しに少額のMONAを送信してみると表示された。

f:id:ohac:20170514153730p:plain

しかし6検証を終えているのに何故かNot Verifiedのまま。 頻繁にNot connectedになり、どこかおかしいようだ。

また、別アドレスに送信しようとしたが以下の例外が出てうまく動かなかった。 もう少し調整が必要っぽい。

Traceback (most recent call last):
  File "/root/electrum/gui/qt/main_window.py", line 576, in timer_actions
    self.do_update_fee()
  File "/root/electrum/gui/qt/main_window.py", line 1172, in do_update_fee
    fee_rate = fee * 1000 / tx.estimated_size()
  File "/root/electrum/lib/util.py", line 203, in <lambda>
    return lambda *args, **kw_args: do_profile(func, args, kw_args)
  File "/root/electrum/lib/util.py", line 199, in do_profile
    o = func(*args, **kw_args)
  File "/root/electrum/lib/transaction.py", line 788, in estimated_size
    return len(self.serialize(True)) / 2 if not self.is_complete() or self.raw is None else len(self.raw) / 2 # ASCII hex string
  File "/root/electrum/lib/transaction.py", line 737, in serialize
    nLocktime = int_to_hex(self.locktime, 4)
  File "/root/electrum/lib/bitcoin.py", line 168, in int_to_hex
    return rev_hex(s)
  File "/root/electrum/lib/bitcoin.py", line 162, in rev_hex
    return s.decode('hex')[::-1].encode('hex')
  File "/usr/lib/python2.7/encodings/hex_codec.py", line 42, in hex_decode
    output = binascii.a2b_hex(input)
TypeError: Non-hexadecimal digit found

23:53追記

blockchain_headersをダウンロード可能にしてやればうまく動きました。 electrum-serverの立て方は別途記事にします。

ネットワークから遮断されたDockerコンテナ内でElectrum

以下のような感じのDockerfileを用意してイメージをbuildする。

FROM ubuntu:16.04
RUN apt-get update && \
    apt-get upgrade -y && \
    apt-get install -y vim python-pip git python-qt4 pyqt4-dev-tools && \
    apt-get clean
RUN pip install --upgrade pip && \
    pip install dnspython pyaes ecdsa qrcode pbkdf2 protobuf pip requests \
                pysocks jsonrpclib
WORKDIR /root
RUN git clone https://github.com/spesmilo/electrum.git
WORKDIR /root/electrum
RUN git checkout 2.8.2
RUN pyrcc4 icons.qrc -o gui/qt/icons_rc.py

ビルドする。

$ docker build -t electrum .

ネットで見つけた手順を少しアレンジした以下のような手順でコンテナを立ち上げる。

$ XSOCK=/tmp/.X11-unix
$ XAUTH=/tmp/.docker.xauth
$ touch $XAUTH
$ xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
$ docker run -it --rm \
    -v $XSOCK:$XSOCK:rw -v $XAUTH:$XAUTH:rw \
    -e DISPLAY -e XAUTHORITY=${XAUTH} --ipc=host --net=none \
    electrum
root@xxxxxxxxxxxx:~/electrum# ./electrum 

無事立ち上がった。

オフラインウォレットほど安全ではないが比較的安全かもしれない。

マストドン始めました

マストドン(のインスタンス)始めました。

m.sighash.info

入居者募集中です。 そんだけ。

ohac@sighash - Mastodon

追記(2017/4/17):

  • ちょっとミスってしまい、今はダウンしています。夜には復活させる予定。

追記(2017/4/18 00:50):

  • なおりました。t2.smallに昇格させました。

自作サンプリング音源を公開した

LinuxSamplerを使って、サンプリング音源を色々と物色していたら、自分でも作りたくなってきて、勢いで作ってしまいました。 以下からダウンロード可能です。

www.dropbox.com

音源とパッチは仕様がオープンなFLAC+SFZ形式なので、LinuxSamplerですぐに使えます。

TUNEのエレキベース

  • 型式は覚えていませんが、4弦24フレット、アクティブタイプの以下の写真に写っているやつです。

flic.kr

  • フロントピックアップ使用。弦はまあまあ新しいかな。
  • ノイズ除去以外のエフェクトはかけておりません。お好みのEQやアンプシミュレーターをお使いください。
  • ループは使っておりませんが、適当なところで音がなくなります。2秒以上はあります。
  • 半音ごとに1サンプルで弦違いの音やラウンドロビン用の重複音はありません。ベロシティのバラつきもありますので、コンプを使った方がいいです。
  • ライセンスはCC-BY 4.0です。
  • zip形式で10.31MBです。

tmbox.net

ミニガットギター ARIA PEPE

  • audio-technicaの安いマイクを使用。ノイズ除去やEQをかけてノイズや環境音を誤魔化しているため音は悪いです。
  • オクターブチューニングがあっていないため、高音はピッチがずれています。
  • ループは使っておりませんが、適当なところで音がなくなります。元々サステインは短めで、後半はS/Nが悪くなります。
  • 半音ごとに1サンプルですが、多少弦違いの音も収録しています。
  • ラウンドロビン用の重複音はありません。ベロシティや周波数特性のバラつきもありますので、コンプを使った方がいいです。
  • 音が悪いのでライセンスは放棄します。CC0です。
  • zip形式で3.72MBです。

tmbox.net

追記:

配布サイトを作りました。

Sound Library

WebTorrentとinstant.ioを試してみた

WebTorrentのアプリをWindows用とLinux用をインストールして試してみました。

webtorrent.io

アプリにファイルをドラッグアンドドロップするだけで簡単にシェアできるようです。

試しにギターの練習音源をシェアしてみました。 以下のリンクでinstant.ioを使って再生することができると思います。 (ChromeとかFirefoxでないとだめみたい。)

https://instant.io/#e14cef00945a8d99dc74d65cf52dcb892cf48ed1

家のWifiを経由して、スマホの回線から聞くことができました。これはすごいです。

ちなみにこのギターの練習はクレオフーガでも公開しています。

追記:

コンソールで使いたい場合はwebtorrent-hybridを使うとよいです。Dockerfileを用意しておきましたので、参考にしてみてください。

gist.github.com