Fetch the given list of transactions
        via the JSON-RPC interface.

        Return a dict of parsed transactions on success,
        keyed by txid.

        Return None on error

def fetch_txs_rpc( self, bitcoind_opts, txids ):
        """
        Fetch the given list of transactions
        via the JSON-RPC interface.

        Return a dict of parsed transactions on success,
        keyed by txid.

        Return None on error
        """

        headers = {'content-type': 'application/json'}
        reqs = []
        ret = {}
        for i in xrange(0, len(txids)):
            txid = txids[i]
            if txid == "0000000000000000000000000000000000000000000000000000000000000000":
                # coinbase; we never send these
                ret[txid] = {
                    'version': 1,
                    'locktime': 0,
                    'ins': [],
                    'outs': [
                        {
                            'script': '',
                            'value': 0      # not really 0, but we don't care about coinbases anyway
                        }
                    ],
                }
                continue

            req = {'method': 'getrawtransaction', 'params': [txid, 0], 'jsonrpc': '2.0', 'id': i}
            reqs.append( req )

        proto = "http"
        if bitcoind_opts.has_key('bitcoind_use_https') and bitcoind_opts['bitcoind_use_https']:
            proto = "https"
            
        server_url = "%s://%s:%s@%s:%s" % (proto, bitcoind_opts['bitcoind_user'], bitcoind_opts['bitcoind_passwd'], bitcoind_opts['bitcoind_server'], bitcoind_opts['bitcoind_port'])
        try:
            resp = requests.post( server_url, headers=headers, data=simplejson.dumps(reqs), verify=False )
        except Exception, e:
            log.exception(e)
            log.error("Failed to fetch %s transactions" % len(txids))
            return None

        # get responses
        try:
            resp_json = resp.json()
            assert type(resp_json) in [list]
        except Exception, e:
            log.exception(e)
            log.error("Failed to parse transactions")
            return None

        try:
            for resp in resp_json:
                assert 'result' in resp, "Missing result"

                txhex = resp['result']
                assert txhex is not None, "Invalid RPC response '%s' (for %s)" % (simplejson.dumps(resp), txids[resp['id']])
               
                if bits.btc_tx_is_segwit(txhex) and not get_features('segwit'):
                    # no segwit support yet
                    log.error("FATAL: SegWit transaction detected!  Support for SegWit-formatted transactions is not yet activated")
                    log.error("Please ensure your bitcoind node has `rpcserialversion=0` set.")
                    log.error("Aborting...")
                    os.abort()

                try:

                    tx_bin = txhex.decode('hex')
                    assert tx_bin is not None

                    tx_hash_bin = hashing.bin_double_sha256(tx_bin)[::-1]
                    assert tx_hash_bin is not None

                    tx_hash = tx_hash_bin.encode('hex')
                    assert tx_hash is not None

                except Exception, e:
                    log.error("Failed to calculate txid of %s" % txhex)
                    raise

                # solicited transaction?
                assert tx_hash in txids, "Unsolicited transaction %s" % tx_hash
                
                # unique?
                if tx_hash in ret.keys():
                    continue

                # parse from hex string
                txn_serializer = TxSerializer()
                txn = txn_serializer.deserialize( StringIO( binascii.unhexlify(txhex) ) )

                ret[tx_hash] = self.parse_tx( txn, {}, "", -1 )


        except Exception, e:
            log.exception(e)
            log.error("Failed to receive transactions")
            return None

        return ret