Пример #1
0
class RpcTest(TestCase):
    client = None

    def setUp(self):
        self.client = EthJsonRpc()

    def tearDown(self):
        self.client.close()

    def test_eth_coinbase(self):
        coinbase = self.client.eth_coinbase()
        self.assertTrue(coinbase.startswith("0x"),
                        "coinbase should be a hex string")
        self.assertEqual(len(coinbase), 42,
                         "coinbase is a string with length of 42")

    def test_eth_blockNumber(self):
        block_number = self.client.eth_blockNumber()
        self.assertGreater(
            block_number, 0,
            "we have made sure the blockNumber is > 0 for testing")

    def test_eth_getBalance(self):
        balance = self.client.eth_getBalance(
            address="0x0000000000000000000000000000000000000000")
        self.assertGreater(balance, 10000000,
                           "specified address should have a lot of balance")

    def test_eth_getStorageAt(self):
        storage = self.client.eth_getStorageAt(
            address="0x0000000000000000000000000000000000000000")
        self.assertEqual(
            storage,
            '0x0000000000000000000000000000000000000000000000000000000000000000'
        )

    def test_eth_getBlockByNumber(self):
        block = self.client.eth_getBlockByNumber(0)
        self.assertEqual(
            block["extraData"],
            "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
            "the data of the first block should be right")

    def test_eth_getCode(self):
        # TODO: can't find a proper address for getting code
        code = self.client.eth_getCode(
            address="0x0000000000000000000000000000000000000001")
        self.assertEqual(code, "0x")

    def test_eth_getTransactionReceipt(self):
        transaction = self.client.eth_getTransactionReceipt(
            tx_hash=
            "0xe363505adc6b2996111f8bd774f8653a61d244cc6567b5372c2e781c6c63b737"
        )
        self.assertEqual(transaction["from"],
                         "0x22f2dcff5ad78c3eb6850b5cb951127b659522e6")
        self.assertEqual(transaction["to"],
                         "0x0000000000000000000000000000000000000000")
Пример #2
0
    def initialize(self, rpchost, rpcport, sync_all):

        eth = EthJsonRpc(rpchost, rpcport)

        if self.last_block:
            blockNum = self.last_block
            print("Resuming synchronization from block " + str(blockNum))
        else:

            blockNum = eth.eth_blockNumber()
            print("Starting synchronization from latest block: " +
                  str(blockNum))

        while (blockNum > 0):

            if not blockNum % 1000:
                print("Processing block " + str(blockNum) + ", " +
                      str(len(self.contracts.keys())) +
                      " individual contracts in database")

            block = eth.eth_getBlockByNumber(blockNum)

            for tx in block['transactions']:

                if not tx['to']:

                    receipt = eth.eth_getTransactionReceipt(tx['hash'])

                    contract_address = receipt['contractAddress']

                    contract_code = eth.eth_getCode(contract_address)
                    contract_balance = eth.eth_getBalance(contract_address)

                    if not contract_balance or sync_all:
                        # skip contracts with zero balance (disable with --sync-all)
                        continue

                    code = ETHContract(contract_code, tx['input'])

                    m = hashlib.md5()
                    m.update(contract_code.encode('UTF-8'))
                    contract_hash = m.digest()

                    try:
                        self.contracts[contract_hash]
                    except KeyError:
                        self.contracts[contract_hash] = code
                        m = InstanceList()
                        self.instance_lists[contract_hash] = m

                    self.instance_lists[contract_hash].add(
                        contract_address, contract_balance)

                    transaction.commit()

            self.last_block = blockNum
            blockNum -= 1
Пример #3
0
class LocalNotifier(Notifier):
    def __init__(self, rpc_address, rpc_port):
        """
        Constructor for LocalNotifier class
        :param rpc_address: Address of ethereum rpc interface
        :param rpc_port: Port of ethereum rpc interface
        :param callback: Callback function to call when a contract is found
        """
        logging.info("Initializing local notifier")

        super().__init__()
        self.rpc_client = EthJsonRpc(rpc_address, rpc_port, True)

        logging.info("Initialized rpc client")
        logging.info("Geth version: {}".format(
            self.rpc_client.web3_clientVersion()))

        self.current_block = self.rpc_client.eth_blockNumber()

        logging.info("The ethereum client is currently at block {}".format(
            self.current_block))

    def scan(self):
        """
        Scan for new blocks and examine them for new contracts
        """
        new_block = self.rpc_client.eth_blockNumber()

        logging.info("Starting analysis of blocks {} to {}".format(
            self.current_block + 1, new_block))
        for i in range(self.current_block + 1, new_block):
            self._examine_block(i)

        self.current_block = new_block - 1

    def _new_blocks(self):
        """
        :return: Amount of new blocks available
        """
        return self.rpc_client.eth_blockNumber() - self.current_block

    def _examine_block(self, number):
        """
        Examine all transactions in a block and report found contracts
        :param number: blocknumber of block to examine
        """
        # Gets the block by number, true indicates that we want the entire transactions instead of only hashes
        block = self.rpc_client.eth_getBlockByNumber(number, True)

        logging.info("Examining block with number {}".format(number))

        try:
            transactions = block['transactions']
        except TypeError:
            logging.debug(
                "No transactions element found in block {}".format(number))

        # Examine all transactions
        for transaction in transactions:
            self._examine_transaction(transaction)

    def _examine_transaction(self, transaction_object):
        """
        Examine a transaction and report any found contracts
        :param transaction_object: object from ethjsonrpc describing the transaction
        """
        if transaction_object['to'] is not None:
            logging.debug(
                "Transaction with hash {} is not a contract creating transaction"
                .format(transaction_object['hash']))
            return

        logging.info("Found contract creating transaction with hash {}".format(
            transaction_object['hash']))

        transaction_receipt = self.rpc_client.eth_getTransactionReceipt(
            transaction_object['hash'])

        try:
            contract_address = transaction_receipt['contractAddress']
        except TypeError:
            logging.debug(
                f"Found transaction with no to value and the receipt contained no contract address. Transaction hash: {transaction_object['hash']}"
            )
            return

        logging.info(
            "Found new contract with address {}".format(contract_address))

        self.encounter(contract_address, "LocalNotifier")