Accessing Bitcoin core RPCs
Bitcoin Core client is composed of a daemon, bitcoind
, a GUI oriented client, bitcoin-qt
and a CLI oriented client, bitcoin-cli
. bitcoind
offerts an JSON-RPC interface over a HTTP socket to perform functions on the wallet, transactions, mempool, etc.
In this post, I’ll quickly show how to access this interface using python and no extra library.
Firstly, you need to set RPC cookie authentification (it is also possible to set a login/password authentification, but this method will soon become obsolete as I’m writing this.). By default, no cookie is defined so one is created randomly at each bitcoind
start, and is usable by bitcoin-cli
. To be able to use ours, there is a script in Bitcoin Core’s github repository to allow creating login credentials for a JSON-RPC user. This script is named rpcauth.py. Let’s try it:
$ curl -sO https://raw.githubusercontent.com/bitcoin/bitcoin/master/share/rpcauth/rpcauth.py
$ python rpcauth.py rpc
String to be appended to bitcoin.conf:
rpcauth=rpc:3bd32b56fbdc43c8a4685f38a79498f$4432004590c837aafb86bf58962a67bda9f4aea47a3a9c0bd891465e28c44515
Your password:
1yC70vJ8-NPQ9LwFgNMf0VRxiKWavTwVLIPUetZ2kBQ=
You’ll have to add in bitcoin.conf said line, and restart (start) bitcoind:
$ echo 'rpcauth=rpc:3bd32b56fbdc43c8a4685f38a79498f$4432004590c837aafb86bf58962a67bda9f4aea47a3a9c0bd891465e28c44515' >> $HOME/.bitcoin/testnet3/bitcoin.conf
$ /opt/bitcoin/bin/bitcoind -server -testnet -daemon -conf=/home/mycroft/.bitcoin/testnet3/bitcoin.conf
Bitcoin server starting
Please note that I’m using testnet on my examples.
You can test authentification using bitcoin-cli
, using -rpcuser
and -rpcpassword
flags:
$ /opt/bitcoin/bin/bitcoin-cli -testnet -rpcuser=rpc -rpcpassword=aaa listaccounts
error: incorrect rpcuser or rpcpassword (authorization failed)
$ /opt/bitcoin/bin/bitcoin-cli -testnet -rpcuser=rpc -rpcpassword='1yC70vJ8-NPQ9LwFgNMf0VRxiKWavTwVLIPUetZ2kBQ=' listaccounts
{
"": 64.33773267,
"testaroo0": 0.00000000
}
We are done for this part! Still have to write some python code to connect & send commands. There is a lot of other ways to reach the API, but in this example I’ll just use raw python
with only requests
module.
#!/usr/bin/env python
import requests
from requests.auth import HTTPBasicAuth
import json
import sys
class RpcCli:
"""
Port is 8332 for mainnet, 18332 for testnet
"""
def __init__(self, username, password, hostname='localhost', port=8332):
self.username = username
self.password = password
self.hostname = hostname
self.port = port
def run(self, method='help', params=[]):
url = "http://%s:%d" % (self.hostname, self.port)
auth = HTTPBasicAuth(self.username, self.password)
headers = {'content-type': 'application/json'}
payload = {
"method": method,
"params": params,
"jsonrpc": "1.0",
"id": "curltext",
}
response = requests.post(
url, data=json.dumps(payload), headers=headers, auth=auth)
if response.status_code != 200:
print(response.reason)
return None
result = response.json()['result']
return self.prettyfy(result)
def prettyfy(self, content):
return json.dumps(content, indent=4, sort_keys=True)
def value(self, content):
return json.loads(content)
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Usage: %s <command> [param1] [param2] ..." % (sys.argv[0]))
print("Help: %s help" % (sys.argv[0]))
sys.exit(0)
cli = RpcCli("rpc", "1yC70vJ8-NPQ9LwFgNMf0VRxiKWavTwVLIPUetZ2kBQ=", port=18332)
resp = cli.run(sys.argv[1], sys.argv[2:])
print(cli.value(resp))
This code is pretty much straightforward: We are just doing a http query with authentification headers, and returning the result. Nothing more is required.
Let’s test it:
$ ./rpc-cli.py help
== Blockchain ==
getbestblockhash
getblock "blockhash" ( verbosity )
getblockchaininfo
...
$ ./rpc-cli.py listaccounts
{u'': 64.33773267, u'testaroo0': 0.0}
There is a lot of api calls available. They go from wallet management, to stats, transaction creation, etc. More things can be done through the API than bitcoin-qt
. Recently, I’ve sent some custom raw data messages on the testnet blockchain, creating my own custom transaction, in just a few lines of code using that API. I’ll come back later on another article.
This API is also used for mining. Miners like bfgminer can connect to that API as well (if you don’t use a pool/stratum server). Finally, there is some interesting examples in the developers examples wiki page.