Exemple #1
0
    def get_all_contracts(self):
        '''
        get all contracts
        '''
        if not self.all_contracts:
            self.all_contracts = []
            self.active_contracts = []
            self.instance_lists = []
            state = self._get_head_state()
            accounts = state.get_all_accounts()

            for a in accounts:
                if a.code is not None:
                    code = _encode_hex(a.code)
                    md5 = hashlib.md5()
                    md5.update(code.encode('UTF-8'))
                    contract_hash = md5.digest()
                    contract = ETHContract(code, name=contract_hash.hex())
                    self.all_contracts.append(contract)

                    if a.balance != 0:
                        md5 = InstanceList()
                        md5.add(_encode_hex(a.address), a.balance)
                        self.instance_lists.append(md5)
                        self.active_contracts.append(contract)

        return self.all_contracts
Exemple #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
Exemple #3
0
    def initialize(self, eth):

        self.eth = eth

        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))

        processed = 0

        while (blockNum > 0):

            numbers = []

            for i in range(1, NUM_THREADS + 1):
                numbers.append(max(0, blockNum - (i * BLOCKS_PER_THREAD)))

            pool = Pool(NUM_THREADS, initargs=(self.eth))
            results = pool.map(SyncBlocks(self.eth), numbers)
            pool.close()
            pool.join()

            for result in results:
                for (contract_hash, data) in result.items():

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

                    self.instance_lists[contract_hash].add(
                        data['address'], data['balance'])

            blockNum -= NUM_THREADS * BLOCKS_PER_THREAD
            processed += NUM_THREADS * BLOCKS_PER_THREAD
            self.last_block = blockNum
            transaction.commit()

            cost_time = time.time() - ether.start_time
            print(
                "%d blocks processed (in %d seconds), %d unique contracts in database, next block: %d"
                %
                (processed, cost_time, len(self.contracts), max(0, blockNum)))

        # If we've finished initializing the database, start over from the end of the chain if we want to initialize again
        self.last_block = 0
        print("Finished synchronization")
Exemple #4
0
    def initialize(self, eth, sync_all):

        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))
        ''' 
        On INFURA, the latest block is not immediately available. Here is a workaround to allow for database sync over INFURA.
        Note however that this is extremely slow, contracts should always be loaded from a local node.
        '''

        block = eth.eth_getBlockByNumber(blockNum)

        if not block:
            blockNum -= 2

        while (blockNum > 0):

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

            block = eth.eth_getBlockByNumber(blockNum)

            for tx in block['transactions']:

                if not tx['to']:

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

                    if receipt is not None:

                        contract_address = receipt['contractAddress']

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

                        if not contract_balance and not 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

        # If we've finished initializing the database, start over from the end of the chain if we want to initialize again
        self.last_block = 0
        transaction.commit()