Esempio n. 1
0
class LocalBlockchainRPCReader(object):
    """Fetches blockchain data from bitcoind RPC interface."""
    def __init__(self, username=None, password=None, host=None, port=None):
        if None in (username, password, host, port):
            username, password, host, port, _ = get_config_settings()
        self.rpc_connection = AuthServiceProxy(
            "http://%s:%s@%s:%s" % (username, password, host, port))

    def get_block_hash_at_height(self, block_height):
        """Get the hash of the block at the specified height."""
        return self.rpc_connection.getblockhash(block_height)

    def get_json_for_block_hash(self, block_hash):
        """Get a JSON representation of all transactions at specified height."""
        return self.rpc_connection.getblock(block_hash)

    def _get_raw_tx(self, tx_id):
        """Returns tx in raw format.

        If the requested transaction is the sole transaction of the genesis
        block, bitcoind's RPC interface will throw an error 'No information
        available about transaction (code -5)' so we preempt this by raising an
        error. Iterating callers should just move on to the next tx or block.
        """
        if tx_id == (
                '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7af'
                'deda33b'):
            raise NoDataAvailableForGenesisBlockError
        else:
            return self.rpc_connection.getrawtransaction(tx_id)

    def get_decoded_tx(self, tx_id):
        """Returns a human-readable string of the transaction in JSON format."""
        #print "DEBUG: get_decoded_tx %s" % tx_id
        try:
            return self.rpc_connection.decoderawtransaction(
                self._get_raw_tx(tx_id))
        except NoDataAvailableForGenesisBlockError:
            #bitcoind won't generate this, but here's what it would look like
            genesis_json = {
                'txid': ('4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2'
                         '127b7afdeda33b'),
                'version':
                1,
                'locktime':
                0,
                'vin': [{
                    "sequence":
                    4294967295,
                    'coinbase':
                    ('04ffff001d0104455468652054696d65732030332f4a6'
                     '16e2f32303039204368616e63656c6c6f72206f6e2062'
                     '72696e6b206f66207365636f6e64206261696c6f75742'
                     '0666f722062616e6b73')
                }],
                'vout': [{
                    'value': 50.00000000,
                    'n': 0,
                    'scriptPubKey': {
                        'asm': ('04678afdb0fe5548271967f1a67130b7105cd6a828'
                                'e03909a67962e0ea1f61deb649f6bc3f4cef38c4f3'
                                '5504e51ec112de5c384df7ba0b8d578a4c702b6bf1'
                                '1d5f OP_CHECKSIG'),
                        'hex': ('4104678afdb0fe5548271967f1a67130b7105cd6a8'
                                '28e03909a67962e0ea1f61deb649f6bc3f4cef38c4'
                                'f35504e51ec112de5c384df7ba0b8d578a4c702b6b'
                                'f11d5fac'),
                        'reqSigs':
                        1,
                        'type':
                        'pubkey',
                        'addresses': ['1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa']
                    }
                }]
            }
            return genesis_json

    def get_decoded_script(self, asm):
        """Convert bitcoind's 'asm' value to decoded format."""
        return self.rpc_connection.decodescript(asm)