mirror of
https://github.com/arnaucube/goBlockchainDataAnalysis.git
synced 2026-02-06 19:26:41 +01:00
added web visualizer, added CORS to server
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -16,4 +16,3 @@
|
|||||||
|
|
||||||
/*.conf
|
/*.conf
|
||||||
/*.json
|
/*.json
|
||||||
web
|
|
||||||
|
|||||||
@@ -43,48 +43,50 @@ func explore(client *btcrpcclient.Client, blockHash string) {
|
|||||||
Each Tx moves all the wallet amount, and the realTx amount is sent to the destination
|
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
|
and the rest of the wallet amount, is send to another owned wallet
|
||||||
*/
|
*/
|
||||||
for k, txHash := range block.Tx {
|
if len(block.Tx) < 10 {
|
||||||
//first Tx is the Fee
|
for k, txHash := range block.Tx {
|
||||||
//after first Tx is the Sent Amount
|
//first Tx is the Fee
|
||||||
if k > 0 {
|
//after first Tx is the Sent Amount
|
||||||
th, err := chainhash.NewHashFromStr(txHash)
|
if k > 0 {
|
||||||
check(err)
|
th, err := chainhash.NewHashFromStr(txHash)
|
||||||
tx, err := client.GetRawTransactionVerbose(th)
|
|
||||||
check(err)
|
|
||||||
var originAddress string
|
|
||||||
for _, Vi := range tx.Vin {
|
|
||||||
th, err := chainhash.NewHashFromStr(Vi.Txid)
|
|
||||||
check(err)
|
check(err)
|
||||||
txVi, err := client.GetRawTransactionVerbose(th)
|
tx, err := client.GetRawTransactionVerbose(th)
|
||||||
check(err)
|
check(err)
|
||||||
if len(txVi.Vout[0].ScriptPubKey.Addresses) > 0 {
|
var originAddress string
|
||||||
originAddress = txVi.Vout[0].ScriptPubKey.Addresses[0]
|
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
|
||||||
|
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if totalAmount > 0 {
|
if totalAmount > 0 {
|
||||||
newBlock.Amount = totalAmount
|
newBlock.Amount = totalAmount
|
||||||
saveBlock(blockCollection, newBlock)
|
saveBlock(blockCollection, newBlock)
|
||||||
fmt.Print("Height: ")
|
fmt.Print("Height: ")
|
||||||
fmt.Println(newBlock.Height)
|
fmt.Println(newBlock.Height)
|
||||||
fmt.Print("Amount: ")
|
fmt.Print("Amount: ")
|
||||||
fmt.Println(newBlock.Amount)
|
fmt.Println(newBlock.Amount)
|
||||||
fmt.Print("Fee: ")
|
fmt.Print("Fee: ")
|
||||||
fmt.Println(newBlock.Fee)
|
fmt.Println(newBlock.Fee)
|
||||||
fmt.Println("-----")
|
fmt.Println("-----")
|
||||||
realBlocks++
|
realBlocks++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//set the next block
|
//set the next block
|
||||||
@@ -96,10 +98,12 @@ func explore(client *btcrpcclient.Client, blockHash string) {
|
|||||||
var n2 NodeModel
|
var n2 NodeModel
|
||||||
n1.Id = t.From
|
n1.Id = t.From
|
||||||
n1.Label = t.From
|
n1.Label = t.From
|
||||||
|
n1.Title = t.From
|
||||||
n1.Value = 1
|
n1.Value = 1
|
||||||
n1.Shape = "dot"
|
n1.Shape = "dot"
|
||||||
n2.Id = t.To
|
n2.Id = t.To
|
||||||
n2.Label = t.To
|
n2.Label = t.To
|
||||||
|
n2.Title = t.To
|
||||||
n2.Value = 1
|
n2.Value = 1
|
||||||
n2.Shape = "dot"
|
n2.Shape = "dot"
|
||||||
|
|
||||||
|
|||||||
12
main.go
12
main.go
@@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/btcsuite/btcrpcclient"
|
"github.com/btcsuite/btcrpcclient"
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
|
"github.com/gorilla/handlers"
|
||||||
)
|
)
|
||||||
|
|
||||||
var blockCollection *mgo.Collection
|
var blockCollection *mgo.Collection
|
||||||
@@ -51,7 +52,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
if len(os.Args) > 1 {
|
if len(os.Args) > 1 {
|
||||||
if os.Args[1] == "-explore" {
|
if os.Args[1] == "-explore" {
|
||||||
fmt.Println("starting to explore blockchain")
|
color.Blue("starting to explore blockchain")
|
||||||
explore(client, config.GenesisBlock)
|
explore(client, config.GenesisBlock)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,7 +67,14 @@ func main() {
|
|||||||
//http server start
|
//http server start
|
||||||
readServerConfig("./serverConfig.json")
|
readServerConfig("./serverConfig.json")
|
||||||
color.Green("server running")
|
color.Green("server running")
|
||||||
|
fmt.Print("port: ")
|
||||||
|
color.Green(serverConfig.ServerPort)
|
||||||
router := NewRouter()
|
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))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,19 +16,19 @@ type BlockModel struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type NodeModel struct {
|
type NodeModel struct {
|
||||||
Id string
|
Id string `json:"id"`
|
||||||
Label string
|
Label string `json:"label"`
|
||||||
Title string
|
Title string `json:"title"`
|
||||||
Group string
|
Group string `json:"group"`
|
||||||
Value int
|
Value int `json:"value"`
|
||||||
Shape string
|
Shape string `json:"shape"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type EdgeModel struct {
|
type EdgeModel struct {
|
||||||
Txid string
|
Txid string
|
||||||
From string
|
From string `json:"from"`
|
||||||
To string
|
To string `json:"to"`
|
||||||
Label float64
|
Label float64 `json:"label"`
|
||||||
Arrows string
|
Arrows string
|
||||||
}
|
}
|
||||||
type NetworkModel struct {
|
type NetworkModel struct {
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ var routes = Routes{
|
|||||||
|
|
||||||
func Index(w http.ResponseWriter, r *http.Request) {
|
func Index(w http.ResponseWriter, r *http.Request) {
|
||||||
fmt.Fprintln(w, "ask for recommendations in /r")
|
fmt.Fprintln(w, "ask for recommendations in /r")
|
||||||
|
//http.FileServer(http.Dir("./web"))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
4
web/.gitignore
vendored
Normal file
4
web/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
logs/*
|
||||||
|
!.gitkeep
|
||||||
|
node_modules
|
||||||
|
bower_components
|
||||||
16
web/bower.json
Normal file
16
web/bower.json
Normal file
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
53
web/controllers.js
Normal file
53
web/controllers.js
Normal file
@@ -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");
|
||||||
|
};
|
||||||
|
});
|
||||||
116
web/index.html
Normal file
116
web/index.html
Normal file
@@ -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>
|
||||||
22
web/package.json
Normal file
22
web/package.json
Normal file
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
web/webserver.js
Normal file
6
web/webserver.js
Normal file
@@ -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...');
|
||||||
|
});
|
||||||
|
|
||||||
Reference in New Issue
Block a user