def test_history_reverse2(self): stm = self.bts account = Account("beembot", steem_instance=stm) h_list = [] max_index = account.virtual_op_count() for h in account.history_reverse(start=max_index, stop=max_index - 4, use_block_num=False, batch_size=2, raw_output=False): h_list.append(h) self.assertEqual(len(h_list), 5) for i in range(1, 5): self.assertEqual(h_list[i]["index"] - h_list[i - 1]["index"], -1) h_list = [] for h in account.history_reverse(start=max_index, stop=max_index - 4, use_block_num=False, batch_size=6, raw_output=False): h_list.append(h) self.assertEqual(len(h_list), 5) for i in range(1, 5): self.assertEqual(h_list[i]["index"] - h_list[i - 1]["index"], -1) h_list = [] for h in account.history_reverse(start=max_index, stop=max_index - 4, use_block_num=False, batch_size=6, raw_output=True): h_list.append(h) self.assertEqual(len(h_list), 5) for i in range(1, 5): self.assertEqual(h_list[i][0] - h_list[i - 1][0], -1) h_list = [] for h in account.history_reverse(start=max_index, stop=max_index - 4, use_block_num=False, batch_size=2, raw_output=True): h_list.append(h) self.assertEqual(len(h_list), 5) for i in range(1, 5): self.assertEqual(h_list[i][0] - h_list[i - 1][0], -1)
def issue(self, to, amount, symbol): """Issues a specific token amount. :param str to: Recipient :param float amount: Amount to issue :param str symbol: Token to issue Issue example: .. code-block:: python from steemengine.wallet import Wallet from beem import Steem active_wif = "5xxxx" stm = Steem(keys=[active_wif]) wallet = Wallet("test", steem_instance=stm) wallet.issue(1, "my_token") """ token = Token(symbol, api=self.api) if token["issuer"] != self.account: raise TokenIssueNotPermitted("%s is not the issuer of token %s" % (self.account, symbol)) if token["maxSupply"] == token["supply"]: raise MaxSupplyReached("%s has reached is maximum supply of %d" % (symbol, token["maxSupply"])) quant_amount = token.quantize(amount) if quant_amount <= decimal.Decimal("0"): raise InvalidTokenAmount( "Amount to issue is below token precision of %d" % token["precision"]) check_to = Account(to, steem_instance=self.steem) contract_payload = { "symbol": symbol.upper(), "to": to, "quantity": str(quant_amount) } json_data = { "contractName": "tokens", "contractAction": "issue", "contractPayload": contract_payload } tx = self.steem.custom_json(self.ssc_id, json_data, required_auths=[self.account]) return tx
def analyze(account): """Analyze an account for possible hack leftovers. """ acc = Account(account) 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: logger.warning("Account is currently powering down:") logger.warning( "Next vesting withdrawal: %s at %s" % (acc['vesting_withdraw_rate'], 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: print(route) 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 steem_sbd(key, player, token, mymoney, toplayer, memo): local_values.s = Steem(keys=[key]) set_shared_steem_instance(local_values.s) account = Account(player) # 转账 kk = account.transfer(toplayer, mymoney, token, memo) tx = Signed_Transaction(kk) tx.data.pop("signatures", None) print(tx) h = hashlib.sha256(bytes(tx)).digest() transaction_id = hexlify(h[:20]).decode("ascii") print(transaction_id) url = "https://steemd.com/tx/%s" % transaction_id print("转账完成") print(url) return url
async def claim(): stm = Steem(node="https://api.steemit.com", keys=[SR]) rc = RC(steem_instance=stm) acc = Account('sourovafrin') current_mana = acc.get_rc_manabar()["current_mana"] mana_cost = stm.get_rc_cost( rc.get_resource_count(tx_size=250, execution_time_count=0, state_bytes_count=0, new_account_op_count=1)) mana_cost += 2500000000 if current_mana > mana_cost: stm.claim_account('sourovafrin', '0 STEEM') await client.send_message( client.get_channel('544916428881657856'), "<@397972596207124480> I have claimed a steem discounted account just now and that's only for you" )
def setUpClass(cls): nodelist = NodeList() nodes = nodelist.get_nodes(hive=True, exclude_limited=False) nodelist.update_nodes(steem_instance=Steem(node=nodes, num_retries=10)) node_list = nodelist.get_nodes(hive=True) cls.bts = Steem( node=node_list, nobroadcast=True, bundle=False, unsigned=True, # Overwrite wallet to use this list of wifs only keys={"active": wif}, num_retries=10 ) cls.account = Account("beembot", steem_instance=cls.bts) set_shared_steem_instance(cls.bts)
def test_transfer(self): bts = self.bts bts.nobroadcast = False bts.wallet.unlock("123") # bts.wallet.addPrivateKey(self.active_key) # bts.prefix ="STX" acc = Account("beem", steem_instance=bts) tx = acc.transfer("beem1", 1.33, "SBD", memo="Foobar") self.assertEqual(tx["operations"][0][0], "transfer") self.assertEqual(len(tx['signatures']), 1) op = tx["operations"][0][1] self.assertIn("memo", op) self.assertEqual(op["from"], "beem") self.assertEqual(op["to"], "beem1") amount = Amount(op["amount"], steem_instance=bts) self.assertEqual(float(amount), 1.33) bts.nobroadcast = True
def __init__(self, account, path, trxStorage, transactionStorage, transactionOutStorage, member_data, memberStorage = None, steem_instance=None): self.steem = steem_instance or shared_steem_instance() self.account = Account(account, steem_instance=self.steem) self.delegated_vests_in = {} self.delegated_vests_out = {} self.timestamp = addTzInfo(datetime(1970, 1, 1, 0, 0, 0, 0)) self.path = path self.member_data = member_data self.memberStorage = memberStorage self.memo_parser = MemoParser(steem_instance=self.steem) self.excluded_accounts = ["minnowbooster", "smartsteem", "randowhale", "steemvoter", "jerrybanfield", "boomerang", "postpromoter", "appreciator", "buildawhale", "upme", "smartmarket", "minnowhelper", "pushup", "steembasicincome", "sbi2", "sbi3", "sbi4", "sbi5", "sbi6", "sbi7", "sbi8", "sbi9"] self.trxStorage = trxStorage self.transactionStorage = transactionStorage self.transactionOutStorage = transactionOutStorage
def claim_it(chain, mana): """Very simple Utility to claim HIVE and/or STEEM account tokens""" api = {"steem": "https://api.steemit.com", "hive": "https://api.hive.blog"} wif = click.prompt("Enter private key", confirmation_prompt=False, hide_input=True) for network in chain: steem = Steem(node=api[network], keys=wif) set_shared_steem_instance(steem) wallet = Wallet(shared_steem_instance()) steemid = wallet.getAccountFromPrivateKey(wif) account = Account(steemid, steem_instance=shared_steem_instance()) mana_old = account.get_rc_manabar() mana_human_readable = mana_old["current_mana"] / 1e9 tries = 2 for i in range(tries): try: if mana_human_readable > mana: click.echo(f"[Mana on {network} Before: %f RC]" % (mana_old["current_mana"] / 1e9)) tx = steem.claim_account(creator=steemid, fee=None) pprint(tx) time.sleep(5) mana_new = account.get_rc_manabar() click.echo(f"[Mana on {network} After: %f RC]" % (mana_new["current_mana"] / 1e9)) rc_costs = mana_old["current_mana"] - mana_new[ "current_mana"] click.echo("[Mana cost: %f RC]" % (rc_costs / 1e9)) else: click.echo( f"[Skipping claim account: current mana of %f lower than the set limit of %f on {network}]" % (mana_human_readable, mana)) time.sleep(5) except Exception as e: click.echo('[Error:', e, ' - Trying Again]') time.sleep(2) if i < tries: continue else: click.echo('[Failed to claim]') else: break
def anyx(): SV = os.environ.get('SV') di = { '16': .55, '15': .03, '5': .42, '49': .45, '27': .42, '38': .42, '70': .50, '71': .45, '72': .55, '73': .45, '74': .4, } dic = {'16': .7, '5': .50, '49': .7, '27': .56, '38': .68} stm = Steem(node="https://anyx.io", keys=SV) acc = Account('sourovafrin', steem_instance=stm) bo = Blockchain(stm, 'head') print("started anyx") for detail in bo.stream(['custom_json']): try: if detail['id'] == 'sm_sell_cards': for i in ast.literal_eval(detail['json']): lin = requests.get( "https://steemmonsters.com/cards/find?ids=" + i['cards'][0]).json() for ii in lin: id = ii['market_id'] idd = str(ii['card_detail_id']) price = float(ii['buy_price']) if int(ii['edition']) == 1 and price <= di[idd]: acc.transfer( 'svirus', 2, 'SBD', "sm_market_purchase:" + id + ":sourovafrin") elif int(ii['edition']) == 0 and price <= dic[idd]: acc.transfer( 'svirus', 2, 'SBD', "sm_market_purchase:" + id + ":sourovafrin") except Exception as e: print("Error found anyx: {}".format(e))
def test_sign_message(self): def new_refresh(self): dict.__init__( self, { "identifier": "test", "name": "test", "id_item": "name", "memo_key": "STM6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" }) with mock.patch( "beem.account.Account.refresh", new=new_refresh ): account = Account("test") account["memo_key"] = "STM6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" p = Message("message foobar").sign(account=account) Message(p).verify(account=account)
def test_TransactionConstructor(self): stm = self.bts opTransfer = Transfer(**{"from": "beem", "to": "beem1", "amount": Amount("1 STEEM", steem_instance=stm), "memo": ""}) tx1 = TransactionBuilder(use_condenser_api=True, steem_instance=stm) tx1.appendOps(opTransfer) tx = TransactionBuilder(tx1, steem_instance=stm) self.assertFalse(tx.is_empty()) self.assertTrue(len(tx.list_operations()) == 1) self.assertTrue(repr(tx) is not None) self.assertTrue(str(tx) is not None) account = Account("beem", steem_instance=stm) tx.appendSigner(account, "active") self.assertTrue(len(tx.wifs) > 0) tx.sign() self.assertTrue(len(tx["signatures"]) > 0)
def get_friends(username, follow_type): # Create account object try: account = Account(username) logging.warning(account) except Exception as e: logging.warning(e) return {} followers = account.get_followers() following = account.get_following() if follow_type == 'follower': return make_dict(followers, following) elif follow_type == 'following': return make_dict(following, followers) else: return {}
def test_verifyAuthority(self): stm = self.bts stm.wallet.unlock("123") tx = TransactionBuilder(use_condenser_api=True, steem_instance=stm) tx.appendOps( Transfer( **{ "from": "beem", "to": "beem1", "amount": Amount("1.300 SBD", steem_instance=stm), "memo": "Foobar" })) account = Account("beem", steem_instance=stm) tx.appendSigner(account, "active") self.assertTrue(len(tx.wifs) > 0) tx.sign() tx.verify_authority() self.assertTrue(len(tx["signatures"]) > 0)
def payout(): """prepare and execute the payout for all delegators payout will use all SBD that are currently on the chain and distribute them. Payout will only start if there is at least 1 SBD available. Arguments: none Returns: 0 in case of everything ok -1 in any other case """ acc = Account(NAME_ACCOUNT) to_distribute = acc.get_balance("available", "SBD") if to_distribute < 1: print("Nur %s SBD auf dem Account, Auszahlung beginnt erst ab 1 SBD" % to_distribute) return -1 print("Gesamtsumme zum Verteilen %s" % to_distribute) CURSOR.execute( "SELECT delegator, prozent from delegations WHERE prozent > 0") result = CURSOR.fetchall() message = "Thanks alot for delegating to STEEMPUNKNET, this is your daily payout!" safety = to_distribute * 0.2 print("Transfer an Steempunksnet %s" % safety) safety = str(safety) safety = safety.replace(" SBD", "") acc.transfer("steempunksnet", safety, "SBD", memo="safety transfer", account=NAME_ACCOUNT) time.sleep(3) to_distribute = to_distribute - safety - 0.1 print("Gesamtsumme zum Verteilen an Delegierer %s" % to_distribute) for row in result: sbd = to_distribute * float(row[1]) / 100 sbd = str(sbd) sbd = sbd.replace(" SBD", "") delegator = row[0] acc.transfer(delegator, sbd, "SBD", memo=message, account=NAME_ACCOUNT) print("Delegator %s mit %s Prozent wurden %s SBD transferiert" % (delegator, row[1], sbd)) time.sleep(3) return 0
def upload(self, image, account, image_name=None): """ Uploads an image :param image: path to the image or image in bytes representation which should be uploaded :type image: str, bytes :param str account: Account which is used to upload. A posting key must be provided. :param str image_name: optional .. code-block:: python from beem import Steem from beem.imageuploader import ImageUploader stm = Steem(keys=["5xxx"]) # private posting key iu = ImageUploader(steem_instance=stm) iu.upload("path/to/image.png", "account_name") # "private posting key belongs to account_name """ account = Account(account, steem_instance=self.steem) if "posting" not in account: account.refresh() if "posting" not in account: raise AssertionError("Could not access posting permission") for authority in account["posting"]["key_auths"]: posting_wif = self.steem.wallet.getPrivateKeyForPublicKey(authority[0]) if isinstance(image, string_types): image_data = open(image, 'rb').read() elif isinstance(image, io.BytesIO): image_data = image.read() else: image_data = image message = py23_bytes(self.challenge, "ascii") + image_data signature = sign_message(message, posting_wif) signature_in_hex = hexlify(signature).decode("ascii") files = {image_name or 'image': image_data} url = "%s/%s/%s" % ( self.base_url, account["name"], signature_in_hex ) r = requests.post(url, files=files) return r.json()
def get_user_posts(username, from_id, limit=100): stm = Steem("https://steemd.privex.io") acc = Account(username, steem_instance=stm) blog_entries = acc.get_blog_entries(from_id, limit) entries_list = [] for entry in blog_entries: if username == entry['author']: comment = Comment("@" + entry['author'] + "/" + entry['permlink']) entry_dict = { 'id': comment.id, 'title': comment.title, 'clickable': 'https://www.steemit.com/{0}/@{1}/{2}'.format( comment.category, comment.author, comment.permlink, ), 'url': '/{0}/@{1}/{2}'.format( comment.category, comment.author, comment.permlink, ), 'author': comment.author, 'category': comment.category, 'tags': comment.json_metadata['tags'], 'entry_id': entry['entry_id'] } if 'images' in comment.json_metadata: entry_dict['images'] = comment.json_metadata['images'] entries_list.append(entry_dict) return entries_list
def test_history_op_filter(self): stm = Hive("https://api.hive.blog") account = Account("beembot", blockchain_instance=stm) votes_list = list(account.history(only_ops=["vote"])) other_list = list(account.history(exclude_ops=["vote"])) all_list = list(account.history()) self.assertEqual(len(all_list), len(votes_list) + len(other_list)) index = 0 for h in sorted((votes_list + other_list), key=lambda h: h["index"]): self.assertEqual(index, h["index"]) index += 1 votes_list = list(account.history_reverse(only_ops=["vote"])) other_list = list(account.history_reverse(exclude_ops=["vote"])) all_list = list(account.history_reverse()) self.assertEqual(len(all_list), len(votes_list) + len(other_list)) index = 0 for h in sorted((votes_list + other_list), key=lambda h: h["index"]): self.assertEqual(index, h["index"]) index += 1
def setUpClass(cls): node_list = get_hive_nodes() cls.bts = Hive(node=node_list, use_condenser=True, nobroadcast=True, unsigned=True, keys={"active": wif}, num_retries=10) acc = Account("fullnodeupdate", blockchain_instance=cls.bts) comment = Comment(acc.get_blog_entries(limit=5)[1], blockchain_instance=cls.bts) cls.authorperm = comment.authorperm [author, permlink] = resolve_authorperm(cls.authorperm) cls.author = author cls.permlink = permlink cls.category = comment.category cls.title = comment.title
def test_verifyAuthority_appbase(self): stm = self.appbase tx = TransactionBuilder(steem_instance=stm) tx.appendOps( Transfer( **{ "from": "test", "to": "test1", "amount": Amount("1 STEEM", steem_instance=stm), "memo": "" })) account = Account("test", steem_instance=stm) tx.appendSigner(account, "active") tx.appendWif(wif) self.assertTrue(len(tx.wifs) > 0) tx.sign() with self.assertRaises(exceptions.MissingRequiredActiveAuthority): tx.verify_authority() self.assertTrue(len(tx["signatures"]) > 0)
def setUpClass(cls): cls.nodelist = NodeList() cls.nodelist.update_nodes(steem_instance=Steem( node=cls.nodelist.get_nodes(normal=True, appbase=True), num_retries=10)) stm = Steem(node=cls.nodelist.get_nodes()) stm.config.refreshBackup() stm.set_default_nodes(["xyz"]) del stm cls.urls = cls.nodelist.get_nodes() cls.bts = Steem(node=cls.urls, nobroadcast=True, num_retries=10) set_shared_steem_instance(cls.bts) acc = Account("holger80", steem_instance=cls.bts) comment = acc.get_blog(limit=20)[-1] cls.authorperm = comment.authorperm votes = acc.get_account_votes() last_vote = votes[-1] cls.authorpermvoter = '@' + last_vote['authorperm'] + '|' + acc["name"]
def check_account_on_activity(self, account, timestamp): if account not in self.accounts: return acc = Account(account, blockchain_instance=self.hive) self.accounts[account]["rc"] = acc.get_rc_manabar()["current_mana"] self.accounts[account]["hp"] = acc.get_token_power(only_own_vests=True) self.accounts[account]["rc_comments"] = self.accounts[account][ "rc"] / self.comment_rc_costs store_data(self.data_file, "accounts", self.accounts) if self.accounts[account]["delegated_hp"] > 0: return if self.accounts[account]["delegation_revoked"]: return if self.accounts[account]["hp"] > self.config["maxUserHP"]: return if self.accounts[account]["rc_comments"] < self.config["minPostRC"]: ok = self.add_delegation(account, timestamp) if ok: self.notify_account(account, self.config["delegationMsg"])
def sign(self, account=None, **kwargs): """ Sign a message with an account's memo key :param str account: (optional) the account that owns the bet (defaults to ``default_account``) :raises ValueError: If not account for signing is provided :returns: the signed message encapsulated in a known format """ if not account: if "default_account" in self.blockchain.config: account = self.blockchain.config["default_account"] if not account: raise ValueError("You need to provide an account") # Data for message account = Account(account, blockchain_instance=self.blockchain) info = self.blockchain.info() meta = dict( timestamp=info["time"], block=info["head_block_number"], memokey=account["memo_key"], account=account["name"], ) # wif key wif = self.blockchain.wallet.getPrivateKeyForPublicKey( account["memo_key"]) # We strip the message here so we know for sure there are no trailing # whitespaces or returns message = self.message.strip() enc_message = self.SIGNED_MESSAGE_META.format(**locals()) # signature signature = hexlify(sign_message(enc_message, wif)).decode("ascii") self.signed_by_account = account self.signed_by_name = account["name"] self.meta = meta self.plain_message = message return self.SIGNED_MESSAGE_ENCAPSULATED.format( MESSAGE_SPLIT=self.MESSAGE_SPLIT, **locals())
def stop_powerdown(account): """Stop power-down for ACCOUNT. """ acc = Account(account.replace("@", "")) if acc['next_vesting_withdrawal'] in time_unset: logger.error("@%s is not powering down - nothing to do." % (acc['name'])) return pwd = getpass("Enter master password or active key for @%s: " % (acc['name'])) pk = passwordkey_to_key(pwd, acc['name'], role="active", prefix=acc.blockchain.prefix) acc.blockchain.wallet.setKeys([pk]) tx = acc.withdraw_vesting(0, account=acc['name']) logger.debug(tx) logger.info("Stopped power-down for @%s" % (acc['name']))
def setUpClass(cls): cls.nodelist = NodeList() cls.nodelist.update_nodes(steem_instance=Steem( node=cls.nodelist.get_nodes(hive=True), num_retries=10)) stm = Steem(node=cls.nodelist.get_nodes(hive=True)) stm.config.refreshBackup() stm.set_default_nodes(["xyz"]) del stm cls.urls = cls.nodelist.get_nodes(hive=True) cls.bts = Steem(node=cls.urls, nobroadcast=True, num_retries=10) set_shared_steem_instance(cls.bts) acc = Account("fullnodeupdate", steem_instance=cls.bts) comment = Comment(acc.get_blog_entries(limit=20)[-1], steem_instance=cls.bts) cls.authorperm = comment.authorperm votes = comment.get_votes() last_vote = votes[-1] cls.authorpermvoter = comment['authorperm'] + '|' + last_vote["voter"]
def test_account_by_pub(self): stm = self.stm self.wallet.steem = stm self.wallet.unlock(pwd="TestingOneTwoThree") acc = Account("gtg") pub = acc["owner"]["key_auths"][0][0] acc_by_pub = self.wallet.getAccount(pub) self.assertEqual("gtg", acc_by_pub["name"]) gen = self.wallet.getAccountsFromPublicKey(pub) acc_by_pub_list = [] for a in gen: acc_by_pub_list.append(a) self.assertEqual("gtg", acc_by_pub_list[0]) gen = self.wallet.getAllAccounts(pub) acc_by_pub_list = [] for a in gen: acc_by_pub_list.append(a) self.assertEqual("gtg", acc_by_pub_list[0]["name"]) self.assertEqual(pub, acc_by_pub_list[0]["pubkey"])
def test_allow(self): bts = self.bts self.assertIn(bts.prefix, "STX") acc = Account("beem", steem_instance=bts) self.assertIn(acc.steem.prefix, "STX") tx = acc.allow( "STX55VCzsb47NZwWe5F3qyQKedX9iHBHMVVFSc96PDvV7wuj7W86n", account="beem", weight=1, threshold=1, permission="active", ) self.assertEqual((tx["operations"][0][0]), "account_update") op = tx["operations"][0][1] self.assertIn("active", op) self.assertIn( ["STX55VCzsb47NZwWe5F3qyQKedX9iHBHMVVFSc96PDvV7wuj7W86n", '1'], op["active"]["key_auths"]) self.assertEqual(op["active"]["weight_threshold"], 1)
def test_disallow(self): bts = self.bts acc = Account("beem", steem_instance=bts) if sys.version > '3': _assertRaisesRegex = self.assertRaisesRegex else: _assertRaisesRegex = self.assertRaisesRegexp with _assertRaisesRegex(ValueError, ".*Changes nothing.*"): acc.disallow( "STX55VCzsb47NZwWe5F3qyQKedX9iHBHMVVFSc96PDvV7wuj7W86n", weight=1, threshold=1, permission="active") with _assertRaisesRegex(ValueError, ".*Changes nothing!.*"): acc.disallow( "STX6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", weight=1, threshold=1, permission="active")
def getRSSFromHive(auth): """ Gets the RSS from a Hive account if it is in metadata Returns 4 values, rss compressed rsss """ acc = Account(auth,blockchain_instance=h) mData = json.loads(acc['posting_json_metadata']) hasData = {} hasData['podcastindex'] = False hasData['pod-rss'] = False hasData['pod-rss-text'] = False mData['pod-rss-text'] = False if 'pod-rss' in mData: mData['pod-rss-text'] = txtDecomp(mData['pod-rss']) hasData['pod-rss'] = True hasData['pod-rss-text'] = True if 'podcastindex' in mData: hasData['podcastindex'] = True return mData,hasData
def test_estimate_virtual_op_num(self): stm = self.bts account = Account("gtg", steem_instance=stm) block_num = 21248120 block = Block(block_num, steem_instance=stm) op_num1 = account.estimate_virtual_op_num(block.time(), stop_diff=1, max_count=100) op_num2 = account.estimate_virtual_op_num(block_num, stop_diff=1, max_count=100) op_num3 = account.estimate_virtual_op_num(block_num, stop_diff=100, max_count=100) op_num4 = account.estimate_virtual_op_num(block_num, stop_diff=0.00001, max_count=100) self.assertTrue(abs(op_num1 - op_num2) < 2) self.assertTrue(abs(op_num1 - op_num4) < 2) self.assertTrue(abs(op_num1 - op_num3) < 200) block_diff1 = 0 block_diff2 = 0 for h in account.get_account_history(op_num4 - 1, 0): block_diff1 = (block_num - h["block"]) for h in account.get_account_history(op_num4 + 1, 0): block_diff2 = (block_num - h["block"]) self.assertTrue(block_diff1 > 0) self.assertTrue(block_diff2 <= 0)