added web visualizer, added CORS to server
arnaucode idoctnef@openmailbox.org
Mon, 24 Jul 2017 12:38:42 +0200
11 files changed,
276 insertions(+),
47 deletions(-)
M
exploreBlockchain.go
→
exploreBlockchain.go
@@ -43,48 +43,50 @@ and the Vout[1] is the rest of the amount in the original wallet.
Each Tx moves all the wallet amount, and the realTx amount is sent to the destination and the rest of the wallet amount, is send to another owned wallet */ - for k, txHash := range block.Tx { - //first Tx is the Fee - //after first Tx is the Sent Amount - if k > 0 { - th, err := chainhash.NewHashFromStr(txHash) - check(err) - tx, err := client.GetRawTransactionVerbose(th) - check(err) - var originAddress string - for _, Vi := range tx.Vin { - th, err := chainhash.NewHashFromStr(Vi.Txid) + if len(block.Tx) < 10 { + for k, txHash := range block.Tx { + //first Tx is the Fee + //after first Tx is the Sent Amount + if k > 0 { + th, err := chainhash.NewHashFromStr(txHash) check(err) - txVi, err := client.GetRawTransactionVerbose(th) + tx, err := client.GetRawTransactionVerbose(th) check(err) - if len(txVi.Vout[0].ScriptPubKey.Addresses) > 0 { - originAddress = txVi.Vout[0].ScriptPubKey.Addresses[0] + var originAddress string + for _, Vi := range tx.Vin { + th, err := chainhash.NewHashFromStr(Vi.Txid) + check(err) + txVi, err := client.GetRawTransactionVerbose(th) + check(err) + if len(txVi.Vout[0].ScriptPubKey.Addresses) > 0 { + originAddress = txVi.Vout[0].ScriptPubKey.Addresses[0] + } } - } - for _, Vo := range tx.Vout { - totalAmount = totalAmount + Vo.Value + for _, Vo := range tx.Vout { + totalAmount = totalAmount + Vo.Value - var blockTx TxModel - blockTx.Txid = tx.Txid - blockTx.Amount = Vo.Value - blockTx.From = originAddress - blockTx.To = Vo.ScriptPubKey.Addresses[0] - newBlock.Tx = append(newBlock.Tx, blockTx) + var blockTx TxModel + blockTx.Txid = tx.Txid + blockTx.Amount = Vo.Value + blockTx.From = originAddress + blockTx.To = Vo.ScriptPubKey.Addresses[0] + newBlock.Tx = append(newBlock.Tx, blockTx) + } } } - } - if totalAmount > 0 { - newBlock.Amount = totalAmount - saveBlock(blockCollection, newBlock) - fmt.Print("Height: ") - fmt.Println(newBlock.Height) - fmt.Print("Amount: ") - fmt.Println(newBlock.Amount) - fmt.Print("Fee: ") - fmt.Println(newBlock.Fee) - fmt.Println("-----") - realBlocks++ + if totalAmount > 0 { + newBlock.Amount = totalAmount + saveBlock(blockCollection, newBlock) + fmt.Print("Height: ") + fmt.Println(newBlock.Height) + fmt.Print("Amount: ") + fmt.Println(newBlock.Amount) + fmt.Print("Fee: ") + fmt.Println(newBlock.Fee) + fmt.Println("-----") + realBlocks++ + } } //set the next block@@ -96,10 +98,12 @@ var n1 NodeModel
var n2 NodeModel n1.Id = t.From n1.Label = t.From + n1.Title = t.From n1.Value = 1 n1.Shape = "dot" n2.Id = t.To n2.Label = t.To + n2.Title = t.To n2.Value = 1 n2.Shape = "dot"
M
main.go
→
main.go
@@ -10,6 +10,7 @@ mgo "gopkg.in/mgo.v2"
"github.com/btcsuite/btcrpcclient" "github.com/fatih/color" + "github.com/gorilla/handlers" ) var blockCollection *mgo.Collection@@ -51,7 +52,7 @@ log.Printf("%s: %s", label, amount)
} if len(os.Args) > 1 { if os.Args[1] == "-explore" { - fmt.Println("starting to explore blockchain") + color.Blue("starting to explore blockchain") explore(client, config.GenesisBlock) } }@@ -66,7 +67,14 @@
//http server start readServerConfig("./serverConfig.json") color.Green("server running") + fmt.Print("port: ") + color.Green(serverConfig.ServerPort) router := NewRouter() - log.Fatal(http.ListenAndServe(":"+serverConfig.ServerPort, router)) + + headersOk := handlers.AllowedHeaders([]string{"X-Requested-With", "Access-Control-Allow-Origin"}) + originsOk := handlers.AllowedOrigins([]string{"*"}) + methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"}) + log.Fatal(http.ListenAndServe(":"+serverConfig.ServerPort, handlers.CORS(originsOk, headersOk, methodsOk)(router))) + //log.Fatal(http.ListenAndServe(":"+serverConfig.ServerPort, router)) }
M
mongoModels.go
→
mongoModels.go
@@ -16,19 +16,19 @@ Tx []TxModel
} type NodeModel struct { - Id string - Label string - Title string - Group string - Value int - Shape string + Id string `json:"id"` + Label string `json:"label"` + Title string `json:"title"` + Group string `json:"group"` + Value int `json:"value"` + Shape string `json:"shape"` } type EdgeModel struct { Txid string - From string - To string - Label float64 + From string `json:"from"` + To string `json:"to"` + Label float64 `json:"label"` Arrows string } type NetworkModel struct {
M
serverRoutes.go
→
serverRoutes.go
@@ -42,6 +42,7 @@ //ROUTES
func Index(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "ask for recommendations in /r") + //http.FileServer(http.Dir("./web")) } /*
A
web/bower.json
@@ -0,0 +1,16 @@
+{ + "name": "goBlockchainDataAnalysis", + "description": "goBlockchainDataAnalysis", + "version": "0.0.0", + "homepage": "https://github.com/arnaucode/goBlockchainDataAnalysis", + "license": "MIT", + "private": true, + "dependencies": { + "angular": "^1.6.2", + "angular-route": "^1.6.1", + "angular-chart.js": "^1.1.1", + "vis": "^4.18.1", + "materialize": "^0.100.1", + "toastr": "^2.1.3" + } +}
A
web/controllers.js
@@ -0,0 +1,53 @@
+var urlapi = "http://127.0.0.1:3014/"; + +//var urlapi = document.location.href + "api/"; +console.log(urlapi); + +var app = angular.module("webApp", ['chart.js']); +var nodes, edges, container; +var options = { + layout:{ + improvedLayout: false + }/*, + physics:{ + //stabilization: false, + // enabled: false + }*/ +}; +app.controller("webCtrl", function($scope, $http) { + //chart + $scope.labels=[]; + $scope.data=[]; + $scope.nodes=[]; + $scope.edges=[]; + + $http.get(urlapi + 'map') + .then(function (data) { + console.log('data success'); + console.log(data); // for browser console + $scope.nodes=data.data.Nodes; + $scope.edges=data.data.Edges; + console.log($scope.nodes); + console.log($scope.edges); + $scope.showMap(); + //alert("Ara mateix es mostren (entre persones i tweets): " + nodes.length + " nodes."); + //$scope.refreshChart(); + }, function(data){ + console.log('data error'); + console.log(status); + console.log(data); + }); + + $scope.showMap=function(){ + var nodes = $scope.nodes; + var edges = $scope.edges; + + container = document.getElementById('mynetwork'); + var data = { + nodes: nodes, + edges: edges + }; + var network = new vis.Network(container, data, options); + toastr.info("map completed"); + }; +});
A
web/index.html
@@ -0,0 +1,116 @@
+<!DOCTYPE html> +<html> + +<head> + <meta charset=utf-8> + <!--Import Google Icon Font--> + <link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> + <!--Import materialize.css--> + <link type="text/css" rel="stylesheet" href="bower_components/materialize/dist/css/materialize.min.css" media="screen,projection" /> + + <!--Let browser know website is optimized for mobile--> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + + + + <script type="text/javascript" src="bower_components/vis/dist/vis.min.js"></script> + <link href="bower_components/vis/dist/vis.min.css" rel="stylesheet" type="text/css" /> + <link href="bower_components/vis/dist/vis-network.min.css" rel="stylesheet" type="text/css" /> + <style type="text/css"> + #mynetwork { + /*width: 75%;*/ + height: 600px; + border: 1px solid lightgray; + display: inline-block; + top: 0px; + 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; + } + </style> +</head> + +<body> + + + + + <nav> + <div class="nav-wrapper teal lighten-2"> + <a href="#" class="brand-logo">goBlockchainDataAnalysis</a> + <ul id="nav-mobile" class="right hide-on-med-and-down"> + <li><a href="https://github.com/arnaucode/goBlockchainDataAnalysis" target="_blank"><b>Code</b></a></li> + </ul> + </div> + </nav> + + + <div class="row" ng-app="webApp" ng-controller="webCtrl"> + + <div class="col s3 o-height600"> + + <b>Comptes:</b><br> + <div class="input-field col s12"> + <i class="material-icons prefix">search</i> + <input ng-model="userfilter" id="search" type="text" class="validate"> + <label for="search">Search...</label> + </div> + <ul class="collection o-overflowScroll o-height500"> + <li ng-click="clickUser(node)" class="collection-item o-mouseoverGrey" ng-repeat="node in nodes"> + <img ng-src="{{node.image}}" alt="" class="circle"> + <span class="title">{{node.id}}</title> + <i class="material-icons">launch</i> + </a> + </li> + </ul> + </div> + <div id="mynetwork" class="col s9"> + </div> + </div> + <div class="row"> + </div> + + <!--Import jQuery before materialize.js--> + <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script> + <script type="text/javascript" src="bower_components/materialize/dist/js/materialize.min.js"></script> + + <!--<script src="/socket.io/socket.io.js"></script>--> + + <!-- Angular js --> + <script src="bower_components/angular/angular.js"></script> + <script src="bower_components/angular-route/angular-route.js"></script> + + <!-- Angular Chart --> + <script src="bower_components/chart.js/dist/Chart.min.js"></script> + <script src="bower_components/angular-chart.js/dist/angular-chart.min.js"></script> + + <link type="text/css" rel="stylesheet" href="bower_components/toastr/toastr.css"/> + <script type="text/javascript" src="bower_components/toastr/toastr.js"></script> + + <script type="text/javascript" src="controllers.js"></script> + </body> + </html>
A
web/package.json
@@ -0,0 +1,22 @@
+{ + "name": "goBlockchainDataAnalysis", + "private": true, + "version": "0.0.0", + "description": "goBlockchainDataAnalysis", + "repository": "https://github.com/arnaucode/goBlockchainDataAnalysis", + "license": "MIT", + "devDependencies": { + "bower": "^1.7.7", + "http-server": "^0.9.0" + }, + "scripts": { + "postinstall": "bower install", + "prestart": "npm install", + "start": "http-server -p 8080 -c-1 ./" + }, + "dependencies": { + "bower": "latest", + "connect": "latest", + "serve-static": "latest" + } +}
A
web/webserver.js
@@ -0,0 +1,6 @@
+connect = require('connect'); +var serveStatic = require('serve-static'); +connect().use(serveStatic(__dirname)).listen(3010, function(){ + console.log('Server running on 3010...'); +}); +