SteemHub: Automated Token Emission 202002120850

in #steemhub4 years ago

Python3 version 0.0.1.0-beta by Oaldamster

Originally forked from Steem Engine Airdrop Tool {seairdrop} by The Marky Mark.

[+] Load Config, autoload Airdrop file

Creating a Token on Steem-Engine dot com can be one thing, spreading the love is another. Thanks to a few fellow Steemians though, The Marky Mark and 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 and Python3 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:

Eventually for reference:

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 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.

(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

#
# 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 ####


\FILE: config.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 ####


\FILE: airdrop.dat

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

/FILE: airdrop.dat ####



Testing ATE with some ENGAGE.
send_engage_with_ate.png
Screenshot taken at https://steem-engine.com

Please note that SteemHub (STMhub?) is merely an idea. Whomever is able to create it for real: Make it so!

Sort:  

\FILE: airdrop.dat

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



This was the only part of this post I understood, hahaha
All to much tech for me mate.
Cheers.

Lol, me too!!

I have to go back to my years at school for having mentioned my name first.
And that has never been for "cheerful" reasons ...

And I saved it for last! 😄👍

It is the best part Amigo! 😁👍

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 ...

On one side, it is a good thing, to have the orderbook filled. On the other side, overload can be tricky. Handle with care buddy.

And you're going to be in the neighborhood soon?
Then we'll meet up, you know where my house lives. 😄👍

And I'll probably plan a trip to da midst of NL, somewhere this spring/ summer. Lots to talk about. 🍻

Indeed lots to talk about.

Big project in Baarn (Sherpa; zorginstelling), with a tight schedule and deadlines, so not really in your neighborhood.

About the possible trip to center NL: you can stay over at my place if that fits in better in travel schedule.

No worries about work, can deal with it.

Alright, thanks Amigo, we'll fill in the dots on another occasion.

Latex!

ESTM Boosting refund to @oaldamster!
Due to one of these reasons:
1. Not posted from eSteem apps.
2. Already curated by eSteem team.
3. Need bit more improvement on quality of post.
4. Might be too old post.
5. User already received vote in last couple hours, you can try boosting again afterwhile.
Android, iOS, Windows, Mac, Linux
Learn more: https://esteem.app
Join our discord: https://discord.me/esteem