Browse Source

updated to new version of btcsuite. Implemented blockchain stats on exploring blockchain, and show it in frontend

master
arnaucode 7 years ago
parent
commit
9f8fdcd740
11 changed files with 173 additions and 39 deletions
  1. +2
    -3
      DevelopmentNotes.md
  2. +1
    -5
      addressTree.go
  3. +16
    -2
      exploreBlockchain.go
  4. BIN
      goBlockchainDataAnalysis
  5. +5
    -3
      main.go
  6. +7
    -0
      mongoModels.go
  7. +5
    -0
      mongoOperations.go
  8. +17
    -0
      serverRoutes.go
  9. +23
    -0
      stats.go
  10. +64
    -18
      web/views/main/main.html
  11. +33
    -8
      web/views/main/main.js

+ 2
- 3
DevelopmentNotes.md

@ -2,10 +2,7 @@
## ToDo list ## ToDo list
- Sankey generation without loops
- Backend - Backend
- Network Address generation avoiding infinite relation loops
- Sankey Address generation without loops - Sankey Address generation without loops
- Frontend - Frontend
- After Sankey visualization, go to Network Address visualization and render without Sankey dots - After Sankey visualization, go to Network Address visualization and render without Sankey dots
@ -31,3 +28,5 @@ other
``` ```
- mantain connection with wallet using websockets - mantain connection with wallet using websockets
- num address evolution throught time

+ 1
- 5
addressTree.go

@ -45,11 +45,7 @@ func upTree(address string, network NetworkModel) NetworkModel {
//need to be fixed when there is a bucle between the addresses (A-->B, B-->C, C-->A) //need to be fixed when there is a bucle between the addresses (A-->B, B-->C, C-->A)
fmt.Println(e.From + " - " + e.To) 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) upNetwork = upTree(e.From, network)
for _, upN := range upNetwork.Nodes { for _, upN := range upNetwork.Nodes {
if nodeInNodes(network.Nodes, upN) == false { if nodeInNodes(network.Nodes, upN) == false {

+ 16
- 2
exploreBlockchain.go

@ -5,10 +5,10 @@ import (
"strconv" "strconv"
"github.com/btcsuite/btcd/chaincfg/chainhash" "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 realBlocks int
/*var nOrigin NodeModel /*var nOrigin NodeModel
nOrigin.Id = "origin" nOrigin.Id = "origin"
@ -39,9 +39,23 @@ func explore(client *btcrpcclient.Client, blockHash string) {
newBlock.DateT = unixTimeToTime(block.Time) newBlock.DateT = unixTimeToTime(block.Time)
newBlock.Date.Year, newBlock.Date.Month, newBlock.Date.Day, newBlock.Date.Hour = decomposeDate(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 { for k, txHash := range block.Tx {
if k > 0 { if k > 0 {
realBlocks++ realBlocks++
//stats txs
stats := getStats()
stats.TxCount++
updateStats(stats)
fmt.Print("Block Height: ") fmt.Print("Block Height: ")
fmt.Print(block.Height) fmt.Print(block.Height)
fmt.Print(", num of Tx: ") fmt.Print(", num of Tx: ")

BIN
goBlockchainDataAnalysis


+ 5
- 3
main.go

@ -10,10 +10,11 @@ import (
mgo "gopkg.in/mgo.v2" mgo "gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
"github.com/btcsuite/btcrpcclient"
"github.com/btcsuite/btcd/rpcclient"
"github.com/gorilla/handlers" "github.com/gorilla/handlers"
) )
var statsCollection *mgo.Collection
var blockCollection *mgo.Collection var blockCollection *mgo.Collection
var txCollection *mgo.Collection var txCollection *mgo.Collection
var addressCollection *mgo.Collection var addressCollection *mgo.Collection
@ -31,6 +32,7 @@ func main() {
//readMongodbConfig("./mongodbConfig.json") //readMongodbConfig("./mongodbConfig.json")
session, err := getSession() session, err := getSession()
check(err) check(err)
statsCollection = getCollection(session, "stats")
blockCollection = getCollection(session, "blocks") blockCollection = getCollection(session, "blocks")
txCollection = getCollection(session, "txs") txCollection = getCollection(session, "txs")
addressCollection = getCollection(session, "address") addressCollection = getCollection(session, "address")
@ -42,7 +44,7 @@ func main() {
if len(os.Args) > 1 { if len(os.Args) > 1 {
if os.Args[1] == "-explore" { if os.Args[1] == "-explore" {
// create new client instance // create new client instance
client, err := btcrpcclient.New(&btcrpcclient.ConnConfig{
client, err := rpcclient.New(&rpcclient.ConnConfig{
HTTPPostMode: true, HTTPPostMode: true,
DisableTLS: true, DisableTLS: true,
Host: config.Host + ":" + config.Port, Host: config.Host + ":" + config.Port,
@ -77,7 +79,7 @@ func main() {
} }
if os.Args[1] == "-continue" { if os.Args[1] == "-continue" {
// create new client instance // create new client instance
client, err := btcrpcclient.New(&btcrpcclient.ConnConfig{
client, err := rpcclient.New(&rpcclient.ConnConfig{
HTTPPostMode: true, HTTPPostMode: true,
DisableTLS: true, DisableTLS: true,
Host: config.Host + ":" + config.Port, Host: config.Host + ":" + config.Port,

+ 7
- 0
mongoModels.go

@ -102,3 +102,10 @@ type DateCountModel struct {
Date string `json:"date"` Date string `json:"date"`
Count int `json:"count"` 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"`
}

+ 5
- 0
mongoOperations.go

@ -117,6 +117,11 @@ func saveAddress(address AddressModel) {
//address not found, so let's add a new entry //address not found, so let's add a new entry
err = addressCollection.Insert(address) err = addressCollection.Insert(address)
check(err) check(err)
//stats addr
stats := getStats()
stats.AddrCount++
updateStats(stats)
} }
} }
func saveTx(tx TxModel) { func saveTx(tx TxModel) {

+ 17
- 0
serverRoutes.go

@ -22,6 +22,12 @@ var routes = Routes{
"/", "/",
Index, Index,
}, },
Route{
"Stats",
"Get",
"/stats",
Stats,
},
Route{ Route{
"AllAddresses", "AllAddresses",
"Get", "Get",
@ -106,6 +112,16 @@ func NewUser(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "new user added: ", newUser.ID) 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) { func AllAddresses(w http.ResponseWriter, r *http.Request) {
ipFilter(w, r) ipFilter(w, r)
@ -154,6 +170,7 @@ func AddressNetwork(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "not valid address") fmt.Fprintln(w, "not valid address")
} else { } else {
network := addressTree(address) network := addressTree(address)
network.Nodes[0].Shape = "triangle"
//convert []resp struct to json //convert []resp struct to json
jNetwork, err := json.Marshal(network) jNetwork, err := json.Marshal(network)

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

+ 64
- 18
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="row">
<div class="col-sm-4"> <div class="col-sm-4">
<div class="panel"> <div class="panel">
@ -15,31 +57,35 @@
</div> </div>
<div class="col-sm-4"> <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> <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>
<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>
<div class="col-sm-4"> <div class="col-sm-4">
<div class="panel"> <div class="panel">
<div class="panel-heading c_blueGrey300"> <div class="panel-heading c_blueGrey300">
<h3 class="panel-title">Hours</h3>
<h3 class="panel-title">Tx/Day Last 7 Days</h3>
</div> </div>
<div class="panel-body"> <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> </div>
</div> </div>
@ -50,7 +96,7 @@
<div class="panel-heading c_blueGrey300"> <div class="panel-heading c_blueGrey300">
<h3 class="panel-title">Last Tx with amount</h3> <h3 class="panel-title">Last Tx with amount</h3>
</div> </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"> <table class="table table-striped table-hover">
<!--<colgroup> <!--<colgroup>
<col class="col-md-2"> <col class="col-md-2">

+ 33
- 8
web/views/main/main.js

@ -10,13 +10,28 @@ angular.module('app.main', ['ngRoute'])
}]) }])
.controller('MainCtrl', function($scope, $http) { .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 //last addr
$scope.addresses = []; $scope.addresses = [];
$http.get(urlapi + 'lastaddr') $http.get(urlapi + 'lastaddr')
.then(function(data, status, headers, config) { .then(function(data, status, headers, config) {
console.log('data success');
console.log(data); console.log(data);
$scope.addresses = data.data; $scope.addresses = data.data;
}, function(data, status, headers, config) { }, function(data, status, headers, config) {
console.log('data error'); console.log('data error');
@ -26,9 +41,7 @@ angular.module('app.main', ['ngRoute'])
$scope.txs = []; $scope.txs = [];
$http.get(urlapi + 'lasttx') $http.get(urlapi + 'lasttx')
.then(function(data, status, headers, config) { .then(function(data, status, headers, config) {
console.log('data success');
console.log(data); console.log(data);
$scope.txs = data.data; $scope.txs = data.data;
}, function(data, status, headers, config) { }, function(data, status, headers, config) {
console.log('data error'); console.log('data error');
@ -41,9 +54,7 @@ angular.module('app.main', ['ngRoute'])
}; };
$http.get(urlapi + 'last24hour') $http.get(urlapi + 'last24hour')
.then(function(data, status, headers, config) { .then(function(data, status, headers, config) {
console.log('data success');
console.log(data); console.log(data);
$scope.last24hour.data = data.data.data; $scope.last24hour.data = data.data.data;
$scope.last24hour.labels = data.data.labels; $scope.last24hour.labels = data.data.labels;
}, function(data, status, headers, config) { }, function(data, status, headers, config) {
@ -55,13 +66,27 @@ angular.module('app.main', ['ngRoute'])
}; };
$http.get(urlapi + 'last7dayhour') $http.get(urlapi + 'last7dayhour')
.then(function(data, status, headers, config) { .then(function(data, status, headers, config) {
console.log('data success');
console.log(data); console.log(data);
$scope.last7dayhour.data = data.data.data; $scope.last7dayhour.data = data.data.data;
$scope.last7dayhour.labels = data.data.labels; $scope.last7dayhour.labels = data.data.labels;
$scope.last7dayhour.series = data.data.series; $scope.last7dayhour.series = data.data.series;
}, function(data, status, headers, config) { }, function(data, status, headers, config) {
console.log('data error'); 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');
});
}); });

Loading…
Cancel
Save