Making a Steemit Bot Part 4: Stalking

in #steem-python7 years ago

[Part 1] [Part 2] [Part 3]


Information Gathering

This post is going to be different in a few ways. Instead of going in and looking at making a steemit bot as is we are going to take a step back and look at how to do certain things like get information about an account or blockchain. For instance you can use:

from steem import Steem
s = Steem()
s.get_account('ned')

and you will get an output like this:

{'id': 497, 'name': 'ned', 'owner': {'weight_threshold': 1, 'account_auths': [], 'key_auths': [['STM71f6yWztimJuREVyyMXNqAVbx1FzPVW6LLXNoQ35dHwKuszmHX', 1]]}, 'active': {'weight_threshold': 1, 'account_auths': [], 'key_auths': [['STM7RyrKG8e3fUtPD2JH9AB8K1p7ypsLUDPMuiV1gtD4DbNuk6nBw', 1]]}, 'posting': {'weight_threshold': 1, 'account_auths': [], 'key_auths': [['STM6rHZiAKHZS19RSJuRmn3mdukj95AYgUNFCEgnm8jhZE3rcH72P', 1]]}, 'memo_key': 'STM6sUWU9dtss1N8m7tQfUt7PacNHACrt3jBZNtkYkMMBv3e4CH3p', 'json_metadata': '{"profile":{"profile_image":"https://pbs.twimg.com/profile_images/915596048428621825/_nuXsMTT.jpg","location":"Welcome to Steemit!","name":"ned","cover_image":"https://steemit.com/images/steemit.png","website":"https://smt.steem.io"}}', 'proxy': '', 'last_owner_update': '2017-03-02T00:20:39', 'last_account_update': '2018-01-25T22:26:24', 'created': '2016-03-31T14:21:45', 'mined': False, 'owner_challenged': False, 'active_challenged': False, 'last_owner_proved': '1970-01-01T00:00:00', 'last_active_proved': '1970-01-01T00:00:00', 'recovery_account': 'steem', 'last_account_recovery': '1970-01-01T00:00:00', 'reset_account': 'null', 'comment_count': 0, 'lifetime_vote_count': 0, 'post_count': 741, 'can_vote': True, 'voting_power': 10000, 'last_vote_time': '2018-02-05T22:42:03', 'balance': '111865.316 STEEM', 'savings_balance': '0.000 STEEM', 'sbd_balance': '5750.349 SBD', 'sbd_seconds': '3112990678638', 'sbd_seconds_last_update': '2018-02-07T04:04:30', 'sbd_last_interest_payment': '2018-01-31T21:41:27', 'savings_sbd_balance': '1249.949 SBD', 'savings_sbd_seconds': '0', 'savings_sbd_seconds_last_update': '2017-01-01T19:19:27', 'savings_sbd_last_interest_payment': '2017-01-01T19:19:27', 'savings_withdraw_requests': 0, 'reward_sbd_balance': '767.164 SBD', 'reward_steem_balance': '0.000 STEEM', 'reward_vesting_balance': '8048624.290132 VESTS', 'reward_vesting_steem': '3918.633 STEEM', 'vesting_shares': '7344140982.676874 VESTS', 'delegated_vesting_shares': '5555196185.233783 VESTS', 'received_vesting_shares': '0.000000 VESTS', 'vesting_withdraw_rate': '0.000000 VESTS', 'next_vesting_withdrawal': '1969-12-31T23:59:59', 'withdrawn': 0, 'to_withdraw': 0, 'withdraw_routes': 0, 'curation_rewards': 734552321, 'posting_rewards': 8476465, 'proxied_vsf_votes': ['121114137626959', 0, 0, 0], 'witnesses_voted_for': 0, 'average_bandwidth': '17558214870', 'lifetime_bandwidth': '3739769000000', 'last_bandwidth_update': '2018-02-07T22:55:57', 'average_market_bandwidth': 2599317261, 'lifetime_market_bandwidth': '118810000000', 'last_market_bandwidth_update': '2018-01-29T03:31:21', 'last_post': '2018-02-07T22:55:57', 'last_root_post': '2017-11-08T00:11:30', 'vesting_balance': '0.000 STEEM', 'reputation': '78828263679953', 'transfer_history': [], 'market_history': [], 'post_history': [], 'vote_history': [], 'other_history': [], 'witness_votes': [], 'tags_usage': [], 'guest_bloggers': []}

Now first thing I would suggest doing is modifying the program from the previous post to get something a little more practical for output.

Modified Program
from steem import Steem

s = Steem()
follow = str(input("Enter who to follow: "))

action = str(s.get_account(follow))

def nl(nt):
    print('\n', end='')
    for i in range(0,nt):
        print("\t", end='')

def pnjson(js):
    ntabs = 0
    for i in range(0, len(js)):
        if js[i]=='{':
            print(js[i], end='')
            ntabs = ntabs+1
            nl(ntabs)
        elif js[i]=='[':
            print(js[i], end='')
            ntabs = ntabs+1
            nl(ntabs)
        elif js[i]==']':
            ntabs = ntabs-1
            nl(ntabs)
            print(js[i], end='')
        elif js[i]=='}':
            ntabs = ntabs-1
            nl(ntabs)
            print(js[i], end='')
        elif js[i]==',':
            print(js[i], end='')
            nl(ntabs)
        else:
            print(js[i], end='')
    nl(0)

pnjson(str(action))
Output:
kryzsec@kryzsec-a101:~/ssb$ python modified_monitor.py
Enter who to follow: ned
{
    'id': 497,
     'name': 'ned',
     'owner': {
        'weight_threshold': 1,
         'account_auths': [
            
        ],
         'key_auths': [
            [
                'STM71f6yWztimJuREVyyMXNqAVbx1FzPVW6LLXNoQ35dHwKuszmHX',
                 1
            ]
        ]
    },
     'active': {
        'weight_threshold': 1,
         'account_auths': [
            
        ],
         'key_auths': [
            [
                'STM7RyrKG8e3fUtPD2JH9AB8K1p7ypsLUDPMuiV1gtD4DbNuk6nBw',
                 1
            ]
        ]
    },
     'posting': {
        'weight_threshold': 1,
         'account_auths': [
            
        ],
         'key_auths': [
            [
                'STM6rHZiAKHZS19RSJuRmn3mdukj95AYgUNFCEgnm8jhZE3rcH72P',
                 1
            ]

...
This has been cut short because it was really long
For full print out, do it yourself.

As you can see this makes the account data a lot easier to read. So now we have a program that can look at the public account data (which by the way you could just go to the steemd for that persons account and get the same information) but if we truly want to stalk them then we may want it to be more specific, say looking at specific information like the balance of steem and sbd that they have.

Monitor.py

from steem import Steem

s = Steem()

account = str(input("Enter Account to Monitor: "))

print("Steem Balance: " + str(s.get_account(account)['balance']))
print("SBD Balance: " + str(s.get_account(account)['sbd_balance']))
print("Savings Steem Balance: " + str(s.get_account(account)['savings_balance']))
print("Savings SBD Balance: " + str(s.get_account(account)['savings_sbd_balance']))
print("Reward Steem: " + str(s.get_account(account)['reward_vesting_steem']))
print("Reward SBD: " + str(s.get_account(account)['reward_sbd_balance']))

Output

kryzsec@kryzsec-a101:~/ssb$ python monitor.py 
Enter Account to Monitor: ned
Steem Balance: 111865.316 STEEM
SBD Balance: 5750.349 SBD
Savings Steem Balance: 0.000 STEEM
Savings SBD Balance: 1249.949 SBD
Reward Steem: 3918.633 STEEM
Reward SBD: 767.164 SBD

If you want to modify it to look for different information than just add more print lines and print out the output. You have, on the left, a complete output of an account that you can look at the data of. This is, in no way, an attempt to convince everyone to go out and start stalking people, its just if you are reading tutorials on how to make a bot then, depending on what type of bot yo are making, it might be beneficial to know this kind of stuff. So, how can we use the information in this post to create a bot? How about a bot that automatically withdraws funds?


Here is the plan for our bot, it will (every block) check to see if the account has any funds to withdraw and if there are funds then it will withdraw them.

Warning this program will require the use of a private active key (I am pretty certain) and thus should only be done as is if you know what you are doing. Best bet is you should use the cli-wallet to store your keys and use the keys from the wallet instead as it will keep your keys encrypted and safe in case of malware or otherwise. Remember, do not share your private keys with anyone!

from steem import Steem
import time
Account = str(input("Enter account name: "))
pak = str(input("Enter the associating private active key: "))
st = int(input("How often do you want to check? (1 is every block, 2 is ever 2nd block): "))
if st<1:
    st = 1
s = Steem(keys=pak)
while True:
    SBD = s.get_account(Account)['reward_sbd_balance']
    STEEM = s.get_account(Account)['reward_vesting_steem']
    if SBD!='0.000 SBD' or STEEM!='0.000 STEEM':
        print("Collecting " + SBD + " " + STEEM)
        s.claim_reward_balance(account=Account)
    time.sleep(3*st)

Since a new block should be made every 3 seconds we can change how often we check (say to every 30 minutes) by changing the number that we input. To use this to check once every hour then we would input the following:

Enter account name: kryzsec
Enter the associating private active key: P5privatepostingkeyhere462
How often do you want to check? (1 is every block, 2 is ever 2nd block): 1200
Collecting 0.010 SBD 0.003 STEEM

Since 1 hour has 3600 seconds (60 seconds in 1 minute and 60 seconds in 1 hour, i.e. 60*60=3600) and since a new block is minted every 3 seconds we would divide that by 3 to get the number of blocks that we want to have been made before we attempt to check. This can however be used for a lot more things. Maybe you want to write a bot that will go through and see whom all votes for a specific witness or you want to go and write a bot that searches for whom has the mosts vests to try and figure out whom the richest steem users are. I do not know what you would want to do but this will allow you to do a lot of interesting things.


References
Printing An Error In Python: stackoverflow.com/questions/1483429/how-to-print-an-error-in-python
Steem-Python Documentation: steem.readthedocs.io/en/latest/index.html
Installing Steem Python: steemit.com/programming/@themarkymark/how-to-install-steem-python
Python String Documentation: docs.python.org/3/library/stdtypes.html
JSON: www.json.org/
Making A Vote Bot: steemit.com/steem-python/@kryzsec/making-a-steemit-bot-part-1-basic-voting

Kryzsec's Steemit Board


Image Source from @nitesh9

Do you enjoy reading or writing topics related to STEM (Science, Technology, Engineering, and Mathematics) then I would suggest checking out @steemstem! They do wonderful work curating the best STEM related posts on Steemit. For more information check out the SteemStem chat room on steemit.chat or check out their Guidlines and start writing.

Sort:  

That's a whole lot of codes to get my head through. I'm not really good at python language. :)
Alternatively, how possible is it to create a steemit bot with vb?

Very possible. All you need is a library to handle https (I believe it may have that standard) and then you just need to send specific predefined requests to any of the nodes and they will return with answers. Most of the steem-python library actually works by turning the JSON into dictionaries to make it easier to handle on the users end. In order to do any operation on the blockchain you would first need to have something made to write JSON.

Basically the steem blockchain is a list of JSON (as shown in part 3 I think) and as long as you can handle sending and receiving JSON over https then it is possible.

Like the blockchain itself is written in C++ but there are official API libraries for python and javascript and unofficial libraries for ruby and possibly other languages.

Thanks for the quick lectures buddy

I think I found the pretty serious bug in your code.

Here is the plan for our bot, it will (every block) check to see if the account has any funds to withdraw and if there are funds then it will withdraw them.

First program check Ned's account. This works as intended and yes, there are sufficient funds for drawing.
But when you are drawing, it does not come from Ned's account?!? Pretty sloppy coding if you ask me...

(lol couldn't resist) ;-)

So it isn't a bug at all as you can see with the withdraw method

s.claim_reward_balance(account=Account)

it will instead throw an interrupt exception if the account does not match the keys. This should be surrounded with a try and except. In the second of the tutorials I went over try and except and am expecting others to be able to try out and find where to use these on their own, if that makes sense.

Anyways a bug would mean that the program would do something unexpected and in reality it would be expected that the program gets interrupted.

I could use the steembase modules to actually get the account name from the private key but I would prefer to introduce things simplistically now and later use the more complex methods (that have next to no documentation).

No, I'm sorry, it was a joke.
I was joking that there is plenty of funds in Ned's account for drawing, but I can't draw any of it toward my account. Just having fun, sorry for misunderstanding.

You are doing a great job showing how to use Python and Steem(), thanks for sharing!
I'm up-voting your posts and saving them for when i will start working on my next project. Looking forward for your next posts!

Don't be sorry, its just if others were to follow this as a tutorial in the future and someone thought there was a bug it would be better for an explanation to be present then and there. I figured it was a joke with your last line:

(lol couldn't resist) ;-)

I hope you understand why my answer was as it was?

Gotcha :-)

Yes, you are correct, while joking I was potentially misleading others, bad joke.

No, it is actually in some ways good that it was brought in case people wonder about that in the future. Bad jokes are jokes that just aren't funny and cause harm, because there was an explanation after the joke (which destroys it, I am sorry) it can work towards being educational.

I have a question if you could, How does some one go about getting the funding for a votebot to make the votes actually worth something?

Being an early investor, offering a portion of the rewards to delegators, offer investment opportunities? I don't know, that would be something to ask a marketing professional. I am trying to get the information of how to use the steem-python library out there, what others do with it is on them.

Alright I will keep looking, thanks for the awesome guide.