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