The bitcoin daemon has a very useful & easy-to-use HTTP API built-in, that allows you to talk to it like a simple webserver and get JSON responses back.
By default, it’s enabled but it only listens on localhost port 8332, and it’s unauthenticated.
$ netstat -alpn | grep 8332
tcp 0 0 127.0.0.1:8332 0.0.0.0:* LISTEN 31667/bitcoind
tcp6 0 0 ::1:8332 :::* LISTEN 31667/bitcoind
While useful if you’re on the same machine (you can query it locally without username/password), it won’t help much if you’re querying a remote node.
In order to allow bitcoind to bind on a public-facing IP and have username/password authentication, you can modify the bitcoin.conf.
$ cat .bitcoin/bitcoin.conf
# Expose the RPC/JSON API
server=1
rpcbind=10.0.1.5
rpcallowip=0.0.0.0/0
rpcport=8332
rpcuser=bitcoin
rpcpassword=J9JkYnPiXWqgRzg3vAA
If you restart your daemon with this config, it would try to bind to IP “10.0.1.5” and open the RCP JSON API endpoint on its default port 8332. To authenticate, you’d give the user & password as shown in the config.
Note: the plaintext rpcuser/rpcpassword pair shown above still works, but Bitcoin Core has since deprecated it in favour of rpcauth, which stores a salted hash of the password in the config instead of the password itself. Generate the rpcauth=... line with the rpcauth.py script that ships in share/rpcauth/ of the Bitcoin Core source (or via Jameson Lopp’s generator
), drop it in bitcoin.conf, and keep using the same user & password on the client side.
If you do not pass the rpcallowip parameter, the server won’t bind on the requested IP, as confirmed in the manpage:
-rpcbind=
[:port]
Bind to given address to listen for JSON-RPC connections. Do not expose
the RPC server to untrusted networks such as the public internet!
This option is ignored unless -rpcallowip is also passed. Port is
optional and overrides -rpcport. Use [host]:port notation for
IPv6. This option can be specified multiple times (default:
127.0.0.1 and ::1 i.e., localhost)
Keep that note that it’s a lot safer to actually pass the allowed IPs and treat it as a whitelist, not as a workaround to listen to all IPs like I did above.
Here’s an example of a curl call to query the daemon.
$ curl \
--user bitcoin \
--data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getnetworkinfo", "params": [] }' \
-H 'content-type: text/plain;' \
http://10.0.1.5:8332/
Enter host password for user 'bitcoin':
{
"result":
{
"version":180000,
...
}
}
You can now safely query your bitcoin daemon with authentication.