def test_witness_update():
    # TODO: Remove when witness_update is fixed.
    return
    wif = '5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3'
    c = Commit(steemd_instance=Steemd(nodes=[]), keys=[wif])

    signing_key = 'BMT1111111111111111111111111111111114T1Anm'
    props = {
        'account_creation_fee': '0.500 BMT',
        'maximum_block_size': 65536,
        'sbd_interest_rate': 0
    }

    rpc_error = None
    try:
        c.witness_update(signing_key=signing_key,
                         account='test',
                         props=props,
                         url='foo')
    except RPCError as e:
        rpc_error = str(e)
    else:
        raise Exception('expected RPCError')

    assert 'tx_missing_active_auth' in rpc_error
def test_transfer():
    wif = '5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3'
    c = Commit(steemd_instance=Steemd(nodes=[]), keys=[wif])

    rpc_error = None
    try:
        c.transfer('test2', '1.000', 'STEEM', 'foo', 'test')
    except RPCError as e:
        rpc_error = str(e)
    else:
        raise Exception('expected RPCError')

    assert 'tx_missing_active_auth' in rpc_error
def claim_rewards(steem, account_name):
    logger.info('Logged In. Checking for rewards.')
    account = steem.get_account(account_name)
    rewards = reward_available(account)
    if rewards:
        logger.info('Claiming rewards.')
        commit = Commit(steem)
        commit.claim_reward_balance(account=account_name)
        logger.info(
            'Rewards are claimed. %s STEEM, %s SBD, %s VESTS',
            rewards["steem"],
            rewards["sbd"],
            rewards["vesting"],
        )
def test_claim_reward():
    wif = '5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3'
    c = Commit(steemd_instance=Steemd(nodes=[]), keys=[wif])

    rpc_error = None
    try:
        c.claim_reward_balance(account='test',
                               reward_steem='1.000 STEEM',
                               reward_vests='0.000000 VESTS',
                               reward_sbd='0.000 SBD')
    except RPCError as e:
        rpc_error = str(e)
    else:
        raise Exception('expected RPCError')

    assert 'tx_missing_posting_auth' in rpc_error
def test_witness_set_properties():
    wif = '5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3'
    c = Commit(steemd_instance=Steemd(nodes=[]),
               keys=[wif])

    signing_key = 'STM1111111111111111111111111111111114T1Anm'
    props = [
        ['account_creation_fee', 'd0070000000000000354455354530000'],
        ['key', ('032d2a4af3e23294e0a1d9dbc46e0272d'
                 '8e1977ce2ae3349527cc90fe1cc9c5db9')]
    ]

    rpc_error = None
    try:
        c.witness_set_properties(
            signing_key=signing_key,
            props=props,
            account='test')
    except RPCError as e:
        rpc_error = str(e)
    else:
        raise Exception('expected RPCError')

    assert 'tx_missing_other_auth' in rpc_error
Exemple #6
0
def run(args):
    log.info("Market summary mode activated", args=args)

    if args is None or len(args) < 3:
        raise ValueError(
            "You must specify a currency pair, title, and one or more tags")

    pair = args[0]
    title = args[1]
    tags = args[2:]

    log.debug("initializing...")
    steem = Steem(keys=[account.key])
    commit = Commit(steem)
    api = Poloniex()
    market = Market(commit, api, pair)
    log.debug("ready", steem=steem, commit=commit, api=api, market=market)

    market.summarize(title, tags)
Exemple #7
0
 def __init__(self, steemd_instance, bot_account):
     self.s = steemd_instance
     self.commit = Commit(steemd_instance=self.s)
     self.bot_account = bot_account
     self.debug = bool(1)
 def reconnect(self):
     """Creates a new Steemd and Commit"""
     self.steemd = Steemd(nodes=self.nodes.copy(), **self.kwargs.copy())
     self.commit = Commit(steemd_instance=self.steemd,
                          no_broadcast=self.no_broadcast,
                          **self.kwargs.copy())
from steem import Steem
from steem.commit import Commit

s = Steem()

query = {
    "limit": 5,  #number of posts
    "tag": ""  #tag of posts
}
# post list from trending post list
posts = s.get_discussions_by_trending(query)

title = 'Please choose post to reblog: '
options = []
# post list
for post in posts:
    options.append('@' + post["author"] + '/' + post["permlink"])

# get index and selected post
option, index = pick(options, title)
pprint.pprint("You selected: " + option)

account = input("Enter your username? ")
wif = input("Enter your Posting private key? ")

# commit or build transaction
c = Commit(steem=Steem(keys=[wif]))

# broadcast transaction
c.resteem(option, account=account)
Exemple #10
0
class Game:
    def __init__(self, steemd_instance, bot_account):
        self.s = steemd_instance
        self.commit = Commit(steemd_instance=self.s)
        self.bot_account = bot_account
        self.debug = bool(1)

    def build_permlink(self):
        return str(uuid.uuid4())

    def get_sample_comment(self, user):
        data = {
            'derasmo':
            'vorstellung-von-mir-und-meiner-projektidee',
            'flurgx':
            're-derasmo-vorstellung-von-mir-und-meiner-projektidee-20180213t210718018z',
            'kurodevs':
            're-derasmo-vorstellung-von-mir-und-meiner-projektidee-20180213t203220853z'
        }

        if user in data:
            return data[user]

        return bool(0)

    def get_valid_votes(self, votes, limit):
        v_votes = []
        s_votes = sorted(votes, key=lambda tmp: tmp['time'])

        if self.debug:
            for vote in s_votes:
                if self.get_sample_comment(vote['voter']) != bool(0):
                    v_votes.append(vote)
        else:
            v_votes = s_votes

        return itertools.islice(v_votes, limit)

    def post_to_webhooks(self, score):

        hook = Webhook(None)
        hook.set_author(
            name=self.bot_account,
            url="http://steemit.com/@%s" % self.bot_account,
            icon="https://img.busy.org/@%s?height=100&width=100" %
            self.bot_account,
        )

        hook.add_field(
            name="Message",
            value=score,
        )

        for hook_url in HOOKS:
            hook.url = hook_url
            hook.post()

    def post(self,
             title,
             body,
             author,
             permlink=None,
             reply_identifier=None,
             beneficiaries=None):
        print('post parameter')
        print('--------------------')
        print('title: ' + title)
        print('author: ' + author)
        if permlink is not None:
            print('permlink: ' + permlink)
        if reply_identifier is not None:
            print('reply_identifier: ' + reply_identifier)
        if beneficiaries is not None:
            print('beneficiearies: ')
            print(beneficiaries)
        print('')

        if self.debug:
            permlink = self.get_sample_comment(author)
            print('---')
            print('Called post but post will not be submitted')
            print(
                'Function was called with %(auth)s as author and %(ttl)s as the title'
                % {
                    'auth': author,
                    'ttl': title
                })
            print('A permlink was created: %(link)s' % {'link': permlink})
            print('The posts content:')
            print(body)

        elif permlink is not None:
            self.commit.post(title, body, author, permlink, reply_identifier)
        else:
            permlink = self.build_permlink()
            self.commit.post(title, body, author, permlink, reply_identifier)

        return permlink

    def evaluate(self, results):
        output = '<div>The game has finished. Voting results are:</div>'

        for voter, result in results.items():
            oLine = '<div>' + voter + ': ' + str(result) + '</div>'
            output = output + oLine

        thanks = '<div>Thanks for participating. If you want to support me in this project please consider voting on this comment.</div>'
        output = output + thanks

        return output

    def start_game(self):

        self.post_to_webhooks('A game has started!')

        #settings
        duration_hours = 12
        duration_minutes = 0
        duration_seconds = 0

        limit = 2

        # 1. create post
        title = 'testing a bot'
        body = 'This post is auto generated and ment for testing pupose. You can read in more detail what it\'s all about in the [introdutction post](https://steemit.com/@derasmo/vorstellung-von-mir-und-meiner-projektidee). All rewards go to @deutschbot, because I use his code, @markus.light, because he volunteered, and @reeceypie, because @ocd resteemed a post I liked.'

        permlink = 'testing-a-bot-bot-bot'

        beneficiaries = [{
            'account': '@deutschbot',
            'weight': 2500
        }, {
            'account': '@markus.light',
            'weight': 3750
        }, {
            'account': '@reeceypie',
            'weight': 3750
        }]

        permlink = self.post(title,
                             body,
                             self.bot_account,
                             permlink=permlink,
                             beneficiaries=beneficiaries)

        # 2. catch upvotes and create comments
        postid = "@" + self.bot_account + "/" + permlink
        start = time.time()
        duration = duration_hours * 360 + duration_minutes * 60 + duration_seconds

        voters = []
        permlinks = {}

        while time.time() < start + duration:
            if len(voters) < limit:
                votes = self.s.get_active_votes(self.bot_account, permlink)

                if len(votes) > 0:
                    # sort votes by time and cut off above limit
                    v_votes = self.get_valid_votes(votes, limit)

                    for vote in v_votes:
                        if vote['voter'] not in voters:

                            if len(voters) < 1:
                                comment_body = vote[
                                    'voter'] + 'is collecting for @mack-bot. In Addition to the users mentioned in the post @mack-bot will receive a share. Please vote if you want them to win.'
                                comment_beneficiaries = [{
                                    'account': '@deutschbot',
                                    'weight': 2500
                                }, {
                                    'account': '@markus.light',
                                    'weight': 2500
                                }, {
                                    'account': '@reeceypie',
                                    'weight': 2500
                                }, {
                                    'account': '@mack-bot',
                                    'weight': 2500
                                }]
                            else:
                                comment_body = '@' + vote[
                                    'voter'] + 'is collecting for @spaminator. In Addition to the users mentioned in the post @spaminator will receive a share. Please vote if you want them to win.'
                                comment_beneficiaries = [{
                                    'account': '@deutschbot',
                                    'weight': 2500
                                }, {
                                    'account': '@markus.light',
                                    'weight': 2500
                                }, {
                                    'account': '@reeceypie',
                                    'weight': 2500
                                }, {
                                    'account': '@spaminator',
                                    'weight': 2500
                                }]

                            if self.debug and self.get_sample_comment(
                                    vote['voter']) != bool(0):
                                self.post_to_webhooks(vote['voter'] +
                                                      ' joined the game.')
                                voters.append(vote['voter'])
                                permlinks[vote['voter']] = self.post(
                                    '',
                                    comment_body,
                                    vote['voter'],
                                    reply_identifier=postid,
                                    beneficiaries=comment_beneficiaries)
                            elif self.debug == bool(0):
                                self.post_to_webhooks(vote['voter'] +
                                                      ' joined the game.')
                                voters.append(vote['voter'])
                                permlink = 'testing-a-bot-bot-bot-comment-' + len(
                                    voters)
                                permlinks[vote['voter']] = self.post(
                                    '',
                                    comment_body,
                                    self.bot_account,
                                    permlink=permlink,
                                    reply_identifier=postid,
                                    beneficiaries=comment_beneficiaries)

            time.sleep(5)

        # 3. post summary
        results = {}
        for voter in voters:
            if self.debug:
                votes = self.s.get_active_votes(voter, permlinks[voter])
            else:
                votes = self.s.get_active_votes(self.bot_account,
                                                permlinks[voter])

            results[voter] = len(votes)

        results_body = self.evaluate(results)
        self.post_to_webhooks(results_body)
        self.post('', results_body, self.bot_account, reply_identifier=postid)
Exemple #11
0
 def __init__(self, steem, config):
     self.steem = steem
     self.account = config["account"]
     self.mysql_uri = config["mysql_uri"]
     self.config = config
     self.commit = Commit(steem)
Exemple #12
0
class TransactionListener(object):
    def __init__(self, steem, config):
        self.steem = steem
        self.account = config["account"]
        self.mysql_uri = config["mysql_uri"]
        self.config = config
        self.commit = Commit(steem)

    def get_table(self, table):
        db = dataset.connect(self.mysql_uri)
        return db[table]

    @property
    def properties(self):
        props = self.steem.get_dynamic_global_properties()
        if not props:
            logger.info('Couldnt get block num. Retrying.')
            return self.properties
        return props

    @property
    def last_block_num(self):
        return self.properties['head_block_number']

    @property
    def block_interval(self):
        config = self.steem.get_config()
        return config["STEEMIT_BLOCK_INTERVAL"]

    def process_block(self, block_num, retry_count=0):
        block_data = self.steem.get_block(block_num)

        if not block_data:
            if retry_count > 3:
                logger.error('Retried 3 times to get this block: %s Skipping.',
                             block_num)
                return

            logger.error('Couldnt read the block: %s. Retrying.', block_num)
            self.process_block(block_num, retry_count=retry_count + 1)

        logger.info('Processing block: %s', block_num)
        if 'transactions' not in block_data:
            return

        self.check_block(block_num)
        dump_state(self.properties)

    def run(self, start_from=None):
        if start_from is None:
            last_block = load_checkpoint(
                fallback_block_num=self.last_block_num, )
            logger.info('Last processed block: %s', last_block)
        else:
            last_block = start_from
        while True:

            while (self.last_block_num - last_block) > 0:
                last_block += 1
                self.process_block(last_block)
                dump_checkpoint(last_block)

            # Sleep for one block
            block_interval = self.block_interval
            logger.info('Sleeping for %s seconds.', block_interval)
            time.sleep(block_interval)

    def daily_message(self):
        post_list = []
        query = {"limit": 15, "tag": "tr"}  # limit for 5 posts
        for p in self.steem.get_discussions_by_hot(query):
            metadata = json.loads(p["json_metadata"])
            if metadata and 'utopian-io' in metadata["tags"]:
                continue
            if metadata and 'sndbox' in metadata["tags"]:
                continue

            if p["author"] == "turbot":
                continue

            link = "https://steemit.com/@%s/%s" % (p["author"], p["permlink"])
            author_link = "https://steemit.com/%s" % p["author"]
            post = Post(link, steemd_instance=self.steem)
            try:
                self.upvote(post, 20)
                time.sleep(4)
                pass
            except Exception as error:
                logger.error(error)

            post_list.append("- [%s](%s) - [@%s](%s)" %
                             (p["title"], link, p["author"], author_link))

        body = open(self.config["daily_message"]).read()
        body = body.replace("$post_list", "\n".join(post_list))

        today = date.today().strftime("%Y.%m.%d")
        self.steem.commit.post(
            "Son 24 saatte turbot tarafından oylanan yazılar (%s)" % today,
            body,
            "turbot",
            tags=["tr", "turbot"])

    def upvote(self, post, weight=+5):

        full_link = "@%s/%s" % (post["author"], post["permlink"])
        already_upvoted = self.get_table('upvote').find_one(
            author=post["author"], permlink=post["permlink"])
        if already_upvoted:
            logger.info('Already voted. Skipping. %s', full_link)
            return

        resp = post.commit.vote(post.identifier, weight, account=self.account)
        if not resp:
            logger.error("Failed upvoting. %s", full_link)

    def handle_command(self, post):
        if post["author"] in self.config["blacklisted_users"]:
            logger.info("User on blacklist. (%s). Skipping", post["permlink"])
            return

        # welcome command
        if re.findall("@%s\s!(welcome)" % self.account, post["body"]):

            main_post = Post(post.root_identifier, steemd_instance=self.steem)
            already_welcomed = self.get_table('welcome').find_one(
                author=main_post["author"])

            if already_welcomed:
                logger.info("This user: %s already welcomed. Skipping" %
                            main_post["author"])
                return

            body = open(self.config["welcome_message"]).read()
            body = body.replace("$username", main_post["author"])
            main_post.reply(
                body=body,
                author=self.account,
            )
            if not main_post.is_main_post():
                logger.info("Skipping. Not a main post.")
                return
            try:
                self.upvote(main_post)
            except Exception as e:
                logger.error(e)

            logger.info("Replied and upvoted user: %s", main_post["author"])
            self.get_table('welcome').insert(
                dict(
                    author=main_post["author"],
                    permlink=main_post["permlink"],
                    created_at=str(datetime.now()),
                ))
            if self.config["send_welcome_gift"] == "yes":
                self.commit.transfer(main_post["author"],
                                     self.config["welcome_gift"],
                                     memo=self.config["welcome_gift_message"],
                                     asset="SBD",
                                     account=self.account)
        # handle help commands
        help_commands = [
            "creating_new_accounts", "bots", "curation_rewards", "downvote",
            "esteem", "security", "voting_power", "upvote", "tag_spam",
            "comment_spam", "wallet", "plagiarism", "posting"
        ]
        for command in help_commands:
            if re.findall("@%s\s!(%s)" % (self.account, command),
                          post["body"]):

                message_path = "%s%s.md" % (self.config["help_commands_path"],
                                            command)
                main_post = Post(post.root_identifier,
                                 steemd_instance=self.steem)
                body = open(message_path).read()
                body = body.replace("$username", main_post["author"])
                if not main_post.is_main_post():
                    logger.info("Skipping. Not a main post.")
                    return
                main_post.reply(
                    body=body,
                    author=self.account,
                )
                logger.info("Posted %s command reply." % command)

    def check_block(self, block_num):
        operation_data = self.steem.get_ops_in_block(block_num,
                                                     virtual_only=False)

        for operation in operation_data:
            operation_type, raw_data = operation["op"][0:2]
            if operation_type == "comment":
                try:
                    post = Post(raw_data, steemd_instance=self.steem)
                except Exception as error:
                    logger.error(error)
                    continue
                if post.is_main_post():
                    # we're only interested in comments.
                    continue
                if "@" + self.account in post["body"]:
                    try:
                        self.handle_command(post)
                    except Exception as e:
                        logger.error(e)
Exemple #13
0
 def __init__(self, steem):
     self.steem = steem
     self.commit = Commit(steem)
     self.watch_account = settings.BOT_ACCOUNT
Exemple #14
0
class TransactionListener(object):
    def __init__(self, steem):
        self.steem = steem
        self.commit = Commit(steem)
        self.watch_account = settings.BOT_ACCOUNT

    @property
    def last_irreversible_block_num(self):
        props = self.steem.get_dynamic_global_properties()
        if not props:
            logger.info('Couldnt get block num. Retrying.')
            return self.last_irreversible_block_num
        return props['last_irreversible_block_num']

    @property
    def block_interval(self):
        config = self.steem.get_config()
        return config["STEEMIT_BLOCK_INTERVAL"]

    @property
    def upvote_weight(self):
        min_weight, max_weight = settings.UPVOTE_WEIGHTS
        return float(random.randint(min_weight, max_weight))

    def process_block(self, block_id, retry_count=0):

        block_data = self.steem.get_block(block_id)

        if not block_data:
            if retry_count > 3:
                logger.error('Retried 3 times to get this block: %s Skipping.',
                             block_id)
                return

            logger.error('Couldnt read the block: %s. Retrying.', block_id)
            self.process_block(block_id, retry_count=retry_count + 1)

        logger.info('Processing block: %s', block_id)

        if 'transactions' not in block_data:
            return

        for tx in block_data['transactions']:
            for operation in tx['operations']:
                operation_type, operation_data = operation[0:2]
                if operation_type == 'transfer':
                    self.process_transfer(operation_data, block_data, block_id)

    def process_transfer(self, op, block_data, block_id):
        if op["to"] == self.watch_account:
            logger.info("%d | %s | %s -> %s: %s -- %s" %
                        (block_id, block_data["timestamp"], op["from"],
                         op["to"], op["amount"], op["memo"]))
            if "SBD" in op['amount']:
                amount_in_float = float(op['amount'].split(' ')[0])
                if amount_in_float < settings.MINIMUM_SBD_FOR_UPVOTE:
                    self.refund(
                        op, 'Minimum SBD for upvote: %s' %
                        settings.MINIMUM_SBD_FOR_UPVOTE)
                    return
                self.upvote(op)
            else:
                logger.info('There is a transfer but its not SBD. Ignoring.')

    def refund(self, op, message):
        refund_key = db.refund_key(op['from'], op['memo'], op['amount'])
        if db.already_refunded(op['from'], op['memo'], op['amount']):
            logger.info('This is already refunded. Skipping. %s', refund_key)
            return
        refund_amount, asset = op['amount'].split(' ')

        if float(refund_amount) > 0.5:
            logger.error('Too much for a auto-refund. Skipping.')
            return

        self.commit.transfer(op['from'],
                             float(refund_amount),
                             memo=message,
                             asset=asset,
                             account=self.watch_account)
        logger.info('Refunded %s for invalid request.', op['from'])
        db.add_refund(op['from'], op['memo'], op['amount'])

    def upvote(self, op):
        try:
            post = Post(op['memo'])
        except ValueError:
            logger.info('Invalid identifier: %s', op['memo'])
            self.refund(op, message='invalid url')
            return
        try:
            weight = self.upvote_weight

            post.upvote(weight=weight, voter=self.watch_account)

        except VotingInvalidOnArchivedPost as e:
            logger.info('Archived post. Cannot upvote. %s', op['memo'])
            self.refund(op,
                        message='Couldnt vote. Archived post. %s' % op['memo'])
            return
        except Exception as e:
            if 'already voted' in e.args[0]:
                self.refund(op, message='Already upvoted. %s' % op['memo'])
                logger.info('Already voted: %s. Skipping.', op['memo'])
                return

            if 'Read timed' in e.args[0]:
                logger.info('Node is not responding. Trying again to upvote.')
                return self.upvote(op)

        logger.info('Upvoted %s with weight: %s', op['memo'], weight)

    def run(self):
        last_block = db.load_checkpoint(
            fallback_block_num=self.last_irreversible_block_num, )
        logger.info('Last processed block: %s', last_block)
        while True:

            while (self.last_irreversible_block_num - last_block) > 0:
                last_block += 1
                self.process_block(last_block)
                db.dump_checkpoint(last_block)

            # Sleep for one block
            block_interval = self.block_interval
            logger.info('Sleeping for %s seconds.', block_interval)
            time.sleep(block_interval)
Exemple #15
0
def run():
    log.info("Timely post mode activated")

    log.debug("initializing...")
    steem = Steem(keys=[cred.key])
    account = Account(cred.id, steem)
    chain = Blockchain(steem)
    commit = Commit(steem)
    log.debug("ready", steem=steem, account=account, blockchain=chain, commit=commit)

    # Because subsequent edits to a post show up as separate post entries in the blockchain,
    # we'll keep a list of candidates keyed by the post identifier which the edits share.
    candidates = {}

    log.info("Checking post history...")
    history = map(Post, account.history(filter_by=['comment']))

    # FIXME: use steem.get_posts() instead?

    for post in history:
        if post.is_main_post():
            log.debug("found a top-level post", post=post, tags=post.tags)

            if post.tags[0] == cred.id and 'boiled' not in post.tags:
                candidates[post.identifier] = post

    if len(candidates) > 0:
        log.info("Found one or more historical posts to process", posts=candidates)

        deleting = []
        for key, post in candidates.items():
            result = process(commit, post)
            if result or result is None:
                deleting.append(key)
        for key in deleting:
            del candidates[key]

    log.info("Watching for new posts...")
    while True:
        stream = map(Post, chain.stream(filter_by=['comment']))

        try:
            for post in stream:
                if post.is_main_post() and post.author == cred.id:
                    log.debug("found a top-level post", post=post, tags=post.tags)

                    if len(post.tags) == 2 and post.tags[0] == cred.id and post.tags[1] == cred.id:
                        candidates[post.identifier] = post

                deleting = []
                for key, post in candidates.items():
                    result = process(commit, post)
                    if result or result is None:
                        deleting.append(key)
                for key in deleting:
                    del candidates[key]

        except PostDoesNotExist as e:
            log.debug("Post has vanished", exception=e)

        except RPCError as e:
            log.error("RPC problem while streaming posts", exception=e)
 def get_steem_committer(self):
     retval = Commit(steemd_instance=self.steemd_rpc,
                     debug=self.debug_mode,
                     keys=self.keys)
     return retval
Exemple #17
0
# globals
misses = 0
failover_after = 5
counter = 0

# witness
witness_url = "https://yourwebsite.com"
witness_props = {
    "account_creation_fee": "3.000 STEEM",
    "maximum_block_size": 65536,
    "sbd_interest_rate": 0,
}

b = Blockchain(steemd_instance=s)
t = Commit(steemd_instance=s, no_broadcast=debug, keys=steem_keys)


def l(msg, slack=False):
    caller = inspect.stack()[1][3]
    print("[{}] {}".format(str(caller), str(msg)))
    sys.stdout.flush()


def get_witness_key():
    return s.get_witness_by_account(steem_account)['signing_key']


def get_misses():
    return s.get_witness_by_account(steem_account)['total_missed']