date and hour analysis added
arnaucode idoctnef@openmailbox.org
Sat, 29 Jul 2017 16:08:10 +0200
13 files changed,
231 insertions(+),
67 deletions(-)
A
dateAnalysis.go
@@ -0,0 +1,64 @@
+package main + +import ( + "fmt" + "strconv" + "strings" + "time" + + "gopkg.in/mgo.v2/bson" +) + +func timeToDate(blockTime int64) string { + stringTime := strconv.FormatInt(blockTime, 10) + i, err := strconv.ParseInt(stringTime, 10, 64) + if err != nil { + panic(err) + } + tm := time.Unix(i, 0) + fmt.Println(tm) + stringDate := tm.String() + fmt.Println(stringDate) + return stringDate +} +func hourAnalysis(e EdgeModel, blockTime int64) { + fmt.Println(blockTime) + date := timeToDate(blockTime) + date_hour := strings.Split(date, " ")[1] + hour := strings.Split(date_hour, ":")[0] + + hourCount := HourCountModel{} + err := hourCountCollection.Find(bson.M{"hour": hour}).One(&hourCount) + if err != nil { + //date not yet in DB + var hourCount HourCountModel + hourCount.Hour = hour + hourCount.Count = 1 + err = hourCountCollection.Insert(hourCount) + check(err) + } else { + hourCount.Count++ + err = hourCountCollection.Update(bson.M{"hour": hour}, &hourCount) + check(err) + } +} +func dateAnalysis(e EdgeModel, blockTime int64) { + fmt.Println(blockTime) + date := timeToDate(blockTime) + + dateCount := DateCountModel{} + err := dateCountCollection.Find(bson.M{"date": date}).One(&dateCount) + if err != nil { + //date not yet in DB + var dateCount DateCountModel + dateCount.Date = date + dateCount.Time = blockTime + dateCount.Count = 1 + err = dateCountCollection.Insert(dateCount) + check(err) + } else { + dateCount.Count++ + err = dateCountCollection.Update(bson.M{"date": date}, &dateCount) + check(err) + } +}
M
exploreBlockchain.go
→
exploreBlockchain.go
@@ -26,80 +26,84 @@ check(err)
block, err := client.GetBlockVerbose(bh) check(err) - //if len(block.Tx) < 10 { - for k, txHash := range block.Tx { - if k > 0 { - realBlocks++ - fmt.Print("Block Height: ") - fmt.Print(block.Height) - fmt.Print(", num of Tx: ") - fmt.Print(k) - fmt.Print("/") - fmt.Println(len(block.Tx) - 1) + if block.Height > 160 { + for k, txHash := range block.Tx { + if k > 0 { + realBlocks++ + fmt.Print("Block Height: ") + fmt.Print(block.Height) + fmt.Print(", num of Tx: ") + fmt.Print(k) + fmt.Print("/") + fmt.Println(len(block.Tx) - 1) - th, err := chainhash.NewHashFromStr(txHash) - check(err) - tx, err := client.GetRawTransactionVerbose(th) - check(err) - - var originAddresses []string - var outputAddresses []string - for _, Vo := range tx.Vout { - //if Vo.Value > 0 { - for _, outputAddr := range Vo.ScriptPubKey.Addresses { - outputAddresses = append(outputAddresses, outputAddr) - var n2 NodeModel - n2.Id = outputAddr - n2.Label = outputAddr - n2.Title = outputAddr - n2.Group = strconv.FormatInt(block.Height, 10) - n2.Value = 1 - n2.Shape = "dot" - saveNode(nodeCollection, n2) - } - //} - } - for _, Vi := range tx.Vin { - th, err := chainhash.NewHashFromStr(Vi.Txid) + th, err := chainhash.NewHashFromStr(txHash) check(err) - txVi, err := client.GetRawTransactionVerbose(th) + tx, err := client.GetRawTransactionVerbose(th) check(err) - if len(txVi.Vout[Vi.Vout].ScriptPubKey.Addresses) > 0 { - for _, originAddr := range txVi.Vout[Vi.Vout].ScriptPubKey.Addresses { - originAddresses = append(originAddresses, originAddr) - var n1 NodeModel - n1.Id = originAddr - n1.Label = originAddr - n1.Title = originAddr - n1.Group = string(block.Height) - n1.Value = 1 - n1.Shape = "dot" - saveNode(nodeCollection, n1) - for _, outputAddr := range outputAddresses { - var e EdgeModel - e.From = originAddr - e.To = outputAddr - e.Label = txVi.Vout[Vi.Vout].Value - e.Txid = tx.Txid - e.Arrows = "to" - e.BlockHeight = block.Height - saveEdge(edgeCollection, e) - //fmt.Println(e) - } + var originAddresses []string + var outputAddresses []string + for _, Vo := range tx.Vout { + //if Vo.Value > 0 { + for _, outputAddr := range Vo.ScriptPubKey.Addresses { + outputAddresses = append(outputAddresses, outputAddr) + var n2 NodeModel + n2.Id = outputAddr + n2.Label = outputAddr + n2.Title = outputAddr + n2.Group = strconv.FormatInt(block.Height, 10) + n2.Value = 1 + n2.Shape = "dot" + saveNode(nodeCollection, n2) } - } else { - originAddresses = append(originAddresses, "origin") + //} } + for _, Vi := range tx.Vin { + th, err := chainhash.NewHashFromStr(Vi.Txid) + check(err) + txVi, err := client.GetRawTransactionVerbose(th) + check(err) + if len(txVi.Vout[Vi.Vout].ScriptPubKey.Addresses) > 0 { + for _, originAddr := range txVi.Vout[Vi.Vout].ScriptPubKey.Addresses { + originAddresses = append(originAddresses, originAddr) + var n1 NodeModel + n1.Id = originAddr + n1.Label = originAddr + n1.Title = originAddr + n1.Group = string(block.Height) + n1.Value = 1 + n1.Shape = "dot" + saveNode(nodeCollection, n1) + for _, outputAddr := range outputAddresses { + var e EdgeModel + e.From = originAddr + e.To = outputAddr + e.Label = txVi.Vout[Vi.Vout].Value + e.Txid = tx.Txid + e.Arrows = "to" + e.BlockHeight = block.Height + saveEdge(edgeCollection, e) + + //date analysis + //dateAnalysis(e, tx.Time) + //hour analysis + hourAnalysis(e, tx.Time) + } + } + } else { + originAddresses = append(originAddresses, "origin") + } + + } + fmt.Print("originAddresses: ") + fmt.Println(len(originAddresses)) + fmt.Print("outputAddresses: ") + fmt.Println(len(outputAddresses)) } - fmt.Print("originAddresses: ") - fmt.Println(len(originAddresses)) - fmt.Print("outputAddresses: ") - fmt.Println(len(outputAddresses)) } } - //} //set the next block blockHash = block.NextHash }
M
main.go
→
main.go
@@ -16,6 +16,8 @@
var blockCollection *mgo.Collection var nodeCollection *mgo.Collection var edgeCollection *mgo.Collection +var dateCountCollection *mgo.Collection +var hourCountCollection *mgo.Collection func main() { //read goBlockchainDataAbalysis config@@ -28,6 +30,8 @@ check(err)
blockCollection = getCollection(session, "blocks") nodeCollection = getCollection(session, "nodes") edgeCollection = getCollection(session, "edges") + dateCountCollection = getCollection(session, "dateCounts") + hourCountCollection = getCollection(session, "hourCounts") // create new client instance client, err := btcrpcclient.New(&btcrpcclient.ConnConfig{
M
mongoModels.go
→
mongoModels.go
@@ -53,3 +53,17 @@ type SankeyModel struct {
Nodes []SankeyNodeModel `json:"nodes"` Links []SankeyLinkModel `json:"links"` } + +type HourCountModel struct { + Hour string `json:"hour"` + Count int `json:"count"` +} +type HourAnalysisResp struct { + Labels []string `json:"labels"` + Data []int `json:"data"` +} +type DateCountModel struct { + Time int64 `json:"time"` + Date string `json:"date"` + Count int `json:"count"` +}
M
serverRoutes.go
→
serverRoutes.go
@@ -4,6 +4,7 @@ import (
"encoding/json" "fmt" "net/http" + "sort" "gopkg.in/mgo.v2/bson"@@ -42,6 +43,12 @@ "NetworkMap",
"Get", "/map", NetworkMap, + }, + Route{ + "GetHourAnalysis", + "Get", + "/houranalysis", + GetHourAnalysis, }, /* Route{@@ -200,3 +207,26 @@
fmt.Fprintln(w, "user: "+userid+", selects item: "+itemid) } */ +func GetHourAnalysis(w http.ResponseWriter, r *http.Request) { + ipFilter(w, r) + + hourAnalysis := []HourCountModel{} + iter := hourCountCollection.Find(bson.M{}).Limit(10000).Iter() + err := iter.All(&hourAnalysis) + + //sort by hour + sort.Slice(hourAnalysis, func(i, j int) bool { + return hourAnalysis[i].Hour < hourAnalysis[j].Hour + }) + + var resp HourAnalysisResp + for _, d := range hourAnalysis { + 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)) +}
M
web/app.js
→
web/app.js
@@ -12,7 +12,8 @@ 'app.navbar',
'app.main', 'app.network', 'app.addressNetwork', - 'app.sankey' + 'app.sankey', + 'app.dateAnalysis' ]). config(['$locationProvider', '$routeProvider', function($locationProvider, $routeProvider) { $locationProvider.hashPrefix('!');
M
web/index.html
→
web/index.html
@@ -95,6 +95,7 @@ <script src="views/main/main.js"></script>
<script src="views/network/network.js"></script> <script src="views/addressNetwork/addressNetwork.js"></script> <script src="views/sankey/sankey.js"></script> + <script src="views/dateAnalysis/dateAnalysis.js"></script> </body> </html>
A
web/views/dateAnalysis/dateAnalysis.html
@@ -0,0 +1,13 @@
+<div class="container"> + <div class="row"> + <div class="col-sm-12"> + <div class="panel-heading c_blueGrey300"> + <h3 class="panel-title">Tx for each Hour</h3> + </div> + <div class="panel-body"> + <canvas id="bar" class="chart chart-bar" chart-data="data" chart-labels="labels"> + </canvas> + </div> + </div> + </div> +</div>
A
web/views/dateAnalysis/dateAnalysis.js
@@ -0,0 +1,27 @@
+'use strict'; + +angular.module('app.dateAnalysis', ['ngRoute', 'chart.js']) + + .config(['$routeProvider', function($routeProvider) { + $routeProvider.when('/dateAnalysis', { + templateUrl: 'views/dateAnalysis/dateAnalysis.html', + controller: 'DateAnalysisCtrl' + }); + }]) + + .controller('DateAnalysisCtrl', function($scope, $http, $routeParams) { + $scope.data=[]; + $scope.labels=[]; + + $http.get(urlapi + 'houranalysis') + .then(function(data, status, headers, config) { + console.log('data success'); + console.log(data); + + $scope.data = data.data.data; + $scope.labels=data.data.labels; + }, function(data, status, headers, config) { + console.log('data error'); + }); + + });
M
web/views/sankey/sankey.html
→
web/views/sankey/sankey.html
@@ -22,7 +22,12 @@ <div class="panel-heading c_blueGrey300">
<h3 class="panel-title">Sankey</h3> </div> <div class="panel-body"> - <ng-sankey id="sankeyChart" options="options" data="data"></ng-sankey> + <!--<ng-sankey id="sankeyChart" options="options" data="data"></ng-sankey> + --> + <div id="sankeyChart"> + <canvas></canvas> + <svg></svg> + </div> </div> </div> </div>