arnaucube
arnaucube/goBlockchainDataAnalysisPublic Self-hosted repository
date and hour analysis added
arnaucode idoctnef@openmailbox.org
Sat, 29 Jul 2017 16:08:10 +0200
commit

2c67f57b7b1f62062b629cd5548c58e0275845a1

parent

017aa8c73328d992175a10b281f1f254ccdd4d4e

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/navbar.html → web/views/navbar.html

@@ -11,9 +11,10 @@ <a class="navbar-brand" href="/">goBlockchainDataAnalysis</a>

</div> <div class="navbar-collapse collapse navbar-responsive-collapse"> <ul class="nav navbar-nav"> - <li class="active"><a href="#!/network">Network</a></li> + <li><a href="#!/network">Network</a></li> <li><a href="#!/addressNetwork">Address Network</a></li> <li><a href="#!/sankey">Sankey diagram</a></li> + <li class="active"><a href="#!/dateAnalysis">Date Analysis</a></li> <li><a href="javascript:void(0)">Timeline</a></li> </ul> <form class="navbar-form navbar-left">
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>