酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

tipbotが使っている機能をbitcoin-cliを使って再現するにはどうしたらいいんだろう?

仮想通貨(暗号通貨)をTwitterとかDiscordで@tipmona tip @ch3cooh 393./tip sakusan 393のように投げ銭の仲介役をするBotを総じてtipbot(ちっぷぼっと)と呼びます。

tipbotを作るためにはどうしたらいいんだろう?

「tipbotってどうやって作っているんだろうか?」と調べていったところ、使っている言語はRubyやNode.jsであったり様々なのですが、仮想通貨の残高の管理にはcoindを使うところまで理解できました。

Bitcoinだったらbitcoind、モナコインだったらmonacoindやmonadといったようなものです。最後についているdはdeamonのdのようです。

高額なビットコインや大切なモナコインをおもちゃにするわけにはいかないので、代わりにbitcoindと互換性のある暗号通貨SanDeGoのdeamonであるsandegodを使って色々なコマンドを試してみたいと思います。SanDeGoは高利率PoSで放置しておけば勝手に増えるのでおもちゃにするには最適です。

coindにアクセスするためには、bitcoin-cliというコマンドを利用します。bitcoin-cli getinfoでcoindの情報を取得したりです。

tipbotはbitcoin-cli(のようなRPCライブラリ)を使って投げ銭機能を提供しています。tipbotが使っている機能をbitcoin-cliを使って再現するにはどうしたらいいのか考えていきたいと思います。

coindを起動する

coindを起動します。ここではSanDeGoを使うのでsandegodとなります。適時利用しているdeamonに合わせて読み替えていただければと思います。

deamonを起動する

ログ出力モードでdeamonを起動します。

sandegod -printtoconsole

ログがめっちゃ流れるので起動するだけなら-printtoconsoleオプションは不要です。

sandegod

deamonのアカウントAPIを使う場合

addnode=108.160.130.190
rpcuser=xxxxxx
rpcpassword=xxxxxx
rpcport=39452
rpcallowip=127.0.0.1/24
server=1

#アカウント機能を有効にする
enableaccounts=1
#ステーキングを無効にする(アカウントAPIを使う場合はOFF必須)
staking=0

どのポートで動いているのかわからなかったので調べた

$ netstat -an | grep LISTEN

tipbotが使っている機能をbitcoin-cliを使って再現する

bitcoin-cliを使って、sandegodにアクセスすることができます。tipbotの役割は

  • 入金
  • 出金

deamonの情報を取得する

$ bitcoin-cli getinfo
{
  "version": "v1.0.0.0-g32a928e",
  "protocolversion": 60013,
  "walletversion": 60000,
  "balance": 0.00000000,
  "newmint": 0.00000000,
  "stake": 0.00000000,
  "blocks": 5653,
  "timeoffset": -1,
  "moneysupply": 10063866299.54738998,
  "connections": 16,
  "proxy": "",
  "ip": "xxx.xxx.xxx.xxx",
  "difficulty": {
    "proof-of-work": 0.39751911,
    "proof-of-stake": 0.07476573
  },
  "testnet": false,
  "keypoololdest": 1524325572,
  "keypoolsize": 101,
  "paytxfee": 0.00010000,
  "mininput": 0.00000000,
  "errors": ""
}

sakusanに紐づいたアドレスを取得する

$ bitcoin-cli getaddressesbyaccount sakusan
[
  "SRLqbZBn2gDxbg8vtge4wvX17EMopXieRZ",
  "SeWRpdbSo5nrZk7wCivsz5t1emZwRGasYN",
  "ScmTCFKjy6bBRW7nVXs9PVRBcBQQFfxk63",
  "ST7LXAJMbsTekPUihk6e4inojeu3e8zUAk"
]

アドレスがたくさんできたけど消す方法がわからない。

sakusanに紐づいたアドレスを生成する

sakusanに紐づいたアドレスを生成します。

$ bitcoin-cli getaccountaddress sakusan
ScmTCFKjy6bBRW7nVXs9PVRBcBQQFfxk63

sakusanに紐づいた残高を取得する

$ bitcoin-cli getbalance sakusan
0.00000000

ScmTCFKjy6bBRW7nVXs9PVRBcBQQFfxk63に0.14114000コイン送ったあと、数分すると残高が増えていました。ちゃんと動いていることが確認できました。

$ bitcoin-cli getbalance sakusan
0.14114000

ユーザー全員の残高を取得する

$ bitcoin-cli listaccounts
{
  "": 0.00000000,
  "sakusan": 0.14114000
}

6回以上承認されているのを条件とする場合は以下のようにします。

$ bitcoin-cli getbalance sakusan 6
0.13114000

ユーザー全員の残高をまとめて取得する

$ bitcoin-cli getbalance
0.14114000

sakusanからnekoへ送金する

nekoに紐づいたアカウントを作成しました。

$ bitcoin-cli getaccountaddress neko
ShDkkBR3uwjs1EMRuBUtEhJdktazDKhMo8

現時点での全員の残高を調べます。

$ bitcoin-cli listaccounts
{
  "": 0.00000000,
  "neko": 0.00000000,
  "sakusan": 0.14114000
}

アカウント間送金はmoveを使います。

$ bitcoin-cli move sakusan neko 0.01
true

sakusanからnekoへのアカウントへ残高が移動していることがわかります。

$ bitcoin-cli listaccounts
{
  "": 0.00000000,
  "neko": 0.01000000,
  "sakusan": 0.13114000
}

同一ウォレット内の移動なので手数料はかからないのかな?

sakusanから別のアドレスへ送金する

現在の状態です。

$ bitcoin-cli listaccounts
{
  "": 0.00000000,
  "neko": 0.01000000,
  "sakusan": 0.13114000
}

外部アドレスへ送金してみました。トランザクションIDが発行されました。

$ bitcoin-cli sendfrom sakusan SPVm9mbZ1rYyLhgHitJBk5wfzLCZDGUAPd 0.01
45accb03b4dc3b8c728560702377f7123d65eeeff3f5f0357ee279978ad4d90b

sakusanの残高から送金分と手数料が引かれました。

$ bitcoin-cli listaccounts
{
  "": 0.00000000,
  "neko": 0.01000000,
  "sakusan": 0.12104000
}

にゃーん。

トランザクションIDから手数料を調べる

手数料がいくらかかったかはトランザクションIDから取得することが可能です。

$ bitcoin-cli gettransaction 45accb03b4dc3b8c728560702377f7123d65eeeff3f5f0357ee279978ad4d90b
{
  "txid": "45accb03b4dc3b8c728560702377f7123d65eeeff3f5f0357ee279978ad4d90b",
  "version": 1,
  "time": 1524406007,
  "locktime": 0,
(長いので省略)
  "amount": -0.01000000,
  "fee": -0.00010000,
  "confirmations": 1,
(長いので省略)
  "details": [
    {
      "account": "sakusan",
      "address": "SPVm9mbZ1rYyLhgHitJBk5wfzLCZDGUAPd",
      "category": "send",
      "amount": -0.01000000,
      "fee": -0.00010000
    }
  ]
}

feeから手数料を調べることができます。