Java(SpringBoot)でbitcoindのJSON-RPCを利用する
やること
bitcoindはJSON形式でブロックやトランザクションの情報を取得できるJSON-RPCという通信プロトコルをサポートしています。
今回はSpringBootで作成したプロジェクト上で、bitcoind JSON-RPCを呼び出すサンプル実装を行います。
事前準備
SPRING INITIALIZR を使ってテンプレートプロジェクトを作成します。
以下の環境で作業を行います。
- Java9
- SpringBoot2.0.0M6
- jsonrpc4j
実装してみる
jsonrpc4j(Java向けJSON-RPCライブラリ)
JavaでJSON-RPCを利用するのにJava用ライブラリであるjsonrpc4jを使用します。
build.gradleの依存関係に追加します。
build.gradle
dependencies { (Spring関連は省略) compile group: 'com.github.briandilley.jsonrpc4j', name: 'jsonrpc4j', version: '1.5.1' }
Configクラスの作成
JSON-RPC Clientが呼び出すURLやユーザー・パスワードの設定を行います。
Server側となるbitcoindのconf設定は以下の記事と同じ前提です。
以下のクラスを作成して適当なディレクトリに配置します。
BitcoindConfig.java
@Configuration public class BitcoindConfig { private static final String endpoint = "http://localhost:18332"; private static final String rpcuser ="username"; private static final String rpcpassword ="password"; public BitcoindConfig() { Authenticator.setDefault(new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication (rpcuser, rpcpassword.toCharArray()); } }); } @Bean public JsonRpcHttpClient jsonRpcHttpClient() { URL url = null; //You can add authentication headers etc to this map Map<String, String> map = new HashMap<>(); try { url = new URL(endpoint); } catch (Exception e) { e.printStackTrace(); } return new JsonRpcHttpClient(url, map); } @Bean public BitcoindClientAPI bitcoindClientAPI(JsonRpcHttpClient jsonRpcHttpClient) { return ProxyUtil.createClientProxy(getClass().getClassLoader(), BitcoindClientAPI.class, jsonRpcHttpClient); } }
testnet,regtestのデフォルトポートは18332、本番環境は8332です。
JSON-RPC用のインターフェースクラスの作成
次にJSON-RPC用のインターフェースクラスを作成します。
@JsonRpcMethodアノテーションでマッピングするAPIを指定することでJSON-RPCを呼び出すことができます。
呼び出したいAPIは以下を参考に引数、返り値を合わせます。
今回は getblock APIを呼び出してみるのでblockhashとverbosityを引数に設定して、返り値はverbosity=1の想定でAPI Resultに合わせたPOJOを定義しておきます。
BitcoindClientAPI.java
public interface BitcoindClientAPI { @JsonRpcMethod("getblock") GetBlockResult getBlock(@JsonRpcParam(value = "blockhash") String blockhash, @JsonRpcParam(value = "verbosity") int verbosity); }
GetBlockResult.java
@Getter @Setter public class GetBlockResult { private String hash; private int confirmations; private int size; private int strippedsize; private int weight; private int height; private int version; private String versionHex; private String merkleroot; private List<String> tx; private int time; private int mediantime; private int nonce; private String bits; private int difficulty; private String chainwork; private String previousblockhash; private String nextblockhash; }
呼び出し元コントローラーの作成
@RestController @RequestMapping("bitcoind") public class BitcoindRpcController { @Autowired private BitcoindClientAPI bitcoindClientAPI; @RequestMapping(value = "block/{blockhash}", method = RequestMethod.GET) public GetBlockResult getBlock(@PathVariable("blockhash") String blockhash) { return bitcoindClientAPI.getBlock(blockhash, 1); // verbosity = 1 } }
動作確認
./gradlew bootRunでプロセスを起動し、以下のURLを叩いてブロックの情報が取得できればOKです。 http://localhost:8080/bitcoind/block/{blockhash}
※{blockhash} の部分にはbitcoin-cliのgenerateコマンドで実際に産出されたブロックのHash値を指定してください。