RBC
RBC
try:
import http.client as httplib
except ImportError:
import httplib
import base64
import binascii
import decimal
import json
import os
import platform
import sys
try:
import urllib.parse as urlparse
except ImportError:
import urlparse
import bitcoin
from bitcoin.core import COIN, x, lx, b2lx, CBlock, CBlockHeader, CTransaction,
COutPoint, CTxOut
from bitcoin.core.script import CScript
from bitcoin.wallet import CBitcoinAddress, CBitcoinSecret
DEFAULT_USER_AGENT = "AuthServiceProxy/0.1"
DEFAULT_HTTP_TIMEOUT = 30
SUBCLS_BY_CODE = {}
@classmethod
def _register_subcls(cls, subcls):
cls.SUBCLS_BY_CODE[subcls.RPC_ERROR_CODE] = subcls
return subcls
self = Exception.__new__(cls)
super(JSONRPCError, self).__init__(
'msg: %r code: %r' %
(rpc_error['message'], rpc_error['code']))
self.error = rpc_error
return self
@JSONRPCError._register_subcls
class ForbiddenBySafeModeError(JSONRPCError):
RPC_ERROR_CODE = -2
@JSONRPCError._register_subcls
class InvalidAddressOrKeyError(JSONRPCError):
RPC_ERROR_CODE = -5
@JSONRPCError._register_subcls
class InvalidParameterError(JSONRPCError):
RPC_ERROR_CODE = -8
@JSONRPCError._register_subcls
class VerifyError(JSONRPCError):
RPC_ERROR_CODE = -25
@JSONRPCError._register_subcls
class VerifyRejectedError(JSONRPCError):
RPC_ERROR_CODE = -26
@JSONRPCError._register_subcls
class VerifyAlreadyInChainError(JSONRPCError):
RPC_ERROR_CODE = -27
@JSONRPCError._register_subcls
class InWarmupError(JSONRPCError):
RPC_ERROR_CODE = -28
class BaseProxy(object):
"""Base JSON-RPC proxy class. Contains only private methods; do not use
directly."""
def __init__(self,
service_url=None,
service_port=None,
btc_conf_file=None,
timeout=DEFAULT_HTTP_TIMEOUT):
if service_url is None:
# Figure out the path to the bitcoin.conf file
if btc_conf_file is None:
if platform.system() == 'Darwin':
btc_conf_file = os.path.expanduser('~/Library/Application
Support/Bitcoin/')
elif platform.system() == 'Windows':
btc_conf_file = os.path.join(os.environ['APPDATA'], 'Bitcoin')
else:
btc_conf_file = os.path.expanduser('~/.bitcoin')
btc_conf_file = os.path.join(btc_conf_file, 'bitcoin.conf')
if service_port is None:
service_port = bitcoin.params.RPC_PORT
conf['rpcport'] = int(conf.get('rpcport', service_port))
conf['rpchost'] = conf.get('rpcconnect', 'localhost')
service_url = ('%s://%s:%d' %
('http', conf['rpchost'], conf['rpcport']))
cookie_dir = os.path.dirname(btc_conf_file)
if bitcoin.params.NAME != "mainnet":
cookie_dir = os.path.join(cookie_dir, bitcoin.params.NAME)
cookie_file = os.path.join(cookie_dir, ".cookie")
try:
with open(cookie_file, 'r') as fd:
authpair = fd.read()
except IOError as err:
if 'rpcpassword' in conf:
authpair = "%s:%s" % (conf['rpcuser'], conf['rpcpassword'])
else:
raise ValueError('Cookie file unusable (%s) and rpcpassword
not specified in the configuration file: %r' % (err, btc_conf_file))
self.__service_url = service_url
self.__url = urlparse.urlparse(service_url)
if self.__url.port is None:
port = httplib.HTTP_PORT
else:
port = self.__url.port
self.__id_count = 0
authpair = authpair.encode('utf8')
self.__auth_header = b"Basic " + base64.b64encode(authpair)
response = self._get_response()
if response['error'] is not None:
raise JSONRPCError(response['error'])
elif 'result' not in response:
raise JSONRPCError({
'code': -343, 'message': 'missing JSON-RPC result'})
else:
return response['result']
return self._get_response()
def _get_response(self):
http_response = self.__conn.getresponse()
if http_response is None:
raise JSONRPCError({
'code': -342, 'message': 'missing HTTP response from server'})
return json.loads(http_response.read().decode('utf8'),
parse_float=decimal.Decimal)
def __del__(self):
if self.__conn is not None:
self.__conn.close()
class RawProxy(BaseProxy):
"""Low-level proxy to a bitcoin JSON-RPC service
Unlike ``Proxy``, no conversion is done besides parsing JSON. As far as
Python is concerned, you can call any method; ``JSONRPCError`` will be
raised if the server does not recognize it.
"""
def __init__(self,
service_url=None,
service_port=None,
btc_conf_file=None,
timeout=DEFAULT_HTTP_TIMEOUT,
**kwargs):
super(RawProxy, self).__init__(service_url=service_url,
service_port=service_port,
btc_conf_file=btc_conf_file,
timeout=timeout,
**kwargs)
class Proxy(BaseProxy):
"""Proxy to a bitcoin RPC service
Unlike ``RawProxy``, data is passed as ``bitcoin.core`` objects or packed
bytes, rather than JSON or hex strings. Not all methods are implemented
yet; you can use ``call`` to access missing ones in a forward-compatible
way. Assumes Bitcoin Core version >= v0.13.0; older versions mostly work,
but there are a few incompatibilities.
"""
def __init__(self,
service_url=None,
service_port=None,
btc_conf_file=None,
timeout=DEFAULT_HTTP_TIMEOUT,
**kwargs):
"""Create a proxy object
If ``service_url`` is not specified, the username and password are read
out of the file ``btc_conf_file``. If ``btc_conf_file`` is not
specified, ``~/.bitcoin/bitcoin.conf`` or equivalent is used by
default. The default port is set according to the chain parameters in
use: mainnet, testnet, or regtest.
Usually no arguments to ``Proxy()`` are needed; the local bitcoind will
be used.
``timeout`` - timeout in seconds before the HTTP interface times out
"""
super(Proxy, self).__init__(service_url=service_url,
service_port=service_port,
btc_conf_file=btc_conf_file,
timeout=timeout,
**kwargs)
return CBitcoinSecret(r)
r['tx'] = CTransaction.deserialize(unhexlify(r['hex']))
del r['hex']
return r
def getbestblockhash(self):
"""Return hash of best (tip) block in longest block chain."""
return lx(self._call('getbestblockhash'))
if verbose:
nextblockhash = None
if 'nextblockhash' in r:
nextblockhash = lx(r['nextblockhash'])
return {'confirmations':r['confirmations'],
'height':r['height'],
'mediantime':r['mediantime'],
'nextblockhash':nextblockhash,
'chainwork':x(r['chainwork'])}
else:
return CBlockHeader.deserialize(unhexlify(r))
def getblockcount(self):
"""Return the number of blocks in the longest block chain"""
return self._call('getblockcount')
def getinfo(self):
"""Return a JSON object containing various state info"""
r = self._call('getinfo')
if 'balance' in r:
r['balance'] = int(r['balance'] * COIN)
if 'paytxfee' in r:
r['paytxfee'] = int(r['paytxfee'] * COIN)
return r
def getmininginfo(self):
"""Return a JSON object containing mining-related information"""
return self._call('getmininginfo')
return CBitcoinAddress(r)
def getrawchangeaddress(self):
"""Returns a new Bitcoin address, for receiving change.
This is for use with raw transactions, NOT normal use.
"""
r = self._call('getrawchangeaddress')
return CBitcoinAddress(r)
return r
if r is None:
raise IndexError('%s.gettxout(): unspent txout %r not found' %
(self.__class__.__name__, outpoint))
r2 = []
for unspent in r:
unspent['outpoint'] = COutPoint(lx(unspent['txid']), unspent['vout'])
del unspent['txid']
del unspent['vout']
unspent['address'] = CBitcoinAddress(unspent['address'])
unspent['scriptPubKey'] = CScript(unhexlify(unspent['scriptPubKey']))
unspent['amount'] = int(unspent['amount'] * COIN)
r2.append(unspent)
return r2
__all__ = (
'JSONRPCError',
'ForbiddenBySafeModeError',
'InvalidAddressOrKeyError',
'InvalidParameterError',
'VerifyError',
'VerifyRejectedError',
'VerifyAlreadyInChainError',
'InWarmupError',
'RawProxy',
'Proxy',
)
� 2019 GitHub, Inc.
Terms
Privacy
Security
Status
Help
Contact GitHub
Pricing
API
Training
Blog
About