SteemAX 1.1 ~ New Feature: Exchange History

in utopian-io •  3 months ago



SteemAX is an auto upvote exchange program that lets Steemians swap votes with each other for an agreed upon length of time.

SteemAX 1.1 Released

First I'd like to give much thanks to @outwork who has once again stepped up and delivered excellent quality work in response to my task request for a new homepage for SteemAX. This is the first of many task requests I plan on creating in the upcoming weeks as SteemAX needs help with the creation, revamping and redesigning of certain pages and functions. I'm just a meek back-end programmer with an idea and I could use help from visionary designers and graphics experts like @outwork. Thank you!

In this new release from SteemAX, version 1.1 provides an optimized vote exchange algorithm aimed at a faster run-time and that's less consuming of resources. This will be a continual endeavor throughout all future releases. New functionality has been added as well. A page that shows the history of all exchanges was created to show details about the time, post identifiers, and vote values traded in each exchange. This can be displayed as a list of all exchanges on SteemAX, or a list of all exchanges for a particular account.


Some Of The Benefits Of Using SteemAX

  • Better relations with your fellow Steemians.
  • A mechanism for supporting minnows long-term.
  • A better way for whales to distribute upvotes.
  • An avenue for minnows to seek support without feeling like they have their hand out.
  • A way of socializing the current platform away from pure capitalism...
  • But also a true "open market" where upvotes can be traded and bartered upon.
  • Since Steemians can trade their vote at disproportional ratios, they can seek profits above and beyond what self voting could achieve, thus eliminating the temptation to over self vote.
  • Whales that exchange at ratios favorable to minnows stand a better chance of receiving curation rewards, plus a substantial return on the value of their vote.
  • To use SteemAX is free since no fees are taken and all SBD used to start and accept invites goes directly to the other party.

SteemAX Benefits The Whole System

  • Because whales are unable to manually distribute their upvote consistently, bid bots were created. SteemAX is a much better solution for distributing upvotes automatically than a bid bot:

  • Because the number of blocks processed by witnesses is perhaps as equally important as the "distribution of wealth" on the Steemit platform, bid bots were created to provide both. SteemAX solves this problem by still maintaining a high number of transactions, but via an exchange, from voter to voter, rather than centrally distributed by a bid bot.

  • Because each exchange must be manually agreed upon, the likely-hood of upvotes going to human created content rather than spam is greatly increased, as people are much more likely to agree to things they support.

Exchanges Have Been Running Smoothly

The first users of SteemAX have already created a number of exchanges which have commenced since my last post. Each exchange has occurred automatically without any problems, and it appears that transactions are at least scalable beyond what they are currently running at by several factors. Of course, I anticipate the need for optimization will arrive quickly. As a step towards a faster algorithm, I've reduced the need for SteemAX to renew access tokens to only when they expire. I accomplished this by refactoring the methods vote_on_it and renew_token and by creating a new method which, for lack of imagination, I named sc_vote, which actually initializes SteemConnect and makes the vote. vote_on_it checks if sc_vote fails and if so uses renew_token to use the refresh token to gain a new access token and save it to the database, then tries sc_vote to make a vote again.

    def vote_on_it(self, voter, author, post, weight):
        """ Use the tokens in the database to vote on
        a post. If the vote fails, renews the token
        and tries again.
        db = axdb.AXdb(default.dbuser,
        if db.get_user_token(voter) is not False:
            accesstoken = db.dbresults[0][1]
            refreshtoken = db.dbresults[0][2]
            return False
        # If the vote fails then we renew the token
        if not self.sc_vote(voter, author, post, weight, accesstoken):
            print("Renewing token for " + voter)
            newtoken = self.renew_token(voter, refreshtoken)
            if newtoken is not False:
                return self.sc_vote(voter, author, post, weight, newtoken)
                self.msg.error_message("A NEW TOKEN COULD NOT BE CREATED")
                return False

    def sc_vote(self, voter, author, post, weight, token):
        """ Takes the given token and initializes SteemConnect
        to make a vote. Analyzes the result and prints the
        outcome to screen as well as returns a boolean result.
        """ = None
        result =
        # We use a broad exception clause to "catch" everything
        # that is not an error
            # The vote was successful
            print(str(voter) + " has voted on "
                  + str(post) + " "
                  + str(weight) + "%")
            return True
            return False

    def renew_token(self, accountname, refreshtoken):
        """ If the access token has expired
        use the refresh token to get a new access token.
        if self.steem.verify_key(
                acctname="", tokenkey=refreshtoken):
            return self.steem.accesstoken
            return False

The commit for these changes also includes some PEP 8 inspired adjustments of whitespace and triple double quotes for the doc strings.

New Feature: Exchange History

SteemAX now has a public page that displays a history of all exchanges that have taken place between its users. The history details the two parties involved in the exchange (inviter vs. invitee), the amount exchanged ($0.10 vs. $0.10), the date and time the exchange took place, and the respective blog posts that were upvoted, which can be seen by placing the cursor over the account names.


This page has been placed at the address:

Or see an individual account history by visiting

Please do not judge the web page design because layout and design are not my primary skills. It's my intention to create a task request to hand over the actual design of this page (plus a few others) to someone with more skill than myself. My goal was to create the back-end functionality and have a front-end that demonstrates that functionality.

Steps Taken

These new features were accomplished by creating a new table in the database that records all the archived exchanges and their pertinent information. A method was also created for inserting an exchange into the database.

        if not self.get_results("SELECT * FROM axhistory WHERE 1;"):
            self.commit('CREATE TABLE IF NOT EXISTS axhistory '
                        + '(ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY, '
                        + 'MemoID varchar(100), '
                        + 'Account1 varchar(200), Account2 varchar(200), '
                        + 'VoteValue1 varchar(100), VoteValue2 varchar(100), '
                        + 'Identifier1 varchar(400), Identifier2 varchar(400), '
                        + 'Time TIMESTAMP NOT NULL '
                        + 'DEFAULT CURRENT_TIMESTAMP '
                        + 'ON UPDATE CURRENT_TIMESTAMP);')

    def archive_exchange(self, memoid, account1, account2,
                         ident1, ident2, vote1, vote2):
        """ If posts and votes are eligible and
        an exchange occurs it is recorded in the
        return self.commit('INSERT INTO axhistory (MemoID, Account1, '
                           + 'Account2, VoteValue1, VoteValue2, Identifier1, Identifier2) '
                           + 'VALUES (%s, %s, %s, %s, %s, %s, %s);',
                           memoid, account1, account2, vote1, vote2, ident1, ident2)


I also created a method for retrieving archived exchanges for all of steemax or just an individual account.

    def get_exchange_archive(self, account=None):
        """ Returns a list of all the recent exchanges
        that have occured on steemax
        if account is None:
            if self.get_results('SELECT Account1, Account2, VoteValue1, '
                                + 'VoteValue2, Identifier1, Identifier2, Time '
                                + 'FROM axhistory WHERE 1 ORDER BY Time DESC;'):
                return self.dbresults
            if self.get_results('SELECT Account1, Account2, VoteValue1, '
                                + 'VoteValue2, Identifier1, Identifier2, Time '
                                + 'FROM axhistory WHERE %s IN (Account1, Account2) '
                                + 'ORDER BY Time DESC;',
                return self.dbresults

The commit for this code also contains a change to the archive_exchange method and a slight change to the size of the table columns.

Next, the code in was created that is necessary for displaying the list of archived exchanges on the command line, both for easy access as well as testing prior to going live on the website.

    def do_exchanges(self, args):
        """ Lists all the archived exchanges for an account
        account = input("Account (press enter for none): ")
        # If no account is entered return the whole list
        if not account or account == "" or account == 0:
            account = None
            print ("Looking up " + account)
        axlist = db.get_exchange_archive(account)
        for trade in axlist:
            print("@" + str(trade[0]) + "/" + str(trade[2])
                  + "\nvs.\n" + "@" + str(trade[1]) + "/" + str(trade[3]))
            print(str(trade[4]) + " vs. " + str(trade[5]) + "\n\n")


Obviously the command line list is for administrator use so a method was created for displaying the list as a web page. It simply gets the list of archived exchanges from the database, then using the load_template and make_page methods generates and returns an HTML page of the list.

    def archive_page(self, account=None):
        """ Provides a list of all the exchanges that
        have occurred for a particular account. if
        no account is provided then a list of all exchanges
        for all accounts is returned.
        infobox = ""
        if account is not None:
            account = sec.filter_account(account)
            # If the token is invalid return user to the login page
            if not self.db.get_user_token(account):
                return self.auth_url()
        axlist = self.db.get_exchange_archive(account)
        boxtemplate = self.load_template("templates/archivebox.html")
        for trade in axlist:
            date = (str(trade[6].hour) + ":"
                    + str(trade[6].minute) + " "
                    + str(trade[6].strftime("%B")) + " "
                    + str(trade[6].day) + ", "
                    + str(trade[6].year) + " ")
            box = self.make_page(boxtemplate,
            infobox = infobox + box
        pagetemplate = self.load_template("templates/archive.html")
      # If the account was provide we display it with the @
      # however if it's not we convert it to an empty string
      # so that it is not displayed in HTML
        if account is None:
            account = ""
            account = "@" + account
        return ("\r\n" + self.make_page(pagetemplate,

This commit also contains some minor refactoring to better conform to PEP 8 standards.

Finally, the HTML and CSS were created for the history page as well as the Python script that executes the 'archive_page` on the server.

from cgi import FieldStorage
from steemax.web import Web
account = FieldStorage().getvalue('account')
print ("Content-type: text/html")
print (Web().archive_page(account))

Commit #1 for HTML

Commit #2 for HTML

Commit #3 for HTML

Commit #4 for CSS

Commit #5 for Python

Technology Stack

SteemAX is written to use Python 3.5 and MySQL. The web interface for and has been written in HTML, CSS and Javascript.


In the future more contributors will be brought into the fold
via Task Requests to help improve the functionality of the site and most especially the look and feel. After all, projects always benefit from the synergistic action of teamwork.


Please contact Mike (Mike-A) on Discord

GitHub Account

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Thank you learnelectronics! You've just received an upvote of 61% by @ArtTurtle!

@ArtTurtle Wants To Upvote Your Art & Music!

The quickest and easiest way to start receiving an upvote for each and every single one of your art and music posts is by delegating 20 SP or more to @ArtTurtle using this delegate button. It's fully automatic and once your delegation has hit the blockchain @ArtTurtle will begin upvoting your art and music content within 45 minutes.

Don't want to give up your SP? You can also get @ArtTurtle's upvotes by signing up for free to! For more detailed information about @ArtTurtle and how it works be sure to check out this recent article by @Artopium titled @ArtTurtle Will Upvote Each & Every One of Your Art/Music Posts


DISCLAIMER: Your post is upvoted based on curation algorithm configured to find good articles e.g. stories, arts, photography, health, etc. This is to reward you (authors) for sharing good content using the Steem platform especially newbies.
If you're a dolphin or whales, and wish not to be included in future selection, please let me know so I can exclude your account. And if you find the upvoted post is inappropriate, FLAG if you must. This will help a better selection of post.

Keep steeming good content.

Posted using condenser site.

Hi @learnelectronics!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server

Congratulations @learnelectronics! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

Award for the number of upvotes

Click on the badge to view your Board of Honor.
If you no longer want to receive notifications, reply to this comment with the word STOP

Support SteemitBoard's project! Vote for its witness and get one more award!

Thank you for you kind words @learnelectronics! Feel fre to reach me out when you need my help!

Hey, @learnelectronics!

Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Get higher incentives and support!
Simply set as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).

Want to chat? Join us on Discord

Vote for Utopian Witness!