mirror of
https://github.com/arnaucube/goBlockchainDataAnalysis.git
synced 2026-02-06 19:26:41 +01:00
implemented getLast24HourAnalysis, to show the Tx/Hour of the last 24 hours
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -15,6 +15,6 @@
|
||||
|
||||
|
||||
/*.conf
|
||||
/*.json
|
||||
config.json
|
||||
*.mp4
|
||||
logs
|
||||
|
||||
@@ -33,3 +33,7 @@ other
|
||||
BlockHeight string `json:"blockheight"`
|
||||
}
|
||||
```
|
||||
|
||||
- mantain connection with wallet using websockets
|
||||
|
||||
- add 24h to hour analysis, to show also hours with 0 transactions
|
||||
|
||||
22
configEXAMPLE.json
Normal file
22
configEXAMPLE.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"user": "faircoinrpc",
|
||||
"pass": "password",
|
||||
"host": "127.0.0.1",
|
||||
"port": "3021",
|
||||
"genesisTx": "7c27ade2c28e67ed3077f8f77b8ea6d36d4f5eba04c099be3c9faa9a4a04c046",
|
||||
"genesisBlock": "beed44fa5e96150d95d56ebd5d2625781825a9407a5215dd7eda723373a0a1d7",
|
||||
"startFromBlock": 0,
|
||||
"server": {
|
||||
"serverIP": "127.0.0.1",
|
||||
"serverPort": "3014",
|
||||
"webServerPort": "8080",
|
||||
"allowedIPs": [
|
||||
"127.0.0.1"
|
||||
],
|
||||
"blockedIPs": []
|
||||
},
|
||||
"mongodb": {
|
||||
"ip": "127.0.0.1",
|
||||
"database": "goBlockchainDataAnalysis"
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,21 @@ import (
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
)
|
||||
|
||||
func decomposeDate(blockTime int64) (int, int, int, int) {
|
||||
/*i, err := strconv.ParseInt(blockTime, 10, 64)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}*/
|
||||
i := blockTime
|
||||
year := time.Unix(i, 0).Year()
|
||||
month := time.Unix(i, 0).Month()
|
||||
day := time.Unix(i, 0).Day()
|
||||
hour := time.Unix(i, 0).Hour()
|
||||
return year, int(month), day, hour
|
||||
}
|
||||
func unixTimeToTime(blockTime int64) time.Time {
|
||||
return time.Unix(blockTime, 0)
|
||||
}
|
||||
func timeToDate(blockTime int64) string {
|
||||
stringTime := strconv.FormatInt(blockTime, 10)
|
||||
i, err := strconv.ParseInt(stringTime, 10, 64)
|
||||
|
||||
@@ -37,6 +37,8 @@ func explore(client *btcrpcclient.Client, blockHash string) {
|
||||
newBlock.PreviousHash = block.PreviousHash
|
||||
newBlock.NextHash = block.NextHash
|
||||
newBlock.Time = block.Time
|
||||
newBlock.DateT = unixTimeToTime(block.Time)
|
||||
newBlock.Date.Year, newBlock.Date.Month, newBlock.Date.Day, newBlock.Date.Hour = decomposeDate(block.Time)
|
||||
|
||||
for k, txHash := range block.Tx {
|
||||
if k > 0 {
|
||||
@@ -53,7 +55,7 @@ func explore(client *btcrpcclient.Client, blockHash string) {
|
||||
blockTx, err := client.GetRawTransactionVerbose(th)
|
||||
check(err)
|
||||
|
||||
//save Tx
|
||||
//save Tx Node
|
||||
var nodeTx NodeModel
|
||||
nodeTx.Id = txHash
|
||||
nodeTx.Label = txHash
|
||||
@@ -105,6 +107,8 @@ func explore(client *btcrpcclient.Client, blockHash string) {
|
||||
newTx.BlockHash = block.Hash
|
||||
newTx.BlockHeight = strconv.FormatInt(block.Height, 10)
|
||||
newTx.Time = blockTx.Time
|
||||
newTx.DateT = unixTimeToTime(block.Time)
|
||||
newTx.Date.Year, newTx.Date.Month, newTx.Date.Day, newTx.Date.Hour = decomposeDate(block.Time)
|
||||
for _, originAddr := range txVi.Vout[Vi.Vout].ScriptPubKey.Addresses {
|
||||
originAddresses = append(originAddresses, originAddr)
|
||||
|
||||
|
||||
Binary file not shown.
@@ -1,32 +0,0 @@
|
||||
# Instructions
|
||||
|
||||
#### Install FairCoin Wallet and configure
|
||||
now, need to configure wallet:
|
||||
.FairCoin/
|
||||
FairCoin.conf
|
||||
|
||||
```
|
||||
rpcuser=usernamerpc
|
||||
rpcpassword=password
|
||||
rpcport=3021
|
||||
rpcworkqueue=2000
|
||||
server=1
|
||||
rpcbind=127.0.0.1
|
||||
rpcallowip=127.0.0.1
|
||||
```
|
||||
|
||||
execute wallet:
|
||||
./faircoind -txindex -reindex-chainstate
|
||||
|
||||
### Configure
|
||||
|
||||
```json
|
||||
{
|
||||
"user": "usernamerpc",
|
||||
"pass": "password",
|
||||
"host": "127.0.0.1",
|
||||
"port": "3021",
|
||||
"genesisTx": "7c27ade2c28e67ed3077f8f77b8ea6d36d4f5eba04c099be3c9faa9a4a04c046",
|
||||
"genesisBlock": "beed44fa5e96150d95d56ebd5d2625781825a9407a5215dd7eda723373a0a1d7"
|
||||
}
|
||||
```
|
||||
@@ -1,29 +1,32 @@
|
||||
package main
|
||||
|
||||
import "time"
|
||||
|
||||
type AddressModel struct {
|
||||
Hash string `json:"hash"`
|
||||
Amount float64 `json:"amount"`
|
||||
InBittrex bool `json:"inbittrex"`
|
||||
}
|
||||
type DateModel struct {
|
||||
Hour string `json:"hour"`
|
||||
Day string `json:"day"`
|
||||
Month string `json:"month"`
|
||||
Amount float64 `json:"amount"`
|
||||
Hour int `json:"hour"`
|
||||
Day int `json:"day"`
|
||||
Month int `json:"month"`
|
||||
Year int `json:"year"`
|
||||
/*Amount float64 `json:"amount"`
|
||||
BlockHash string `json:"blockhash"`
|
||||
BlockHeight string `json:"blockheight"`
|
||||
BlockHeight string `json:"blockheight"`*/
|
||||
}
|
||||
type TxModel struct {
|
||||
Hex string `json:"hex"`
|
||||
Txid string `json:"txid"`
|
||||
Hash string `json:"hash"`
|
||||
From string `json:"from"` //hash of address
|
||||
To string `json:"to"` //hash of address
|
||||
Amount float64 `json:"amount"`
|
||||
BlockHash string `json:"blockhash"`
|
||||
BlockHeight string `json:"blockheight"`
|
||||
Time int64 `json:"time"`
|
||||
DateF string `json:"datef"` //date formated
|
||||
Hex string `json:"hex"`
|
||||
Txid string `json:"txid"`
|
||||
Hash string `json:"hash"`
|
||||
From string `json:"from"` //hash of address
|
||||
To string `json:"to"` //hash of address
|
||||
Amount float64 `json:"amount"`
|
||||
BlockHash string `json:"blockhash"`
|
||||
BlockHeight string `json:"blockheight"`
|
||||
Time int64 `json:"time"`
|
||||
DateT time.Time `json:"datef"` //date formated
|
||||
Date DateModel
|
||||
}
|
||||
type BlockModel struct {
|
||||
@@ -33,11 +36,11 @@ type BlockModel struct {
|
||||
Height int64 `json:"height"`
|
||||
//Amount float64 `json:"amount"`
|
||||
//Fee float64 `json:"fee"`
|
||||
Tx []string `json:"txid"` //txid of the TxModel
|
||||
PreviousHash string `json:"previoushash"`
|
||||
NextHash string `json:"nexthash"`
|
||||
Time int64 `json:"time"`
|
||||
DateF string `json:"datef"` //date formated
|
||||
Tx []string `json:"txid"` //txid of the TxModel
|
||||
PreviousHash string `json:"previoushash"`
|
||||
NextHash string `json:"nexthash"`
|
||||
Time int64 `json:"time"`
|
||||
DateT time.Time `json:"datef"` //date formated
|
||||
Date DateModel
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
|
||||
@@ -57,10 +59,16 @@ var routes = Routes{
|
||||
NetworkMap,
|
||||
},
|
||||
Route{
|
||||
"GetHourAnalysis",
|
||||
"GetTotalHourAnalysis",
|
||||
"Get",
|
||||
"/houranalysis",
|
||||
GetHourAnalysis,
|
||||
"/totalhouranalysis",
|
||||
GetTotalHourAnalysis,
|
||||
},
|
||||
Route{
|
||||
"GetLast24HourAnalysis",
|
||||
"Get",
|
||||
"/last24hour",
|
||||
GetLast24HourAnalysis,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -199,44 +207,7 @@ func NetworkMap(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintln(w, string(jNetwork))
|
||||
}
|
||||
|
||||
/*
|
||||
func SelectItem(w http.ResponseWriter, r *http.Request) {
|
||||
ipFilter(w, r)
|
||||
vars := mux.Vars(r)
|
||||
userid := vars["userid"]
|
||||
itemid := vars["itemid"]
|
||||
//find item
|
||||
item, err := getItemById(itemid)
|
||||
if err != nil {
|
||||
fmt.Fprintln(w, "item "+itemid+" not found")
|
||||
}
|
||||
|
||||
//find user
|
||||
user, err := getUserById(userid)
|
||||
if err != nil {
|
||||
fmt.Fprintln(w, "user "+userid+" not found")
|
||||
}
|
||||
|
||||
//increase TActed in item
|
||||
item.TActed = item.TActed + 1
|
||||
|
||||
//save item
|
||||
item, err = updateItem(item)
|
||||
check(err)
|
||||
fmt.Println(item)
|
||||
|
||||
//add item to []Actions of user
|
||||
user.Actions = append(user.Actions, itemid)
|
||||
|
||||
//save user
|
||||
user, err = updateUser(user)
|
||||
check(err)
|
||||
fmt.Println(user)
|
||||
|
||||
fmt.Fprintln(w, "user: "+userid+", selects item: "+itemid)
|
||||
}
|
||||
*/
|
||||
func GetHourAnalysis(w http.ResponseWriter, r *http.Request) {
|
||||
func GetTotalHourAnalysis(w http.ResponseWriter, r *http.Request) {
|
||||
ipFilter(w, r)
|
||||
|
||||
hourAnalysis := []HourCountModel{}
|
||||
@@ -259,3 +230,43 @@ func GetHourAnalysis(w http.ResponseWriter, r *http.Request) {
|
||||
check(err)
|
||||
fmt.Fprintln(w, string(jsonResp))
|
||||
}
|
||||
|
||||
func GetLast24HourAnalysis(w http.ResponseWriter, r *http.Request) {
|
||||
ipFilter(w, r)
|
||||
|
||||
fromDate := time.Now().AddDate(0, 0, -1)
|
||||
toDate := time.Now()
|
||||
|
||||
txs := []TxModel{}
|
||||
err := txCollection.Find(bson.M{
|
||||
"datet": bson.M{
|
||||
"$gt": fromDate,
|
||||
"$lt": toDate,
|
||||
},
|
||||
}).Sort("-$natural").All(&txs)
|
||||
check(err)
|
||||
|
||||
hourFrequencies := make(map[int]int)
|
||||
for _, tx := range txs {
|
||||
hourFrequencies[tx.Date.Hour]++
|
||||
}
|
||||
var hourCount []HourCountModel
|
||||
for hour, frequency := range hourFrequencies {
|
||||
hourCount = append(hourCount, HourCountModel{strconv.Itoa(hour), frequency})
|
||||
}
|
||||
//sort by hour
|
||||
sort.Slice(hourCount, func(i, j int) bool {
|
||||
return hourCount[i].Hour < hourCount[j].Hour
|
||||
})
|
||||
|
||||
var resp HourAnalysisResp
|
||||
for _, d := range hourCount {
|
||||
resp.Labels = append(resp.Labels, d.Hour)
|
||||
resp.Data = append(resp.Data, d.Count)
|
||||
}
|
||||
|
||||
//convert []resp struct to json
|
||||
jsonResp, err := json.Marshal(resp)
|
||||
check(err)
|
||||
fmt.Fprintln(w, string(jsonResp))
|
||||
}
|
||||
|
||||
BIN
web/img/favicon.png
Normal file
BIN
web/img/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -6,6 +6,8 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>goBlockchainDataAnalysis</title>
|
||||
|
||||
<link rel="icon" type="image/png" href="img/favicon.png">
|
||||
|
||||
<link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Open+Sans:400,700'>
|
||||
<!-- Material Design fonts -->
|
||||
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700">
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="col-md-6">
|
||||
<div class="panel-heading c_blueGrey300">
|
||||
<h3 class="panel-title">Tx for each Hour</h3>
|
||||
<h3 class="panel-title">All time Tx/Hour</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<canvas id="bar" class="chart chart-bar" chart-data="data" chart-labels="labels">
|
||||
<canvas id="line" class="chart chart-line" chart-data="totalhour.data" chart-labels="totalhour.labels">
|
||||
</canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="panel-heading c_blueGrey300">
|
||||
<h3 class="panel-title">Last 24 hours Tx/Hour</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<canvas id="line" class="chart chart-line" chart-data="last24hour.data" chart-labels="last24hour.labels">
|
||||
</canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,18 +10,35 @@ angular.module('app.dateAnalysis', ['ngRoute', 'chart.js'])
|
||||
}])
|
||||
|
||||
.controller('DateAnalysisCtrl', function($scope, $http, $routeParams) {
|
||||
$scope.data=[];
|
||||
$scope.labels=[];
|
||||
$scope.totalhour={
|
||||
data: [],
|
||||
labels: []
|
||||
};
|
||||
|
||||
$http.get(urlapi + 'houranalysis')
|
||||
$http.get(urlapi + 'totalhouranalysis')
|
||||
.then(function(data, status, headers, config) {
|
||||
console.log('data success');
|
||||
console.log(data);
|
||||
|
||||
$scope.data = data.data.data;
|
||||
$scope.labels=data.data.labels;
|
||||
$scope.totalhour.data = data.data.data;
|
||||
$scope.totalhour.labels=data.data.labels;
|
||||
}, function(data, status, headers, config) {
|
||||
console.log('data error');
|
||||
});
|
||||
|
||||
//date analysis
|
||||
$scope.last24hour= {
|
||||
data:[],
|
||||
labels: []
|
||||
};
|
||||
$http.get(urlapi + 'last24hour')
|
||||
.then(function(data, status, headers, config) {
|
||||
console.log('data success');
|
||||
console.log(data);
|
||||
|
||||
$scope.last24hour.data = data.data.data;
|
||||
$scope.last24hour.labels = data.data.labels;
|
||||
}, function(data, status, headers, config) {
|
||||
console.log('data error');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div class="panel-heading c_blueGrey300">
|
||||
<h3 class="panel-title">Tx/Hour</h3>
|
||||
<h3 class="panel-title">Last 24 hours Tx/Hour</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<canvas id="line" class="chart chart-line" chart-data="data" chart-labels="labels">
|
||||
|
||||
@@ -37,7 +37,7 @@ angular.module('app.main', ['ngRoute'])
|
||||
//date analysis
|
||||
$scope.data = [];
|
||||
$scope.labels = [];
|
||||
$http.get(urlapi + 'houranalysis')
|
||||
$http.get(urlapi + 'last24hour')
|
||||
.then(function(data, status, headers, config) {
|
||||
console.log('data success');
|
||||
console.log(data);
|
||||
|
||||
Reference in New Issue
Block a user