Source code for mythril.ethereum.interface.rpc.client

"""This module contains a basic Ethereum RPC client.

This code is adapted from: https://github.com/ConsenSys/ethjsonrpc
"""
import json
import logging

import requests
from requests.adapters import HTTPAdapter
from requests.exceptions import ConnectionError as RequestsConnectionError

from .base_client import BaseClient
from .exceptions import (
    BadJsonError,
    BadResponseError,
    BadStatusCodeError,
    ConnectionError,
)

log = logging.getLogger(__name__)

GETH_DEFAULT_RPC_PORT = 8545
ETH_DEFAULT_RPC_PORT = 8545
PARITY_DEFAULT_RPC_PORT = 8545
PYETHAPP_DEFAULT_RPC_PORT = 4000
MAX_RETRIES = 3
JSON_MEDIA_TYPE = "application/json"


[docs]class EthJsonRpc(BaseClient): """Ethereum JSON-RPC client class.""" def __init__(self, host="localhost", port=GETH_DEFAULT_RPC_PORT, tls=False): """ :param host: :param port: :param tls: """ self.host = host self.port = port self.tls = tls self.session = requests.Session() self.session.mount(self.host, HTTPAdapter(max_retries=MAX_RETRIES)) def _call(self, method, params=None, _id=1): """ :param method: :param params: :param _id: :return: """ params = params or [] data = {"jsonrpc": "2.0", "method": method, "params": params, "id": _id} scheme = "http" if self.tls: scheme += "s" if self.host: if self.port: url = "{}://{}:{}".format(scheme, self.host, self.port) else: url = "{}://{}".format(scheme, self.host) else: url = "{}".format(scheme) headers = {"Content-Type": JSON_MEDIA_TYPE} log.debug("rpc send: %s" % json.dumps(data)) try: r = self.session.post(url, headers=headers, data=json.dumps(data)) except RequestsConnectionError: raise ConnectionError if r.status_code / 100 != 2: raise BadStatusCodeError(r.status_code) try: response = r.json() log.debug("rpc response: %s" % response) except ValueError: raise BadJsonError(r.text) try: return response["result"] except KeyError: raise BadResponseError(response)
[docs] def close(self): """Close the RPC client's session.""" self.session.close()