瀏覽代碼

交易记录对接完成

DevYK 2 年之前
父節點
當前提交
0f512385e1
共有 11 個文件被更改,包括 589 次插入36 次删除
  1. 4 0
      README.md
  2. 2 1
      app.js
  3. 1 0
      config/dev_config.js
  4. 1 0
      config/prd_config.js
  5. 1 0
      config/test_config.js
  6. 219 10
      model/db/account_info_db.js
  7. 1 1
      model/db/mysql_db.js
  8. 259 17
      model/moralis_sdk.js
  9. 35 7
      model/utils.js
  10. 53 0
      routes/sdk.js
  11. 13 0
      test/accout_info_db_test.js

+ 4 - 0
README.md

@@ -1,3 +1,7 @@
+生成 koa2 项目:
+npm install koa2-generator -g
+koa2 project
+
 安装必要的库
 ```shell
 npm install

+ 2 - 1
app.js

@@ -15,6 +15,7 @@ require('./model/timer')
 const log = require('./model/logger')
 
 var test = require('./test/test');
+var accout_info_db_test = require('./test/accout_info_db_test')
 // error handler
 onerror(app)
 
@@ -46,7 +47,7 @@ app.use(async (ctx, next) => {
 app.use(users.routes(), users.allowedMethods())
 app.use(sdk.routes(), sdk.allowedMethods())
 app.use(db_test.routes(), db_test.allowedMethods())
-
+app.use(accout_info_db_test.routes(), accout_info_db_test.allowedMethods())
 
 app.use(test.routes(), test.allowedMethods())
 // error-handling

+ 1 - 0
config/dev_config.js

@@ -54,6 +54,7 @@ const db_config = {
     // },
     mysql: {
         DATABASE: 'denet_chain',   //数据库名称
+        DATABASE_MY_NODE: 'bnb_block_sync',   //自建 node 存储
         TABLENAME: 'user_key_manage',   //表名
         USERNAME: 'denet',   //用户名
         PASSWORD: 'cyber#Together_2022', //密码

+ 1 - 0
config/prd_config.js

@@ -47,6 +47,7 @@ const db_config = {
     // 数据库配置
     mysql: {
         DATABASE: 'denet_chain',   //数据库名称
+        DATABASE_MY_NODE: 'bnb_block_sync',   //自建 node 存储
         TABLENAME: 'user_key_manage',   //表名
         USERNAME: 'denet',   //用户名
         PASSWORD: 'cyber#Together_2022', //密码

+ 1 - 0
config/test_config.js

@@ -45,6 +45,7 @@ const http_log_report_config = {
 const db_config = {
     mysql: {
         DATABASE: 'denet_chain',   //数据库名称
+        DATABASE_MY_NODE: 'bnb_block_sync',   //自建 node 存储
         TABLENAME: 'user_key_manage',   //表名
         USERNAME: 'denet',   //用户名
         PASSWORD: 'cyber#Together_2022', //密码

+ 219 - 10
model/db/account_info_db.js

@@ -1,31 +1,240 @@
-const mysql = require("./mysql_db")
 const logger = require('../logger')
 var { db_config } = require('../../config/config.js')
 const utils = require('../utils.js')
+var mysql = require('mysql');
+var port = db_config.mysql.PORT
+var host = db_config.mysql.HOST
+var username = db_config.mysql.USERNAME
+var password = db_config.mysql.PASSWORD
+var database = db_config.mysql.DATABASE_MY_NODE
+var open_pool = db_config.mysql.OPEN_POOL
+var pool_size = db_config.mysql.POOL_SIZE
 
+var opts = {
+    host: host,
+    user: username,
+    password: password,
+    port: port,
+    database: database,
+}
+var MYSQL_INSTANCE = null;
 
+//程序启动默认创建一个 mysql 连接
+createDefMysqlConnect();
+// 开始创建
+function createDefMysqlConnect() {
+    disDefMysqlConnect();
+    logger.log('createDefMysqlConnect', database)
+    if (open_pool) {//创建连接池
+        opts.connectionLimit = pool_size
+        MYSQL_INSTANCE = mysql.createPool(opts);
+        addConnEvent()
+    } else {//创建单连接
+        MYSQL_INSTANCE = mysql.createConnection(opts);
+        addConnEvent()
+        MYSQL_INSTANCE.connect();
+    }
+    return MYSQL_INSTANCE;
+}
+//关闭 mysql
+function disDefMysqlConnect() {
+    if (MYSQL_INSTANCE) {
+        if (open_pool) {
+            MYSQL_INSTANCE.end();
+        } else {
+            MYSQL_INSTANCE.end();
+        }
+        MYSQL_INSTANCE = null;
+        logger.debug('disDefMysqlConnect')
+    }
+}
 
-async function getAccountBalances(opts) {
+function getMySqlInstance() {
+    if (MYSQL_INSTANCE) return MYSQL_INSTANCE
+    return createDefMysqlConnect();
+}
+
+function addConnEvent() {
+    if (!MYSQL_INSTANCE) return
+    if (open_pool) {
+        MYSQL_INSTANCE.on('acquire', function (connection) {
+            logger.log('Connection %d acquired', connection.threadId);
+        });
+
+        MYSQL_INSTANCE.on('connection', function (connection) {
+            logger.log('mysql connection', connection.threadId);
+        });
+        MYSQL_INSTANCE.on('enqueue', function () {
+            logger.log('Waiting for available connection slot');
+        });
+
+        MYSQL_INSTANCE.on('release', function (connection) {
+            logger.log('Connection %d released', connection.threadId);
+        });
+    } else {
+        // logger.log('connected to mysql ps=', db_config.mysql)
+        MYSQL_INSTANCE.on('connect', () => {
+            logger.log('connected to mysql')
+        })
+
+        MYSQL_INSTANCE.on('error', function (err) {
+            logger.error('mysql  Error =>', err);
+        });
+
+
+        MYSQL_INSTANCE.on('restart', function () {
+            logger.error('mysql  restart =>');
+        });
+    }
+}
+
+
+async function getAccountBalances_(opts) {
     logger.log('getAccountBalances', opts)
     var sql_main = 'select * from '
-    var sql_table_name = 'company_key_manage'
+    var sql_table_name = ' user_banlance '
     var sql_where = ' WHERE '
     var sql_where_name = ' id= ? '
-    var sql_where_value = id
     var new_sql = sql_main.concat(sql_table_name, sql_where, sql_where_name);
-    var query_account_balances_sql = ""
+    var query_account_balances_sql = new_sql
+
+    var query_account_balances_params = [withdrawId]
 
+    return new Promise((resolve) => {
+        getMySqlInstance().getConnection(function (err, connection) {
+            if (err) {
+                logger.error('getAccountBalances error', err)
+                logger.error('getAccountBalances sql', create_withdraw_sql)
+                resolve(null);
+                return;
+            }
+            connection.query(
+                query_account_balances_sql, query_account_balances_params,
+                function selectCb(error, results) {
+                    if (error) {
+                        logger.error('create_collect_coins_task', error, query_account_balances_sql, query_account_balances_params)
+                        resolve(null);
+                        return;
+                    }
+                    logger.log('create_collect_coins_task ret=', error, results);
+                    //用完当前连接需要释放,归还给连接池
+                    connection.release();
+                    resolve({
+                        err: error,
+                        results: results
+                    });
+                }
+            );
+        })
+    })
 }
 
-async function getAccountTransactions(opts){
+async function getAccountTransactions_(opts) {
     logger.log('getAccountTransactions', opts)
     var sql_main = 'select * from '
-    var sql_table_name = 'company_key_manage'
+    var sql_table_name = ' user_transaction_log '
     var sql_where = ' WHERE '
-    var sql_where_name = ' id= ? '
-    var sql_where_value = id
+    var sql_where_name = ' usr_to_address=? AND block_num>=?'
+    var query_account_transactions_params = [opts.address, opts.from_block ? opts.from_block : 1]
+    if (opts.type == 'native') {
+        sql_where_name = ' usr_to_address=? AND block_num>=? AND token_address=? '
+        query_account_transactions_params = [opts.address, opts.from_block ? opts.from_block : 1, '0x0000000000000000000000000000000000000000']
+    } else if (opts.type == 'token') {
+        sql_where_name = ' usr_to_address=? AND block_num>=? AND token_address!=? '
+        query_account_transactions_params = [opts.address, opts.from_block ? opts.from_block : 1, '0x0000000000000000000000000000000000000000']
+    } else if (opts.type == 'hash') {
+        sql_where_name = ' trx_hash=? '
+        query_account_transactions_params = [opts.transaction_hash, opts.from_block ? opts.from_block : 1, '0x0000000000000000000000000000000000000000']
+    }
     var new_sql = sql_main.concat(sql_table_name, sql_where, sql_where_name);
-    var query_account_transactions_sql = ""
+    var query_account_transactions_sql = new_sql
+
+    return new Promise((resolve) => {
+        getMySqlInstance().getConnection(function (err, connection) {
+            if (err) {
+                logger.error('getAccountTransactions_', err)
+                logger.error('getAccountTransactions_', query_account_transactions_sql)
+                resolve(null);
+                return;
+            }
+            connection.query(
+                query_account_transactions_sql, query_account_transactions_params,
+                function selectCb(error, results) {
+                    if (error) {
+                        logger.error('getAccountTransactions_', error, query_account_transactions_sql, query_account_transactions_params)
+                        resolve(null);
+                        return;
+                    }
+                    //用完当前连接需要释放,归还给连接池
+                    connection.release();
+                    resolve({
+                        results: results
+                    });
+                }
+            );
+        })
+    })
+}
+
+async function getAccountBalances(opts) {
+
+}
+
+
+async function getAccountTransactions(opts) {
+    var ret = await getAccountTransactions_(opts);
+    if (ret && ret.results) {
+        if (ret.results && Array.isArray(ret.results) && ret.results.length > 0) {
+            try {
+                var results = []
+                ret.results.forEach(element => {
+                    var isNativeTrans = element.token_address == '0x0000000000000000000000000000000000000000'
+                    element.type = isNativeTrans == true ? 'native' : 'token'
+                    element.gas = element.gas.toString()
+                    element.gas_price = element.gas_price.toString()
+                    try {
+                        element.value = utils.scientificNotationToString(element.value).toString()
+                    } catch (error) {
+                        element.value = element.value.toString();
+                    }
+                    logger.log('getAccountTransactions_ element:', element)
+                    results.push({
+                        type: isNativeTrans == true ? 'native' : 'token',
+                        from_address: element.usr_from_address,
+                        to_address: element.usr_to_address,
+                        token_address: isNativeTrans == false ? element.token_address : null,
+                        block_number: element.block_num.toString(),
+                        value: element.value,
+                        gas: element.gas,
+                        gas_price: element.gas_price,
+                        block_timestamp: utils.getTimestampToDate(element.block_tm*1000),
+                        trx_hash: element.trx_hash,
+                        responseType:'yqcx'
+                    })
+                });
+                ret.results = results
+            } catch (error) {
+
+            }
+            logger.log('getAccountTransactions_ respose:', ret)
+            return {
+                code: 0,
+                data: {
+                    total: ret.results.length,
+                    results: ret.results
+                },
+                errMsg: null,
+            }
+        }
+    }
+    return {
+        code: 0,
+        data: {
+            total: 0,
+            results: []
+        },
+        errMsg: null,
+    }
 }
 
 module.exports = {

+ 1 - 1
model/db/mysql_db.js

@@ -30,7 +30,7 @@ createDefMysqlConnect();
 // 开始创建
 function createDefMysqlConnect() {
     disDefMysqlConnect();
-    logger.log('createDefMysqlConnect')
+    logger.log('createDefMysqlConnect',database)
     if (open_pool) {//创建连接池
         opts.connectionLimit = pool_size
         MYSQL_INSTANCE = mysql.createPool(opts);

+ 259 - 17
model/moralis_sdk.js

@@ -7,6 +7,7 @@ var utils = require('./utils.js');
 var { moralis_config, reids_token_config, account_config } = require('../config/config.js')
 const redis = require("./db/redis_db")  //导入 db.js
 const mysql = require("./db/mysql_db")
+const account_mysql = require("../model/db/account_info_db")  //导入 db.js
 const logger = require('./logger')
 const report = require("./report")  //导入 db.js
 const BigNumber = require('bignumber.js')
@@ -233,10 +234,10 @@ async function getAccountBalances(options) {
         try {
             if (options.type == 'native') {
                 // result = await Moralis.Web3API.account.getNativeBalance(balance_opts);
-                result = await getBalances(balance_opts,'native')
+                result = await getBalances(balance_opts, 'native')
                 logger.log('getNativeBalance=', result);
             } else {
-                result = await getBalances(balance_opts,'token')
+                result = await getBalances(balance_opts, 'token')
                 // result = await Moralis.Web3API.account.getTokenBalances(balance_opts);
                 logger.log('getTokenBalances=', result);
             }
@@ -481,7 +482,7 @@ async function updateNativeBalance(nativeBalance, obj) {
         do {
             //上面转账完 BNB 会减去,这里再获取一次
             // var native_ret = await Moralis.Web3API.account.getNativeBalance(temp);
-            var native_ret = await getBalances(balance_opts,'native');
+            var native_ret = await getBalances(balance_opts, 'native');
             logger.log('更新余额 :', nativeBalance, native_ret, retryCount)
             if (nativeBalance != native_ret.balance && BigInt(nativeBalance) < BigInt(native_ret.balance)) {
                 return native_ret.balance;
@@ -1041,7 +1042,6 @@ async function getTokenTransfers(opt) {
             try {
                 logger.log('getTokenTransfers account getTransactions>>>>>', options);
                 t_1 = await Moralis.Web3API.account.getTransactions(options);
-                // t_1 = await getTransferRecord(options, 'native');
                 logger.log('getTokenTransfers native ret -->>> t_1', t_1);
                 setTransfersDataType('native', t_1.result)
                 break
@@ -1069,8 +1069,7 @@ async function getTokenTransfers(opt) {
                     options.to_block = '10000000000'
                 }
                 logger.log('getTokenTransfers account getTokenTransfers>>>>>', options);
-                // t_2 = await Moralis.Web3API.account.getTokenTransfers(options);
-                t_2 = await getTransferRecord(options, 'token');
+                t_2 = await Moralis.Web3API.account.getTokenTransfers(options);
                 logger.log('getTokenTransfers token ret -->>> t_2', t_2);
                 setTransfersDataType('token', t_2.result)
                 break
@@ -1098,7 +1097,7 @@ async function getTokenTransfers(opt) {
             if (Array.isArray(arr1) && Array.isArray(arr)) {
                 let arr2 = arr.concat(arr1);
                 t_1.result = arr2;
-                logger.log('getTokenTransfers-->>>concat t_1', t_1,t_1.result.length);
+                logger.log('getTokenTransfers-->>>concat t_1', t_1, t_1.result.length);
                 if (t_1.total != null) {
                     t_1.total = t_1.result.length
                     logger.log('getTokenTransfers-->>>concat total', t_1.total);
@@ -1123,8 +1122,7 @@ async function getTokenTransfers(opt) {
             try {
                 logger.log('transaction_hash getTransaction options-->>> ', options);
                 //native
-                // const transaction = await Moralis.Web3API.native.getTransaction(options);
-                const transaction = await getTransferRecord(options, 'hash');
+                const transaction = await Moralis.Web3API.native.getTransaction(options);
                 var arr = [];
                 if (transaction)
                     arr.push(transaction)
@@ -1146,25 +1144,268 @@ async function getTokenTransfers(opt) {
 
 
 
+//获取交易记录
+//hash 0xe09ba3a4c9f7a8902e01af68d0f1f91906f3f7db1195227e61c45c0e86b2630a
+async function getTokenTransfersV2(opt) {
+    await initMasterSDK();
+    logger.log("fun getTokenTransfersV2 in ", opt);
+    const options = {};
+    options.type = 'all';
+    options.chain = 'bsc_mainnet';
+
+    if (opt.chain != null) {
+        options.chain = utils.getChainName(opt.chain);
+        logger.log('getTokenTransfersV2 getChainName =', options.chain);
+    }
+
+    if (opt.order != null) {
+        options.order = opt.order;
+    }
+
+    if (opt.startTime != null) {
+        options.from_date = opt.startTime;
+    }
+
+    if (opt.endTime != null) {
+        options.to_date = opt.endTime;
+    }
+
+    if (opt.from_block != null) {
+        options.from_block = opt.from_block;
+    }
+
+    if (opt.to_block != null) {
+        options.to_block = opt.to_block;
+    }
+
+    if (opt.transaction_hash) {
+        options.transaction_hash = opt.transaction_hash;
+        options.type = 'transaction_hash';
+    }
+
+
+    logger.log('getTokenTransfersV2 >>>>>', options);
+    if (options.type == 'all') {//查询主流币和 20 币所有的交易
+
+        if (opt.address != null) {
+            options.address = opt.address;
+        } else {
+            logger.error('getTokenTransfersV2 error please check address parameter is ok ?', options);
+            return toJson(ERROR_CODE_001, null, "please check address parameter is ok ?");
+        }
+
+        var t_1
+        var t_2
+
+        // Error: Request failed with status code 524
+        // 做一次重试
+        var tryCount = 4;
+        var delay = 1000
+        var interval = 500
+        do {
+            //主流币
+            try {
+                logger.log('getTokenTransfersV2 account getTransactions>>>>>', options);
+                t_1 = await getTransferRecord(options, 'native', 1);
+                logger.log('getTokenTransfersV2 native ret -->>> t_1', t_1);
+                break
+            } catch (error) {
+                if (tryCount == 1) {
+                    t_1 = await getTransferRecord(options, 'native', 0);
+                    if (t_1) {
+                        logger.error('sync-node-native-data', JSON.stringify(t_1))
+                        break
+                    } else {
+                        logger.error('sync-node-native-data error', JSON.stringify(options))
+                    }
+                    logger.error("getTokenTransfersV2 error:", '主流币:', error.toString(), JSON.stringify(options))
+                    return toJson(ERROR_CODE_001, null, error.toString());
+                }
+                tryCount -= 1;
+                await utils.sleep(delay)
+                delay += interval
+            }
+        } while (tryCount >= 1);
+
+        // Error: Request failed with status code 524
+        tryCount = 4
+        delay = 1000
+        interval = 500
+        do {
+            //20币
+            try {
+                //token 获取交易记录如果没有时间有些地址会失败
+                if (!options.to_block) {
+                    options.to_block = '10000000000'
+                }
+                logger.log('getTokenTransfersV2 account getTokenTransfers>>>>>', options);
+                t_2 = await getTransferRecord(options, 'token', 1);
+                logger.log('getTokenTransfersV2 token ret -->>> t_2', t_2);
+                break
+            } catch (error) {
+                if (tryCount == 1) {
+                    t_2 = await getTransferRecord(options, 'token', 0);
+                    if (t_2) {
+                        logger.error('sync-node-token-data', JSON.stringify(t_2))
+                        break
+                    } else {
+                        logger.error('sync-node-token-data error', JSON.stringify(options))
+                    }
+                    logger.error("getTokenTransfersV2 error:", 'token币:', error.toString(), JSON.stringify(options))
+                    return toJson(ERROR_CODE_001, null, error.toString());
+                }
+                tryCount -= 1;
+                await utils.sleep(delay)
+                delay += interval
+            }
+        } while (tryCount >= 1);
+
+        //异常
+        if (t_2 && t_2.data.total > 0 && Array.isArray(t_2.data.results) && t_2.data.results.length <= 0) {
+            logger.error('getTokenTransfersV2 token 数据异常 -->>>', t_2.toString(), JSON.stringify(options));
+            return toJson(ERROR_CODE_001, null, 'token 数据异常.');
+        }
+
+        //排序组合
+        try {
+            let arr = t_1.data.results;
+            let arr1 = t_2.data.results;
+            if (Array.isArray(arr1) && Array.isArray(arr)) {
+                let arr2 = arr.concat(arr1);
+                t_1.data.results = arr2;
+                logger.log('getTokenTransfersV2-->>>concat t_1', t_1, t_1.data.results.length);
+                if (t_1.data.total != null) {
+                    t_1.data.total = t_1.data.results.length
+                    logger.log('getTokenTransfersV2-->>>concat total', t_1.data.total);
+                }
+            }
+
+            //将结果排序
+            t_1.data.results.sort((a, b) => {
+                let t1 = new Date(Date.parse(a.block_timestamp))
+                let t2 = new Date(Date.parse(b.block_timestamp))
+                return t2.getTime() - t1.getTime()
+            })
+            logger.log('getTokenTransfersV2-->>> sort t_1', t_1);
+            return toJson(SUCCEED_CODE, t_1.data, null);
+        } catch (error) {
+            logger.error("getTokenTransfersV2 排序组合 error :", error.toString(), JSON.stringify(options), JSON.stringify(t_1), JSON.stringify(t_2))
+            return toJson(ERROR_CODE_001, null, error.toString());
+        }
+    } else if (options.type == 'transaction_hash') {//根据哈希查询
+        var tryCount = 2
+        do {
+            try {
+                logger.log('getTokenTransfersV2 getTransaction options-->>> ', options);
+                const transaction = await getTransferRecord(options, 'hash', 1);
+                logger.log('getTokenTransfersV2 getTransaction ret-->>> ', transaction);
+                return transaction;
+            } catch (error) {
+                if (tryCount == 1) {
+                    logger.error("native getTokenTransfersV2 error:", error.toString(), JSON.stringify(options))
+                    var transaction = await getTransferRecord(options, 'hash', 0);
+                    if (transaction) {
+                        logger.error('sync-node-hash-data', JSON.stringify(transaction))
+                        logger.log('getTokenTransfersV2 getTransaction ret-->>> ', transaction);
+                        return transaction;
+                    }
+                    return toJson(ERROR_CODE_001, null, error.toString());
+                }
+                tryCount -= 1;
+            }
+        } while (tryCount >= 1);
+    } else {
+        return toJson(ERROR_CODE_001, null, "This type is not supported.");;
+    }
+}
+
+
+
 /**
  * 获取交易记录 token,native 
  * @param {} opts 
  */
-async function getTransferRecord(opts, type) {
-    logger.info('getTransferRecord>>>>>>>>',opts,type)
+async function getTransferRecord(opts, type, use_moralis_sdk_) {
+    logger.info('getTransferRecord>>>>>>>>', opts, type)
     //是否使用 moralis sdk 进行查询
-    var use_moralis_sdk = 1
+    var use_moralis_sdk = use_moralis_sdk_
     var temp_opts = { ...opts }
     if (use_moralis_sdk) {
+        var results = []
         if (type == 'native') {
-            return await Moralis.Web3API.account.getTransactions(temp_opts)
+            var ret = await Moralis.Web3API.account.getTransactions(temp_opts)
+            if (ret.total > 0 && Array.isArray(ret.result) && ret.result.length > 0) {
+                for (let index = 0; index < ret.result.length; index++) {
+                    const element = ret.result[index];
+                    results.push({
+                        type: 'native',
+                        from_address: element.from_address,
+                        to_address: element.to_address,
+                        token_address: null,
+                        block_number: element.block_number,
+                        value: element.value,
+                        gas: element.gas,
+                        gas_price: element.gas_price,
+                        block_timestamp: element.block_timestamp,
+                        trx_hash: element.hash,
+                        responseType:'moralis'
+                    })
+                }
+            }
         } else if (type == 'token') {
-            return await Moralis.Web3API.account.getTokenTransfers(temp_opts);
+            var ret = await Moralis.Web3API.account.getTokenTransfers(temp_opts);
+            if (ret.total > 0 && Array.isArray(ret.result) && ret.result.length > 0) {
+                for (let index = 0; index < ret.result.length; index++) {
+                    const element = ret.result[index];
+                    results.push({
+                        type: 'token',
+                        from_address: element.from_address,
+                        to_address: element.to_address,
+                        token_address: element.address,
+                        block_number: element.block_number,
+                        value: element.value,
+                        block_timestamp: element.block_timestamp,
+                        trx_hash: element.transaction_hash,
+                        responseType:'moralis'
+                    })
+                }
+            }
         } else if (type == 'hash') {
-            return await Moralis.Web3API.native.getTransaction(temp_opts);
+            var ret = await Moralis.Web3API.native.getTransaction(temp_opts);
+            if (ret)
+                results.push({
+                    type: 'hash',
+                    from_address: ret.from_address,
+                    to_address: ret.to_address,
+                    token_address: null,
+                    block_number: ret.block_number,
+                    value: ret.value,
+                    gas: ret.gas,
+                    gas_price: ret.gas_price,
+                    block_timestamp: ret.block_timestamp,
+                    trx_hash: ret.hash,
+                    responseType:'moralis'
+                })
+        }
+        return {
+            code: 0,
+            data: {
+                total: results.length,
+                results: results
+            },
+            errMsg: null,
         }
     } else { //使用自建节点缓存 mysql 查询
-
+        if (type == 'native') {
+            temp_opts.type = 'native'
+            return await account_mysql.getAccountTransactions(temp_opts)
+        } else if (type == 'token') {
+            temp_opts.type = 'token'
+            return await account_mysql.getAccountTransactions(temp_opts)
+        } else if (type == 'hash') {
+            temp_opts.type = 'hash'
+            return await account_mysql.getAccountTransactions(temp_opts)
+        }
     }
 }
 
@@ -1173,7 +1414,7 @@ async function getTransferRecord(opts, type) {
  * @param {*} opts 
  */
 async function getBalances(opts, type) {
-    logger.info('getBalances>>>>>>>>',opts,type)
+    logger.info('getBalances>>>>>>>>', opts, type)
     //是否使用 moralis sdk 进行查询
     var use_moralis_sdk = 1
     var temp_opts = { ...opts }
@@ -1192,6 +1433,7 @@ async function getBalances(opts, type) {
 module.exports = {
     transfer,
     getTokenTransfers,
+    getTokenTransfersV2,
     toJson,
     getAllTokenWithdrawInfoLists,
     getAllTotkenPrice,

+ 35 - 7
model/utils.js

@@ -129,16 +129,42 @@ function getTimestamp() {
 
 function getCurrentDate() {
     return chinaTime('YYYY-MM-DD HH:mm:ss');
-    // return moment().locale('zh-cn').format();
-
-    // var now = new Date(getTimestamp()),
-    //     y = now.getFullYear(),
-    //     m = now.getMonth() + 1,
-    //     d = now.getDate();
-    // return y + '-' + (m < 10 ? '0' + m : m) + '-' + (d < 10 ? '0' + d : d) + ' ' + now.toTimeString().substr(0, 8);
 }
 
+function getTimestampToDate(tm)
+{
+        var now = new Date(tm),
+        y = now.getFullYear(),
+        m = now.getMonth() + 1,
+        d = now.getDate();
+    return y + '-' + (m < 10 ? '0' + m : m) + '-' + (d < 10 ? '0' + d : d) + 'T' + now.toTimeString().substr(0, 8)+'.000Z';
+}
 
+/**
+ * @description 科学计数法转为string
+ * @param {string, number} param
+ */
+function scientificNotationToString(param) {
+    let strParam = String(param)
+    let flag = /e/.test(strParam)
+    if (!flag) return param
+
+    // 指数符号 true: 正,false: 负
+    let sysbol = true
+    if (/e-/.test(strParam)) {
+        sysbol = false
+    }
+    // 指数
+    let index = Number(strParam.match(/\d+$/)[0])
+    // 基数
+    let basis = strParam.match(/^[\d\.]+/)[0].replace(/\./, '')
+
+    if (sysbol) {
+        return basis.padEnd(index + 1, 0)
+    } else {
+        return basis.padStart(index + basis.length, 0).replace(/^0/, '0.')
+    }
+}
 
 module.exports = {
     toJson,
@@ -153,4 +179,6 @@ module.exports = {
     getTimestamp,
     getChainIdToName,
     getCurrentDate,
+    scientificNotationToString,
+    getTimestampToDate,
 }

+ 53 - 0
routes/sdk.js

@@ -76,6 +76,58 @@ async function getTransfers(ctx) {
 
 
 
+/**
+ * 获取交易记录
+ * @param {*} ctx 
+ */
+ async function getTransfersV2(ctx) {
+    const obj = ctx.request.body;
+    console.log("getTransfers body", obj);
+    if (!obj.chain)//默认 bsc 币安链
+        obj.chain = 'bsc_mainnet'
+    var temp_obj = { ...obj }
+    var index = 0
+
+    await moralis.getTokenTransfersV2(obj).then((result) => {
+        logger.log('getTokenTransfersV2 response', 'index=' + index, result)
+        ctx.body = result;
+        if (result) {
+            //提交归集任务 native 能获取到 gas 、token 无法获取到 gas 费
+            try {
+                if (temp_obj.address && moralis.isTransferSucceed(result)) {
+                    var log_obj = { ...obj }
+                    log_obj.results = result
+                    log_obj.type = report.REPORT_TYPE.transfer_record
+                    //埋点日志上报-入金检查
+                    report.logReport(log_obj)
+                    
+                    var json_obj = JSON.parse(result);
+                    //缓存当前交易的 gas 费用
+                    var tr = moralis.getTransferRecordGasFree('native', json_obj, temp_obj.address)
+                    logger.log('getTransferRecordGasFree:', tr, temp_obj.address)
+                    if (tr && tr.totalGasFree > 0) {
+                        logger.log('getTransferRecordGasFree redis_set LAST_TOTAL_BNB_FREE:', tr.totalGasFree.toString())
+                        logger.log('getTransferRecordGasFree redis_set LAST_TOTAL_TOKEN_FREE:', (parseInt(tr.totalGasFree) * parseInt(account_config.TOKEN_GAS_LIMIT)).toString())
+                        redis.redis_set(reids_token_config.LAST_TOTAL_BNB_FREE, tr.totalGasFree.toString());
+                        redis.redis_set(reids_token_config.LAST_TOTAL_TOKEN_FREE, (parseInt(tr.gas_price) * parseInt(account_config.TOKEN_GAS_LIMIT)).toString());
+                    }
+
+                    if (json_obj.data.total > 0) {
+                        //提交归集任务
+                        if (temp_obj.address) {
+                            logger.log('pushCollectConisObj>>>', temp_obj.address)
+                            redis.redis_push(reids_token_config.COLLECT_CONIS_QUEUE_KEY, JSON.stringify(temp_obj))
+                        }
+                    }
+                }
+            } catch (error) {
+                console.error('pushCollectConisObj error=', error)
+            }
+        }
+    })
+}
+
+
 async function getAllTokenWithdrawInfoLists(ctx) {
     if (ctx.request == null || ctx.request.body == null) {
         ctx.body = utils.toJson(-1, null, "request error. ");
@@ -441,6 +493,7 @@ async function getWithdrawStatus(ctx) {
 
 //获取交易记录
 router.post('/getTransfers', getTransfers)
+router.post('/getTransfersV2', getTransfersV2)
 // 获取所有代币价格
 router.post('/getAllTotkenPrice', getAllTotkenPrice)
 

+ 13 - 0
test/accout_info_db_test.js

@@ -0,0 +1,13 @@
+const router = require('koa-router')() //导入 koa-router
+const redis = require("../model/db/redis_db")  //导入 db.js
+const mysql = require("../model/db/account_info_db")  //导入 db.js
+const logger = require('../model/logger')
+const BigNumber = require('bignumber.js')
+var moralis = require('../model/moralis_sdk.js')
+router.prefix('/test/account/');
+
+router.post('/getAccountTransactions', async (ctx) => {
+    ctx.body = await moralis.getTokenTransfersV2(ctx.request.body)
+})
+module.exports = router
+