def find_steem_tx(self, tx_data: dict, last_blocks=15) -> dict: """ Used internally to get the transaction ID after a Steem transaction has been broadcasted. See :py:meth:`.send_token` and :py:meth:`.issue_token` for how this is used. :param dict tx_data: Transaction data returned by a beem broadcast operation, must include ``signatures`` :param int last_blocks: Amount of previous blocks to search for the transaction :return dict: Transaction data from the blockchain, see below. **Return format:** .. code-block:: js { transaction_id, ref_block_num, ref_block_prefix, expiration, operations, extensions, signatures, block_num, transaction_num } :return None: If the transaction wasn't found, ``None`` will be returned. """ from beem.blockchain import Blockchain # Code taken/based from @holgern/beem blockchain.py chain = Blockchain(steem_instance=self.steem, mode='head') current_num = chain.get_current_block_num() for block in chain.blocks(start=current_num - last_blocks, stop=current_num + 5): for tx in block.transactions: if sorted(tx["signatures"]) == sorted(tx_data["signatures"]): return tx return None
def run(self): b = Blockchain(steem_instance=self.stm) yesterday = date.today() - timedelta(days=1) yesterday_0_0_0 = datetime(yesterday.year, yesterday.month, yesterday.day) yesterday_23_59_59 = datetime(yesterday.year, yesterday.month, yesterday.day, 23, 59, 59) start_block = b.get_estimated_block_num(addTzInfo(yesterday_0_0_0)) stop_block = b.get_estimated_block_num(addTzInfo(yesterday_23_59_59)) logger.info("Check token transfer from %s..." % self.config["scot_account"]) token_sent_last_24_h = self.get_token_transfer_last_24_h() if token_sent_last_24_h > 0: logger.warning("Token were already sent today...") return logger.info("No token transfer were found, continue...") token_per_100_vote = self.get_token_holder() logger.info("%d token holder were found." % len(token_per_100_vote)) token_to_authors = self.get_token_to_sent(start_block, stop_block, token_per_100_vote) token_to_authors = self.adapt_to_precision(token_to_authors) token_amount_to_sent = self.count_token(token_to_authors) logger.info("Start to send %f token to %d accounts" % (token_amount_to_sent, len(token_to_authors))) self.send_token(token_to_authors)
def read_missing_block_data(self, start_block=None): # Go trough all transfer ops cnt = 0 blockchain = Blockchain() current_block = blockchain.get_current_block_num() if start_block is not None: trx_num = start_block["trx_num"] block_num = start_block["block_num"] start_block = block_num # print("account %s - %d" % (account["name"], start_block)) else: trx_num = 0 block_num = 0 start_block = current_block - self.block_history data = [] for op in blockchain.stream(start=start_block, stop=current_block, only_ops=self.only_ops, only_virtual_ops=self.only_virtual_ops): if op["block_num"] < start_block: # last_block = op["block"] continue elif op["block_num"] == start_block: if op["trx_num"] <= trx_num: continue data.append(op) cnt += 1 return data
def test_stream_threading(self): bts = self.bts b = Blockchain(steem_instance=bts) ops_stream_no_threading = [] opNames = ["transfer", "vote"] block_num_list2 = [] for op in b.stream(opNames=opNames, start=self.start, stop=self.stop, threading=False): ops_stream_no_threading.append(op) if op["block_num"] not in block_num_list2: block_num_list2.append(op["block_num"]) for n in range(5): ops_stream = [] block_num_list = [] for op in b.stream(opNames=opNames, start=self.start, stop=self.stop, threading=True, thread_num=8): ops_stream.append(op) if op["block_num"] not in block_num_list: block_num_list.append(op["block_num"]) self.assertEqual(ops_stream[0]["block_num"], ops_stream_no_threading[0]["block_num"]) self.assertEqual(ops_stream[-1]["block_num"], ops_stream_no_threading[-1]["block_num"]) self.assertEqual(len(ops_stream_no_threading), len(ops_stream)) self.assertEqual(len(block_num_list), len(block_num_list2)) for i in range(len(block_num_list)): self.assertEqual(block_num_list[i], block_num_list2[i])
def test_stream_batch(self): bts = self.bts b = Blockchain(steem_instance=bts) ops_stream = [] opNames = ["transfer", "vote"] for op in b.stream(opNames=opNames, start=self.start, stop=self.stop, max_batch_size=self.max_batch_size, threading=False): ops_stream.append(op) self.assertTrue(ops_stream[0]["block_num"] >= self.start) self.assertTrue(ops_stream[-1]["block_num"] <= self.stop) op_stat = b.ops_statistics(start=self.start, stop=self.stop) self.assertEqual(op_stat["vote"] + op_stat["transfer"], len(ops_stream)) ops_blocks = [] for op in b.blocks(start=self.start, stop=self.stop, max_batch_size=self.max_batch_size, threading=False): ops_blocks.append(op) op_stat4 = {"transfer": 0, "vote": 0} self.assertTrue(len(ops_blocks) > 0) for block in ops_blocks: for tran in block["transactions"]: for op in tran['operations']: if isinstance(op, dict) and "type" in op and "value" in op: op_type = op["type"] if len(op_type) > 10 and op_type[len(op_type) - 10:] == "_operation": op_type = op_type[:-10] if op_type in opNames: op_stat4[op_type] += 1 elif op[0] in opNames: op_stat4[op[0]] += 1 self.assertTrue(block.identifier >= self.start) self.assertTrue(block.identifier <= self.stop) self.assertEqual(op_stat["transfer"], op_stat4["transfer"]) self.assertEqual(op_stat["vote"], op_stat4["vote"])
def test_stream_threading(self): bts = self.bts b = Blockchain(steem_instance=bts) ops_stream = [] opNames = ["transfer", "vote"] for op in b.stream(opNames=opNames, start=self.start, stop=self.stop): ops_stream.append(op) self.assertTrue(len(ops_stream) > 0) op_stat = b.ops_statistics(start=self.start, stop=self.stop) ops_blocks = [] for op in b.blocks(start=self.start, stop=self.stop, threading=True, thread_num=8): ops_blocks.append(op) op_stat4 = {"transfer": 0, "vote": 0} self.assertTrue(len(ops_blocks) > 0) for block in ops_blocks: for tran in block["transactions"]: for op in tran['operations']: if op[0] in opNames: op_stat4[op[0]] += 1 self.assertTrue(block.identifier >= self.start) self.assertTrue(block.identifier <= self.stop) self.assertEqual(op_stat["transfer"], op_stat4["transfer"]) self.assertEqual(op_stat["vote"], op_stat4["vote"])
def profiling(name_list): stm = Steem() set_shared_steem_instance(stm) del stm print("start") for name in name_list: print("account: %s" % (name)) acc = Account(name) max_index = acc.virtual_op_count() print(max_index) stopTime = datetime(2018, 4, 22, 0, 0, 0) hist_elem = None for h in acc.history_reverse(stop=stopTime): hist_elem = h print(hist_elem) print("blockchain") blockchain_object = Blockchain() current_num = blockchain_object.get_current_block_num() startBlockNumber = current_num - 20 endBlockNumber = current_num block_elem = None for o in blockchain_object.ops(start=startBlockNumber, stop=endBlockNumber): print("block %d" % (o["block_num"])) block_elem = o print(block_elem)
def __init__(self, config, data_file, hived_instance): self.config = config self.data_file = data_file self.hive = hived_instance self.token_config = {} # add log stats self.log_data = { "start_time": 0, "last_block_num": None, "new_commands": 0, "stop_block_num": 0, "stop_block_num": 0, "time_for_blocks": 0 } config_cnt = 0 necessary_fields = [ "token_account", "symbol", "min_token_in_wallet", "comment_command", "token_memo", "reply", "sucess_reply_body", "fail_reply_body", "no_token_left_body", "user_can_specify_amount", "usage_upvote_percentage", "no_token_left_for_today", "token_in_wallet_for_each_outgoing_token", "maximum_amount_per_comment", "count_only_staked_token" ] self.token_config = check_config(self.config["config"], necessary_fields, self.hive) self.blockchain = Blockchain(mode='head', blockchain_instance=self.hive)
def test_signing_appbase(self): b = Blockchain(steem_instance=self.bts) st = None for block in b.blocks(start=25304468, stop=25304468): for trx in block.transactions: st = Signed_Transaction(trx.copy()) self.assertTrue(st is not None)
def test_hash_op(self): bts = self.bts b = Blockchain(steem_instance=bts) op1 = {'type': 'vote_operation', 'value': {'voter': 'ubg', 'author': 'yesslife', 'permlink': 'steemit-sandwich-contest-week-25-2da-entry', 'weight': 100}} op2 = ['vote', {'voter': 'ubg', 'author': 'yesslife', 'permlink': 'steemit-sandwich-contest-week-25-2da-entry', 'weight': 100}] hash1 = b.hash_op(op1) hash2 = b.hash_op(op2) self.assertEqual(hash1, hash2)
def test_stream2(self): bts = self.bts b = Blockchain(steem_instance=bts) stop_block = b.get_current_block_num() start_block = stop_block - 10 ops_stream = [] for op in b.stream(start=start_block, stop=stop_block): ops_stream.append(op) self.assertTrue(len(ops_stream) > 0)
def test_get_all_accounts(self): bts = self.bts b = Blockchain(steem_instance=bts) accounts = [] limit = 200 for acc in b.get_all_accounts(steps=100, limit=limit): accounts.append(acc) self.assertEqual(len(accounts), limit) self.assertEqual(len(set(accounts)), limit)
def test_get_all_accounts(self, node_param): if node_param == "non_appbase": bts = self.bts else: bts = self.appbase b = Blockchain(steem_instance=bts) accounts = [] for acc in b.get_all_accounts(steps=100, limit=100): accounts.append(acc) self.assertEqual(len(accounts), 100)
def stream_blocks(self, start=None): blockchain = Blockchain() current_block = blockchain.get_current_block_num() ops = [] for op in blockchain.stream(start=start, stop=current_block, only_ops=self.only_ops, only_virtual_ops=self.only_virtual_ops): ops.append(op) return ops
def listen_blockchain_ops(opNames: list): """Listens to Steem blockchain and yields specified operations. :param opNames: List of operations to yield :type opNames: list """ bc = Blockchain(mode="head") block_num = bc.get_current_block_num() for op in bc.stream(opNames=opNames, start=block_num, threading=True): yield op
def __init__(self, name, blockchain): self.__name = name if blockchain == "hive": self._blockchain = Blockchain( blockchain_instance=blockchains.HIVE_INSTANCE) pass elif blockchain == "steem": self._blockchain = Blockchain( blockchain_instance=blockchains.STEEM_INSTANCE) else: raise NotImplementedError
def stream_votes(stm, threading, thread_num): b = Blockchain(steem_instance=stm) opcount = 0 start_time = time.time() for op in b.stream(start=23483000, stop=23483200, threading=threading, thread_num=thread_num, opNames=['vote']): sys.stdout.write("\r%s" % op['block_num']) opcount += 1 now = time.time() total_duration = now - start_time print(" votes: %d, time %.2f" % (opcount, total_duration)) return opcount, total_duration
def test_awaitTX(self): bts = self.bts b = Blockchain(steem_instance=bts) trans = {'ref_block_num': 3855, 'ref_block_prefix': 1730859721, 'expiration': '2018-03-09T06:21:06', 'operations': [], 'extensions': [], 'signatures': ['2033a872a8ad33c7d5b946871e4c9cc8f08a5809258355fc909058eac83' '20ac2a872517a52b51522930d93dd2c1d5eb9f90b070f75f838c881ff29b11af98d6a1b']} with self.assertRaises( Exception ): b.awaitTxConfirmation(trans)
def test_stream2(self, node_param): if node_param == "normal": bts = self.bts else: bts = self.testnet b = Blockchain(steem_instance=bts) stop_block = b.get_current_block_num() start_block = stop_block - 10 ops_stream = [] for op in b.stream(start=start_block, stop=stop_block): ops_stream.append(op) self.assertTrue(len(ops_stream) > 0)
def test_get_all_accounts(self, node_param): if node_param == "normal": bts = self.bts else: bts = self.testnet b = Blockchain(steem_instance=bts) accounts = [] limit = 200 for acc in b.get_all_accounts(steps=100, limit=limit): accounts.append(acc) self.assertEqual(len(accounts), limit) self.assertEqual(len(set(accounts)), limit)
def setUpClass(cls): cls.bts = Steem(node=get_hive_nodes(), nobroadcast=True, keys={"active": wif}, num_retries=10) b = Blockchain(blockchain_instance=cls.bts) num = b.get_current_block_num() cls.start = num - 5 cls.stop = num # from getpass import getpass # self.bts.wallet.unlock(getpass()) set_shared_blockchain_instance(cls.bts)
def test_stream_batch2(self): bts = self.bts b = Blockchain(steem_instance=bts) ops_stream = [] start_block = 25097000 stop_block = 25097100 opNames = ["account_create", "custom_json"] for op in b.stream(start=int(start_block), stop=int(stop_block), opNames=opNames, max_batch_size=50, threading=False, thread_num=8): ops_stream.append(op) self.assertTrue(ops_stream[0]["block_num"] >= start_block) self.assertTrue(ops_stream[-1]["block_num"] <= stop_block) op_stat = b.ops_statistics(start=start_block, stop=stop_block) self.assertEqual(op_stat["account_create"] + op_stat["custom_json"], len(ops_stream))
class Crawler: def __init__(self, name, blockchain): self.__name = name if blockchain == "hive": self._blockchain = Blockchain( blockchain_instance=blockchains.HIVE_INSTANCE) pass elif blockchain == "steem": self._blockchain = Blockchain( blockchain_instance=blockchains.STEEM_INSTANCE) else: raise NotImplementedError def _stream(self, opNames=[]): if hasattr(self, "start") and hasattr(self, "stop"): # get starting block id start_block_id = self._blockchain.get_estimated_block_num( self.start, accurate=True) stop_block_id = self._blockchain.get_estimated_block_num( self.stop, accurate=True) # looping trough generator for op_json in self._blockchain.stream(opNames=opNames, start=start_block_id, stop=stop_block_id): yield op_json else: print( "[DEBUG] Timeframe was not set in criteria, direct streaming used" ) # looping trough generator for op_json in self._blockchain.stream(opNames=opNames): yield op_json def set_timeframe(self, start, stop): if isinstance(start, datetime.datetime): self.start = start else: raise TypeError( "start argument must be an instance of datetime.datetime") if isinstance(stop, datetime.datetime): self.stop = stop else: raise TypeError( "stop argument must be an instance of datetime.datetime") if start >= stop: raise RuntimeError("stop({}) < start({})".format(stop, start))
async def stream(): try: stm = Steem(node=[ "https://api.steemit.com", "https://steemd.minnowsupportproject.org", "https://anyx.io" ]) chain = Blockchain(stm, "head") for tx in chain.stream(['custom_json']): if tx['id'] == 'sm_sell_cards': user_perm_posting = "" user_perm_active = "" try: user_perm_posting = tx['required_posting_auths'][0] except: pass try: user_perm_active = tx['required_auths'][0] except: pass json_data = json.loads(tx['json']) loop.create_task( process(json_data, user_perm_posting, user_perm_active)) elif tx['id'] == 'sm_update_price': market_id_list = json.loads(tx['json'])['ids'] card_uid_dict = [] for market_id in market_id_list: time.sleep(2) try: response_json = requests.get( f"https://steemmonsters.com/market/status?id={market_id}" ).json() card_uid = response_json['cards'][0]['uid'] card_uid_dict.append(card_uid) except: pass user_perm_posting = "" user_perm_active = "" try: user_perm_posting = tx['required_posting_auths'][0] except: pass try: user_perm_active = tx['required_auths'][0] except: pass loop.create_task( process(card_uid_dict, user_perm_posting, user_perm_active)) await asyncio.sleep(0) except: print(traceback.format_exc())
def __init__(self): """Initialisation.""" self.load_settings() self.nodes = [ 'https://api.steemit.com', 'https://rpc.buildteam.io', 'https://api.steem.house', 'https://steemd.steemitdev.com', 'https://steemd.steemitstage.com', 'https://steemd.steemgigs.org' ] self.s = Steem(keys=self.posting_key) self.s.set_default_nodes(self.nodes) self.b = Blockchain(self.s) set_shared_steem_instance(self.s) self.p = Pool(4)
def test_wait_for_and_get_block(self, node_param): if node_param == "non_appbase": bts = self.bts else: bts = self.appbase b = Blockchain(steem_instance=bts, max_block_wait_repetition=6) start_num = b.get_current_block_num() blocknum = start_num last_fetched_block_num = None for i in range(3): block = b.wait_for_and_get_block(blocknum) last_fetched_block_num = block.block_num blocknum = last_fetched_block_num + 2 self.assertEqual(last_fetched_block_num, start_num + 4)
def test_block_threading(self): bts = self.bts b = Blockchain(steem_instance=bts) blocks_no_threading = [] for block in b.blocks(start=self.start, stop=self.stop, threading=False, thread_num=8): blocks_no_threading.append(block) for n in range(5): blocks = [] for block in b.blocks(start=self.start, stop=self.stop, threading=True, thread_num=8): blocks.append(block) for i in range(min(len(blocks), len(blocks_no_threading))): self.assertEqual(blocks[i]["block_id"], blocks_no_threading[i]["block_id"]) self.assertEqual(len(blocks_no_threading), len(blocks))
def accountmatch(account, limit=10): """Find account names similar to the provided string. [account] can be an existing account of a partial name. Limit the output to [limit] results. :param str account: account to parse :param int limit: maximum number of similar account names to return :return list of account names """ bc = Blockchain() return [ acc['name'] for acc in bc.get_similar_account_names(account, limit=limit) ]
def analyze(account): """Analyze ACCOUNT for possible hack leftovers. """ acc = Account(account.replace("@", "")) if acc['last_owner_update'] not in time_unset: days = (addTzInfo(datetime.utcnow()) - \ acc['last_owner_update']).days last_update = "%s (%d days ago)" % (acc['last_owner_update'], days) else: last_update = "never" logger.info("Last owner update: %s" % (last_update)) logger.info("Recovery account: @%s" % (acc['recovery_account'])) # check if the account is currently powering down if acc['next_vesting_withdrawal'] not in time_unset: vests = acc['vesting_withdraw_rate'] sp = acc.blockchain.vests_to_sp(vests.amount) logger.warning("Account is currently powering down:") logger.warning("Next vesting withdrawal: %s (~%.3f %s) at %s" % (vests, sp, acc.blockchain.token_symbol, acc['next_vesting_withdrawal'])) else: logger.info("Account is not powering down.") # check for active withdraw vesting routes routes = acc.get_withdraw_routes() if len(routes): tbl = PrettyTable(['From', 'To', 'Percent', 'Auto-vest']) for route in routes: tbl.add_row([ route['from_account'], route['to_account'], int(route['percent']) / STEEM_1_PERCENT, route['auto_vest'] ]) logger.warning("Account has withdraw routes set:\n" + str(tbl)) else: logger.info("Account has no withdraw routes set") bc = Blockchain() requests = bc.find_change_recovery_account_requests([account]) if len(requests): logger.warning( "Request to change the recovery account to " "@%s, will be effective on: %s" % (requests[0]['recovery_account'], requests[0]['effective_on'])) else: logger.info("No pending requests to change the recovery account")
def hour_active(chain): nodelist = NodeList() nodelist.update_nodes() if chain=='steem': s = Steem(node=nodelist.get_steem_nodes()) else: s = Steem(node=nodelist.get_hive_nodes()) b=Blockchain(s) bl_=[] bl_num=int(b.get_current_block_num()) bl_num_=bl_num-1250 bl=b.blocks(bl_num_,bl_num) for i in bl: bl_.append(i['transactions']) x=('follower','account','voter','from','author') account=[] new=[] for i in x: acc=re.findall('"'+i+'":"(.+?)"',str(bl_)) for l in acc: if l not in account: account.append(l) if chain=='steem': file=open('active_acc_steem.txt','r') old=file.readlines() file.close() file=open('active_acc_steem.txt','a') for i in account: if i+'\n' not in old: file.write(str(i)+'\n') new.append(i) file.close() else: file=open('active_acc_hive.txt','r') old=file.readlines() file.close() file=open('active_acc_hive.txt','a') for i in account: if i+'\n' not in old: file.write(str(i)+'\n') new.append(i) file.close() print ('one hour accounts '+chain,len(account)) print ('one hour brand new '+chain,len(new)) print ('total ACTIVE accounts '+chain,len(old))