Browse Source

date and hour analysis added

master
arnaucode 7 years ago
parent
commit
2c67f57b7b
13 changed files with 231 additions and 67 deletions
  1. +64
    -0
      dateAnalysis.go
  2. +68
    -64
      exploreBlockchain.go
  3. BIN
      goBlockchainDataAbalysis.gif
  4. BIN
      goBlockchainDataAnalysis04.png
  5. +4
    -0
      main.go
  6. +14
    -0
      mongoModels.go
  7. +30
    -0
      serverRoutes.go
  8. +2
    -1
      web/app.js
  9. +1
    -0
      web/index.html
  10. +13
    -0
      web/views/dateAnalysis/dateAnalysis.html
  11. +27
    -0
      web/views/dateAnalysis/dateAnalysis.js
  12. +2
    -1
      web/views/navbar.html
  13. +6
    -1
      web/views/sankey/sankey.html

+ 64
- 0
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)
}
}

+ 68
- 64
exploreBlockchain.go

@ -26,80 +26,84 @@ func explore(client *btcrpcclient.Client, blockHash string) {
block, err := client.GetBlockVerbose(bh) block, err := client.GetBlockVerbose(bh)
check(err) 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) check(err)
txVi, err := client.GetRawTransactionVerbose(th)
tx, err := client.GetRawTransactionVerbose(th)
check(err) 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 //set the next block
blockHash = block.NextHash blockHash = block.NextHash
} }

BIN
goBlockchainDataAbalysis.gif

Before After
Width: 600  |  Height: 338  |  Size: 3.2 MiB

BIN
goBlockchainDataAnalysis04.png

Before After
Width: 1254  |  Height: 690  |  Size: 25 KiB

+ 4
- 0
main.go

@ -16,6 +16,8 @@ import (
var blockCollection *mgo.Collection var blockCollection *mgo.Collection
var nodeCollection *mgo.Collection var nodeCollection *mgo.Collection
var edgeCollection *mgo.Collection var edgeCollection *mgo.Collection
var dateCountCollection *mgo.Collection
var hourCountCollection *mgo.Collection
func main() { func main() {
//read goBlockchainDataAbalysis config //read goBlockchainDataAbalysis config
@ -28,6 +30,8 @@ func main() {
blockCollection = getCollection(session, "blocks") blockCollection = getCollection(session, "blocks")
nodeCollection = getCollection(session, "nodes") nodeCollection = getCollection(session, "nodes")
edgeCollection = getCollection(session, "edges") edgeCollection = getCollection(session, "edges")
dateCountCollection = getCollection(session, "dateCounts")
hourCountCollection = getCollection(session, "hourCounts")
// create new client instance // create new client instance
client, err := btcrpcclient.New(&btcrpcclient.ConnConfig{ client, err := btcrpcclient.New(&btcrpcclient.ConnConfig{

+ 14
- 0
mongoModels.go

@ -53,3 +53,17 @@ type SankeyModel struct {
Nodes []SankeyNodeModel `json:"nodes"` Nodes []SankeyNodeModel `json:"nodes"`
Links []SankeyLinkModel `json:"links"` 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"`
}

+ 30
- 0
serverRoutes.go

@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"sort"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
@ -43,6 +44,12 @@ var routes = Routes{
"/map", "/map",
NetworkMap, NetworkMap,
}, },
Route{
"GetHourAnalysis",
"Get",
"/houranalysis",
GetHourAnalysis,
},
/* /*
Route{ Route{
"SelectItem", "SelectItem",
@ -200,3 +207,26 @@ func SelectItem(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "user: "+userid+", selects item: "+itemid) 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))
}

+ 2
- 1
web/app.js

@ -12,7 +12,8 @@ angular.module('webApp', [
'app.main', 'app.main',
'app.network', 'app.network',
'app.addressNetwork', 'app.addressNetwork',
'app.sankey'
'app.sankey',
'app.dateAnalysis'
]). ]).
config(['$locationProvider', '$routeProvider', function($locationProvider, $routeProvider) { config(['$locationProvider', '$routeProvider', function($locationProvider, $routeProvider) {
$locationProvider.hashPrefix('!'); $locationProvider.hashPrefix('!');

+ 1
- 0
web/index.html

@ -95,6 +95,7 @@
<script src="views/network/network.js"></script> <script src="views/network/network.js"></script>
<script src="views/addressNetwork/addressNetwork.js"></script> <script src="views/addressNetwork/addressNetwork.js"></script>
<script src="views/sankey/sankey.js"></script> <script src="views/sankey/sankey.js"></script>
<script src="views/dateAnalysis/dateAnalysis.js"></script>
</body> </body>
</html> </html>

+ 13
- 0
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>

+ 27
- 0
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');
});
});

+ 2
- 1
web/views/navbar.html

@ -11,9 +11,10 @@
</div> </div>
<div class="navbar-collapse collapse navbar-responsive-collapse"> <div class="navbar-collapse collapse navbar-responsive-collapse">
<ul class="nav navbar-nav"> <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="#!/addressNetwork">Address Network</a></li>
<li><a href="#!/sankey">Sankey diagram</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> <li><a href="javascript:void(0)">Timeline</a></li>
</ul> </ul>
<form class="navbar-form navbar-left"> <form class="navbar-form navbar-left">

+ 6
- 1
web/views/sankey/sankey.html

@ -22,7 +22,12 @@
<h3 class="panel-title">Sankey</h3> <h3 class="panel-title">Sankey</h3>
</div> </div>
<div class="panel-body"> <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> </div>
</div> </div>

Loading…
Cancel
Save