arnaucube
arnaucube/goBlockchainDataAnalysisPublic Self-hosted repository
updated to new version of btcsuite. Implemented blockchain stats on exploring blockchain, and show it in frontend
arnaucode idoctnef@openmailbox.org
Tue, 22 Aug 2017 14:23:16 +0200
commit

9f8fdcd740ecf7a32c708d7a9fdde9608a0d9c2e

parent

d21f0b11320e3bfdf84bd168b148f484b0e5992a

M DevelopmentNotes.md → DevelopmentNotes.md

@@ -2,10 +2,7 @@ # Development Notes

## ToDo list -- Sankey generation without loops - - Backend - - Network Address generation avoiding infinite relation loops - Sankey Address generation without loops - Frontend - After Sankey visualization, go to Network Address visualization and render without Sankey dots

@@ -31,3 +28,5 @@ }

``` - mantain connection with wallet using websockets + +- num address evolution throught time
M addressTree.go → addressTree.go

@@ -45,11 +45,7 @@ }

//need to be fixed when there is a bucle between the addresses (A-->B, B-->C, C-->A) fmt.Println(e.From + " - " + e.To) - //if e.From != e.To && e.From != upLevelEdge.To && e.To != upLevelEdge.From { - //if e.From != e.To { - fmt.Println(endBranch) - fmt.Println(edgeInEdges(network.Edges, edgeUpCheck)) - if edgeInEdges(network.Edges, edgeUpCheck) == false && endBranch == false { + if edgeInEdges(network.Edges, edgeUpCheck) == false && endBranch == false && edgeUpCheck.BlockHeight <= e.BlockHeight && e.To != edgeUpCheck.From { upNetwork = upTree(e.From, network) for _, upN := range upNetwork.Nodes { if nodeInNodes(network.Nodes, upN) == false {
M exploreBlockchain.go → exploreBlockchain.go

@@ -5,10 +5,10 @@ "fmt"

"strconv" "github.com/btcsuite/btcd/chaincfg/chainhash" - "github.com/btcsuite/btcrpcclient" + "github.com/btcsuite/btcd/rpcclient" ) -func explore(client *btcrpcclient.Client, blockHash string) { +func explore(client *rpcclient.Client, blockHash string) { var realBlocks int /*var nOrigin NodeModel nOrigin.Id = "origin"

@@ -39,9 +39,23 @@ newBlock.Time = block.Time

newBlock.DateT = unixTimeToTime(block.Time) newBlock.Date.Year, newBlock.Date.Month, newBlock.Date.Day, newBlock.Date.Hour = decomposeDate(block.Time) + //stats blocks + stats := getStats() + stats.BlockCount++ + if len(block.Tx) > 1 { + stats.RealBlockCount++ + } + updateStats(stats) + for k, txHash := range block.Tx { if k > 0 { realBlocks++ + + //stats txs + stats := getStats() + stats.TxCount++ + updateStats(stats) + fmt.Print("Block Height: ") fmt.Print(block.Height) fmt.Print(", num of Tx: ")
M main.go → main.go

@@ -10,10 +10,11 @@

mgo "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" - "github.com/btcsuite/btcrpcclient" + "github.com/btcsuite/btcd/rpcclient" "github.com/gorilla/handlers" ) +var statsCollection *mgo.Collection var blockCollection *mgo.Collection var txCollection *mgo.Collection var addressCollection *mgo.Collection

@@ -31,6 +32,7 @@ //connect with mongodb

//readMongodbConfig("./mongodbConfig.json") session, err := getSession() check(err) + statsCollection = getCollection(session, "stats") blockCollection = getCollection(session, "blocks") txCollection = getCollection(session, "txs") addressCollection = getCollection(session, "address")

@@ -42,7 +44,7 @@

if len(os.Args) > 1 { if os.Args[1] == "-explore" { // create new client instance - client, err := btcrpcclient.New(&btcrpcclient.ConnConfig{ + client, err := rpcclient.New(&rpcclient.ConnConfig{ HTTPPostMode: true, DisableTLS: true, Host: config.Host + ":" + config.Port,

@@ -77,7 +79,7 @@ log.Printf("Block count: %d", blockCount)

} if os.Args[1] == "-continue" { // create new client instance - client, err := btcrpcclient.New(&btcrpcclient.ConnConfig{ + client, err := rpcclient.New(&rpcclient.ConnConfig{ HTTPPostMode: true, DisableTLS: true, Host: config.Host + ":" + config.Port,
M mongoModels.go → mongoModels.go

@@ -102,3 +102,10 @@ Time int64 `json:"time"`

Date string `json:"date"` Count int `json:"count"` } +type StatsModel struct { + Title string `json:"title"` + RealBlockCount int `json:"realblockcount"` + BlockCount int `json:"blockcount"` + TxCount int `json:"txcount"` + AddrCount int `json:"addrcount"` +}
M mongoOperations.go → mongoOperations.go

@@ -117,6 +117,11 @@ if err != nil {

//address not found, so let's add a new entry err = addressCollection.Insert(address) check(err) + + //stats addr + stats := getStats() + stats.AddrCount++ + updateStats(stats) } } func saveTx(tx TxModel) {
M serverRoutes.go → serverRoutes.go

@@ -23,6 +23,12 @@ "/",

Index, }, Route{ + "Stats", + "Get", + "/stats", + Stats, + }, + Route{ "AllAddresses", "Get", "/alladdresses",

@@ -106,6 +112,16 @@ fmt.Println(newUser)

fmt.Fprintln(w, "new user added: ", newUser.ID) } */ +func Stats(w http.ResponseWriter, r *http.Request) { + ipFilter(w, r) + + stats := getStats() + + jsonResp, err := json.Marshal(stats) + check(err) + + fmt.Fprintln(w, string(jsonResp)) +} func AllAddresses(w http.ResponseWriter, r *http.Request) { ipFilter(w, r)

@@ -154,6 +170,7 @@ if address == "undefined" {

fmt.Fprintln(w, "not valid address") } else { network := addressTree(address) + network.Nodes[0].Shape = "triangle" //convert []resp struct to json jNetwork, err := json.Marshal(network)
A stats.go

@@ -0,0 +1,23 @@

+package main + +import "gopkg.in/mgo.v2/bson" + +func getStats() StatsModel { + var stats StatsModel + err := statsCollection.Find(bson.M{"title": "stats"}).One(&stats) + check(err) + stats.Title = "stats" + return stats +} + +func updateStats(stats StatsModel) { + var oldStats StatsModel + err := statsCollection.Find(bson.M{"title": "stats"}).One(&oldStats) + if err != nil { + err = statsCollection.Insert(stats) + check(err) + } else { + err = statsCollection.Update(bson.M{"title": "stats"}, &stats) + check(err) + } +}
M web/views/main/main.html → web/views/main/main.html

@@ -1,3 +1,45 @@

+<div class="row"> + <div class="col-sm-4"> + <div class="panel"> + <div class="panel-body"> + <h4>{{stats.realblockcount}}/{{stats.blockcount}} Blocks with content</h4> + <div class="progress" style="margin:0;"> + <div class="progress-bar c_blueGrey500" ng-style="blockProgress"></div> + </div> + </div> + </div> + </div> + <div class="col-sm-2"> + <div class="panel"> + <div class="panel-body"> + <h4>{{stats.txcount}} Txs</h4> + <div class="progress" style="margin:0;"> + <div class="progress-bar c_blueGrey500" ng-style="txProgress"></div> + </div> + </div> + </div> + </div> + <div class="col-sm-2"> + <div class="panel"> + <div class="panel-body"> + <h4>{{stats.addrcount}} Addr</h4> + <div class="progress" style="margin:0;"> + <div class="progress-bar c_blueGrey500" ng-style="txProgress"></div> + </div> + </div> + </div> + </div> + <div class="col-sm-4"> + <div class="panel"> + <div class="panel-body"> + <h4>300-500 Min-Max Block Size</h4> + <div class="progress" style="margin:0;"> + <div class="progress-bar c_blueGrey500" ng-style="txProgress"></div> + </div> + </div> + </div> + </div> +</div> <div class="row"> <div class="col-sm-4"> <div class="panel">

@@ -15,31 +57,35 @@ </div>

</div> <div class="col-sm-4"> - <div class="panel-heading c_blueGrey300"> - <h3 class="panel-title">Last 24 hours Tx/Hour - <a ng-href="#!/dateAnalysis" class="pull-right c_blueGrey300">View more</a></h3> - </div> - <div class="panel-body"> - <canvas id="line" class="chart chart-line" chart-data="last24hour.data" chart-labels="last24hour.labels"> - </canvas> - </div> - <div class="panel-heading c_blueGrey300"> - <h3 class="panel-title">Last 7 days Tx/Hour + <div class="panel"> + <div class="panel-heading c_blueGrey300"> + <h3 class="panel-title">Last 24 hours Tx/Hour <a ng-href="#!/dateAnalysis" class="pull-right c_blueGrey300">View more</a></h3> + </div> + <div class="panel-body"> + <canvas id="line" class="chart chart-line" chart-data="last24hour.data" chart-labels="last24hour.labels"> + </canvas> + </div> </div> - <div class="panel-body"> - <canvas id="line" class="chart chart-line" chart-data="last7dayhour.data" chart-labels="last7dayhour.labels" chart-series="last7dayhour.series"> - </canvas> - </div> + <div class="panel"> + <div class="panel-heading c_blueGrey300"> + <h3 class="panel-title">Last 7 days Tx/Hour + <a ng-href="#!/dateAnalysis" class="pull-right c_blueGrey300">View more</a></h3> + </div> + <div class="panel-body"> + <canvas id="line" class="chart chart-line" chart-data="last7dayhour.data" chart-labels="last7dayhour.labels" chart-series="last7dayhour.series"> + </canvas> + </div> + </div> </div> <div class="col-sm-4"> <div class="panel"> <div class="panel-heading c_blueGrey300"> - <h3 class="panel-title">Hours</h3> + <h3 class="panel-title">Tx/Day Last 7 Days</h3> </div> <div class="panel-body"> - <canvas id="doughnut" class="chart chart-doughnut" chart-data="last24hour.data" chart-labels="last24hour.labels"> - </canvas> + <canvas id="horizontal-bar" class="chart chart-horizontal-bar" chart-data="last7day.data" chart-labels="last7day.labels" chart-series="last7day.series"> + </canvas> </div> </div> </div>

@@ -50,7 +96,7 @@ <div class="panel">

<div class="panel-heading c_blueGrey300"> <h3 class="panel-title">Last Tx with amount</h3> </div> - <div class="panel-body" style="max-height: 350px;overflow-y: scroll;"> + <div class="panel-body" style="max-height: 200px;overflow-y: scroll;"> <table class="table table-striped table-hover"> <!--<colgroup> <col class="col-md-2">
M web/views/main/main.js → web/views/main/main.js

@@ -10,13 +10,28 @@ });

}]) .controller('MainCtrl', function($scope, $http) { + $scope.stats = []; + $scope.blockProgress={ + "width": "0%" + }; + $http.get(urlapi + 'stats') + .then(function(data, status, headers, config) { + console.log(data); + $scope.stats = data.data; + var tantpercent = ($scope.stats.realblockcount/$scope.stats.blockcount)*100; + $scope.blockProgress={ + "width": tantpercent+"%" + }; + }, function(data, status, headers, config) { + console.log('data error'); + }); + + //last addr $scope.addresses = []; $http.get(urlapi + 'lastaddr') .then(function(data, status, headers, config) { - console.log('data success'); console.log(data); - $scope.addresses = data.data; }, function(data, status, headers, config) { console.log('data error');

@@ -26,9 +41,7 @@ //last tx

$scope.txs = []; $http.get(urlapi + 'lasttx') .then(function(data, status, headers, config) { - console.log('data success'); console.log(data); - $scope.txs = data.data; }, function(data, status, headers, config) { console.log('data error');

@@ -41,9 +54,7 @@ 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) {

@@ -55,12 +66,26 @@ labels: []

}; $http.get(urlapi + 'last7dayhour') .then(function(data, status, headers, config) { - console.log('data success'); console.log(data); - $scope.last7dayhour.data = data.data.data; $scope.last7dayhour.labels = data.data.labels; $scope.last7dayhour.series = data.data.series; + }, function(data, status, headers, config) { + console.log('data error'); + }); + + $scope.last7day={ + data: [], + labels: [] + }; + + $http.get(urlapi + 'last7day') + .then(function(data, status, headers, config) { + console.log('data success'); + console.log(data); + + $scope.last7day.data = data.data.data; + $scope.last7day.labels=data.data.labels; }, function(data, status, headers, config) { console.log('data error'); });