mirror of
https://github.com/arnaucube/goBlockchainDataAnalysis.git
synced 2026-02-06 19:26:41 +01:00
updated to new version of btcsuite. Implemented blockchain stats on exploring blockchain, and show it in frontend
This commit is contained in:
@@ -2,10 +2,7 @@
|
||||
|
||||
## 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 @@ other
|
||||
```
|
||||
|
||||
- mantain connection with wallet using websockets
|
||||
|
||||
- num address evolution throught time
|
||||
@@ -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)
|
||||
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 {
|
||||
|
||||
@@ -5,10 +5,10 @@ import (
|
||||
"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 @@ func explore(client *btcrpcclient.Client, blockHash string) {
|
||||
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: ")
|
||||
|
||||
Binary file not shown.
8
main.go
8
main.go
@@ -10,10 +10,11 @@ import (
|
||||
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 @@ func main() {
|
||||
//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 @@ func main() {
|
||||
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 @@ func main() {
|
||||
}
|
||||
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,
|
||||
|
||||
@@ -102,3 +102,10 @@ type DateCountModel struct {
|
||||
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"`
|
||||
}
|
||||
|
||||
@@ -117,6 +117,11 @@ func saveAddress(address AddressModel) {
|
||||
//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) {
|
||||
|
||||
@@ -22,6 +22,12 @@ var routes = Routes{
|
||||
"/",
|
||||
Index,
|
||||
},
|
||||
Route{
|
||||
"Stats",
|
||||
"Get",
|
||||
"/stats",
|
||||
Stats,
|
||||
},
|
||||
Route{
|
||||
"AllAddresses",
|
||||
"Get",
|
||||
@@ -106,6 +112,16 @@ func NewUser(w http.ResponseWriter, r *http.Request) {
|
||||
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 @@ func AddressNetwork(w http.ResponseWriter, r *http.Request) {
|
||||
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)
|
||||
|
||||
23
stats.go
Normal file
23
stats.go
Normal file
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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 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-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">
|
||||
|
||||
@@ -10,13 +10,28 @@ angular.module('app.main', ['ngRoute'])
|
||||
}])
|
||||
|
||||
.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 @@ angular.module('app.main', ['ngRoute'])
|
||||
$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 @@ angular.module('app.main', ['ngRoute'])
|
||||
};
|
||||
$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,13 +66,27 @@ angular.module('app.main', ['ngRoute'])
|
||||
};
|
||||
$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');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user