1

I want to calculate the historical balance of an account, but I don't know how to process the data (data returned from the main chain and the data returned by the RPC interface), now I have synchronized some part of the data from the main chain to the mongodb database, but I don't know How to deal with a collection in mongodb database, I did not find any information about the account balance in the collection. Can anyone give me any ideas? I am very grateful for any response.

1 Answer 1

0

Mongodb call would be --mongodb-filter-on=receiver:action:actor | Docs link

--mongodb-filter-on                   Mongodb: Track actions which match
                                        receiver:action:actor. Actor may be blank
                                        to include all. Receiver and Action may
                                        not be blank. Default is * include
                                        everything.

So for the below account it would be: --mongodb-filter-on=moonaccount1:transfer I'm assuming "actor" would be the contract eosio.token so you can add that on as well for: --mongodb-filter-on=moonaccount1:transfer:eosio.token to not filter all the other tokens who use the transfer method.

#  seq  when                              contract::action => receiver      trx id...   args
================================================================================================================
#    0   2018-11-22T05:36:09.500     eosio.token::transfer => moonaccount1  edd0c861... {"from":"fairdapp1111","to":"moonaccount1","quantity":"200.0..

This looks like a good resource: https://github.com/EOS-BP-Developers/eosio-mongodb-queries


Current account balance is held in a row in the multi index container which is RAM.

From currency.hpp in eosiolib

struct account { // struct returning balance for primary_key()
            asset    balance;
            bool     frozen    = false;
            bool     whitelist = true;

            uint64_t primary_key()const { return balance.symbol.name(); }

            EOSLIB_SERIALIZE( account, (balance)(frozen)(whitelist) )
         };

// typedefing multi index as accounts
typedef eosio::multi_index<N(accounts), account> accounts;  

So when you want to transfer, the contract will iterate through the multi index container to find your "balance" based on your account name. From there you can see the logic for a transfer here:

void add_balance( account_name owner, asset value, const currency_stats& st, account_name ram_payer )
          {
// searching accounts typedef'd multi index container with the contract's scope 
//(who's multi index) and the owner's row (what person in the multi index)
             accounts to_acnts( _contract, owner );  
             auto to = to_acnts.find( value.symbol.name() );
             if( to == to_acnts.end() ) {
                eosio_assert( !st.enforce_whitelist, "can only transfer to white listed accounts" );
                to_acnts.emplace( ram_payer, [&]( auto& a ){
                  a.balance = value;
                });
             } else {
                eosio_assert( !st.enforce_whitelist || to->whitelist, "receiver requires whitelist by issuer" );
                to_acnts.modify( to, 0, [&]( auto& a ) {
                  a.balance.amount += value.amount;
                });
             }
          }

In essence, the contract isn't going through all of your previous transactions to prove that you have that balance, it trusts the balance it pulls from the multi index container and acts off of it.


To get the historical actions from an account, you don't need the mongodb database for that, you can use cleos or the RPC api and do:

./cleos -u https://nodes.get-scatter.com:443 get actions moonaccount1 0 200
  • account_name TEXT - name of account to query on (required)
  • pos INT - sequence number of action for this account, -1 for last
  • offset INT - get actions [pos,pos+offset] for positive offset or [pos-offset,pos) for negative offset

Options:

  • -j,--json print full json
  • --full don't truncate action json
  • --pretty pretty print full action json
  • --console print console output generated by action

RPC: curl --request POST --url https://nodes.get-scatter.com:443/v1/history/get_actions --data '{"pos":0,"offset":200,"account_name":"moonaccount1"}'

RPC magic:

  • Add | head -n 50 for top 50 results
  • Add | json_pp to make the json pretty

./cleos -u https://nodes.get-scatter.com:443 get actions moonaccount1 20

#    0   2018-11-22T05:36:09.500     eosio.token::transfer => moonaccount1  edd0c861... {"from":"fairdapp1111","to":"moonaccount1","quantity":"200.0...
#    1   2018-11-22T05:36:56.500     chintailease::prepare => chintailease  32636812... {"memo":"moonaccount1|1|2000|0.0055|28|1.0000|3lmgzl0ybr"}...
#    2   2018-11-22T05:36:56.500     eosio.token::transfer => eosio.token   32636812... {"from":"moonaccount1","to":"chintailease","quantity":"11.00...
#    3   2018-11-22T05:36:56.500     eosio.token::transfer => moonaccount1  32636812... {"from":"moonaccount1","to":"chintailease","quantity":"11.00...
#    4   2018-11-22T05:36:56.500     eosio.token::transfer => chintailease  32636812... {"from":"moonaccount1","to":"chintailease","quantity":"11.00...
#    5   2018-11-22T05:36:56.500    chintailease::activate => chintailease  32636812... {"memo":"moonaccount1|1|2000|0.0055|28|1.0000|3lmgzl0ybr"}...
#    6   2018-11-22T05:50:08.500     eosio.token::transfer => eosio.token   3d87fcdd... {"from":"moonaccount1","to":"eospokerwins","quantity":"3.000...
#    7   2018-11-22T05:50:08.500     eosio.token::transfer => moonaccount1  3d87fcdd... {"from":"moonaccount1","to":"eospokerwins","quantity":"3.000...
#    8   2018-11-22T05:50:08.500     eosio.token::transfer => eospokerwins  3d87fcdd... {"from":"moonaccount1","to":"eospokerwins","quantity":"3.000...
#    9   2018-11-22T05:50:18.500         eospokerwins::hit => eospokerwins  b3e0ebb4... {"player":"moonaccount1","hand":1,"slot":3}...
#   10   2018-11-22T05:50:19.000    eospokercoin::transfer => moonaccount1  be9f0010... {"from":"eospokermine","to":"moonaccount1","quantity":"0.056...
#   11   2018-11-22T05:50:35.500     eosio.token::transfer => eosio.token   73f1f85d... {"from":"moonaccount1","to":"eospokerwins","quantity":"3.000...
#   12   2018-11-22T05:50:35.500     eosio.token::transfer => moonaccount1  73f1f85d... {"from":"moonaccount1","to":"eospokerwins","quantity":"3.000...
#   13   2018-11-22T05:50:35.500     eosio.token::transfer => eospokerwins  73f1f85d... {"from":"moonaccount1","to":"eospokerwins","quantity":"3.000...
#   14   2018-11-22T05:50:47.000       eospokerwins::stand => eospokerwins  f314b6f8... {"player":"moonaccount1","hand":1}...
#   15   2018-11-22T05:50:48.000     eosio.token::transfer => moonaccount1  7dc88fe9... {"from":"eospokerwins","to":"moonaccount1","quantity":"3.000...
#   16   2018-11-22T05:50:48.000    eospokercoin::transfer => moonaccount1  7dc88fe9... {"from":"eospokermine","to":"moonaccount1","quantity":"0.056...
#   17   2018-11-22T05:51:02.500     eosio.token::transfer => eosio.token   47e6de1f... {"from":"moonaccount1","to":"eospokerwins","quantity":"3.000...
#   18   2018-11-22T05:51:02.500     eosio.token::transfer => moonaccount1  47e6de1f... {"from":"moonaccount1","to":"eospokerwins","quantity":"3.000...
#   19   2018-11-22T05:51:02.500     eosio.token::transfer => eospokerwins  47e6de1f... {"from":"moonaccount1","to":"eospokerwins","quantity":"3.000...
#   20   2018-11-22T05:51:12.000       eospokerwins::stand => eospokerwins  d876a62a... {"player":"moonaccount1","hand":1}...
6
  • 1
    Thank you for your answer, but I still have a few questions: 1. I tested the get actions API and found that it can only return a certain number of actions. Is there any way to get all the actions of an account one or more times? 2. If I use this method to calculate the account history balance, do I only need to count the eosio.token::transfer operation? Other actions such as refund action can also cause account balance changes?
    – 陈自民
    Commented Nov 28, 2018 at 3:44
  • 1
    3. If I want to improve this feature, I use mongodb to synchronize the data of the main chain, and then use this tool locally link to run the mongodb database. Query? Thank you again for your answer.
    – 陈自民
    Commented Nov 28, 2018 at 3:46
  • 1. I think you can pull as much as you want from RPC. I just tried this and it filled my console, so I assume it works: curl --request POST --url https://nodes.get-scatter.com:443/v1/history/get_actions --data '{"pos":0,"offset":200,"account_name":"moonaccount1"}' May want to add | head -n 50 to only pull 50 at first developers.eos.io/eosio-nodeos/reference#get_actions-1 Also can add | json_pp so the JSON looks nice. I believe pos is starting positiong and offset is where to go to
    – Nat
    Commented Nov 28, 2018 at 3:52
  • 2. I've never tried to do that, so I'm not sure. 3. I found that from googling some stuff. I haven't actually used it, but it looks like it could be a good resource to query. So I'm 1/3 answers :). Feel free to ask another question on the stack exchange.
    – Nat
    Commented Nov 28, 2018 at 3:55
  • Thank you again for your patience, I will continue to try to solve these problems.
    – 陈自民
    Commented Nov 28, 2018 at 4:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.