My First Steem.js Adventure: Tallying Account Power Ups

nerdicorn.3c1d00a8c7a242e5a3ad420be5b9f081.png

Emoji Source

Posts in this series: Part 1 / Part 2 / Part 3 / Part 4

I just spent a couple hours coding something to interact with the STEEM blockchain for the first time. 🙂 I want to create a tool that will calculate the total power ups for all of the @sndbox fellows each week (for the weekly challenge that they do, like at the end of this post).

What I Used


My app is built with Node.js and the steem.js node module. At first I tried hacking something together with Browserify to avoid having to use Node, something I’m in the process of learning right now, but I’m really glad I ended up pushing myself. It showed me that there were a lot of basic concepts about Node that I hadn’t wrapped my head around yet, and building this project helped fill some of those gaps.

Getting Started


First, I made my project folder and then ran npm init to create my package.json. Then I installed express and steem.js with npm install --save express steem. I added a .gitignore file for my node_modules folder and then started coding.

First, I created my app.js file and imported express and steem like this:

const express = require('express');
const app = express();

const steem = require('steem');
steem.api.setOptions({ url: 'https://api.steemit.com' });

Exploring the STEEM Blockchain


SteemJS-intro.74a380181ff54fd39c88337490e38b46.png

Image Source

I set up my app to listen on port 8080, and used the example code in the docs for getAccounts to test it out:

app.get('/', (req, res) => {
    steem.api.getAccounts(['jeffbernst'], function(err, response){
        res.send(err, response);
    });
});

app.listen(8080, () => console.log('Example app listening on port 8080!'));

 
This returns this JSON object. As you can see down towards the bottom, the array for transfer history is empty. How can I get that data!?

"transfer_history": [],
"market_history": [],
"post_history": [],
"vote_history": [],
"other_history": [],

 
After looking around at the different methods available in the docs, the approach I settled on for calculating the total power ups was the following:

  1. pull in a big slice of all transactions on an account
  2. hone in on the 7 day period I want to check
  3. find the power ups in that 7 day period and total them

In this first post I’ll explain how I calculated the total SBD power ups on a 1000 transaction slice of account history.

To get the history, including all votes, posts, and comments, I used the getAccountHistory method, which looks like this:

steem.api.getAccountHistory(account, from, limit, function(err, result) {
    console.log(err, result);
}); 

 
I tinkered with it for awhile, before realizing that the “from” parameter needs to be set to -1 for some reason (I still don’t understand why this is). The “limit” parameter sets how many results to return.

I looked through the results and found what the different account activity looks like.

Here’s transaction number 1029, a comment:

{
    "trx_id": "9c5e88a97ef0cf2d7b639e54a835a9699e9b2b16",
    "block": 19126254,
    "trx_in_block": 4,
    "op_in_trx": 0,
    "virtual_op": 0,
    "timestamp": "2018-01-19T22:22:57",
    "op": [
        "comment",
        {
            "parent_author": "raizel",
            "parent_permlink": "re-jeffbernst-re-raizel-re-jeffbernst-teaching-english-in-japan-as-an-alt-20180119t220058008z",
            "author": "jeffbernst",
            "permlink": "re-raizel-re-jeffbernst-re-raizel-re-jeffbernst-teaching-english-in-japan-as-an-alt-20180119t222256705z",
            "title": "",
            "body": "Awesome! I just joined steemit chat -- been meaning to anyway. My name on there is also jeffbernst.",
            "json_metadata": "{\"tags\":[\"japan\"],\"app\":\"steemit/0.1\"}"
        }
    ]
}

 
Here’s transaction 1025, a vote:

{
    "trx_id": "a355bcfe75fe671865452651702faf4e2629e283",
    "block": 19124421,
    "trx_in_block": 1,
    "op_in_trx": 0,
    "virtual_op": 0,
    "timestamp": "2018-01-19T20:51:15",
    "op": [
        "vote",
        {
            "voter": "jeffbernst",
            "author": "raizel",
            "permlink": "re-jeffbernst-teaching-english-in-japan-as-an-alt-20180119t172929514z",
            "weight": 10000
        }
    ]
}

 
And, finally, what I was looking for, a transfer showing me powering up 18.5 STEEM:

{
    "trx_id": "fee93f921e66b5ea17549ef363016b48cf2f86ed",
    "block": 18888666,
    "trx_in_block": 20,
    "op_in_trx": 0,
    "virtual_op": 0,
    "timestamp": "2018-01-11T16:14:42",
    "op": [
        "transfer_to_vesting",
        {
            "from": "jeffbernst",
            "to": "jeffbernst",
            "amount": "18.500 STEEM"
        }
    ]
}

 
After I found this, I set up my app to pull in 1000 transactions from my account, and cycled through them to count any marked “transfer_to_vesting.”

I was having some trouble getting everything to work, but then I realized I probably need to use a promise to make sure I'm not trying to calculate the totals before the data is returned from the API call. This was really useful experience because I definitely need more practice with promises.

Here’s the code I settled on to take care of this for me in my app.js file:

const express = require('express');
const app = express();

const steem = require('steem');
steem.api.setOptions({ url: 'https://api.steemit.com' });

function totalPowerUps(data) {
  let total = 0;
  for (let i = 0; i < data.length; i++) {
    if (data[i][1].op[0] === 'transfer_to_vesting') {
      let transferString = data[i][1].op[1].amount;
      total += Number(transferString.substr(0, transferString.indexOf(' ')));
    }
  }
  return total.toString();
}

let jeffHistoryPromise = new Promise((resolve, reject) => {
  steem.api.getAccountHistory('jeffbernst', -1, 1000, function(err, result) {
    if (err) reject(err);
    resolve(result);
  });
});

let totalPowerUpsVal;

jeffHistoryPromise
  .then(data => {
    totalPowerUpsVal = totalPowerUps(data);
  })
  .catch(err => {
    console.error(err);
  });

app.get('/', (req, res) => {
  res.send(totalPowerUpsVal);
});

app.listen(8080, () => console.log('Example app listening on port 8080!'));

 
It worked! When I start up my server with node app.js and go to localhost:8080 I’m met with this beautiful webpage:

Screen Shot 2018-01-19 at 7.16.23 PM.162bfba2fb844b05b38061a5333bacdb.png

There it is! The total STEEM I’ve powered up in the last 1000 transactions.

Next Iteration


Now that I’ve gotten this very minor interaction with the STEEM blockchain to work, I want to figure out a way to finish this tool. The final app will need to take an array of users and return a ranking of total STEEM powered up over a specified time period. I’m worried that handling 100 arrays with 1000+ transactions won’t really work, but I’ll just have to give it a shot and see what happens.

Thanks so much for reading! If you have any recommendations or corrections for absolutely any of my code, please let me know in the comments! My goal with writing about this is to help me think through my process and get any tips I can from more experienced developers.

Here is the github repo in case you'd like to take a look. 🙂

Posts in this series: Part 1 / Part 2 / Part 3 / Part 4


follow_jeffbernst.gif

H2
H3
H4
3 columns
2 columns
1 column
8 Comments