JSでBitcoin開発: JavaScriptでbitcoin-cliと同じ事をする

Bitcoinで遊ぶ・開発する場合、`bitcoin-cli`は必須ツールですが、いちいちコマンドラインで叩くのも面倒です。そこで`bitcoin-core`というnpmパッケージを使ってJavaScriptから叩いてみましょう。

```sh
$ yarn add bitcoin-core
もしくは
$ npm i bitcoin-core -S
```

でインストールします。

これ関連は似たような名前のnpmや別の言語でのツールなど色々ヒットしやすくて情報を探すのが面倒です。確実なのは[bitcoin-core - npm](https://www.npmjs.com/package/bitcoin-core)及び[ruimarinho/bitcoin-core: A modern Bitcoin Core REST and RPC client.](https://github.com/ruimarinho/bitcoin-core)を読むのが手っ取り早いです。

## 使い方

async/awaitを使うのが一番楽です。

```js
const Client = require('bitcoin-core')

const cl = new Client({
  network: 'testnet',
  username: 'user',
  password: 'pass',
  port: 18444,
})

const testBitcoinCore = async () => {
  await cl.generate(1)
  console.log(await cl.getBlockchainInfo())
}

testBitcoinCore().catch(err => console.error(err)
```

これを実行すると`bitcoin-cli generate 1`と同じ操作が行われてその次に、`bitcoin-cli getblockchaininfo`と同じ操作を行った結果が表示されます。

ここでの注意点はbitcoin-cliのコマンドでは全て小文字ですが、bitcoin-coreでは`cl.getBlockchainInfo()`のようにキャメルケースで表記する必要があるということです。慣れるとどれを大文字にすればいいのかなんとなくわかるんですが、一番確実な方法としては、https://github.com/ruimarinho/bitcoin-core/blob/master/src/methods.js を読むと手っ取り早いです。

>   getBlockchainInfo: { version: '>=0.9.2' },

ブラウザで大文字小文字無視で`getblockchaininfo`を検索すれば、bitcoin-coreのメソッド名がヒットするので、それを使います。バージョンはBitcoinのコアのバージョンです(ex. 0.16.0)。

## サンプル

regtestモード ([JSでBitcoin開発: Bitcoinネットワークの種類と起動スクリプト - Qiita](https://qiita.com/erukiti/items/fdad1d41bbdb22ae599b))を使って、マイニング＆ユーザーへのBTC送金を行ってみましょう。

```js
const testBitcoinCore = async () => {
  console.log('#getBlockchainInfo')
  console.log(await cl.getBlockchainInfo())
  console.log()

  console.log('#generate 1')
  const firstBlockIds = await cl.generate(1)
  console.log()

  console.log('#getBlockchainInfo')
  console.log(await cl.getBlockchainInfo())
  console.log()

  console.log('#getBlock <BlockId>')
  const firstBlock = await cl.getBlock(firstBlockIds[0])
  console.log(firstBlock)
  const firstCoinbaseId = firstBlock.tx[0]
  console.log()

  console.log('#getRawTransaction <TxId>')
  const firstCoinbaseHex = await cl.getRawTransaction(firstCoinbaseId)
  console.log(firstCoinbaseHex)
  console.log()

  console.log('#decodeRawTransaction <TxHex>')
  const firstCoinbaseTx = await cl.decodeRawTransaction(firstCoinbaseHex)
  console.log(firstCoinbaseTx)
  console.log()

  console.log('#getNewAddress hoge 1')
  const address = await cl.getNewAddress('hoge')
  console.log(address)
  try {
    await cl.sendToAddress(address, 1)
  } catch (e) {
    console.log(e.code)
    console.log(e.message)
  }
  console.log()

  console.log('#generate 100')
  await cl.generate(100)
  console.log()

  console.log('#sendToAddress hoge 1')
  const sendTxId = await cl.sendToAddress(address, 1)
  console.log(sendTxId)
  console.log()

  console.log('#getRawTransaction <TxId>')
  const sendTxHex = await cl.getRawTransaction(sendTxId)
  console.log()

  console.log('#decodeRawTransaction <TxHex>')
  const sendTx = await cl.decodeRawTransaction(sendTxHex)
  console.log(sendTx)
  console.log()

  console.log('#getBalance hoge')
  console.log(await cl.getBalance('hoge'))
  console.log()

  console.log('#generate 1')
  await cl.generate(1)
  console.log()

  console.log('#getBalance hoge')
  console.log(await cl.getBalance('hoge'))
}
```

## JavaScriptで覚える暗号通貨入門シリーズ

本記事は、[JavaScriptで覚える暗号通貨入門#1 Bitcoin完全に理解した](https://rabbit-house.tokyo/books/bitcoin-complete/)の技術調査によるものです。また、[JavaScriptで覚える暗号通貨入門#1 Bitcoin完全に理解した (サンプルコード)](https://github.com/erukiti/bitcoin-complete-sample)のリポジトリを公開しています。