SteemHub: Automated Token Emission 202002120850 by oaldamster

View this thread on steempeak.com
· @oaldamster ·
$0.86
SteemHub: Automated Token Emission 202002120850
# Python3 version 0.0.1.0-beta by Oaldamster
_Originally forked from Steem Engine Airdrop Tool {[seairdrop](https://github.com/themarkymark-steem/seairdrop)} by [The Marky Mark](https://steemit.com/@themarkymark)._ 

## [+] Load Config, autoload Airdrop file  
**Creating a Token on [Steem-Engine dot com](https://steem-engine.com) can be one thing, spreading the love is another. Thanks to a few fellow Steemians though, [The Marky Mark](https://steemit.com/@themarkymark) and [Holger80](https://steemit.com/@holger80), it now has become as easy as _Py(thon 3)_. This second version, ATE, of the original go.py file will load a separate config file, that will have the airdrop file loaded. The main file is now called _gogogo.py_.** 

## About ATE  (Sounds like Aid) 
Easy emission of  any Token on Steem-Engine dot com in an airdrop alike fashion, using [the Beem Python Module](https://github.com/holgern/beem) and [Python3](https://www.python.org/downloads/) on Linux. This version adds the user defined loading of a Config-'TokenName'.JSON file. That will point to an Airdrop-'TokenName'.dat file, to be loaded. It is presumed that the .dat files are in a sub-folder. Relative to the working directory. 

### Supported methods:

   * Transfer
   * [-] Issue 
   * [-] Stake 

### Required: 

* Python3 :: https://www.python.org/downloads/
* Beem Python Module :: https://github.com/holgern/beem 

Eventually for reference: 
* Original version :: https://github.com/themarkymark-steem/seairdrop

### How to use 
**It is best to use Beem(PY) to first create a (Key-)Wallet. Only to store a Post and an Active key in there. Then secure it with a password. That will be used to unlock the (Key-)Wallet, instead of using the Post and or Active key. The Beem Python Module has all kinds of easy to use commands. And in $BASH (command-line) it is even easier to use beempy to create a (Key-)Wallet. (Use "beempy --help" first, if you are new to BEEM.)** 

After all the needed setups, create a _config-'tokename'.json_ file that has all the settings for a Token emission. First try a so called '_Dry-Run_' by setting _"dry_run" : true_. (Make that a default setting.) If it all goes well, change it to _false_ and it goes live. Then create an _airdrop-'tokenname'.dat_ file, in a sub-folder, in a CSV {Comma Seperated Values} fashion. In there put the name of the Steem account first, then a comma and after that the amount to send. (See the example (s) below the gogogo.py source.) 

### Notes 
This  version is mainly aimed at the '_Transfer_' of [Steem-Engine dot com](https://steem-engine.com) Tokens. Although it might seem relatively easy to add some functionality to it to '_Issue_' and/or '_Stake_'.  (Suggestion: Forked code can be put in a reply at '_SteemHub_') Maybe create a front-end in Kivy? In essence it is possible to use all kinds of different setups, using unique config and dat files. Even automate it more using data pulled from the Steem blockchain first. 

Please note that this is software is something that comes as it is. Use at your own responsibility. And keep the time-out at 10 seconds or more. 

> Original copyrights seAirdrop project by: _The Marky Mark_.

Some tutorials on Python3, and the usage of Beem, can be found at fellow Steemian [Felixxx' his blog](https://steemit.com/busy/@felixxx/python-for-steem-how-to-beem). 

(_Developed on a Linux driven Laptop by Oaldamster._) 

### 

- [x] Use it with a combination of unique config. json and airdrop.dat files. 
- [-] Make it work for '_Issue_' and '_Stake_', right out of the box. 
- [-] Switch between different servers. 
- [-] Create a GUI, in Kivy for instance. :: https://kivy.org/#download 
- [-] Grab data from Steem blockchain, then create a Transfer list, completely automated. 

#### [+] Command line 

`python3 gogogo.py config-tkn.json` 

> (Where tkn is the one to be send.)

#### [+] FILES 

* gogogo.py 
The main file, will do the actual airdropping 
* ./config-'tokenname'.json 
A JSON preferences file, in the same folder as gogogo.py
* data/airdrop-'tokenname'.dat 
A CSV data file that holds the Steem accounts and the values, in a data subfolder.


#### \FILE: gogogo.py
```python
#
# Automated Token Emission, ATE, for Steem
# A fork from the Steem Engine Airdrop project, by The Marky Mark 
# Version 202002120850 - 0.0.1.0 - beta, by Oaldamster
# 

# Import some Python modules

import csv
import json
import sys
import time
import os

# Import the Beem Steem module by Holger80

from beem import Steem
from beem.account import Account
from beem.exceptions import AccountDoesNotExistsException
from beem.instance import set_shared_steem_instance

# Some global variables

config = {}
user_list = [] 

# Get the Current Working Directory
# Assume files are stored relative from here

current_Dir = os.getcwd() + "/"
print (current_Dir) 
load_Configfile = current_Dir + (sys.argv[1])

# Load the config file

def load_config():	
	global config

	if len(sys.argv) == 1:
		# Instead of this create a default?
		print("ERROR: Please specify a config file")
		quit()
	else:
		print (load_Configfile)

	try:
		with open(load_Configfile) as config_file:
			config = json.load(config_file)
			print(f"Loading emission file: {config['loadfile']}\n")

	except:
		print("Unable to open configuration file")
		quit()		           

# Load the user list to airdrop to

def load_users():
	global user_list
	
	# Add Try etc later
	if config['loadfile']:	
		get_file = current_Dir + config['data_path'] + config['data_file'] + "-" + config['token'] + "." + config['data_file_ext']
		try:
			with open(get_file) as user_file:	
				reader = csv.reader(user_file)
				user_list = list(reader)
				print("Loaded emission file.\n")
			
		except:
			print("Unable to open emission file")
			quit()

# Build from the data to store on the Steem blockchain			
			
def build_payload(user, amount):
    data = {}
    data['contractName'] = 'tokens'
    data['contractAction'] = config['mode']

    data['contractPayload'] = {}
    data['contractPayload']['to'] = user
    data['contractPayload']['symbol'] = config['token'].upper()
    data['contractPayload']['quantity'] = f"{amount}"
    data['contractPayload']['memo'] = config['memo']

    return data

# Hey Hoo, let's go! Send them Tokens

def send_tokens(stm, user, amount, retries=0):
    data = build_payload(user, amount)

    if not config['dry_run']:
        try:
            stm.custom_json('ssc-mainnet1', data,
                            required_auths=[config['account_name']])
        except:
            if retries < 3:
                send_tokens(stm, user, amount, retries=retries)
            else:
                print(f"Airdrop aborted at user: {user[0]}")
                quit()

# Prepare for launch, check for Dry Run.

def do_airdrop(stm):
    estimated_time = round((len(user_list) * config['delay']) / 60, 1)

    estimated_tokens = 0
    for user in user_list:
        estimated_tokens += float(user[1])

    print("Starting Airdrop\n")

    if config['dry_run']:
        print("DRY RUN! - Tokens will not be transfered.\n")
    print(f"Estimated Time: {estimated_time} minutes")
    print(f"Estimated Tokens Used: {estimated_tokens}")
    print("")

    for x in range(10, -1, -1):
        print(f"Starting in {x} seconds...", end='\r')
        time.sleep(1)
        sys.stdout.flush()

    for user in user_list:
        try:
            Account(user[0])
        except AccountDoesNotExistsException:
            print(f"Skipping user {user[0]} - Does not exist")
            continue

        print(f"Sending {user[1]} {config['token']} tokens to @{user[0]}")
        if not config['dry_run']:
            send_tokens(stm, user[0], user[1])

        time.sleep(config['delay'])

# The main file, ground control

def main():
	print("\n")

	load_config()
	load_users()

	stm = Steem(node=["https://api.steemit.com"])
	stm.wallet.unlock(config['pw'])
	set_shared_steem_instance(stm)

	do_airdrop(stm)

# Start it all

if __name__ == '__main__':
    main()

```
/FILE: gogogo.py ####

<hr/>

#### \FILE: config.json
```json
{
	"dry_run" : true,
	"account_name" : "youraccount",
	"pw" : "beemwalletopenup", 
	"token" : "tokenname",
	"memo" : "A message, could be a random qoute even.", 
	"issue_first" : false,
	"mode" : "transfer", 
	"loadfile" : true,
	"data_path" : "data/",
	"data_file" : "airdrop",
	"data_file_ext" : "dat",
	"delay" : 10
}
```
/FILE: config.json ####

<hr/>

#### \FILE: airdrop.dat
```cvs
	smasssh, 10
	meesterboom, 10
	mistakili, 5
	geekgirl, 5
	rodino, 5
```
/FILE: airdrop.dat ####

<hr/> 

<center> 
**Testing ATE with some ENGAGE.** 
![send_engage_with_ate.png](https://cdn.steemitimages.com/DQmcxbZeMhQ67PUzcjuWckg8oAmoZkPyWZn3TaW6ueRbSYT/send_engage_with_ate.png)
_Screenshot taken at https://steem-engine.com_ 
</center> 

***Please note that _SteemHub_ (STMhub?) is merely an idea. Whomever is able to create it for real: Make it so!***
👍  , , , , , , , , , , , , , , , , , , , ,
properties (23)
post_id84,312,379
authoroaldamster
permlinksteemhub-automated-token-emission-202002120850
categorysteemhub
json_metadata{"tags":["steemhub","developement","token","ate","steem-engine","neoxian","python","beem"],"image":["https:\/\/cdn.steemitimages.com\/DQmcxbZeMhQ67PUzcjuWckg8oAmoZkPyWZn3TaW6ueRbSYT\/send_engage_with_ate.png"],"links":["https:\/\/github.com\/themarkymark-steem\/seairdrop","https:\/\/steemit.com\/@themarkymark","https:\/\/steem-engine.com","https:\/\/steemit.com\/@holger80","https:\/\/github.com\/holgern\/beem","https:\/\/www.python.org\/downloads\/","https:\/\/steemit.com\/busy\/@felixxx\/python-for-steem-how-to-beem","https:\/\/kivy.org\/#download"],"app":"steemit\/0.1","format":"markdown"}
created2020-02-12 08:58:42
last_update2020-02-12 08:58:42
depth0
children11
net_rshares3,767,295,259,999
last_payout2020-02-19 08:58:42
cashout_time1969-12-31 23:59:59
total_payout_value0.462 SBD
curator_payout_value0.397 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length8,930
author_reputation69,006,323,355,244
root_title"SteemHub: Automated Token Emission 202002120850"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
author_curate_reward""
vote details (21)
@smasssh ·
\FILE: airdrop.dat

    smasssh, 10
    meesterboom, 10
    mistakili, 5
    geekgirl, 5
    rodino, 5

<br>
This was the only part of this post I understood, hahaha
All to much tech for me mate.
Cheers.
👍  
properties (23)
post_id84,323,823
authorsmasssh
permlinkq5lhy8
categorysteemhub
json_metadata{"app":"steemit\/0.1"}
created2020-02-12 15:34:51
last_update2020-02-12 15:34:51
depth1
children9
net_rshares24,963,760,043
last_payout2020-02-19 15:34:51
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length203
author_reputation38,116,332,880,898
root_title"SteemHub: Automated Token Emission 202002120850"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
author_curate_reward""
vote details (1)
@meesterboom ·
Lol, me too!!
👍  
properties (23)
post_id84,324,180
authormeesterboom
permlinkq5lilu
categorysteemhub
json_metadata{"app":"steemit\/0.1"}
created2020-02-12 15:49:06
last_update2020-02-12 15:49:06
depth2
children3
net_rshares24,463,874,511
last_payout2020-02-19 15:49:06
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length13
author_reputation823,295,147,248,484
root_title"SteemHub: Automated Token Emission 202002120850"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
author_curate_reward""
vote details (1)
@oaldamster ·
And I saved it for last! 😄👍
properties (22)
post_id84,324,351
authoroaldamster
permlinkq5liwk
categorysteemhub
json_metadata{"app":"steemit\/0.1"}
created2020-02-12 15:55:36
last_update2020-02-12 15:55:36
depth3
children0
net_rshares0
last_payout2020-02-19 15:55:36
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length27
author_reputation69,006,323,355,244
root_title"SteemHub: Automated Token Emission 202002120850"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
@smasssh ·
I have to go back to my years at school for having mentioned my name first. 
And that has never been for "cheerful" reasons ...
👍  
properties (23)
post_id84,325,227
authorsmasssh
permlinkq5ljvw
categorysteemhub
json_metadata{"app":"steemit\/0.1"}
created2020-02-12 16:16:39
last_update2020-02-12 16:16:39
depth3
children1
net_rshares21,629,746,571
last_payout2020-02-19 16:16:39
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length127
author_reputation38,116,332,880,898
root_title"SteemHub: Automated Token Emission 202002120850"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
author_curate_reward""
vote details (1)
@oaldamster ·
It is the best part Amigo! 😁👍
properties (22)
post_id84,324,320
authoroaldamster
permlinkq5liuq
categorysteemhub
json_metadata{"app":"steemit\/0.1"}
created2020-02-12 15:54:30
last_update2020-02-12 15:54:30
depth2
children4
net_rshares0
last_payout2020-02-19 15:54:30
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length29
author_reputation69,006,323,355,244
root_title"SteemHub: Automated Token Emission 202002120850"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
@smasssh ·
Am getting curious more and more every day. 
Am (over)loaded with work till the end of March but we should actually meet again soon ...
👍  
properties (23)
post_id84,324,862
authorsmasssh
permlinkq5ljgw
categorysteemhub
json_metadata{"app":"steemit\/0.1"}
created2020-02-12 16:07:39
last_update2020-02-12 16:07:39
depth3
children3
net_rshares24,097,316,862
last_payout2020-02-19 16:07:39
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length135
author_reputation38,116,332,880,898
root_title"SteemHub: Automated Token Emission 202002120850"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
author_curate_reward""
vote details (1)
@esteemapp ·
ESTM Boosting refund to @oaldamster! <br>Due to one of these reasons: <br>1. Not posted from eSteem apps. <br>2. Already curated by eSteem team. <br>3. Need bit more improvement on quality of post. <br>4. Might be too old post.<br>5. User already received vote in last couple hours, you can try boosting again afterwhile.<br>[Android](https://play.google.com/store/apps/details?id=app.esteem.mobile.android), [iOS](https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=1451896376&mt=8), [Windows, Mac, Linux](https://github.com/esteemapp/esteem-surfer/releases)<br>Learn more: https://esteem.app <br>Join our discord: https://discord.me/esteem
properties (22)
post_id84,337,164
authoresteemapp
permlinkre-2020212t2326874z
categorysteemhub
json_metadata{"tags":["esteem"],"app":"esteem\/2.2.2-welcome","format":"markdown+html","community":"esteem.app"}
created2020-02-12 22:02:06
last_update2020-02-12 22:02:06
depth1
children0
net_rshares0
last_payout2020-02-19 22:02:06
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length656
author_reputation396,075,316,369,469
root_title"SteemHub: Automated Token Emission 202002120850"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000