From 42bfe7cda1e0d8b36fcd572fb26218e4eab718ae Mon Sep 17 00:00:00 2001 From: arnaucode Date: Mon, 14 Aug 2017 21:19:12 +0200 Subject: [PATCH] fixed generation of tx and address relations structure. Improved webapp layout. Not finished addressTree generation algorithm --- README.md | 31 ++--- addressTree.go | 4 +- dateAnalysis.go | 6 +- exploreBlockchain.go | 48 ++++++-- mongoModels.go | 1 + serverRoutes.go | 22 +++- web/css/style.css | 39 +++++++ web/index.html | 43 ++----- web/views/addressNetwork/addressNetwork.html | 40 ++++--- web/views/dateAnalysis/dateAnalysis.html | 16 ++- web/views/main/main.html | 114 +++++++++++-------- web/views/main/main.js | 63 +++++++--- web/views/navbar.html | 2 +- web/views/network/network.html | 48 ++++---- web/views/sankey/sankey.html | 46 ++++---- web/views/sidebar.html | 34 ++++++ 16 files changed, 347 insertions(+), 210 deletions(-) create mode 100644 web/css/style.css create mode 100644 web/views/sidebar.html diff --git a/README.md b/README.md index a772b2e..53110b6 100644 --- a/README.md +++ b/README.md @@ -2,21 +2,10 @@ blockchain data analysis, written in Go -![goBlockchainDataAnalysis](https://raw.githubusercontent.com/arnaucode/goBlockchainDataAnalysis/master/goBlockchainDataAnalysis01.png "goBlockchainDataAnalysis") - - -![goBlockchainDataAnalysis](https://raw.githubusercontent.com/arnaucode/goBlockchainDataAnalysis/master/goBlockchainDataAnalysis02.png "goBlockchainDataAnalysis") - - -![goBlockchainDataAnalysis](https://raw.githubusercontent.com/arnaucode/goBlockchainDataAnalysis/master/goBlockchainDataAnalysis05.png "goBlockchainDataAnalysis") - - -![goBlockchainDataAnalysis](https://raw.githubusercontent.com/arnaucode/goBlockchainDataAnalysis/master/goBlockchainDataAnalysis04.png "goBlockchainDataAnalysis") - ### Install -1. Nodejs & NPM https://nodejs.org/ +1. Nodejs & NPM https://nodejs.org/ --> to serve the web, not necessary if the web files are in a webserver 2. MongoDB https://www.mongodb.com/ -3. Faircoin wallet https://download.faircoin.world/ +3. Faircoin wallet https://download.faircoin.world/, or the Cryptocurrency desired wallet 4. goBlockchainDataAnalysis https://github.com/arnaucode/goBlockchainDataAnalysis ### Configure @@ -54,6 +43,7 @@ sudo service mongod start ``` ./faircoind -txindex -reindex-chainstate ``` +Wait until the entire blockchain is downloaded. 3. Run explorer, to fill the database ``` @@ -80,3 +70,18 @@ Webapp will run on 127.0.0.1:8080 - Frontend - AngularJS https://angularjs.org/ - Angular-Bootstrap-Material https://tilwinjoy.github.io/angular-bootstrap-material + + +### Some screenshots + + +![goBlockchainDataAnalysis](https://raw.githubusercontent.com/arnaucode/goBlockchainDataAnalysis/master/goBlockchainDataAnalysis05.png "goBlockchainDataAnalysis") + + +![goBlockchainDataAnalysis](https://raw.githubusercontent.com/arnaucode/goBlockchainDataAnalysis/master/goBlockchainDataAnalysis01.png "goBlockchainDataAnalysis") + + +![goBlockchainDataAnalysis](https://raw.githubusercontent.com/arnaucode/goBlockchainDataAnalysis/master/goBlockchainDataAnalysis02.png "goBlockchainDataAnalysis") + + +![goBlockchainDataAnalysis](https://raw.githubusercontent.com/arnaucode/goBlockchainDataAnalysis/master/goBlockchainDataAnalysis04.png "goBlockchainDataAnalysis") diff --git a/addressTree.go b/addressTree.go index dd639bd..9b83a43 100644 --- a/addressTree.go +++ b/addressTree.go @@ -1,6 +1,8 @@ package main import ( + "fmt" + "gopkg.in/mgo.v2/bson" ) @@ -19,7 +21,6 @@ func upTree(address string, network NetworkModel) NetworkModel { edges := []EdgeModel{} err = edgeCollection.Find(bson.M{"to": address}).All(&edges) check(err) - for _, e := range edges { if edgeInEdges(network.Edges, e) == false { network.Edges = append(network.Edges, e) @@ -31,6 +32,7 @@ func upTree(address string, network NetworkModel) NetworkModel { check(err) */ + fmt.Println(e.From + " - " + e.To) if e.From != e.To { upNetwork = upTree(e.From, network) for _, upN := range upNetwork.Nodes { diff --git a/dateAnalysis.go b/dateAnalysis.go index d633203..484a86b 100644 --- a/dateAnalysis.go +++ b/dateAnalysis.go @@ -16,13 +16,13 @@ func timeToDate(blockTime int64) string { panic(err) } tm := time.Unix(i, 0) - fmt.Println(tm) + //fmt.Println(tm) stringDate := tm.String() - fmt.Println(stringDate) + //fmt.Println(stringDate) return stringDate } func hourAnalysis(e EdgeModel, blockTime int64) { - fmt.Println(blockTime) + //fmt.Println(blockTime) date := timeToDate(blockTime) date_hour := strings.Split(date, " ")[1] hour := strings.Split(date_hour, ":")[0] diff --git a/exploreBlockchain.go b/exploreBlockchain.go index 8057aa9..9f189c4 100644 --- a/exploreBlockchain.go +++ b/exploreBlockchain.go @@ -26,7 +26,7 @@ func explore(client *btcrpcclient.Client, blockHash string) { block, err := client.GetBlockVerbose(bh) check(err) - if block.Height > 160 { + if block.Height > 0 { for k, txHash := range block.Tx { if k > 0 { realBlocks++ @@ -42,12 +42,25 @@ func explore(client *btcrpcclient.Client, blockHash string) { tx, err := client.GetRawTransactionVerbose(th) check(err) + //save Tx + var nTx NodeModel + nTx.Id = txHash + nTx.Label = txHash + nTx.Title = txHash + nTx.Group = strconv.FormatInt(block.Height, 10) + nTx.Value = 1 + nTx.Shape = "square" + nTx.Type = "tx" + saveNode(nodeCollection, nTx) + var originAddresses []string var outputAddresses []string + var outputAmount []float64 for _, Vo := range tx.Vout { //if Vo.Value > 0 { for _, outputAddr := range Vo.ScriptPubKey.Addresses { outputAddresses = append(outputAddresses, outputAddr) + outputAmount = append(outputAmount, Vo.Value) var n2 NodeModel n2.Id = outputAddr n2.Label = outputAddr @@ -55,6 +68,7 @@ func explore(client *btcrpcclient.Client, blockHash string) { n2.Group = strconv.FormatInt(block.Height, 10) n2.Value = 1 n2.Shape = "dot" + n2.Type = "address" saveNode(nodeCollection, n2) } //} @@ -71,25 +85,35 @@ func explore(client *btcrpcclient.Client, blockHash string) { n1.Id = originAddr n1.Label = originAddr n1.Title = originAddr - n1.Group = string(block.Height) + n1.Group = strconv.FormatInt(block.Height, 10) n1.Value = 1 n1.Shape = "dot" + n1.Type = "address" 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) + for k, outputAddr := range outputAddresses { + var eIn EdgeModel + eIn.From = originAddr + eIn.To = txHash + eIn.Label = txVi.Vout[Vi.Vout].Value + eIn.Txid = tx.Txid + eIn.Arrows = "to" + eIn.BlockHeight = block.Height + saveEdge(edgeCollection, eIn) + + var eOut EdgeModel + eOut.From = txHash + eOut.To = outputAddr + eOut.Label = outputAmount[k] + eOut.Txid = tx.Txid + eOut.Arrows = "to" + eOut.BlockHeight = block.Height + saveEdge(edgeCollection, eOut) //date analysis //dateAnalysis(e, tx.Time) //hour analysis - hourAnalysis(e, tx.Time) + hourAnalysis(eIn, tx.Time) } } } else { diff --git a/mongoModels.go b/mongoModels.go index c4f79fb..6a85803 100644 --- a/mongoModels.go +++ b/mongoModels.go @@ -22,6 +22,7 @@ type NodeModel struct { Group string `json:"group"` Value int `json:"value"` Shape string `json:"shape"` + Type string `json:"type"` } type EdgeModel struct { diff --git a/serverRoutes.go b/serverRoutes.go index 3743cdd..51264a8 100644 --- a/serverRoutes.go +++ b/serverRoutes.go @@ -26,6 +26,12 @@ var routes = Routes{ "/alladdresses", AllAddresses, }, + Route{ + "GetLastAddr", + "Get", + "/lastaddr", + GetLastAddr, + }, Route{ "GetLastTx", "Get", @@ -93,7 +99,7 @@ func AllAddresses(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, string(jsonNodes)) } -func GetLastTx(w http.ResponseWriter, r *http.Request) { +func GetLastAddr(w http.ResponseWriter, r *http.Request) { ipFilter(w, r) nodes := []NodeModel{} @@ -106,6 +112,19 @@ func GetLastTx(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, string(jNodes)) } +func GetLastTx(w http.ResponseWriter, r *http.Request) { + ipFilter(w, r) + + edges := []EdgeModel{} + err := edgeCollection.Find(bson.M{}).Limit(10).Sort("-$natural").All(&edges) + check(err) + + //convert []resp struct to json + jsonData, err := json.Marshal(edges) + check(err) + + fmt.Fprintln(w, string(jsonData)) +} func AddressNetwork(w http.ResponseWriter, r *http.Request) { ipFilter(w, r) @@ -125,7 +144,6 @@ func AddressNetwork(w http.ResponseWriter, r *http.Request) { } func AddressSankey(w http.ResponseWriter, r *http.Request) { ipFilter(w, r) - vars := mux.Vars(r) address := vars["address"] if address == "undefined" { diff --git a/web/css/style.css b/web/css/style.css new file mode 100644 index 0000000..4bdfd4f --- /dev/null +++ b/web/css/style.css @@ -0,0 +1,39 @@ +#mynetwork { + /*background: black;*/ +} + +.o-height600 { + max-height: 600px!important; +} + +.o-height500 { + max-height: 500px!important; +} + +.o-height300 { + max-height: 300px!important; +} + +.o-overflowScroll { + /*max-height: 600px;*/ + overflow-y: scroll; +} + +.o-mouseoverGrey { + background: white; + cursor: pointer; +} + +.o-mouseoverGrey:hover { + background: #cccccc; +} + + +/* sidebar */ +.o_sidebar a{ + color: white; +} +.o_sidebar a:hover{ + background: #9E9E9E!important; + color: white; +} diff --git a/web/index.html b/web/index.html index 8fe287d..c2cf056 100644 --- a/web/index.html +++ b/web/index.html @@ -14,48 +14,25 @@ + - - +
+
+
+
+
+
+
+
+
-
diff --git a/web/views/addressNetwork/addressNetwork.html b/web/views/addressNetwork/addressNetwork.html index 398a287..b63b0c5 100644 --- a/web/views/addressNetwork/addressNetwork.html +++ b/web/views/addressNetwork/addressNetwork.html @@ -1,29 +1,27 @@ -
-
-
-
-

All addresses

+
+
+
+

All addresses

+
+
+
+
-
-
- -
-
-
-

{{node.id}}

+
+
+

{{node.id}}

- -
+
-
-
-

Address history Network Map

-
-
-
-
+
+
+
+

Address history Network Map

+
+
+
diff --git a/web/views/dateAnalysis/dateAnalysis.html b/web/views/dateAnalysis/dateAnalysis.html index a03f74b..4f1415c 100644 --- a/web/views/dateAnalysis/dateAnalysis.html +++ b/web/views/dateAnalysis/dateAnalysis.html @@ -1,13 +1,11 @@ -
-
-
-
-

Tx for each Hour

-
-
- +
+
+
+

Tx for each Hour

+
+
+ -
diff --git a/web/views/main/main.html b/web/views/main/main.html index 11a3126..2b06005 100644 --- a/web/views/main/main.html +++ b/web/views/main/main.html @@ -1,57 +1,75 @@ -
-
-
-
-
-

Last addresses

-
-
-
-
-

{{node.id}}

-
+
+
+
+
+

Last addresses

+
+
+
+
+

{{node.id}}

-
-
-
-

Last transactions

-
-
- - - - - - - - - - - - - - - - - - - -
HashFromDatenºSubtx
- txhash - {{tx.f}}{{tx.date}}{{tx.subtx.length}}View
-
+ +
+
+
+

Tx/Hour

+
+
+ + +
+
+
+
+
+

Other

+
+
+ +
-
-
-
-

Other

-
-
-
+
+
+
+
+
+
+

Last Tx with amount

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
BlockHeightFromToAmount
{{tx.blockheight}}{{tx.from}}{{tx.to}}{{tx.label}}View
diff --git a/web/views/main/main.js b/web/views/main/main.js index fb6bd1d..04de367 100644 --- a/web/views/main/main.js +++ b/web/views/main/main.js @@ -2,22 +2,49 @@ angular.module('app.main', ['ngRoute']) -.config(['$routeProvider', function($routeProvider) { - $routeProvider.when('/main', { - templateUrl: 'views/main/main.html', - controller: 'MainCtrl' - }); -}]) - -.controller('MainCtrl', function($scope, $http) { - $scope.addresses = []; - $http.get(urlapi + 'lasttx') - .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'); + .config(['$routeProvider', function($routeProvider) { + $routeProvider.when('/main', { + templateUrl: 'views/main/main.html', + controller: 'MainCtrl' }); -}); + }]) + + .controller('MainCtrl', function($scope, $http) { + //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'); + }); + + //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'); + }); + + //date analysis + $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'); + }); + }); diff --git a/web/views/navbar.html b/web/views/navbar.html index a171768..147bb65 100644 --- a/web/views/navbar.html +++ b/web/views/navbar.html @@ -14,7 +14,7 @@
  • Network
  • Address Network
  • Sankey diagram
  • -
  • Date Analysis
  • +
  • Date Analysis
  • Timeline